47 |
47 |
48 const QStringList labels({tr("Origin"), tr("Hop"), tr("Type"), tr("Form"), tr("Alpha"), tr("Use at"), tr("Time"), |
48 const QStringList labels({tr("Origin"), tr("Hop"), tr("Type"), tr("Form"), tr("Alpha"), tr("Use at"), tr("Time"), |
49 tr("IBU"), tr("Amount"), tr("Stock"), tr("Delete"), tr("Edit") }); |
49 tr("IBU"), tr("Amount"), tr("Stock"), tr("Delete"), tr("Edit") }); |
50 |
50 |
51 ui->hopsTable->setColumnCount(12); |
51 ui->hopsTable->setColumnCount(12); |
52 ui->hopsTable->setColumnWidth(0, 130); /* Origin */ |
52 ui->hopsTable->setColumnWidth(0, 140); /* Origin */ |
53 ui->hopsTable->setColumnWidth(1, 225); /* Hop */ |
53 ui->hopsTable->setColumnWidth(1, 225); /* Hop */ |
54 ui->hopsTable->setColumnWidth(2, 74); /* Type */ |
54 ui->hopsTable->setColumnWidth(2, 74); /* Type */ |
55 ui->hopsTable->setColumnWidth(3, 84); /* Form */ |
55 ui->hopsTable->setColumnWidth(3, 84); /* Form */ |
56 ui->hopsTable->setColumnWidth(4, 55); /* Alpha% */ |
56 ui->hopsTable->setColumnWidth(4, 55); /* Alpha% */ |
57 ui->hopsTable->setColumnWidth(5, 75); /* Added */ |
57 ui->hopsTable->setColumnWidth(5, 75); /* Added */ |
114 item = new QTableWidgetItem(QString("%1 gr").arg(product->hops.at(i).h_inventory * 1000.0, 2, 'f', 1, '0')); |
114 item = new QTableWidgetItem(QString("%1 gr").arg(product->hops.at(i).h_inventory * 1000.0, 2, 'f', 1, '0')); |
115 } else { |
115 } else { |
116 item = new QTableWidgetItem(QString("%1 kg").arg(product->hops.at(i).h_inventory, 4, 'f', 3, '0')); |
116 item = new QTableWidgetItem(QString("%1 kg").arg(product->hops.at(i).h_inventory, 4, 'f', 3, '0')); |
117 } |
117 } |
118 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); |
118 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); |
|
119 if (product->hops.at(i).h_inventory < product->hops.at(i).h_amount) |
|
120 item->setForeground(QBrush(QColor(Qt::red))); |
119 ui->hopsTable->setItem(i, 9, item); |
121 ui->hopsTable->setItem(i, 9, item); |
120 |
122 |
121 /* Add the Delete row button */ |
123 /* Add the Delete row button */ |
122 pWidget = new QWidget(); |
124 pWidget = new QWidget(); |
123 QPushButton* btn_dele = new QPushButton(); |
125 QPushButton* btn_dele = new QPushButton(); |
186 } |
188 } |
187 |
189 |
188 |
190 |
189 void EditProduct::calcIBUs() |
191 void EditProduct::calcIBUs() |
190 { |
192 { |
191 double hop_flavour = 0, hop_aroma = 0, ibus = 0; |
193 double hop_flavour = 0, hop_aroma = 0, ibus = 0, ferm_ibus = 0; |
192 |
194 |
|
195 product->hops_ok = true; |
193 for (int i = 0; i < product->hops.size(); i++) { |
196 for (int i = 0; i < product->hops.size(); i++) { |
194 |
197 |
195 ibus += Utils::toIBU(product->hops.at(i).h_useat, product->hops.at(i).h_form, product->preboil_sg, product->batch_size, product->hops.at(i).h_amount, |
198 ibus += Utils::toIBU(product->hops.at(i).h_useat, product->hops.at(i).h_form, product->preboil_sg, |
196 product->hops.at(i).h_time, product->hops.at(i).h_alpha, product->ibu_method, 0, product->hops.at(i).h_time, 0); |
199 product->batch_size, product->hops.at(i).h_amount, |
|
200 product->hops.at(i).h_time, product->hops.at(i).h_alpha, product->ibu_method, |
|
201 product->brew_whirlpool9, product->brew_whirlpool7, product->brew_whirlpool6); |
|
202 ferm_ibus += Utils::toIBU(product->hops.at(i).h_useat, product->hops.at(i).h_form, product->preboil_sg, |
|
203 product->brew_fermenter_volume + product->brew_fermenter_tcloss, product->hops.at(i).h_amount, |
|
204 product->hops.at(i).h_time, product->hops.at(i).h_alpha, product->ibu_method, |
|
205 product->brew_whirlpool9, product->brew_whirlpool7, product->brew_whirlpool6); |
|
206 |
197 hop_flavour += Utils::hopFlavourContribution(product->hops.at(i).h_time, product->batch_size, product->hops.at(i).h_useat, product->hops.at(i).h_amount); |
207 hop_flavour += Utils::hopFlavourContribution(product->hops.at(i).h_time, product->batch_size, product->hops.at(i).h_useat, product->hops.at(i).h_amount); |
198 hop_aroma += Utils::hopAromaContribution(product->hops.at(i).h_time, product->batch_size, product->hops.at(i).h_useat, product->hops.at(i).h_amount); |
208 hop_aroma += Utils::hopAromaContribution(product->hops.at(i).h_time, product->batch_size, product->hops.at(i).h_useat, product->hops.at(i).h_amount); |
|
209 if ((((product->inventory_reduced <= PROD_STAGE_BREW) && (product->hops.at(i).h_useat <= HOP_USEAT_WHIRLPOOL)) || |
|
210 ((product->inventory_reduced <= PROD_STAGE_PACKAGE) && (product->hops.at(i).h_useat == HOP_USEAT_DRY_HOP))) && |
|
211 (product->hops.at(i).h_inventory < product->hops.at(i).h_amount)) |
|
212 product->hops_ok = false; |
199 } |
213 } |
200 |
214 |
201 hop_flavour = round(hop_flavour * 1000.0 / 5.0) / 10; |
215 hop_flavour = round(hop_flavour * 1000.0 / 5.0) / 10; |
202 hop_aroma = round(hop_aroma * 1000.0 / 6.0) / 10; |
216 hop_aroma = round(hop_aroma * 1000.0 / 6.0) / 10; |
203 if (hop_flavour > 100) |
217 if (hop_flavour > 100) |
204 hop_flavour = 100; |
218 hop_flavour = 100; |
205 if (hop_aroma > 100) |
219 if (hop_aroma > 100) |
206 hop_aroma = 100; |
220 hop_aroma = 100; |
207 qDebug() << "ibu" << product->est_ibu << ibus << "flavour" << hop_flavour << "aroma" << hop_aroma << "method" << product->ibu_method; |
221 qDebug() << "ibu" << product->est_ibu << ibus << "flavour" << hop_flavour << "aroma" << hop_aroma << "method" << product->ibu_method |
|
222 << "fermenter" << ferm_ibus << "supplies" << product->hops_ok; |
208 |
223 |
209 product->est_ibu = ibus; |
224 product->est_ibu = ibus; |
|
225 product->brew_fermenter_ibu = ferm_ibus; |
210 ui->est_ibuEdit->setValue(product->est_ibu); |
226 ui->est_ibuEdit->setValue(product->est_ibu); |
211 ui->est_ibu2Edit->setValue(product->est_ibu); |
227 ui->est_ibu2Edit->setValue(product->est_ibu); |
212 ui->est_ibuShow->setValue(product->est_ibu); |
228 ui->est_ibuShow->setValue(product->est_ibu); |
|
229 ui->brew_fermentibuShow->setValue(product->brew_fermenter_ibu); |
213 ui->hop_tasteShow->setValue(hop_flavour); |
230 ui->hop_tasteShow->setValue(hop_flavour); |
214 ui->hop_aromaShow->setValue(hop_aroma); |
231 ui->hop_aromaShow->setValue(hop_aroma); |
215 } |
232 } |
216 |
233 |
217 |
234 |
297 { |
315 { |
298 QTableWidgetItem *item; |
316 QTableWidgetItem *item; |
299 |
317 |
300 qDebug() << "hop_time_changed()" << product->hops_row << val; |
318 qDebug() << "hop_time_changed()" << product->hops_row << val; |
301 |
319 |
302 if (product->hops.at(product->hops_row).h_useat == 2 || product->hops.at(product->hops_row).h_useat == 4) { // Boil or whirlpool |
320 if (product->hops.at(product->hops_row).h_useat == HOP_USEAT_BOIL || product->hops.at(product->hops_row).h_useat == HOP_USEAT_WHIRLPOOL) { |
303 item = new QTableWidgetItem(QString("%1 min.").arg(val, 1, 'f', 0, '0')); |
321 item = new QTableWidgetItem(QString("%1 min.").arg(val, 1, 'f', 0, '0')); |
304 product->hops[product->hops_row].h_time = val; |
322 product->hops[product->hops_row].h_time = val; |
305 } else if (product->hops.at(product->hops_row).h_useat == 5) { // Dry-hop |
323 } else if (product->hops.at(product->hops_row).h_useat == HOP_USEAT_DRY_HOP) { |
306 item = new QTableWidgetItem(QString("%1 days.").arg(val, 1, 'f', 0, '0')); |
324 item = new QTableWidgetItem(QString("%1 days.").arg(val, 1, 'f', 0, '0')); |
307 product->hops[product->hops_row].h_time = val * 1440; |
325 product->hops[product->hops_row].h_time = val * 1440; |
308 } else { |
326 } else { |
309 item = new QTableWidgetItem(QString("")); |
327 item = new QTableWidgetItem(QString("")); |
310 product->hops[product->hops_row].h_time = val; |
328 product->hops[product->hops_row].h_time = val; |
312 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); |
330 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); |
313 ui->hopsTable->setItem(product->hops_row, 6, item); |
331 ui->hopsTable->setItem(product->hops_row, 6, item); |
314 |
332 |
315 double ibu = Utils::toIBU(product->hops.at(product->hops_row).h_useat, product->hops.at(product->hops_row).h_form, product->preboil_sg, |
333 double ibu = Utils::toIBU(product->hops.at(product->hops_row).h_useat, product->hops.at(product->hops_row).h_form, product->preboil_sg, |
316 product->batch_size, product->hops.at(product->hops_row).h_amount, product->hops.at(product->hops_row).h_time, |
334 product->batch_size, product->hops.at(product->hops_row).h_amount, product->hops.at(product->hops_row).h_time, |
317 product->hops.at(product->hops_row).h_alpha, product->ibu_method, 0, product->hops.at(product->hops_row).h_time, 0); |
335 product->hops.at(product->hops_row).h_alpha, product->ibu_method, |
|
336 product->brew_whirlpool9, product->brew_whirlpool7, product->brew_whirlpool6); |
318 |
337 |
319 ibuEdit->setValue(ibu); |
338 ibuEdit->setValue(ibu); |
320 item = new QTableWidgetItem(QString("%1").arg(ibu, 2, 'f', 1, '0')); |
339 item = new QTableWidgetItem(QString("%1").arg(ibu, 2, 'f', 1, '0')); |
321 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); |
340 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); |
322 ui->hopsTable->setItem(product->hops_row, 7, item); |
341 ui->hopsTable->setItem(product->hops_row, 7, item); |
339 qDebug() << "hop_select_changed()" << product->fermentables_row << val << instock; |
358 qDebug() << "hop_select_changed()" << product->fermentables_row << val << instock; |
340 |
359 |
341 /* |
360 /* |
342 * Search the hop pointed by the index and instock flag. |
361 * Search the hop pointed by the index and instock flag. |
343 */ |
362 */ |
344 QString sql = "SELECT name,origin,alpha,beta,humulene,caryophyllene,cohumulone,myrcene,hsi,total_oil,type,form,cost FROM inventory_hops "; |
363 QString sql = "SELECT name,origin,alpha,beta,humulene,caryophyllene,cohumulone,myrcene,hsi,total_oil,type,form,cost,inventory FROM inventory_hops "; |
345 if (instock) |
364 if (instock) |
346 sql.append("WHERE inventory > 0 "); |
365 sql.append("WHERE inventory > 0 "); |
347 sql.append("ORDER BY origin,name"); |
366 sql.append("ORDER BY origin,name"); |
348 query.prepare(sql); |
367 query.prepare(sql); |
349 query.exec(); |
368 query.exec(); |
350 query.first(); |
369 query.first(); |
351 for (int i = 0; i < (val - 1); i++) { |
370 for (int i = 0; i < (val - 1); i++) { |
352 query.next(); |
371 query.next(); |
353 } |
372 } |
354 qDebug() << "found" << query.value(1).toString() << query.value(0).toString(); |
|
355 |
373 |
356 /* |
374 /* |
357 * Replace the hop record contents |
375 * Replace the hop record contents |
358 */ |
376 */ |
359 product->hops[product->hops_row].h_name = query.value(0).toString(); |
377 product->hops[product->hops_row].h_name = query.value(0).toString(); |
367 product->hops[product->hops_row].h_hsi = query.value(8).toDouble(); |
385 product->hops[product->hops_row].h_hsi = query.value(8).toDouble(); |
368 product->hops[product->hops_row].h_total_oil = query.value(9).toDouble(); |
386 product->hops[product->hops_row].h_total_oil = query.value(9).toDouble(); |
369 product->hops[product->hops_row].h_type = query.value(10).toInt(); |
387 product->hops[product->hops_row].h_type = query.value(10).toInt(); |
370 product->hops[product->hops_row].h_form = query.value(11).toInt(); |
388 product->hops[product->hops_row].h_form = query.value(11).toInt(); |
371 product->hops[product->hops_row].h_cost = query.value(12).toDouble(); |
389 product->hops[product->hops_row].h_cost = query.value(12).toDouble(); |
|
390 product->hops[product->hops_row].h_inventory = query.value(13).toDouble(); |
372 |
391 |
373 /* |
392 /* |
374 * Update the visible fields |
393 * Update the visible fields |
375 */ |
394 */ |
376 hnameEdit->setText(product->hops.at(product->hops_row).h_name); |
395 hnameEdit->setText(product->hops.at(product->hops_row).h_name); |
377 horiginEdit->setText(product->hops.at(product->hops_row).h_origin); |
396 horiginEdit->setText(product->hops.at(product->hops_row).h_origin); |
378 |
397 |
379 double ibu = Utils::toIBU(product->hops.at(product->hops_row).h_useat, product->hops.at(product->hops_row).h_form, product->preboil_sg, |
398 double ibu = Utils::toIBU(product->hops.at(product->hops_row).h_useat, product->hops.at(product->hops_row).h_form, product->preboil_sg, |
380 product->batch_size, product->hops.at(product->hops_row).h_amount, product->hops.at(product->hops_row).h_time, |
399 product->batch_size, product->hops.at(product->hops_row).h_amount, product->hops.at(product->hops_row).h_time, |
381 product->hops.at(product->hops_row).h_alpha, product->ibu_method, 0, product->hops.at(product->hops_row).h_time, 0); |
400 product->hops.at(product->hops_row).h_alpha, product->ibu_method, |
|
401 product->brew_whirlpool9, product->brew_whirlpool7, product->brew_whirlpool6); |
382 ibuEdit->setValue(ibu); |
402 ibuEdit->setValue(ibu); |
383 |
403 |
384 ui->hopsTable->setItem(product->hops_row, 0, new QTableWidgetItem(product->hops.at(product->hops_row).h_origin)); |
404 ui->hopsTable->setItem(product->hops_row, 0, new QTableWidgetItem(product->hops.at(product->hops_row).h_origin)); |
385 ui->hopsTable->setItem(product->hops_row, 1, new QTableWidgetItem(product->hops.at(product->hops_row).h_name)); |
405 ui->hopsTable->setItem(product->hops_row, 1, new QTableWidgetItem(product->hops.at(product->hops_row).h_name)); |
386 |
406 |
397 ui->hopsTable->setItem(product->hops_row, 4, item); |
417 ui->hopsTable->setItem(product->hops_row, 4, item); |
398 |
418 |
399 item = new QTableWidgetItem(QString("%1").arg(ibu, 2, 'f', 1, '0')); |
419 item = new QTableWidgetItem(QString("%1").arg(ibu, 2, 'f', 1, '0')); |
400 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); |
420 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); |
401 ui->hopsTable->setItem(product->hops_row, 7, item); |
421 ui->hopsTable->setItem(product->hops_row, 7, item); |
|
422 |
|
423 if (product->hops.at(product->hops_row).h_inventory < 1.0) { |
|
424 item = new QTableWidgetItem(QString("%1 gr").arg(product->hops.at(product->hops_row).h_inventory * 1000.0, 2, 'f', 1, '0')); |
|
425 } else { |
|
426 item = new QTableWidgetItem(QString("%1 kg").arg(product->hops.at(product->hops_row).h_inventory, 4, 'f', 3, '0')); |
|
427 } |
|
428 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); |
|
429 if (product->hops.at(product->hops_row).h_inventory < product->hops.at(product->hops_row).h_amount) |
|
430 item->setForeground(QBrush(QColor(Qt::red))); |
|
431 ui->hopsTable->setItem(product->hops_row, 9, item); |
402 |
432 |
403 calcIBUs(); |
433 calcIBUs(); |
404 is_changed(); |
434 is_changed(); |
405 } |
435 } |
406 |
436 |
436 product->hops[product->hops_row].h_useat = val; |
466 product->hops[product->hops_row].h_useat = val; |
437 QTableWidgetItem *item = new QTableWidgetItem(hop_useat[val]); |
467 QTableWidgetItem *item = new QTableWidgetItem(hop_useat[val]); |
438 item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter); |
468 item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter); |
439 ui->hopsTable->setItem(product->hops_row, 5, item); |
469 ui->hopsTable->setItem(product->hops_row, 5, item); |
440 |
470 |
441 if (val == 2 || val == 4) { // Boil or whirlpool |
471 if (val == HOP_USEAT_BOIL || val == HOP_USEAT_WHIRLPOOL) { |
442 htimeLabel->setText(tr("Time in minutes:")); |
472 htimeLabel->setText(tr("Time in minutes:")); |
443 htimeEdit->setValue(product->hops.at(product->hops_row).h_time); |
473 htimeEdit->setValue(product->hops.at(product->hops_row).h_time); |
444 htimeEdit->setReadOnly(false); |
474 htimeEdit->setReadOnly(false); |
445 } else if (val == 5) { // Dry-hop |
475 } else if (val == HOP_USEAT_DRY_HOP) { |
446 htimeLabel->setText(tr("Time in days:")); |
476 htimeLabel->setText(tr("Time in days:")); |
447 htimeEdit->setValue(product->hops.at(product->hops_row).h_time / 1440); |
477 htimeEdit->setValue(product->hops.at(product->hops_row).h_time / 1440); |
448 htimeEdit->setReadOnly(false); |
478 htimeEdit->setReadOnly(false); |
449 } else { |
479 } else { |
450 htimeLabel->setText(""); |
480 htimeLabel->setText(""); |
552 htimeEdit->setObjectName(QString::fromUtf8("htimeEdit")); |
582 htimeEdit->setObjectName(QString::fromUtf8("htimeEdit")); |
553 htimeEdit->setGeometry(QRect(160, 130, 121, 24)); |
583 htimeEdit->setGeometry(QRect(160, 130, 121, 24)); |
554 htimeEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); |
584 htimeEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); |
555 htimeEdit->setAccelerated(true); |
585 htimeEdit->setAccelerated(true); |
556 htimeEdit->setMaximum(10000.0); |
586 htimeEdit->setMaximum(10000.0); |
557 if (product->hops.at(product->hops_row).h_useat == 2 || product->hops.at(product->hops_row).h_useat == 4) { // Boil or whirlpool |
587 if (product->hops.at(product->hops_row).h_useat == HOP_USEAT_BOIL || product->hops.at(product->hops_row).h_useat == HOP_USEAT_WHIRLPOOL) { |
558 htimeEdit->setValue(product->hops.at(product->hops_row).h_time); |
588 htimeEdit->setValue(product->hops.at(product->hops_row).h_time); |
559 htimeEdit->setReadOnly(false); |
589 htimeEdit->setReadOnly(false); |
560 } else if (product->hops.at(product->hops_row).h_useat == 5){ // Dry-hop |
590 } else if (product->hops.at(product->hops_row).h_useat == HOP_USEAT_DRY_HOP) { |
561 htimeEdit->setValue(product->hops.at(product->hops_row).h_time / 1440); |
591 htimeEdit->setValue(product->hops.at(product->hops_row).h_time / 1440); |
562 htimeEdit->setReadOnly(false); |
592 htimeEdit->setReadOnly(false); |
563 } else { |
593 } else { |
564 htimeEdit->setReadOnly(true); |
594 htimeEdit->setReadOnly(true); |
565 } |
595 } |
586 ibuEdit->setReadOnly(true); |
616 ibuEdit->setReadOnly(true); |
587 ibuEdit->setButtonSymbols(QAbstractSpinBox::NoButtons); |
617 ibuEdit->setButtonSymbols(QAbstractSpinBox::NoButtons); |
588 ibuEdit->setDecimals(1); |
618 ibuEdit->setDecimals(1); |
589 double ibu = Utils::toIBU(product->hops.at(product->hops_row).h_useat, product->hops.at(product->hops_row).h_form, product->preboil_sg, |
619 double ibu = Utils::toIBU(product->hops.at(product->hops_row).h_useat, product->hops.at(product->hops_row).h_form, product->preboil_sg, |
590 product->batch_size, product->hops.at(product->hops_row).h_amount, product->hops.at(product->hops_row).h_time, |
620 product->batch_size, product->hops.at(product->hops_row).h_amount, product->hops.at(product->hops_row).h_time, |
591 product->hops.at(product->hops_row).h_alpha, product->ibu_method, 0, product->hops.at(product->hops_row).h_time, 0); |
621 product->hops.at(product->hops_row).h_alpha, product->ibu_method, |
|
622 product->brew_whirlpool9, product->brew_whirlpool7, product->brew_whirlpool6); |
592 ibuEdit->setValue(ibu); |
623 ibuEdit->setValue(ibu); |
593 |
624 |
594 hop_instock_changed(true); |
625 hop_instock_changed(true); |
595 |
626 |
596 connect(hselectEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditProduct::hop_select_changed); |
627 connect(hselectEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditProduct::hop_select_changed); |
606 if (dialog->result() == QDialog::Rejected) { |
637 if (dialog->result() == QDialog::Rejected) { |
607 qDebug() << "reject and rollback"; |
638 qDebug() << "reject and rollback"; |
608 product->hops[product->hops_row] = backup; |
639 product->hops[product->hops_row] = backup; |
609 } else { |
640 } else { |
610 /* Clear time if hop is not used for boil, whirlpool or dry-hop. */ |
641 /* Clear time if hop is not used for boil, whirlpool or dry-hop. */ |
611 if (! (product->hops.at(product->hops_row).h_useat == 2 || |
642 if (! (product->hops.at(product->hops_row).h_useat == HOP_USEAT_BOIL || |
612 product->hops.at(product->hops_row).h_useat == 4 || |
643 product->hops.at(product->hops_row).h_useat == HOP_USEAT_WHIRLPOOL || |
613 product->hops.at(product->hops_row).h_useat == 5)) { |
644 product->hops.at(product->hops_row).h_useat == HOP_USEAT_DRY_HOP)) { |
614 if (product->hops.at(product->hops_row).h_time) { |
645 if (product->hops.at(product->hops_row).h_time) { |
615 product->hops[product->hops_row].h_time = 0; |
646 product->hops[product->hops_row].h_time = 0; |
616 is_changed(); |
647 is_changed(); |
617 } |
648 } |
618 } |
649 } |