src/EditProductTab3.cpp

changeset 190
bb6c06910f0f
parent 187
91af2c697345
child 191
7446ee2fb427
equal deleted inserted replaced
189:722a4eed545d 190:bb6c06910f0f
107 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); 107 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
108 ui->fermentablesTable->setItem(i, 7, item); 108 ui->fermentablesTable->setItem(i, 7, item);
109 109
110 item = new QTableWidgetItem(QString("%1 Kg").arg(product->fermentables.at(i).f_inventory, 4, 'f', 3, '0')); 110 item = new QTableWidgetItem(QString("%1 Kg").arg(product->fermentables.at(i).f_inventory, 4, 'f', 3, '0'));
111 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); 111 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
112 if (product->fermentables.at(i).f_inventory < product->fermentables.at(i).f_amount)
113 item->setForeground(QBrush(QColor(Qt::red)));
112 ui->fermentablesTable->setItem(i, 8, item); 114 ui->fermentablesTable->setItem(i, 8, item);
113 115
114 if (product->fermentables.at(i).f_added < 4) { 116 if (product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE) {
115 item = new QTableWidgetItem(QString("%1%").arg(product->fermentables.at(i).f_percentage, 2, 'f', 1, '0')); 117 item = new QTableWidgetItem(QString("%1%").arg(product->fermentables.at(i).f_percentage, 2, 'f', 1, '0'));
116 } else { 118 } else {
117 item = new QTableWidgetItem(QString("")); // Blank for bottling and kegging. 119 item = new QTableWidgetItem(QString("")); // Blank for bottling and kegging.
118 } 120 }
119 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); 121 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
120 ui->fermentablesTable->setItem(i, 9, item); 122 ui->fermentablesTable->setItem(i, 9, item);
121 123
122 to100Fermentables(i); 124 to100Fermentables(i);
123 125
124 /* Add the Delete row button */ 126 /* Add the Delete row button */
125 pWidget = new QWidget(); 127 if (product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE) {
126 QPushButton* btn_dele = new QPushButton(); 128 pWidget = new QWidget();
127 btn_dele->setObjectName(QString("%1").arg(i)); /* Send row with the button */ 129 QPushButton* btn_dele = new QPushButton();
128 btn_dele->setText(tr("Delete")); 130 btn_dele->setObjectName(QString("%1").arg(i)); /* Send row with the button */
129 connect(btn_dele, SIGNAL(clicked()), this, SLOT(deleteFermentRow_clicked())); 131 btn_dele->setText(tr("Delete"));
130 pLayout = new QHBoxLayout(pWidget); 132 connect(btn_dele, SIGNAL(clicked()), this, SLOT(deleteFermentRow_clicked()));
131 pLayout->addWidget(btn_dele); 133 pLayout = new QHBoxLayout(pWidget);
132 pLayout->setContentsMargins(5, 0, 5, 0); 134 pLayout->addWidget(btn_dele);
133 pWidget->setLayout(pLayout); 135 pLayout->setContentsMargins(5, 0, 5, 0);
134 ui->fermentablesTable->setCellWidget(i, 11, pWidget); 136 pWidget->setLayout(pLayout);
135 137 ui->fermentablesTable->setCellWidget(i, 11, pWidget);
136 pWidget = new QWidget(); 138
137 QPushButton* btn_edit = new QPushButton(); 139 pWidget = new QWidget();
138 btn_edit->setObjectName(QString("%1").arg(i)); /* Send row with the button */ 140 QPushButton* btn_edit = new QPushButton();
139 btn_edit->setText(tr("Edit")); 141 btn_edit->setObjectName(QString("%1").arg(i)); /* Send row with the button */
140 connect(btn_edit, SIGNAL(clicked()), this, SLOT(editFermentRow_clicked())); 142 btn_edit->setText(tr("Edit"));
141 pLayout = new QHBoxLayout(pWidget); 143 connect(btn_edit, SIGNAL(clicked()), this, SLOT(editFermentRow_clicked()));
142 pLayout->addWidget(btn_edit); 144 pLayout = new QHBoxLayout(pWidget);
143 pLayout->setContentsMargins(5, 0, 5, 0); 145 pLayout->addWidget(btn_edit);
144 pWidget->setLayout(pLayout); 146 pLayout->setContentsMargins(5, 0, 5, 0);
145 ui->fermentablesTable->setCellWidget(i, 12, pWidget); 147 pWidget->setLayout(pLayout);
148 ui->fermentablesTable->setCellWidget(i, 12, pWidget);
149 } else {
150 item = new QTableWidgetItem("");
151 item->setToolTip(tr("Edit this from the package tab"));
152 ui->fermentablesTable->setItem(i, 11, item);
153 item = new QTableWidgetItem("");
154 item->setToolTip(tr("Edit this from the package tab"));
155 ui->fermentablesTable->setItem(i, 12, item);
156 }
146 } 157 }
147 } 158 }
148 159
149 160
150 void EditProduct::calcFermentables() 161 void EditProduct::calcFermentables()
151 { 162 {
152 int i; 163 int i;
153 double psugar = 0, pcara = 0, d, s = 0, x, color; 164 double psugar = 0, pcara = 0, d, s = 0, x, cw, color;
154 double vol = 0; // Volume sugars after boil 165 double vol = 0; // Volume sugars after boil
155 double addedS = 0; // Added sugars after boil 166 double addedS = 0; // Added sugars after boil
156 double addedmass = 0; // Added mass after boil 167 double addedmass = 0; // Added mass after boil
157 double mvol = 0; // Mash volume 168 double mvol = 0; // Mash volume
158 double lintner = 0; // Total product lintner 169 double lintner = 0; // Total product lintner
163 double mashtemp = 0; // Average mash temperature 174 double mashtemp = 0; // Average mash temperature
164 double mashinfuse = 0; // Mash infuse amount 175 double mashinfuse = 0; // Mash infuse amount
165 double colort = 0; // Colors srm * vol totals 176 double colort = 0; // Colors srm * vol totals
166 double colorh = 0; // Colors ebc * vol * kt 177 double colorh = 0; // Colors ebc * vol * kt
167 double colorn = 0; // Colors ebc * pt * pct 178 double colorn = 0; // Colors ebc * pt * pct
179 double bv = 0.925; // Beer loss efficiency
180 double sr = 0.95; // Mash and sparge efficiency
168 181
169 qDebug() << "calcFermentables()"; 182 qDebug() << "calcFermentables()";
170 183
171 /* 184 /*
172 * Get average mashtemp and mashtime from the Mash schedule. 185 * Get average mashtemp and mashtime from the Mash schedule.
175 if (product->mashs.size() > 0) { 188 if (product->mashs.size() > 0) {
176 for (i = 0; i < product->mashs.size(); i++) { 189 for (i = 0; i < product->mashs.size(); i++) {
177 if (product->mashs.at(i).step_type == 0) // Infusion 190 if (product->mashs.at(i).step_type == 0) // Infusion
178 mashinfuse += product->mashs.at(i).step_infuse_amount; 191 mashinfuse += product->mashs.at(i).step_infuse_amount;
179 if (product->mashs.at(i).step_temp < 75) { // Ignore mashout 192 if (product->mashs.at(i).step_temp < 75) { // Ignore mashout
180 mashtime += product->mashs.at(i).step_time; 193 double timem = product->mashs.at(i).step_time;
181 mashtemp += product->mashs.at(i).step_time * product->mashs.at(i).step_temp; 194 if (i > 0)
195 timem += product->mashs.at(i).ramp_time;
196 mashtime += timem;
197 mashtemp += timem * product->mashs.at(i).step_temp;
182 } 198 }
183 } 199 }
200 mashtime += 5; // Correction for missing last ramp_time.
184 mashtemp = mashtemp / mashtime; 201 mashtemp = mashtemp / mashtime;
185 mvol = mashinfuse; 202 mvol = mashinfuse;
186 qDebug() << " mash time" << mashtime << "temp" << mashtemp << "infuse" << mashinfuse; 203 qDebug() << " mash time" << mashtime << "temp" << mashtemp << "infuse" << mashinfuse;
187 } else { 204 } else {
188 qDebug() << " no mash schedule"; 205 qDebug() << " no mash schedule";
221 ui->mash_kgEdit->setValue(0); 238 ui->mash_kgEdit->setValue(0);
222 return; 239 return;
223 } 240 }
224 qDebug() << " adjust to 100" << product->fermentables_use100; 241 qDebug() << " adjust to 100" << product->fermentables_use100;
225 242
243 product->fermentables_ok = true;
226 product->mashs_kg = 0; 244 product->mashs_kg = 0;
227 for (i = 0; i < product->fermentables.size(); i++) { 245 for (i = 0; i < product->fermentables.size(); i++) {
228 if (product->fermentables.at(i).f_type == 1 && product->fermentables.at(i).f_added < 4) // Sugars 246 if (product->fermentables.at(i).f_type == FERMENTABLE_TYPE_SUGAR && product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE)
229 psugar += product->fermentables.at(i).f_percentage; 247 psugar += product->fermentables.at(i).f_percentage;
230 if (product->fermentables.at(i).f_graintype == 2 && product->fermentables.at(i).f_added < 4) // Crystal/Cara 248 if (product->fermentables.at(i).f_graintype == FERMENTABLE_GRAINTYPE_CRYSTAL && product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE)
231 pcara += product->fermentables.at(i).f_percentage; 249 pcara += product->fermentables.at(i).f_percentage;
232 d = product->fermentables.at(i).f_amount * (product->fermentables.at(i).f_yield / 100) * (1 - product->fermentables.at(i).f_moisture / 100); 250 d = product->fermentables.at(i).f_amount * (product->fermentables.at(i).f_yield / 100) * (1 - product->fermentables.at(i).f_moisture / 100);
233 if (product->fermentables.at(i).f_added == 0) { // Mash 251 if (product->fermentables.at(i).f_added == FERMENTABLE_ADDED_MASH) {
234 if (mvol > 0) { // If mash volume is known 252 if (mvol > 0) { // If mash volume is known
235 mvol += product->fermentables.at(i).f_amount * product->fermentables.at(i).f_moisture / 100; 253 mvol += product->fermentables.at(i).f_amount * product->fermentables.at(i).f_moisture / 100;
236 s += d; 254 s += d;
237 } 255 }
238 d = product->efficiency / 100 * d; 256 d = product->efficiency / 100 * d;
239 sugarsm += d; 257 sugarsm += d;
240 product->mashs_kg += product->fermentables.at(i).f_amount; 258 product->mashs_kg += product->fermentables.at(i).f_amount;
241 } 259 }
242 if (product->fermentables.at(i).f_added == 0 || product->fermentables.at(i).f_added == 1) // Mash or boil 260 if (product->fermentables.at(i).f_added == FERMENTABLE_ADDED_MASH || product->fermentables.at(i).f_added == FERMENTABLE_ADDED_BOIL)
243 sugarsf += d; 261 sugarsf += d;
244 if (product->fermentables.at(i).f_added == 2 || product->fermentables.at(i).f_added == 3) { // Fermentation or lagering 262 if (product->fermentables.at(i).f_added == FERMENTABLE_ADDED_FERMENTATION || product->fermentables.at(i).f_added == FERMENTABLE_ADDED_LAGERING) {
245 x = (product->fermentables.at(i).f_yield / 100) * (1 - product->fermentables.at(i).f_moisture / 100); 263 x = (product->fermentables.at(i).f_yield / 100) * (1 - product->fermentables.at(i).f_moisture / 100);
246 addedS += product->fermentables.at(i).f_amount * x; 264 addedS += product->fermentables.at(i).f_amount * x;
247 addedmass += product->fermentables.at(i).f_amount; 265 addedmass += product->fermentables.at(i).f_amount;
248 vol += (x * sugardensity + (1 - x) * 1) * product->fermentables.at(i).f_amount; 266 vol += (x * sugardensity + (1 - x) * 1) * product->fermentables.at(i).f_amount;
249 } 267 }
250 if (product->fermentables.at(i).f_added == 0 && 268 if (product->fermentables.at(i).f_added == FERMENTABLE_ADDED_MASH &&
251 (product->fermentables.at(i).f_type == 0 || product->fermentables.at(i).f_type == 4) && 269 (product->fermentables.at(i).f_type == FERMENTABLE_TYPE_GRAIN || product->fermentables.at(i).f_type == FERMENTABLE_TYPE_ADJUCT) &&
252 product->fermentables.at(i).f_color < 50) { 270 product->fermentables.at(i).f_color < 50) {
253 lintner += product->fermentables.at(i).f_diastatic_power * product->fermentables.at(i).f_amount; 271 lintner += product->fermentables.at(i).f_diastatic_power * product->fermentables.at(i).f_amount;
254 } 272 }
255 if (product->fermentables.at(i).f_added < 4) { 273 if (product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE) {
256 colort += product->fermentables.at(i).f_amount * Utils::ebc_to_srm(product->fermentables.at(i).f_color); 274 colort += product->fermentables.at(i).f_amount * Utils::ebc_to_srm(product->fermentables.at(i).f_color);
257 colorh += product->fermentables.at(i).f_amount * product->fermentables.at(i).f_color * Utils::get_kt(product->fermentables.at(i).f_color); 275 colorh += product->fermentables.at(i).f_amount * product->fermentables.at(i).f_color * Utils::get_kt(product->fermentables.at(i).f_color);
258 colorn += (product->fermentables.at(i).f_percentage / 100) * product->fermentables.at(i).f_color; // For 8.6 Pt wort. 276 colorn += (product->fermentables.at(i).f_percentage / 100) * product->fermentables.at(i).f_color; // For 8.6 Pt wort.
259 } 277 }
260 if (product->fermentables.at(i).f_added == 4) { // Bottle priming 278 if (product->fermentables.at(i).f_added == FERMENTABLE_ADDED_BOTTLE) { // Bottle priming
261 ui->bottle_sug_weightShow->setValue(product->fermentables.at(i).f_amount * 1000); 279 ui->bottle_sug_weightShow->setValue(product->fermentables.at(i).f_amount * 1000);
262 // product->fermentables.at(i).f_name select in dropdown 280 // product->fermentables.at(i).f_name select in dropdown
263 } 281 }
264 if (product->fermentables.at(i).f_added == 5) { // Keg priming 282 if (product->fermentables.at(i).f_added == FERMENTABLE_ADDED_KEGS) { // Keg priming
265 283
266 } 284 }
267 } 285 /* Check supplies */
286 if ((((product->inventory_reduced <= PROD_STAGE_BREW) && (product->fermentables.at(i).f_added <= FERMENTABLE_ADDED_BOIL)) ||
287 ((product->inventory_reduced <= PROD_STAGE_PRIMARY) && (product->fermentables.at(i).f_added == FERMENTABLE_ADDED_FERMENTATION)) ||
288 ((product->inventory_reduced <= PROD_STAGE_TERTIARY) && (product->fermentables.at(i).f_added == FERMENTABLE_ADDED_LAGERING)) ||
289 ((product->inventory_reduced <= PROD_STAGE_PACKAGE) && (product->fermentables.at(i).f_added == FERMENTABLE_ADDED_BOTTLE)) ||
290 ((product->inventory_reduced <= PROD_STAGE_PACKAGE) && (product->fermentables.at(i).f_added == FERMENTABLE_ADDED_KEGS))) &&
291 product->fermentables.at(i).f_inventory < product->fermentables.at(i).f_amount) {
292 product->fermentables_ok = false;
293 }
294 }
295 qDebug() << " supplies" << product->fermentables_ok;
268 qDebug() << " colort" << colort << "colorh" << colorh << "colorn" << colorn; 296 qDebug() << " colort" << colort << "colorh" << colorh << "colorn" << colorn;
269 qDebug() << " psugar" << psugar << "pcara" << pcara << "mvol" << mvol; 297 qDebug() << " psugar" << psugar << "pcara" << pcara << "mvol" << mvol;
270 qDebug() << " sugarsf" << sugarsf << "sugarsm" << sugarsm; 298 qDebug() << " sugarsf" << sugarsf << "sugarsm" << sugarsm;
271 299
272 double v = s / sugardensity + mvol; 300 double v = s / sugardensity + mvol;
273 s = 1000 * s / (v * 10); //deg. Plato 301 s = 1000 * s / (v * 10); //deg. Plato
274 product->est_mash_sg = Utils::plato_to_sg(s); 302 product->est_mash_sg = Utils::plato_to_sg(s);
275 ui->brew_mashsgShow->setValue(product->est_mash_sg); 303 ui->brew_mashsgShow->setValue(product->est_mash_sg);
276 304
277 double og = Utils::estimate_sg(sugarsf + addedS, product->batch_size); 305 /* Estimate total recipe OG */
278 qDebug() << " OG" << ui->est_ogEdit->value() << og; 306 product->est_og = Utils::estimate_sg(sugarsf + addedS, product->batch_size);
279 product->est_og = og; 307 qDebug() << " OG" << ui->est_ogEdit->value() << product->est_og;
280 ui->est_ogEdit->setValue(og); 308 ui->est_ogEdit->setValue(product->est_og);
281 ui->est_og2Edit->setValue(og); 309 ui->est_og2Edit->setValue(product->est_og);
282 ui->est_og4Edit->setValue(og); 310 ui->est_og4Edit->setValue(product->est_og);
283 ui->est_ogShow->setValue(og); 311 ui->est_ogShow->setValue(product->est_og);
284 312
313 /* Estimate SG in kettle after boil */
285 product->est_og3 = Utils::estimate_sg(sugarsf, product->batch_size); 314 product->est_og3 = Utils::estimate_sg(sugarsf, product->batch_size);
286 ui->brew_aboilsgShow->setValue(product->est_og3); 315 ui->brew_aboilsgShow->setValue(product->est_og3);
287 316
317 /* Estimate SG in kettle before boil */
288 product->preboil_sg = Utils::estimate_sg(sugarsm, product->boil_size); 318 product->preboil_sg = Utils::estimate_sg(sugarsm, product->boil_size);
289 ui->brew_preboilsgShow->setValue(product->preboil_sg); 319 ui->brew_preboilsgShow->setValue(product->preboil_sg);
290 qDebug() << " preboil SG" << product->preboil_sg; 320 qDebug() << " preboil SG" << product->preboil_sg;
291 321
292 /* 322 /*
323 * Recalculate volumes
324 */
325 double aboil_volume = product->batch_size;
326 if (product->brew_aboil_volume > 0)
327 aboil_volume = product->brew_aboil_volume / 1.04; // Volume @ 20 degrees.
328 if (product->brew_fermenter_tcloss == 0) {
329 product->brew_fermenter_tcloss = product->eq_trub_chiller_loss;
330 ui->brew_trublossEdit->setValue(product->brew_fermenter_tcloss);
331 }
332 product->brew_fermenter_volume = aboil_volume - product->brew_fermenter_tcloss + product->brew_fermenter_extrawater;
333 ui->brew_tofermentEdit->setValue(product->brew_fermenter_volume);
334 /* Calculate SG in fermenter */
335 double ogx = product->brew_aboil_sg;
336 if (ogx < 1.002)
337 ogx = product->est_og3;
338 double topw = product->brew_fermenter_extrawater;
339
340 if (product->brew_fermenter_volume > 0) {
341 double sug = Utils::sg_to_plato(ogx) * product->brew_fermenter_volume * ogx / 100; //kg of sugar in
342 sug += addedS; //kg
343
344 if ((product->brew_fermenter_volume * ogx + addedmass) > 0) {
345 double pt = 100 * sug / (product->brew_fermenter_volume * ogx + addedmass + topw);
346 product->og = product->brew_fermenter_sg = round(Utils::plato_to_sg(pt) * 10000) / 10000.0;
347 ui->brew_fermentsgShow->setValue(product->brew_fermenter_sg);
348 // color
349 if (product->color_method == 4) { // Naudts
350 product->brew_fermenter_color = round(((pt / 8.6) * colorn) + (product->boil_time / 60));
351 } else if (product->color_method == 3) { // Hans Halberstadt
352 product->brew_fermenter_color = round((4.46 * bv * sr) / (aboil_volume + topw) * colorh);
353 } else {
354 cw = colort / (aboil_volume + topw) * 8.34436;
355 product->brew_fermenter_color = Utils::kw_to_ebc(product->color_method, cw);
356 }
357 ui->brew_fermentcolorShow->setValue(product->brew_fermenter_color);
358 ui->brew_fermentcolorShow->setStyleSheet(Utils::ebc_to_style(product->brew_fermenter_color));
359 }
360 } else {
361 // Negative volume
362 product->brew_fermenter_sg = product->brew_fermenter_color = 0;
363 ui->brew_fermentsgShow->setValue(0);
364 ui->brew_fermentcolorShow->setStyleSheet(0);
365 ui->brew_fermentcolorShow->setValue(0);
366 }
367
368 /*
293 * Color of the wort 369 * Color of the wort
294 */ 370 */
295 if (product->color_method == 4) { // Naudts 371 if (product->color_method == 4) { // Naudts
296 color = round(((Utils::sg_to_plato(og) / 8.6) * colorn) + (product->boil_time / 60)); 372 color = round(((Utils::sg_to_plato(product->est_og) / 8.6) * colorn) + (product->boil_time / 60));
297 } else if (product->color_method == 3) { // Hans Halberstadt 373 } else if (product->color_method == 3) { // Hans Halberstadt
298 double bv = 0.925; // Beer loss efficiency
299 double sr = 0.95; // Mash and sparge efficiency
300 color = round((4.46 * bv * sr) / product->batch_size * colorh); 374 color = round((4.46 * bv * sr) / product->batch_size * colorh);
301 } else { 375 } else {
302 double cw = colort / product->batch_size * 8.34436; 376 cw = colort / product->batch_size * 8.34436;
303 color = Utils::kw_to_ebc(product->color_method, cw); 377 color = Utils::kw_to_ebc(product->color_method, cw);
304 //qDebug() << " oud EBC" << color << "new EBC" << Utils::kw_to_newebc(product->color_method, cw) << "SRM" << Utils::kw_to_srm(product->color_method, cw); 378 //qDebug() << " oud EBC" << color << "new EBC" << Utils::kw_to_newebc(product->color_method, cw) << "SRM" << Utils::kw_to_srm(product->color_method, cw);
305 } 379 }
306 qDebug() << " color" << ui->est_colorEdit->value() << color << product->est_color; 380 qDebug() << " color" << ui->est_colorEdit->value() << color << product->est_color;
307 product->est_color = color; 381 product->est_color = color;
325 399
326 /* 400 /*
327 * Calculate the apparant attenuation. 401 * Calculate the apparant attenuation.
328 */ 402 */
329 double svg = 0; 403 double svg = 0;
404 double initcells = 0;
330 if (product->yeasts.size() > 0) { 405 if (product->yeasts.size() > 0) {
331 for (i = 0; i < product->yeasts.size(); i++) { 406 for (i = 0; i < product->yeasts.size(); i++) {
332 if (product->yeasts.at(i).y_use == 0) { // Used in primary 407 if (product->yeasts.at(i).y_use == 0) { // Used in primary
333 if (product->yeasts.at(i).y_attenuation > svg) 408 if (product->yeasts.at(i).y_attenuation > svg)
334 svg = product->yeasts.at(i).y_attenuation; // Take the highest if multiple yeasts. 409 svg = product->yeasts.at(i).y_attenuation; // Take the highest if multiple yeasts.
335 } 410 }
411 if (product->yeasts.at(i).y_form == 0)
412 initcells += (product->yeasts.at(i).y_cells / 1000000000) * product->yeasts.at(i).y_amount * (product->starter_viability / 100);
413 else
414 initcells += (product->yeasts.at(i).y_cells / 1000000) * product->yeasts.at(i).y_amount * (product->starter_viability / 100);
336 // TODO: brett or others in secondary. 415 // TODO: brett or others in secondary.
416 product->yeasts_ok = true;
417 if ((((product->inventory_reduced <= PROD_STAGE_PRIMARY) && (product->yeasts.at(i).y_use == 0)) || // Primary
418 ((product->inventory_reduced <= PROD_STAGE_SECONDARY) && (product->yeasts.at(i).y_use == 1)) || // Secondary
419 ((product->inventory_reduced <= PROD_STAGE_TERTIARY) && (product->yeasts.at(i).y_use == 2)) || // Tertiary
420 ((product->inventory_reduced <= PROD_STAGE_PACKAGE) && (product->yeasts.at(i).y_use == 3))) && // Bottle
421 (product->yeasts.at(i).y_inventory < product->yeasts.at(i).y_amount)) {
422 product->yeasts_ok = false;
423 }
337 } 424 }
338 qDebug() << " SVG" << svg; 425 qDebug() << " SVG" << svg;
339 } 426 }
427 calcSupplies();
340 if (svg == 0) 428 if (svg == 0)
341 svg = 77.0; 429 svg = 77.0;
342 ui->est_svgEdit->setValue(svg); 430 ui->est_svgEdit->setValue(svg);
343 431
344 double fg;
345 if (product->mashs_kg > 0 && mashinfuse > 0 && mashtime > 0 && mashtemp > 0) 432 if (product->mashs_kg > 0 && mashinfuse > 0 && mashtime > 0 && mashtemp > 0)
346 fg = Utils::estimate_fg(psugar, pcara, mashinfuse / product->mashs_kg, mashtime, mashtemp, svg, og); 433 product->est_fg = Utils::estimate_fg(psugar, pcara, mashinfuse / product->mashs_kg, mashtime, mashtemp, svg, product->est_og);
347 else 434 else
348 fg = Utils::estimate_fg(psugar, pcara, 0, 0, 0, svg, og); 435 product->est_fg = Utils::estimate_fg(psugar, pcara, 0, 0, 0, svg, product->est_og);
349 qDebug() << " FG" << ui->est_fgEdit->value() << fg; 436 qDebug() << " FG" << ui->est_fgEdit->value() << product->est_fg;
350 product->est_fg = fg; 437 ui->est_fgEdit->setValue(product->est_fg);
351 ui->est_fgEdit->setValue(fg); 438 ui->est_fg3Edit->setValue(product->est_fg);
352 ui->est_fg3Edit->setValue(fg); 439 ui->est_fgShow->setValue(product->est_fg);
353 ui->est_fgShow->setValue(fg); 440
354 441 /*
355 double abv = Utils::abvol(og, fg); 442 * Calculate the final values if available.
356 qDebug() << " ABV" << ui->est_abvEdit->value() << abv; 443 */
357 ui->est_abvEdit->setValue(abv); 444 if ((product->stage >= 6) && (product->fg > 0.990) && (product->fg < product->brew_fermenter_sg)) {
358 ui->est_abv2Edit->setValue(abv); 445
359 ui->est_abvShow->setValue(abv); 446 }
360 product->est_abv = abv; 447
448 product->est_abv = Utils::abvol(product->est_og, product->est_fg);
449 qDebug() << " ABV" << ui->est_abvEdit->value() << product->est_abv;
450 ui->est_abvEdit->setValue(product->est_abv);
451 ui->est_abv2Edit->setValue(product->est_abv);
452 ui->est_abvShow->setValue(product->est_abv);
361 453
362 /* 454 /*
363 * Calculate kilocalories/liter. Formula from brouwhulp. 455 * Calculate kilocalories/liter. Formula from brouwhulp.
364 * Take the alcohol and sugar parts and then combine. 456 * Take the alcohol and sugar parts and then combine.
365 */ 457 */
366 double alc = 1881.22 * fg * (og - fg) / (1.775 - og); 458 double alc = 1881.22 * product->est_fg * (product->est_og - product->est_fg) / (1.775 - product->est_og);
367 double sug = 3550 * fg * (0.1808 * og + 0.8192 * fg - 1.0004); 459 double sug = 3550 * product->est_fg * (0.1808 * product->est_og + 0.8192 * product->est_fg - 1.0004);
368 ui->calEdit->setValue(round((alc + sug) / (12 * 0.0295735296))); 460 ui->calEdit->setValue(round((alc + sug) / (12 * 0.0295735296)));
369 461
370 // Bottle priming 462 // Bottle priming
371 double priming_total = 0; 463 double priming_total = 0;
372 for (i = 0; i < product->fermentables.size(); i++) { 464 for (i = 0; i < product->fermentables.size(); i++) {
373 if (product->fermentables.at(i).f_added == 4) { 465 if (product->fermentables.at(i).f_added == FERMENTABLE_ADDED_BOTTLE) {
374 priming_total += ((product->fermentables.at(i).f_yield / 100) * (1 - product->fermentables.at(i).f_moisture / 100)) * 466 priming_total += ((product->fermentables.at(i).f_yield / 100) * (1 - product->fermentables.at(i).f_moisture / 100)) *
375 product->fermentables.at(i).f_amount; 467 product->fermentables.at(i).f_amount;
376 qDebug() << " priming" << product->fermentables.at(i).f_amount << "total" << priming_total; 468 qDebug() << " priming" << product->fermentables.at(i).f_amount << "total" << priming_total;
377 } 469 }
378 } 470 }
398 double d, amount; 490 double d, amount;
399 double efficiency = product->efficiency; 491 double efficiency = product->efficiency;
400 double sug = Utils::sg_to_plato(og) * product->batch_size * og / 100.0; // total amount of sugars in kg. 492 double sug = Utils::sg_to_plato(og) * product->batch_size * og / 100.0; // total amount of sugars in kg.
401 493
402 for (i = 0; i < product->fermentables.size(); i++) { 494 for (i = 0; i < product->fermentables.size(); i++) {
403 if (product->fermentables.at(i).f_added < 4) { 495 if (product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE) {
404 d = product->fermentables.at(i).f_percentage / 100.0 * 496 d = product->fermentables.at(i).f_percentage / 100.0 *
405 (product->fermentables.at(i).f_yield / 100.0) * 497 (product->fermentables.at(i).f_yield / 100.0) *
406 (1 - product->fermentables.at(i).f_moisture / 100.0); 498 (1 - product->fermentables.at(i).f_moisture / 100.0);
407 if (product->fermentables.at(i).f_added == 0) // Mash 499 if (product->fermentables.at(i).f_added == FERMENTABLE_ADDED_MASH)
408 d = efficiency / 100.0 * d; 500 d = efficiency / 100.0 * d;
409 tot += d; 501 tot += d;
410 } 502 }
411 } 503 }
412 if (tot) 504 if (tot)
475 newf.f_name = "Select one"; 567 newf.f_name = "Select one";
476 newf.f_origin = ""; 568 newf.f_origin = "";
477 newf.f_supplier = ""; 569 newf.f_supplier = "";
478 newf.f_amount = 0; 570 newf.f_amount = 0;
479 newf.f_cost = 0; 571 newf.f_cost = 0;
480 newf.f_type = 0; 572 newf.f_type = FERMENTABLE_TYPE_GRAIN;
481 newf.f_yield = 0; 573 newf.f_yield = 0;
482 newf.f_color = 0; 574 newf.f_color = 0;
483 newf.f_coarse_fine_diff = 0; 575 newf.f_coarse_fine_diff = 0;
484 newf.f_moisture = 0; 576 newf.f_moisture = 0;
485 newf.f_diastatic_power = 0; 577 newf.f_diastatic_power = 0;
486 newf.f_protein = 0; 578 newf.f_protein = 0;
487 newf.f_dissolved_protein = 0; 579 newf.f_dissolved_protein = 0;
488 newf.f_max_in_batch = 100; 580 newf.f_max_in_batch = 100;
489 newf.f_graintype = 0; 581 newf.f_graintype = FERMENTABLE_GRAINTYPE_BASE;
490 newf.f_added = 0; 582 newf.f_added = FERMENTABLE_ADDED_MASH;
491 newf.f_recommend_mash = true; 583 newf.f_recommend_mash = true;
492 newf.f_add_after_boil = false; 584 newf.f_add_after_boil = false;
493 newf.f_adjust_to_total_100 = false; 585 newf.f_adjust_to_total_100 = false;
494 newf.f_percentage = 0; 586 newf.f_percentage = 0;
495 newf.f_di_ph = 0; 587 newf.f_di_ph = 0;
522 /* 614 /*
523 * Recalculate the percentages on the rows left. 615 * Recalculate the percentages on the rows left.
524 */ 616 */
525 double total = 0; 617 double total = 0;
526 for (int i = 0; i < product->fermentables.size(); i++) 618 for (int i = 0; i < product->fermentables.size(); i++)
527 if (product->fermentables.at(i).f_added < 4) // Only before bottle/kegging 619 if (product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE) // Only before bottle/kegging
528 total += product->fermentables.at(i).f_amount; 620 total += product->fermentables.at(i).f_amount;
529 for (int i = 0; i < product->fermentables.size(); i++) 621 for (int i = 0; i < product->fermentables.size(); i++)
530 if (product->fermentables.at(i).f_added < 4) 622 if (product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE)
531 product->fermentables[i].f_percentage = product->fermentables.at(i).f_amount / total * 100; 623 product->fermentables[i].f_percentage = product->fermentables.at(i).f_amount / total * 100;
532 624
533 is_changed(); 625 is_changed();
534 emit refreshAll(); 626 emit refreshAll();
535 } 627 }
538 void EditProduct::ferment_amount_changed(double val) 630 void EditProduct::ferment_amount_changed(double val)
539 { 631 {
540 QTableWidgetItem *item; 632 QTableWidgetItem *item;
541 double total = 0, perc; 633 double total = 0, perc;
542 634
543 if (product->fermentables_use100 && product->fermentables.at(product->fermentables_row).f_added < 4) 635 if (product->fermentables_use100 && product->fermentables.at(product->fermentables_row).f_added < FERMENTABLE_ADDED_BOTTLE)
544 return; 636 return;
545 637
546 qDebug() << "ferment_amount_changed()" << product->fermentables_row << val; 638 qDebug() << "ferment_amount_changed()" << product->fermentables_row << val;
547 639
548 product->fermentables[product->fermentables_row].f_amount = val; 640 product->fermentables[product->fermentables_row].f_amount = val;
549 item = new QTableWidgetItem(QString("%1 Kg").arg(val, 4, 'f', 3, '0')); 641 item = new QTableWidgetItem(QString("%1 Kg").arg(val, 4, 'f', 3, '0'));
550 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); 642 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
551 ui->fermentablesTable->setItem(product->fermentables_row, 7, item); 643 ui->fermentablesTable->setItem(product->fermentables_row, 7, item);
552 644
553 for (int i = 0; i < product->fermentables.size(); i++) 645 for (int i = 0; i < product->fermentables.size(); i++)
554 if (product->fermentables.at(i).f_added < 4) // Only before bottle/kegging 646 if (product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE) // Only before bottle/kegging
555 total += product->fermentables.at(i).f_amount; 647 total += product->fermentables.at(i).f_amount;
556 /* 648 /*
557 * Recalculate the percentages 649 * Recalculate the percentages
558 */ 650 */
559 for (int i = 0; i < product->fermentables.size(); i++) { 651 for (int i = 0; i < product->fermentables.size(); i++) {
560 if (product->fermentables.at(i).f_added < 4) { 652 if (product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE) {
561 perc = product->fermentables.at(i).f_amount / total * 100; 653 perc = product->fermentables.at(i).f_amount / total * 100;
562 product->fermentables[i].f_percentage = perc; 654 product->fermentables[i].f_percentage = perc;
563 item = new QTableWidgetItem(QString("%1%").arg(perc, 2, 'f', 1, '0')); 655 item = new QTableWidgetItem(QString("%1%").arg(perc, 2, 'f', 1, '0'));
564 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); 656 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
565 ui->fermentablesTable->setItem(i, 8, item); 657 ui->fermentablesTable->setItem(i, 8, item);
583 /* 675 /*
584 * Since we have arrived here, adjust_to_100 is active and 676 * Since we have arrived here, adjust_to_100 is active and
585 * this is not the entry to be adjusted to 100. 677 * this is not the entry to be adjusted to 100.
586 */ 678 */
587 for (int i = 0; i < product->fermentables.size(); i++) { 679 for (int i = 0; i < product->fermentables.size(); i++) {
588 if (product->fermentables.at(i).f_added < 4) // Only before bottle/kegging 680 if (product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE) // Only before bottle/kegging
589 total += product->fermentables.at(i).f_amount; 681 total += product->fermentables.at(i).f_amount;
590 if (product->fermentables.at(i).f_adjust_to_total_100) 682 if (product->fermentables.at(i).f_adjust_to_total_100)
591 row100 = i; 683 row100 = i;
592 } 684 }
593 double oldperc = product->fermentables.at(product->fermentables_row).f_percentage; 685 double oldperc = product->fermentables.at(product->fermentables_row).f_percentage;
623 715
624 void EditProduct::ferment_to100_changed(bool val) 716 void EditProduct::ferment_to100_changed(bool val)
625 { 717 {
626 qDebug() << "ferment_to100_changed()" << product->fermentables_row << val << product->fermentables_use100; 718 qDebug() << "ferment_to100_changed()" << product->fermentables_row << val << product->fermentables_use100;
627 719
628 if (product->fermentables.at(product->fermentables_row).f_added >= 4) { 720 if (product->fermentables.at(product->fermentables_row).f_added >= FERMENTABLE_ADDED_BOTTLE) {
629 const QSignalBlocker blocker1(to100Edit); 721 const QSignalBlocker blocker1(to100Edit);
630 product->fermentables[product->fermentables_row].f_adjust_to_total_100 = false; 722 product->fermentables[product->fermentables_row].f_adjust_to_total_100 = false;
631 to100Edit->setChecked(false); 723 to100Edit->setChecked(false);
632 return; 724 return;
633 } 725 }
682 774
683 /* 775 /*
684 * Search the fermentable pointed by the index and instock flag. 776 * Search the fermentable pointed by the index and instock flag.
685 */ 777 */
686 QString sql = "SELECT name,origin,supplier,cost,type,yield,color,coarse_fine_diff,moisture,diastatic_power,protein,dissolved_protein,max_in_batch," 778 QString sql = "SELECT name,origin,supplier,cost,type,yield,color,coarse_fine_diff,moisture,diastatic_power,protein,dissolved_protein,max_in_batch,"
687 "graintype,recommend_mash,add_after_boil,di_ph,acid_to_ph_57 FROM inventory_fermentables "; 779 "graintype,recommend_mash,add_after_boil,di_ph,acid_to_ph_57,inventory FROM inventory_fermentables ";
688 if (instock) 780 if (instock)
689 sql.append("WHERE inventory > 0 "); 781 sql.append("WHERE inventory > 0 ");
690 sql.append("ORDER BY supplier,name"); 782 sql.append("ORDER BY supplier,name");
691 query.prepare(sql); 783 query.prepare(sql);
692 query.exec(); 784 query.exec();
693 query.first(); 785 query.first();
694 for (int i = 0; i < (val - 1); i++) { 786 for (int i = 0; i < (val - 1); i++) {
695 query.next(); 787 query.next();
696 } 788 }
697 qDebug() << "found" << query.value(2).toString() << query.value(0).toString();
698 789
699 /* 790 /*
700 * Replace the fermentable record contents 791 * Replace the fermentable record contents
701 */ 792 */
702 product->fermentables[product->fermentables_row].f_name = query.value(0).toString(); 793 product->fermentables[product->fermentables_row].f_name = query.value(0).toString();
715 product->fermentables[product->fermentables_row].f_graintype = query.value(13).toInt(); 806 product->fermentables[product->fermentables_row].f_graintype = query.value(13).toInt();
716 product->fermentables[product->fermentables_row].f_recommend_mash = query.value(14).toInt() ? true:false; 807 product->fermentables[product->fermentables_row].f_recommend_mash = query.value(14).toInt() ? true:false;
717 product->fermentables[product->fermentables_row].f_add_after_boil = query.value(15).toInt() ? true:false; 808 product->fermentables[product->fermentables_row].f_add_after_boil = query.value(15).toInt() ? true:false;
718 product->fermentables[product->fermentables_row].f_di_ph = query.value(16).toDouble(); 809 product->fermentables[product->fermentables_row].f_di_ph = query.value(16).toDouble();
719 product->fermentables[product->fermentables_row].f_acid_to_ph_57 = query.value(17).toDouble(); 810 product->fermentables[product->fermentables_row].f_acid_to_ph_57 = query.value(17).toDouble();
811 product->fermentables[product->fermentables_row].f_inventory = query.value(18).toDouble();
720 812
721 /* 813 /*
722 * Update the visible fields 814 * Update the visible fields
723 */ 815 */
724 fnameEdit->setText(product->fermentables.at(product->fermentables_row).f_name); 816 fnameEdit->setText(product->fermentables.at(product->fermentables_row).f_name);
742 ui->fermentablesTable->setItem(product->fermentables_row, 4, item); 834 ui->fermentablesTable->setItem(product->fermentables_row, 4, item);
743 835
744 item = new QTableWidgetItem(QString("%1%").arg(product->fermentables.at(product->fermentables_row).f_yield, 2, 'f', 1, '0')); 836 item = new QTableWidgetItem(QString("%1%").arg(product->fermentables.at(product->fermentables_row).f_yield, 2, 'f', 1, '0'));
745 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); 837 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
746 ui->fermentablesTable->setItem(product->fermentables_row, 6, item); 838 ui->fermentablesTable->setItem(product->fermentables_row, 6, item);
839
840 item = new QTableWidgetItem(QString("%1 Kg").arg(product->fermentables.at(product->fermentables_row).f_inventory, 4, 'f', 3, '0'));
841 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
842 if (product->fermentables.at(product->fermentables_row).f_inventory < product->fermentables.at(product->fermentables_row).f_amount)
843 item->setForeground(QBrush(QColor(Qt::red)));
844 ui->fermentablesTable->setItem(product->fermentables_row, 8, item);
747 845
748 calcFermentables(); 846 calcFermentables();
749 is_changed(); 847 is_changed();
750 } 848 }
751 849
781 product->fermentables[product->fermentables_row].f_added = val; 879 product->fermentables[product->fermentables_row].f_added = val;
782 QTableWidgetItem *item = new QTableWidgetItem(fermentable_added[val]); 880 QTableWidgetItem *item = new QTableWidgetItem(fermentable_added[val]);
783 item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter); 881 item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
784 ui->fermentablesTable->setItem(product->fermentables_row, 5, item); 882 ui->fermentablesTable->setItem(product->fermentables_row, 5, item);
785 883
786 famountEdit->setReadOnly(product->fermentables_use100 && product->fermentables.at(product->fermentables_row).f_added < 4); 884 famountEdit->setReadOnly(product->fermentables_use100 && product->fermentables.at(product->fermentables_row).f_added < FERMENTABLE_ADDED_BOTTLE);
787 pctEdit->setReadOnly(! (product->fermentables_use100 && product->fermentables.at(product->fermentables_row).f_added < 4)); 885 pctEdit->setReadOnly(! (product->fermentables_use100 && product->fermentables.at(product->fermentables_row).f_added < FERMENTABLE_ADDED_BOTTLE));
788 886
789 double total = 0; 887 double total = 0;
790 for (int i = 0; i < product->fermentables.size(); i++) 888 for (int i = 0; i < product->fermentables.size(); i++)
791 if (product->fermentables.at(i).f_added < 4) // Only before bottle/kegging 889 if (product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE) // Only before bottle/kegging
792 total += product->fermentables.at(i).f_amount; 890 total += product->fermentables.at(i).f_amount;
793 for (int i = 0; i < product->fermentables.size(); i++) 891 for (int i = 0; i < product->fermentables.size(); i++)
794 if (product->fermentables.at(i).f_added < 4) 892 if (product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE)
795 product->fermentables[i].f_percentage = product->fermentables.at(i).f_amount / total * 100; 893 product->fermentables[i].f_percentage = product->fermentables.at(i).f_amount / total * 100;
796 894
797 is_changed(); 895 is_changed();
798 emit refreshAll(); 896 emit refreshAll();
799 } 897 }
895 pctEdit->setObjectName(QString::fromUtf8("pctEdit")); 993 pctEdit->setObjectName(QString::fromUtf8("pctEdit"));
896 pctEdit->setGeometry(QRect(160, 130, 121, 24)); 994 pctEdit->setGeometry(QRect(160, 130, 121, 24));
897 pctEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); 995 pctEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
898 pctEdit->setAccelerated(true); 996 pctEdit->setAccelerated(true);
899 pctEdit->setDecimals(1); 997 pctEdit->setDecimals(1);
900 if (product->fermentables_use100 && product->fermentables.at(product->fermentables_row).f_added < 4) { 998 if (product->fermentables_use100 && product->fermentables.at(product->fermentables_row).f_added < FERMENTABLE_ADDED_BOTTLE) {
901 if (product->fermentables.at(product->fermentables_row).f_adjust_to_total_100) 999 if (product->fermentables.at(product->fermentables_row).f_adjust_to_total_100)
902 pctEdit->setReadOnly(true); 1000 pctEdit->setReadOnly(true);
903 else 1001 else
904 pctEdit->setReadOnly(false); 1002 pctEdit->setReadOnly(false);
905 } else { 1003 } else {
914 faddedEdit->setGeometry(QRect(160, 190, 161, 23)); 1012 faddedEdit->setGeometry(QRect(160, 190, 161, 23));
915 faddedEdit->addItem(tr("Mash")); 1013 faddedEdit->addItem(tr("Mash"));
916 faddedEdit->addItem(tr("Boil")); 1014 faddedEdit->addItem(tr("Boil"));
917 faddedEdit->addItem(tr("Fermentation")); 1015 faddedEdit->addItem(tr("Fermentation"));
918 faddedEdit->addItem(tr("Lagering")); 1016 faddedEdit->addItem(tr("Lagering"));
919 faddedEdit->addItem(tr("Bottle"));
920 faddedEdit->addItem(tr("Kegs"));
921 faddedEdit->setCurrentIndex(product->fermentables.at(product->fermentables_row).f_added); 1017 faddedEdit->setCurrentIndex(product->fermentables.at(product->fermentables_row).f_added);
922 1018
923 to100Edit = new QCheckBox(dialog); 1019 to100Edit = new QCheckBox(dialog);
924 to100Edit->setObjectName(QString::fromUtf8("to100Edit")); 1020 to100Edit->setObjectName(QString::fromUtf8("to100Edit"));
925 to100Edit->setGeometry(QRect(160, 160, 85, 21)); 1021 to100Edit->setGeometry(QRect(160, 160, 85, 21));
958 /* 1054 /*
959 * Recalculate the percentages 1055 * Recalculate the percentages
960 */ 1056 */
961 double total = 0; 1057 double total = 0;
962 for (int i = 0; i < product->fermentables.size(); i++) 1058 for (int i = 0; i < product->fermentables.size(); i++)
963 if (product->fermentables.at(i).f_added < 4) // Only before bottle/kegging 1059 if (product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE) // Only before bottle/kegging
964 total += product->fermentables.at(i).f_amount; 1060 total += product->fermentables.at(i).f_amount;
965 product->fermentables_use100 = false; 1061 product->fermentables_use100 = false;
966 for (int i = 0; i < product->fermentables.size(); i++) { 1062 for (int i = 0; i < product->fermentables.size(); i++) {
967 if (product->fermentables.at(i).f_adjust_to_total_100) 1063 if (product->fermentables.at(i).f_adjust_to_total_100)
968 product->fermentables_use100 = true; 1064 product->fermentables_use100 = true;
969 if (product->fermentables.at(i).f_added < 4) { 1065 if (product->fermentables.at(i).f_added < FERMENTABLE_ADDED_BOTTLE) {
970 product->fermentables[i].f_percentage = product->fermentables.at(i).f_amount / total * 100; 1066 product->fermentables[i].f_percentage = product->fermentables.at(i).f_amount / total * 100;
971 } 1067 }
972 } 1068 }
973 } 1069 }
974 1070

mercurial