Thu, 30 Jun 2022 10:38:03 +0200
Translated to English.
/** * EditProduct.cpp is part of bmsapp. * * Tab 1, generic settings. * * bmsapp 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 3 of the License, or * (at your option) any later version. * * bmsapp 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 this program. If not, see <http://www.gnu.org/licenses/>. */ void EditProduct::code_changed(QString code) { product->code = code; is_changed(); } void EditProduct::name_changed(QString name) { product->name = name; is_changed(); } void EditProduct::notes_changed() { /* The text cannot be passed in a simple way :) */ product->notes = ui->notesEdit->toPlainText(); is_changed(); } /* * New beerstyle is selected. */ void EditProduct::style_changed(int val) { QSqlQuery query; query.prepare("SELECT * FROM profile_styles ORDER BY style_guide,style_letter,name"); query.exec(); query.first(); // Skip to the record index. for (int i = 0; i < (val - 1); i++) { query.next(); } // Set relevant fields and update ranges. product->st_name = query.value(1).toString(); product->st_category = query.value(2).toString(); product->st_category_number = query.value(3).toInt(); product->st_letter = query.value(4).toString(); product->st_guide = query.value(5).toString(); product->st_type = query.value(6).toInt(); product->st_og_min = query.value(7).toDouble(); product->st_og_max = query.value(8).toDouble(); product->st_fg_min = query.value(9).toDouble(); product->st_fg_max = query.value(10).toDouble(); product->st_ibu_min = query.value(11).toDouble(); product->st_ibu_max = query.value(12).toDouble(); product->st_color_min = query.value(13).toDouble(); product->st_color_max = query.value(14).toDouble(); product->st_carb_min = query.value(15).toDouble(); product->st_carb_max = query.value(16).toDouble(); product->st_abv_min = query.value(17).toDouble(); product->st_abv_max = query.value(18).toDouble(); ui->st_nameEdit->setText(product->st_name); ui->st_groupEdit->setText(product->st_letter); ui->st_guideEdit->setText(product->st_guide); ui->st_catEdit->setText(product->st_category); ui->st_catnrEdit->setText(QString("%1").arg(product->st_category_number)); ui->st_typeEdit->setText(QCoreApplication::translate("BeerType", g_style_types[product->st_type])); ui->est_ogShow->setRange(query.value(7).toDouble(), query.value(8).toDouble()); ui->est_fgShow->setRange(query.value(9).toDouble(), query.value(10).toDouble()); ui->est_ibuShow->setRange(query.value(11).toDouble(), query.value(12).toDouble()); ui->est_colorShow->setRange(query.value(13).toDouble(), query.value(14).toDouble()); ui->est_carbShow->setRange(query.value(15).toDouble(), query.value(16).toDouble()); ui->est_abvShow->setRange(query.value(17).toDouble(), query.value(18).toDouble()); is_changed(); } void EditProduct::colormethod_changed(int val) { product->color_method = val; calcFermentables(); is_changed(); } void EditProduct::ibumethod_changed(int val) { product->ibu_method = val; calcIBUs(); is_changed(); } void EditProduct::est_og_changed(double val) { product->est_og = val; calcFermentablesFromOG(val);// Adjust fermentables amounts calcFermentables(); // Update the product details calcIBUs(); calcMash(); is_changed(); emit refreshAll(); } void EditProduct::efficiency_changed(double val) { double estog = product->est_og; product->efficiency = val; calcFermentablesFromOG(estog); calcFermentables(); calcIBUs(); is_changed(); emit refreshAll(); } void EditProduct::boil_time_changed(int val) { qDebug() << "boil_time_changed" << val; double new_evap = (0.1 * product->batch_size) * val / 60.0; product->boil_size = product->batch_size + new_evap; product->boil_time = val; ui->boil_sizeEdit->setValue(product->boil_size); ui->brew_preboilvolShow->setValue(product->boil_size * 1.04); calcFermentables(); calcIBUs(); is_changed(); } void EditProduct::batch_size_changed(double val) { qDebug() << "batch_size_changed" << val << "old" << product->batch_size; double evap = (0.1 * val) * product->boil_time / 60.0; product->boil_size = val + evap; double factor = val / product->batch_size; ui->boil_sizeEdit->setValue(product->boil_size); ui->brew_preboilvolShow->setValue(product->boil_size * 1.04); product->sparge_volume *= factor; ui->sp_volEdit->setValue(product->sparge_volume); ui->brew_spargevolShow->setValue(product->sparge_volume); product->batch_size = val; calcFermentablesFromOG(product->est_og); // Keep the OG adjustWaters(factor); calcFermentables(); adjustHops(factor); adjustMiscs(factor); adjustYeasts(factor); calcIBUs(); calcWater(); calcMash(); is_changed(); emit refreshAll(); } void EditProduct::brew_type_changed(int val) { product->type; is_changed(); } void EditProduct::locked_changed(bool val) { qDebug() << "locked_changed" << val; if (product->stage < PROD_STAGE_READY) return; product->locked = val; product->stage = val ? PROD_STAGE_CLOSED : PROD_STAGE_READY; setStage(); is_changed(); } void EditProduct::setStage() { int stage = product->stage; bool locked = product->locked; /* * See if we need to set a new stage. */ if ((stage == PROD_STAGE_PLAN) && (product->est_og > 1.005) && (product->est_color > 3) && (product->est_ibu > 3)) stage = PROD_STAGE_WAIT; if ((stage == PROD_STAGE_WAIT) && (product->brew_date_start.date().isValid())) stage = PROD_STAGE_BREW; if ((stage == PROD_STAGE_BREW) && (! product->brew_date_start.date().isValid())) stage = PROD_STAGE_WAIT; /* from PROD_STAGE_BREW to PROD_STAGE_PRIMARY is handled in EditProductTab9.cpp */ /* from PROD_STAGE_PRIMARY to PROD_STAGE_SECONDARY is handled in EditProductTab10.cpp */ /* from PROD_STAGE_SECONDARY to PROD_STAGE_TERIARY is handled in EditProductTab10.cpp */ if ((stage == PROD_STAGE_TERTIARY) && product->package_date.isValid()) stage = PROD_STAGE_PACKAGE; if ((stage == PROD_STAGE_PACKAGE) && (! product->package_date.isValid())) stage = PROD_STAGE_TERTIARY; /* from PROD_STAGE_PACKAGE to PROD_STAGE_CARBONATION is handled in EditProductTab11.cpp */ if ((stage == PROD_STAGE_CARBONATION) && (product->package_date.daysTo(QDate::currentDate()) > 14)) stage = PROD_STAGE_MATURE; if (product->stage != stage) { qDebug() << "setStage() change state:" << g_prod_stages[product->stage] << "to:" << g_prod_stages[stage]; product->stage = stage; is_changed(); } else { qDebug() << "setStage() stage:" << g_prod_stages[stage]; } ui->stageEdit->setText(QCoreApplication::translate("ProdStages", g_prod_stages[stage])); /* Tab 1, generic */ ui->typeEdit->setDisabled(stage > PROD_STAGE_WAIT); ui->color_methodEdit->setDisabled(locked); ui->ibu_methodEdit->setDisabled(locked); ui->beerstyleEdit->setDisabled(stage > PROD_STAGE_WAIT); ui->nameEdit->setReadOnly(stage > PROD_STAGE_WAIT); ui->codeEdit->setReadOnly(stage > PROD_STAGE_WAIT || product->divide_type); /* Never change this in a splitted product. */ ui->notesEdit->setReadOnly(locked); ui->batch_sizeEdit->setReadOnly(stage > PROD_STAGE_WAIT); ui->batch_sizeEdit->setButtonSymbols((stage > PROD_STAGE_WAIT) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->boil_sizeEdit->setReadOnly(stage > PROD_STAGE_WAIT); ui->boil_sizeEdit->setButtonSymbols((stage > PROD_STAGE_WAIT) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->boil_timeEdit->setReadOnly(stage > PROD_STAGE_WAIT); ui->boil_timeEdit->setButtonSymbols((stage > PROD_STAGE_WAIT) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->efficiencyEdit->setReadOnly(stage > PROD_STAGE_WAIT); ui->efficiencyEdit->setButtonSymbols((stage > PROD_STAGE_WAIT) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->est_ogEdit->setReadOnly(stage > PROD_STAGE_WAIT); ui->est_ogEdit->setButtonSymbols((stage > PROD_STAGE_WAIT) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); /* * The next two items are displayed on the same location. * But they are not needed at the same time. */ if (stage > PROD_STAGE_PACKAGE) { ui->ok_pmptLabel->hide(); ui->ok_pmptIcon->hide(); } else { ui->ok_pmptLabel->show(); ui->ok_pmptIcon->show(); } if (stage >= PROD_STAGE_READY) { ui->lockedLabel->show(); ui->lockedEdit->show(); } else { ui->lockedLabel->hide(); ui->lockedEdit->hide(); } /* Tab 2, equipment */ ui->tabWidget->setTabEnabled(1, stage < PROD_STAGE_BREW); /* Tab 3, fermentables */ ui->est_og2Edit->setReadOnly(stage > PROD_STAGE_WAIT); ui->est_og2Edit->setButtonSymbols((stage > PROD_STAGE_WAIT) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->addFermentable->setEnabled(stage <= PROD_STAGE_PACKAGE); /* Tab 4, hops */ ui->addHop->setEnabled(stage <= PROD_STAGE_PACKAGE); /* Tab 5, miscs */ ui->addMisc->setEnabled(stage <= PROD_STAGE_PACKAGE); /* Tab 6, yeasts */ ui->addYeast->setEnabled(stage <= PROD_STAGE_PACKAGE); /* Tab 7, mash */ ui->addMash->setEnabled(stage <= PROD_STAGE_BREW); ui->mash_nameEdit->setReadOnly(stage > PROD_STAGE_BREW); ui->mash_pickEdit->setDisabled(stage > PROD_STAGE_BREW); /* Tab 8, water */ ui->sp_sourceEdit->setDisabled(stage > PROD_STAGE_BREW); ui->wt_sourceEdit->setDisabled(stage > PROD_STAGE_BREW); ui->w1_nameEdit->setDisabled(stage > PROD_STAGE_BREW); ui->w2_nameEdit->setDisabled(stage > PROD_STAGE_BREW); ui->mw_acidPick->setDisabled(stage > PROD_STAGE_BREW); ui->sp_acidtypeEdit->setDisabled(stage > PROD_STAGE_BREW); ui->w2_volEdit->setReadOnly(stage > PROD_STAGE_BREW); ui->w2_volEdit->setButtonSymbols((stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->sp_phEdit->setReadOnly(stage > PROD_STAGE_BREW); ui->sp_phEdit->setButtonSymbols((stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->sp_tempEdit->setReadOnly(stage > PROD_STAGE_BREW); ui->sp_tempEdit->setButtonSymbols((stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->sp_volEdit->setReadOnly(stage > PROD_STAGE_BREW); ui->sp_volEdit->setButtonSymbols((stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->bs_cacl2Edit->setReadOnly(stage > PROD_STAGE_BREW); ui->bs_cacl2Edit->setButtonSymbols((stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->bs_caso4Edit->setReadOnly(stage > PROD_STAGE_BREW); ui->bs_caso4Edit->setButtonSymbols((stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->bs_mgso4Edit->setReadOnly(stage > PROD_STAGE_BREW); ui->bs_mgso4Edit->setButtonSymbols((stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->bs_naclEdit->setReadOnly(stage > PROD_STAGE_BREW); ui->bs_naclEdit->setButtonSymbols((stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->bs_mgcl2Edit->setReadOnly(stage > PROD_STAGE_BREW); ui->bs_mgcl2Edit->setButtonSymbols((stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->bs_nahco3Edit->setReadOnly(stage > PROD_STAGE_BREW); ui->bs_nahco3Edit->setButtonSymbols((stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->bs_caco3Edit->setReadOnly(stage > PROD_STAGE_BREW); ui->bs_caco3Edit->setButtonSymbols((stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); if (stage > PROD_STAGE_BREW) { ui->mw_phEdit->setReadOnly(true); ui->mw_phEdit->setButtonSymbols(QAbstractSpinBox::NoButtons); ui->mw_acidvolEdit->setReadOnly(true); ui->mw_acidvolEdit->setButtonSymbols(QAbstractSpinBox::NoButtons); } else { ui->mw_phEdit->setReadOnly(! product->calc_acid); ui->mw_phEdit->setButtonSymbols(product->calc_acid ? QAbstractSpinBox::UpDownArrows : QAbstractSpinBox::NoButtons); ui->mw_acidvolEdit->setReadOnly(product->calc_acid); ui->mw_acidvolEdit->setButtonSymbols(product->calc_acid ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); } ui->mw_autoEdit->setDisabled(stage > PROD_STAGE_BREW); /* Tab 9, brewday */ ui->tabWidget->setTabEnabled(8, stage > PROD_STAGE_PLAN); if (product->log_brew) { ui->brew_logLabel->show(); ui->brew_logButton->show(); } else { ui->brew_logLabel->hide(); ui->brew_logButton->hide(); } ui->brew_ackLabel->hide(); ui->brew_ackButton->hide(); if (product->stage < PROD_STAGE_BREW) { ui->brew_startButton1->show(); ui->brew_startButton2->show(); ui->brew_startDate->setReadOnly(false); ui->brew_startDate->setMinimumDate(product->birth.addDays(-1)); // The birth date is the first valid date. ui->brew_endButton1->hide(); ui->brew_startLabel2->hide(); ui->brew_endLabel->hide(); ui->brew_endLabel2->hide(); ui->brew_startTime->hide(); ui->brew_endDate->hide(); ui->brew_endTime->hide(); } else if (product->stage == PROD_STAGE_BREW) { ui->brew_startButton1->show(); ui->brew_startButton2->show(); ui->brew_startDate->setReadOnly(false); ui->brew_startLabel2->show(); /* * Enable brew_end settings if it is the right date or later. * If some essential values are filled in. */ int brewTime = product->brew_date_start.date().daysTo(QDate::currentDate()); if ((brewTime >= 0) && (product->brew_cooling_method > 0) && (product->brew_cooling_time > 0) && (product->brew_aboil_sg > 1.002) && (product->brew_aboil_volume > 0)) { ui->brew_endLabel->show(); ui->brew_startLabel2->show(); ui->brew_endLabel2->show(); ui->brew_endButton1->show(); ui->brew_startTime->setButtonSymbols(QAbstractSpinBox::UpDownArrows); ui->brew_startTime->show(); ui->brew_endDate->setButtonSymbols(QAbstractSpinBox::UpDownArrows); ui->brew_endDate->show(); ui->brew_endDate->setReadOnly(false); ui->brew_endTime->setButtonSymbols(QAbstractSpinBox::UpDownArrows); ui->brew_endTime->show(); if (product->brew_date_end.isValid() && product->brew_date_start.isValid() && (product->brew_date_start.msecsTo(product->brew_date_end) > 7200000)) { /* The start and end dates are valid, and the end is more then two hours after the start. */ ui->brew_ackLabel->show(); ui->brew_ackButton->show(); } } else { ui->brew_endButton1->hide(); ui->brew_startLabel2->hide(); ui->brew_endLabel->hide(); ui->brew_endLabel2->hide(); ui->brew_startTime->hide(); ui->brew_endDate->hide(); ui->brew_endTime->hide(); } } else { ui->brew_startButton1->hide(); ui->brew_startButton2->hide(); ui->brew_startDate->setReadOnly(true); ui->brew_startLabel2->show(); ui->brew_endLabel->show(); ui->brew_endLabel2->show(); ui->brew_endButton1->hide(); ui->brew_startTime->setButtonSymbols(QAbstractSpinBox::NoButtons); ui->brew_startTime->show(); ui->brew_startTime->setReadOnly(true); ui->brew_endDate->setButtonSymbols(QAbstractSpinBox::NoButtons); ui->brew_endDate->show(); ui->brew_endDate->setReadOnly(true); ui->brew_endTime->setButtonSymbols(QAbstractSpinBox::NoButtons); ui->brew_endTime->show(); ui->brew_endTime->setReadOnly(true); } ui->brew_mashphEdit->setReadOnly(stage > PROD_STAGE_BREW); ui->brew_mashphEdit->setButtonSymbols( (stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->brew_mashsgEdit->setReadOnly(stage > PROD_STAGE_BREW); ui->brew_mashsgEdit->setButtonSymbols( (stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->brew_spargephEdit->setReadOnly(stage > PROD_STAGE_BREW); ui->brew_spargephEdit->setButtonSymbols( (stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->brew_preboilphEdit->setReadOnly(stage > PROD_STAGE_BREW); ui->brew_preboilphEdit->setButtonSymbols( (stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->brew_preboilsgEdit->setReadOnly(stage > PROD_STAGE_BREW); ui->brew_preboilsgEdit->setButtonSymbols( (stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->brew_preboilvolEdit->setReadOnly(stage > PROD_STAGE_BREW); ui->brew_preboilvolEdit->setButtonSymbols( (stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->brew_preboilButton->setDisabled(stage > PROD_STAGE_BREW); ui->brew_aboilphEdit->setReadOnly(stage > PROD_STAGE_BREW); ui->brew_aboilphEdit->setButtonSymbols( (stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->brew_aboilsgEdit->setReadOnly(stage > PROD_STAGE_BREW); ui->brew_aboilsgEdit->setButtonSymbols( (stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->brew_aboilvolEdit->setReadOnly(stage > PROD_STAGE_BREW); ui->brew_aboilvolEdit->setButtonSymbols( (stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->brew_aboilButton->setDisabled(stage > PROD_STAGE_BREW); ui->brew_cooltoEdit->setReadOnly(stage > PROD_STAGE_BREW); ui->brew_cooltoEdit->setButtonSymbols( (stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->brew_cooltimeEdit->setReadOnly(stage > PROD_STAGE_BREW); ui->brew_cooltimeEdit->setButtonSymbols( (stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->brew_coolwithEdit->setDisabled(stage > PROD_STAGE_BREW); ui->brew_whirlpool9Edit->setReadOnly(stage > PROD_STAGE_BREW); ui->brew_whirlpool9Edit->setButtonSymbols( (stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->brew_whirlpool7Edit->setReadOnly(stage > PROD_STAGE_BREW); ui->brew_whirlpool7Edit->setButtonSymbols( (stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->brew_whirlpool6Edit->setReadOnly(stage > PROD_STAGE_BREW); ui->brew_whirlpool6Edit->setButtonSymbols( (stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->brew_whirlpool2Edit->setReadOnly(stage > PROD_STAGE_BREW); ui->brew_whirlpool2Edit->setButtonSymbols( (stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->brew_aerspeedEdit->setReadOnly(stage > PROD_STAGE_BREW); ui->brew_aerspeedEdit->setButtonSymbols( (stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->brew_aertimeEdit->setReadOnly(stage > PROD_STAGE_BREW); ui->brew_aertimeEdit->setButtonSymbols( (stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->brew_aerwithEdit->setDisabled(stage > PROD_STAGE_BREW); ui->brew_trublossEdit->setReadOnly(stage > PROD_STAGE_BREW); ui->brew_trublossEdit->setButtonSymbols( (stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); ui->brew_topupwaterEdit->setReadOnly(stage > PROD_STAGE_BREW); ui->brew_topupwaterEdit->setButtonSymbols( (stage > PROD_STAGE_BREW) ? QAbstractSpinBox::NoButtons : QAbstractSpinBox::UpDownArrows); /* Tab 10, fermentation */ ui->tabWidget->setTabEnabled(9, stage > PROD_STAGE_WAIT); if (product->log_fermentation) { ui->ferm_log1Label->show(); ui->ferm_log1Button->show(); } else { ui->ferm_log1Label->hide(); ui->ferm_log1Button->hide(); } if (product->log_ispindel) { ui->ferm_log2Label->show(); ui->ferm_log2Button->show(); } else { ui->ferm_log2Label->hide(); ui->ferm_log2Button->hide(); } ui->prim_enddateEdit->setReadOnly(true); ui->prim_enddateEdit->setButtonSymbols(QAbstractSpinBox::NoButtons); ui->prim_enddateButton->hide(); ui->prim_ackButton->hide(); ui->sec_enddateEdit->setReadOnly(true); ui->sec_enddateEdit->setButtonSymbols(QAbstractSpinBox::NoButtons); ui->sec_enddateButton->hide(); ui->sec_ackButton->hide(); ui->prim_startCEdit->setReadOnly(product->stage != PROD_STAGE_PRIMARY); ui->prim_startCEdit->setButtonSymbols((product->stage == PROD_STAGE_PRIMARY) ? QAbstractSpinBox::UpDownArrows : QAbstractSpinBox::NoButtons); ui->prim_maxCEdit->setReadOnly(product->stage != PROD_STAGE_PRIMARY); ui->prim_maxCEdit->setButtonSymbols((product->stage == PROD_STAGE_PRIMARY) ? QAbstractSpinBox::UpDownArrows : QAbstractSpinBox::NoButtons); ui->prim_endCEdit->setReadOnly(product->stage != PROD_STAGE_PRIMARY); ui->prim_endCEdit->setButtonSymbols((product->stage == PROD_STAGE_PRIMARY) ? QAbstractSpinBox::UpDownArrows : QAbstractSpinBox::NoButtons); ui->prim_endsgEdit->setReadOnly(product->stage != PROD_STAGE_PRIMARY); ui->prim_endsgEdit->setButtonSymbols((product->stage == PROD_STAGE_PRIMARY) ? QAbstractSpinBox::UpDownArrows : QAbstractSpinBox::NoButtons); if (product->stage == PROD_STAGE_PRIMARY) ui->prim_endsgButton->show(); else ui->prim_endsgButton->hide(); if ((product->primary_start_temp > 0) && (product->primary_max_temp > 0) && (product->primary_end_temp > 0) && (product->primary_end_sg > 0.980) && (product->stage == PROD_STAGE_PRIMARY)) { ui->prim_enddateEdit->setReadOnly(false); ui->prim_enddateEdit->setButtonSymbols(QAbstractSpinBox::UpDownArrows); ui->prim_enddateEdit->setMinimumDate(product->brew_date_end.date()); ui->prim_enddateEdit->setMaximumDate(QDate::currentDate()); ui->prim_enddateButton->show(); if (product->primary_end_date.isValid()) { ui->prim_ackButton->show(); } } ui->sec_tempEdit->setReadOnly(product->stage != PROD_STAGE_SECONDARY); ui->sec_tempEdit->setButtonSymbols((product->stage == PROD_STAGE_SECONDARY) ? QAbstractSpinBox::UpDownArrows : QAbstractSpinBox::NoButtons); ui->sec_sgEdit->setReadOnly(product->stage != PROD_STAGE_SECONDARY); ui->sec_sgEdit->setButtonSymbols((product->stage == PROD_STAGE_SECONDARY) ? QAbstractSpinBox::UpDownArrows : QAbstractSpinBox::NoButtons); if (product->stage == PROD_STAGE_SECONDARY) ui->sec_sgButton->show(); else ui->sec_sgButton->hide(); if ((product->secondary_end_sg > 0.980) && (product->secondary_temp > 0) && (product->stage == PROD_STAGE_SECONDARY)) { ui->sec_enddateEdit->setReadOnly(false); ui->sec_enddateEdit->setButtonSymbols(QAbstractSpinBox::UpDownArrows); ui->sec_enddateEdit->setMinimumDate(product->primary_end_date.addDays(-1)); // Allow same date as primary end. ui->sec_enddateEdit->setMaximumDate(QDate::currentDate()); ui->sec_enddateButton->show(); if (product->secondary_end_date.isValid()) { ui->sec_ackButton->show(); } } ui->tert_tempEdit->setReadOnly(product->stage != PROD_STAGE_TERTIARY); ui->tert_tempEdit->setButtonSymbols((product->stage == PROD_STAGE_TERTIARY) ? QAbstractSpinBox::UpDownArrows : QAbstractSpinBox::NoButtons); ui->tert_sgEdit->setReadOnly(product->stage != PROD_STAGE_TERTIARY); ui->tert_sgEdit->setButtonSymbols((product->stage == PROD_STAGE_TERTIARY) ? QAbstractSpinBox::UpDownArrows : QAbstractSpinBox::NoButtons); if (product->stage == PROD_STAGE_TERTIARY) ui->tert_sgButton->show(); else ui->tert_sgButton->hide(); /* Tab 11, packaging */ ui->tabWidget->setTabEnabled(10, stage > PROD_STAGE_PLAN); bool pack = ((stage > PROD_STAGE_PLAN) && (stage <= PROD_STAGE_PACKAGE)) ? true:false; ui->pack_volumeEdit->setReadOnly(! pack); ui->pack_volumeEdit->setButtonSymbols((pack) ? QAbstractSpinBox::UpDownArrows : QAbstractSpinBox::NoButtons); ui->pack_phEdit->setReadOnly(! pack); ui->pack_phEdit->setButtonSymbols((pack) ? QAbstractSpinBox::UpDownArrows : QAbstractSpinBox::NoButtons); ui->pack_addvolEdit->setReadOnly(! pack); ui->pack_addvolEdit->setButtonSymbols((pack) ? QAbstractSpinBox::UpDownArrows : QAbstractSpinBox::NoButtons); ui->pack_addabvEdit->setReadOnly(! pack); ui->pack_addabvEdit->setButtonSymbols((pack) ? QAbstractSpinBox::UpDownArrows : QAbstractSpinBox::NoButtons); ui->pack_notesEdit->setReadOnly(! pack); ui->bottle_volumeEdit->setReadOnly(! pack); ui->bottle_volumeEdit->setButtonSymbols((pack) ? QAbstractSpinBox::UpDownArrows : QAbstractSpinBox::NoButtons); ui->bottle_carbEdit->setReadOnly(! pack); ui->bottle_carbEdit->setButtonSymbols((pack) ? QAbstractSpinBox::UpDownArrows : QAbstractSpinBox::NoButtons); ui->bottle_sugarEdit->setDisabled(! pack); ui->bottle_sug_waterEdit->setReadOnly(! pack); ui->bottle_sug_waterEdit->setButtonSymbols((pack) ? QAbstractSpinBox::UpDownArrows : QAbstractSpinBox::NoButtons); ui->bottle_tempEdit->setReadOnly(! pack); ui->bottle_tempEdit->setButtonSymbols((pack) ? QAbstractSpinBox::UpDownArrows : QAbstractSpinBox::NoButtons); ui->keg_volumeEdit->setReadOnly(! pack); ui->keg_volumeEdit->setButtonSymbols((pack) ? QAbstractSpinBox::UpDownArrows : QAbstractSpinBox::NoButtons); ui->keg_carbEdit->setReadOnly(! pack); ui->keg_carbEdit->setButtonSymbols((pack) ? QAbstractSpinBox::UpDownArrows : QAbstractSpinBox::NoButtons); ui->keg_sugarEdit->setDisabled(! pack); ui->keg_sug_waterEdit->setReadOnly(! pack); ui->keg_sug_waterEdit->setButtonSymbols((pack) ? QAbstractSpinBox::UpDownArrows : QAbstractSpinBox::NoButtons); ui->keg_tempEdit->setReadOnly(! pack); ui->keg_tempEdit->setButtonSymbols((pack) ? QAbstractSpinBox::UpDownArrows : QAbstractSpinBox::NoButtons); ui->keg_forcedEdit->setDisabled(! pack); ui->pack_dateEdit->setReadOnly(true); ui->pack_dateEdit->setButtonSymbols(QAbstractSpinBox::NoButtons); ui->pack_dateButton->hide(); ui->pack_ackButton->hide(); if (product->log_co2pressure) { ui->carb_logLabel->show(); ui->carb_logButton->show(); } else { ui->carb_logLabel->hide(); ui->carb_logButton->hide(); } if (((stage == PROD_STAGE_TERTIARY) || (stage == PROD_STAGE_PACKAGE)) && (product->package_volume > 1) && ((product->bottle_amount + product->keg_amount) > 1)) { ui->pack_dateEdit->setReadOnly(false); ui->pack_dateEdit->setButtonSymbols(QAbstractSpinBox::UpDownArrows); ui->pack_dateEdit->setMinimumDate(product->secondary_end_date.addDays(-1)); // Allow same date as secondary end. ui->pack_dateEdit->setMaximumDate(QDate::currentDate()); ui->pack_dateButton->show(); if (stage == PROD_STAGE_PACKAGE) ui->pack_ackButton->show(); } /* Tab 12, tasting */ ui->tabWidget->setTabEnabled(11, stage > PROD_STAGE_PACKAGE); ui->taste_dateEdit->setEnabled(stage == PROD_STAGE_TASTE); if (stage == PROD_STAGE_TASTE) { ui->taste_dateEdit->setMinimumDate(product->package_date.addDays(41)); ui->taste_dateEdit->setMaximumDate(QDate::currentDate()); } ui->taste_dateButton->setEnabled(stage == PROD_STAGE_TASTE); ui->taste_colorEdit->setEnabled(stage == PROD_STAGE_TASTE); ui->taste_transparencyEdit->setEnabled(stage == PROD_STAGE_TASTE); ui->taste_headEdit->setEnabled(stage == PROD_STAGE_TASTE); ui->taste_aromaEdit->setEnabled(stage == PROD_STAGE_TASTE); ui->taste_tasteEdit->setEnabled(stage == PROD_STAGE_TASTE); ui->taste_mouthfeelEdit->setEnabled(stage == PROD_STAGE_TASTE); ui->taste_aftertasteEdit->setEnabled(stage == PROD_STAGE_TASTE); ui->taste_notesEdit->setEnabled(stage == PROD_STAGE_TASTE); ui->taste_rateEdit->setEnabled(stage == PROD_STAGE_TASTE); if ((product->taste_color != "") && (product->taste_transparency != "") && (product->taste_head != "") && (product->taste_aroma != "") && (product->taste_taste != "") && (product->taste_mouthfeel != "") && (product->taste_aftertaste != "") && (product->taste_notes != "") && (product->taste_rate > 0) && (product->taste_date.isValid() && (stage == PROD_STAGE_TASTE))) ui->taste_ackButton->show(); else ui->taste_ackButton->hide(); } void EditProduct::reduce_fermentable(int i) { QSqlQuery query; query.prepare("SELECT record,inventory FROM inventory_fermentables WHERE name=:name AND origin=:origin AND supplier=:supplier LIMIT 1"); query.bindValue(":name", product->fermentables.at(i).name); query.bindValue(":origin", product->fermentables.at(i).origin); query.bindValue(":supplier", product->fermentables.at(i).supplier); query.exec(); if (query.first()) { int record = query.value("record").toInt(); double inventory = query.value("inventory").toDouble() - product->fermentables.at(i).amount; if (inventory < 0) inventory = 0; else inventory = round(inventory * 100000) / 100000; query.prepare("UPDATE inventory_fermentables SET inventory=:inventory WHERE record=:record"); query.bindValue(":inventory", inventory ); query.bindValue(":record", record); query.exec(); if (query.lastError().isValid()) { qWarning() << "UPDATE inventory_fermentables" << query.lastError(); } else { qInfo() << " Reduced" << product->fermentables.at(i).name << "to" << inventory; } } else { qWarning() << " Fermentable" << product->fermentables.at(i).name << "not found"; } } void EditProduct::reduce_hop(int i) { QSqlQuery query; query.prepare("SELECT record,inventory FROM inventory_hops WHERE name=:name AND origin=:origin AND form=:form LIMIT 1"); query.bindValue(":name", product->hops.at(i).name); query.bindValue(":origin", product->hops.at(i).origin); query.bindValue(":form", product->hops.at(i).form); query.exec(); if (query.first()) { int record = query.value("record").toInt(); double inventory = query.value("inventory").toDouble() - product->hops.at(i).amount; if (inventory < 0) inventory = 0; else inventory = round(inventory * 100000) / 100000; query.prepare("UPDATE inventory_hops SET inventory=:inventory WHERE record=:record"); query.bindValue(":inventory", inventory ); query.bindValue(":record", record); query.exec(); if (query.lastError().isValid()) { qWarning() << "UPDATE inventory_hops" << query.lastError(); } else { qInfo() << " Reduced" << product->hops.at(i).name << "to" << inventory; } } else { qWarning() << " Hop" << product->hops.at(i).name << "not found"; } } void EditProduct::reduce_misc(int i) { QSqlQuery query; query.prepare("SELECT record,inventory FROM inventory_miscs WHERE name=:name LIMIT 1"); query.bindValue(":name", product->miscs.at(i).name); query.exec(); if (query.first()) { int record = query.value("record").toInt(); double inventory = query.value("inventory").toDouble() - product->miscs.at(i).amount; if (inventory < 0) inventory = 0; else inventory = round(inventory * 100000) / 100000; query.prepare("UPDATE inventory_miscs SET inventory=:inventory WHERE record=:record"); query.bindValue(":inventory", inventory ); query.bindValue(":record", record); query.exec(); if (query.lastError().isValid()) { qWarning() << "UPDATE inventory_miscs" << query.lastError(); } else { qInfo() << " Reduced" << product->miscs.at(i).name << "to" << inventory; } } else { qWarning() << " Misc" << product->miscs.at(i).name << "not found"; } } void EditProduct::reduce_yeast(int i) { QSqlQuery query; query.prepare("SELECT record,inventory FROM inventory_yeasts WHERE name=:name AND laboratory=:laboratory AND product_id=:product_id AND form=:form LIMIT 1"); query.bindValue(":name", product->yeasts.at(i).name); query.bindValue(":laboratory", product->yeasts.at(i).laboratory); query.bindValue(":product_id", product->yeasts.at(i).product_id); query.bindValue(":form", product->yeasts.at(i).form); query.exec(); if (query.first()) { int record = query.value("record").toInt(); double inventory = query.value("inventory").toDouble() - product->yeasts.at(i).amount; if (inventory < 0) inventory = 0; else inventory = round(inventory * 100000) / 100000; query.prepare("UPDATE inventory_yeasts SET inventory=:inventory WHERE record=:record"); query.bindValue(":inventory", inventory ); query.bindValue(":record", record); query.exec(); if (query.lastError().isValid()) { qWarning() << "UPDATE inventory_yeasts" << query.lastError(); } else { qInfo() << " Reduced" << product->yeasts.at(i).name << "to" << inventory; } } else { qWarning() << " Yeast" << product->yeasts.at(i).name << "not found"; } } /* * Reduce inventory depending on the production stage. * Stage PROD_STAGE_BREW+, after brew, reduce sugars(0-mash, 1-boil), hops(0-mash, 1-fwh, 2-boil, 3-aroma, 4-whirlpool), miscs(0-starter, 1-mash, 2-boil) * Stage PROD_STAGE_PRIMARY+, after primary, reduce sugars(2-fermention), yeasts(0-Primary), miscs(3-primary) * Stage PROD_STAGE_SECONDARY+, after secondary, reduce yeasts(1-Secondary) * Stage PROD_STAGE_TERTIARY+, after tertiary, reduce sugars(3-lagering), hops(5-dry-hop), yeasts(2-Tertiary), miscs(4-secondary) * Stage PROD_STAGE_PACKAGE+, after packaging, reduce sugars(4-bottle, 5-kegs), hops( Extract ), yeasts(3-Bottle), miscs(5-bottling) */ void EditProduct::inventory_reduce() { bool savethis = false; QSqlQuery query; if (product->stage == product->inventory_reduced) return; /* * Nothing to reduce yet, but just set inventory reduced. */ if ((product->stage >= PROD_STAGE_WAIT) && (product->inventory_reduced < PROD_STAGE_WAIT)) { product->inventory_reduced = PROD_STAGE_WAIT; savethis = true; } if ((product->stage >= PROD_STAGE_BREW) && (product->inventory_reduced < PROD_STAGE_BREW)) { product->inventory_reduced = PROD_STAGE_BREW; savethis = true; } /* * If the brew is done, reduce the used ingredients. */ if ((product->stage >= PROD_STAGE_PRIMARY) && (product->inventory_reduced < PROD_STAGE_PRIMARY)) { qInfo() << "Reduce brew inventory from" << product->code << product->name; if (product->fermentables.size()) { for (int i = 0; i < product->fermentables.size(); i++) { if (product->fermentables.at(i).added <= FERMENTABLE_ADDED_BOIL) { /* Mash or boil */ reduce_fermentable(i); } } } if (product->hops.size()) { for (int i = 0; i < product->hops.size(); i++) { if (product->hops.at(i).useat <= HOP_USEAT_WHIRLPOOL) { /* Mash, FWH, Boil, Flameout, Whirlpool */ reduce_hop(i); } } } if (product->miscs.size()) { for (int i = 0; i < product->miscs.size(); i++) { if (product->miscs.at(i).use_use <= MISC_USES_BOIL) { /* Starter, Mash, Boil */ reduce_misc(i); } } } if ((product->w1_name != "") && (product->w1_amount > 0)) { query.prepare("SELECT record,inventory FROM inventory_waters WHERE name=:name AND unlimited_stock=0 LIMIT 1"); query.bindValue(":name", product->w1_name); query.exec(); if (query.first()) { int record = query.value("record").toInt(); double inventory = query.value("inventory").toDouble() - product->w1_amount; if (inventory < 0) inventory = 0; else inventory = round(inventory * 100) / 100; query.prepare("UPDATE inventory_waters SET inventory=:inventory WHERE record=:record"); query.bindValue(":inventory", inventory ); query.bindValue(":record", record); query.exec(); if (query.lastError().isValid()) { qWarning() << "UPDATE inventory_waters" << query.lastError(); } else { qInfo() << " Reduced" << product->w1_name << "to" << inventory; } } } if ((product->w2_name != "") && (product->w2_amount > 0)) { query.prepare("SELECT record,inventory FROM inventory_waters WHERE name=:name AND unlimited_stock=0 LIMIT 1"); query.bindValue(":name", product->w1_name); query.exec(); if (query.first()) { int record = query.value("record").toInt(); double inventory = query.value("inventory").toDouble() - product->w1_amount; if (inventory < 0) inventory = 0; else inventory = round(inventory * 100) / 100; query.prepare("UPDATE inventory_waters SET inventory=:inventory WHERE record=:record"); query.bindValue(":inventory", inventory ); query.bindValue(":record", record); query.exec(); if (query.lastError().isValid()) { qWarning() << "UPDATE inventory_waters" << query.lastError(); } else { qInfo() << " Reduced" << product->w1_name << "to" << inventory; } } } product->inventory_reduced = PROD_STAGE_PRIMARY; savethis = true; } /* * After the Primary fermentation */ if ((product->stage >= PROD_STAGE_SECONDARY) && (product->inventory_reduced < PROD_STAGE_SECONDARY)) { qInfo() << "Reduce primary inventory from" << product->code << product->name; if (product->fermentables.size()) { for (int i = 0; i < product->fermentables.size(); i++) { if (product->fermentables.at(i).added == FERMENTABLE_ADDED_FERMENTATION) { reduce_fermentable(i); } } } if (product->miscs.size()) { for (int i = 0; i < product->miscs.size(); i++) { if (product->miscs.at(i).use_use == MISC_USES_PRIMARY) { reduce_misc(i); } } } if (product->yeasts.size()) { for (int i = 0; i < product->yeasts.size(); i++) { if (product->yeasts.at(i).use == YEAST_USE_PRIMARY) { reduce_yeast(i); } } } product->inventory_reduced = PROD_STAGE_SECONDARY; savethis = true; } /* * After the Seconday fermentation */ if ((product->stage >= PROD_STAGE_TERTIARY) && (product->inventory_reduced < PROD_STAGE_TERTIARY)) { qInfo() << "Reduce secondary inventory from" << product->code << product->name; if (product->yeasts.size()) { for (int i = 0; i < product->yeasts.size(); i++) { if (product->yeasts.at(i).use == YEAST_USE_SECONDARY) { reduce_yeast(i); } } } product->inventory_reduced = PROD_STAGE_TERTIARY; savethis = true; } /* * After the Tertiary fermentation */ if ((product->stage >= PROD_STAGE_PACKAGE) && (product->inventory_reduced < PROD_STAGE_PACKAGE)) { qInfo() << "Reduce tertiary inventory from" << product->code << product->name; if (product->fermentables.size()) { for (int i = 0; i < product->fermentables.size(); i++) { if (product->fermentables.at(i).added == FERMENTABLE_ADDED_LAGERING) { reduce_fermentable(i); } } } if (product->hops.size()) { for (int i = 0; i < product->hops.size(); i++) { if (product->hops.at(i).useat == HOP_USEAT_DRY_HOP) { reduce_hop(i); } } } if (product->miscs.size()) { for (int i = 0; i < product->miscs.size(); i++) { if (product->miscs.at(i).use_use == MISC_USES_SECONDARY) { reduce_misc(i); } } } if (product->yeasts.size()) { for (int i = 0; i < product->yeasts.size(); i++) { if (product->yeasts.at(i).use == YEAST_USE_TERTIARY) { reduce_yeast(i); } } } product->inventory_reduced = PROD_STAGE_PACKAGE; savethis = true; } /* * After packaging * reduce sugars(4/5-bottle), yeasts(3-Bottle), miscs(5-bottling) */ if ((product->stage >= PROD_STAGE_CARBONATION) && (product->inventory_reduced < PROD_STAGE_CARBONATION)) { qInfo() << "Reduce package inventory from" << product->code << product->name; if (product->fermentables.size()) { for (int i = 0; i < product->fermentables.size(); i++) { if (product->fermentables.at(i).added >= FERMENTABLE_ADDED_BOTTLE) { reduce_fermentable(i); } } } if (product->yeasts.size()) { for (int i = 0; i < product->yeasts.size(); i++) { if (product->yeasts.at(i).use == YEAST_USE_BOTTLE) { reduce_yeast(i); } } } if (product->hops.size()) { for (int i = 0; i < product->hops.size(); i++) { if (product->hops.at(i).useat == HOP_USEAT_BOTTLING) { reduce_hop(i); } } } if (product->miscs.size()) { for (int i = 0; i < product->miscs.size(); i++) { if (product->miscs.at(i).use_use == MISC_USES_BOTTLING) { reduce_misc(i); } } } product->inventory_reduced = PROD_STAGE_CARBONATION; savethis = true; } if ((product->stage >= PROD_STAGE_MATURE) && (product->inventory_reduced < PROD_STAGE_MATURE)) { product->inventory_reduced = product->stage; savethis = true; } /* * Update the inventory_reduced state. */ if (savethis) { query.prepare("UPDATE products SET inventory_reduced=:inventory_reduced WHERE record=:record"); query.bindValue(":record", product->record); query.bindValue(":inventory_reduced", product->inventory_reduced); query.exec(); if (query.lastError().isValid()) { qWarning() << "UPDATE products" << query.lastError(); } } }