|
1 /** |
|
2 * EditYeastPack.cpp is part of bmsapp. |
|
3 * |
|
4 * bmsapp is free software: you can redistribute it and/or modify |
|
5 * it under the terms of the GNU General Public License as published by |
|
6 * the Free Software Foundation, either version 3 of the License, or |
|
7 * (at your option) any later version. |
|
8 * |
|
9 * bmsapp is distributed in the hope that it will be useful, |
|
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 * GNU General Public License for more details. |
|
13 * |
|
14 * You should have received a copy of the GNU General Public License |
|
15 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
16 */ |
|
17 #include "EditYeastPack.h" |
|
18 #include "../ui/ui_EditYeastPack.h" |
|
19 #include "MainWindow.h" |
|
20 #include "global.h" |
|
21 |
|
22 |
|
23 EditYeastPack::EditYeastPack(int id, QWidget *parent) : QDialog(parent), ui(new Ui::EditYeastPack) |
|
24 { |
|
25 QSqlQuery query; |
|
26 |
|
27 qDebug() << "EditYeastPack record:" << id; |
|
28 ui->setupUi(this); |
|
29 this->recno = id; |
|
30 |
|
31 WindowTitle(); |
|
32 |
|
33 ui->formEdit->addItem(tr("Liquid")); |
|
34 ui->formEdit->addItem(tr("Dry")); |
|
35 ui->formEdit->addItem(tr("Slant")); |
|
36 ui->formEdit->addItem(tr("Culture")); |
|
37 ui->formEdit->addItem(tr("Frozen")); |
|
38 ui->formEdit->addItem(tr("Bottle")); |
|
39 ui->formEdit->addItem(tr("Dried")); |
|
40 |
|
41 if (id >= 0) { |
|
42 query.prepare("SELECT * FROM inventory_yeastpack WHERE record = :recno"); |
|
43 query.bindValue(":recno", id); |
|
44 query.exec(); |
|
45 query.next(); |
|
46 |
|
47 ui->laboratoryEdit->setText(query.value("laboratory").toString()); |
|
48 ui->packageEdit->setText(query.value("package").toString()); |
|
49 ui->formEdit->setCurrentIndex(query.value("form").toInt()); |
|
50 ui->notesEdit->setPlainText(query.value("notes").toString()); |
|
51 ui->cellsEdit->setValue(query.value("cells").toDouble() / 1000000000); |
|
52 ui->viabilityEdit->setValue(query.value("viability").toDouble()); |
|
53 ui->maxEdit->setValue(query.value("max").toInt()); |
|
54 ui->sizeEdit->setValue(query.value("size").toDouble() * 1000); |
|
55 ui->usedEdit->setValue(query.value("used").toInt()); |
|
56 |
|
57 } else { |
|
58 /* Set some defaults */ |
|
59 ui->formEdit->setCurrentIndex(YEAST_FORMS_DRY); |
|
60 ui->viabilityEdit->setValue(0.99); |
|
61 ui->maxEdit->setValue(100); |
|
62 ui->usedEdit->setValue(0); |
|
63 } |
|
64 |
|
65 PackSet(); |
|
66 Viability(); |
|
67 connect(ui->laboratoryEdit, &QLineEdit::textChanged, this, &EditYeastPack::is_changed); |
|
68 connect(ui->formEdit, &QComboBox::currentTextChanged, this, &EditYeastPack::form_changed); |
|
69 connect(ui->packageEdit, &QLineEdit::textChanged, this, &EditYeastPack::is_changed); |
|
70 connect(ui->notesEdit, SIGNAL(textChanged()), this, SLOT(is_changed())); |
|
71 connect(ui->cellsEdit, &QDoubleSpinBox::textChanged, this, &EditYeastPack::is_changed); |
|
72 connect(ui->viabilityEdit, &QDoubleSpinBox::textChanged, this, &EditYeastPack::viability_changed); |
|
73 connect(ui->maxEdit, &QSpinBox::textChanged, this, &EditYeastPack::viability_changed); |
|
74 connect(ui->sizeEdit, &QDoubleSpinBox::textChanged, this, &EditYeastPack::is_changed); |
|
75 |
|
76 ui->saveButton->setEnabled(false); |
|
77 } |
|
78 |
|
79 |
|
80 EditYeastPack::~EditYeastPack() |
|
81 { |
|
82 delete ui; |
|
83 emit entry_changed(); |
|
84 } |
|
85 |
|
86 |
|
87 /* |
|
88 * Window header, mark any change with '**' |
|
89 */ |
|
90 void EditYeastPack::WindowTitle() |
|
91 { |
|
92 QString txt; |
|
93 |
|
94 if (this->recno < 0) { |
|
95 txt = QString(tr("BMSapp - Add new yeast package")); |
|
96 } else { |
|
97 txt = QString(tr("BMSapp - Edit yeast package %1").arg(this->recno)); |
|
98 } |
|
99 |
|
100 if (this->textIsChanged) { |
|
101 txt.append((QString(" **"))); |
|
102 } |
|
103 setWindowTitle(txt); |
|
104 } |
|
105 |
|
106 |
|
107 void EditYeastPack::on_saveButton_clicked() |
|
108 { |
|
109 QSqlQuery query; |
|
110 |
|
111 /* If there are errors in the form, show a message and do "return;" */ |
|
112 if (ui->laboratoryEdit->text().length() < 2) { |
|
113 QMessageBox::warning(this, tr("Edit Yeast Package"), tr("Laboratory name empty or too short.")); |
|
114 return; |
|
115 } |
|
116 if (ui->packageEdit->text().length() < 2) { |
|
117 QMessageBox::warning(this, tr("Edit Yeast Package"), tr("Package name empty or too short.")); |
|
118 return; |
|
119 } |
|
120 |
|
121 if (this->textIsChanged) { |
|
122 if (this->recno == -1) { |
|
123 query.prepare("INSERT INTO inventory_yeastpack SET laboratory=:laboratory, form=:form, " |
|
124 "package=:package, notes=:notes, cells=:cells, viability=:viability, max=:max, " |
|
125 "size=:size, used='0', uuid = :uuid"); |
|
126 } else { |
|
127 query.prepare("UPDATE inventory_yeastpack SET laboratory=:laboratory, form=:form, " |
|
128 "package=:package, notes=:notes, cells=:cells, viability=:viability, max=:max, " |
|
129 "size=:size WHERE record = :recno"); |
|
130 } |
|
131 query.bindValue(":laboratory", ui->laboratoryEdit->text()); |
|
132 query.bindValue(":form", ui->formEdit->currentIndex()); |
|
133 query.bindValue(":package", ui->packageEdit->text()); |
|
134 query.bindValue(":notes", ui->notesEdit->toPlainText()); |
|
135 query.bindValue(":cells", QString("%1").arg(ui->cellsEdit->value() * 1000000000, 1, 'f', 0, '0')); |
|
136 query.bindValue(":viability", QString("%1").arg(ui->viabilityEdit->value(), 5, 'f', 4, '0')); |
|
137 query.bindValue(":max", ui->maxEdit->value()); |
|
138 query.bindValue(":size", QString("%1").arg(ui->sizeEdit->value() / 1000, 5, 'f', 4, '0')); |
|
139 if (this->recno == -1) { |
|
140 query.bindValue(":uuid", QUuid::createUuid().toString().mid(1, 36)); |
|
141 } else { |
|
142 query.bindValue(":recno", this->recno); |
|
143 } |
|
144 query.exec(); |
|
145 if (query.lastError().isValid()) { |
|
146 qWarning() << "EditYeastPack" << query.lastError(); |
|
147 QMessageBox::warning(this, tr("Database error"), |
|
148 tr("MySQL error: %1\n%2\n%3") |
|
149 .arg(query.lastError().nativeErrorCode()) |
|
150 .arg(query.lastError().driverText()) |
|
151 .arg(query.lastError().databaseText())); |
|
152 } else { |
|
153 qDebug() << "EditYeastPack Saved"; |
|
154 } |
|
155 } |
|
156 |
|
157 ui->saveButton->setEnabled(false); |
|
158 this->textIsChanged = false; |
|
159 WindowTitle(); |
|
160 } |
|
161 |
|
162 |
|
163 void EditYeastPack::on_cloneButton_clicked() |
|
164 { |
|
165 QSqlQuery query; |
|
166 query.prepare("INSERT INTO inventory_yeastpack SET laboratory=:laboratory, form=:form, " |
|
167 "package=:package, notes=:notes, cells=:cells, viability=:viability, max=:max, " |
|
168 "size=:size, used=:used, uuid=:uuid"); |
|
169 query.bindValue(":laboratory", ui->laboratoryEdit->text()); |
|
170 query.bindValue(":form", ui->formEdit->currentIndex()); |
|
171 query.bindValue(":package", ui->packageEdit->text() + " [copy]"); |
|
172 query.bindValue(":notes", ui->notesEdit->toPlainText()); |
|
173 query.bindValue(":cells", QString("%1").arg(ui->cellsEdit->value() * 1000000000, 1, 'f', 0, '0')); |
|
174 query.bindValue(":viability", QString("%1").arg(ui->viabilityEdit->value(), 5, 'f', 4, '0')); |
|
175 query.bindValue(":max", ui->maxEdit->value()); |
|
176 query.bindValue(":size", QString("%1").arg(ui->sizeEdit->value() / 1000, 5, 'f', 4, '0')); |
|
177 query.bindValue(":used", ui->usedEdit->value()); |
|
178 query.bindValue(":uuid", QUuid::createUuid().toString().mid(1, 36)); |
|
179 query.exec(); |
|
180 if (query.lastError().isValid()) { |
|
181 qWarning() << "EditYeastPack" << query.lastError(); |
|
182 QMessageBox::warning(this, tr("Database error"), |
|
183 tr("MySQL error: %1\n%2\n%3") |
|
184 .arg(query.lastError().nativeErrorCode()) |
|
185 .arg(query.lastError().driverText()) |
|
186 .arg(query.lastError().databaseText())); |
|
187 } else { |
|
188 qDebug() << "EditYeastPack Clone saved"; |
|
189 } |
|
190 } |
|
191 |
|
192 |
|
193 void EditYeastPack::on_deleteButton_clicked() |
|
194 { |
|
195 QSqlQuery query; |
|
196 |
|
197 int rc = QMessageBox::warning(this, tr("Delete yeast pack"), tr("Delete %1").arg(ui->packageEdit->text()), |
|
198 QMessageBox::Yes | QMessageBox::No, QMessageBox::No); |
|
199 if (rc == QMessageBox::No) |
|
200 return; |
|
201 |
|
202 query.prepare("DELETE FROM inventory_yeastpack WHERE record = :recno"); |
|
203 query.bindValue(":recno", this->recno); |
|
204 query.exec(); |
|
205 if (query.lastError().isValid()) { |
|
206 qWarning() << "EditYeastPack" << query.lastError(); |
|
207 QMessageBox::warning(this, tr("Database error"), |
|
208 tr("MySQL error: %1\n%2\n%3") |
|
209 .arg(query.lastError().nativeErrorCode()) |
|
210 .arg(query.lastError().driverText()) |
|
211 .arg(query.lastError().databaseText())); |
|
212 } else { |
|
213 qDebug() << "EditYeastPack Deleted" << this->recno; |
|
214 } |
|
215 |
|
216 this->close(); |
|
217 this->setResult(1); |
|
218 } |
|
219 |
|
220 |
|
221 void EditYeastPack::Viability() |
|
222 { |
|
223 double vpm = ui->viabilityEdit->value(); |
|
224 double max = ui->maxEdit->value(); |
|
225 double degrade = 1 - ((1 - vpm) / 30.41); /* viability degradation per day. */ |
|
226 double base = max; |
|
227 |
|
228 for (int i = 0; i < 182; i++) { |
|
229 base = base * degrade; |
|
230 } |
|
231 if (base > max) |
|
232 base = max; |
|
233 |
|
234 ui->resultEdit->setValue(base); |
|
235 qDebug() << "Viability()" << vpm << max << degrade << base; |
|
236 } |
|
237 |
|
238 |
|
239 void EditYeastPack::PackSet() |
|
240 { |
|
241 if (ui->formEdit->currentIndex() == YEAST_FORMS_DRY || ui->formEdit->currentIndex() == YEAST_FORMS_DRIED) { |
|
242 ui->sizeEdit->setSuffix(tr(" gr")); |
|
243 } else { |
|
244 ui->sizeEdit->setSuffix(tr(" ml")); |
|
245 } |
|
246 |
|
247 /* |
|
248 * TODO: The delete button may be enabled for records with used > 0 if |
|
249 * there are more records with the same laboratory and form. |
|
250 * There should always be at least one record, the rest is allowed to |
|
251 * be deleted. So, we need to count. |
|
252 */ |
|
253 |
|
254 if (ui->usedEdit->value() > 0) { |
|
255 ui->laboratoryEdit->setReadOnly(true); |
|
256 ui->formEdit->setDisabled(true); |
|
257 ui->deleteButton->setEnabled(false); |
|
258 qDebug() << "PackSet blocked"; |
|
259 } else { |
|
260 ui->laboratoryEdit->setReadOnly(false); |
|
261 ui->formEdit->setDisabled(false); |
|
262 ui->deleteButton->setEnabled(true); |
|
263 } |
|
264 } |
|
265 |
|
266 |
|
267 void EditYeastPack::is_changed() |
|
268 { |
|
269 ui->saveButton->setEnabled(true); |
|
270 this->textIsChanged = true; |
|
271 WindowTitle(); |
|
272 } |
|
273 |
|
274 |
|
275 void EditYeastPack::form_changed() |
|
276 { |
|
277 PackSet(); |
|
278 is_changed(); |
|
279 } |
|
280 |
|
281 |
|
282 void EditYeastPack::viability_changed() |
|
283 { |
|
284 Viability(); |
|
285 is_changed(); |
|
286 } |
|
287 |
|
288 |
|
289 void EditYeastPack::on_quitButton_clicked() |
|
290 { |
|
291 if (this->textIsChanged) { |
|
292 int rc = QMessageBox::warning(this, tr("Yeast package changed"), tr("The yeast package has been modified. Save changes?"), |
|
293 QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Save); |
|
294 switch (rc) { |
|
295 case QMessageBox::Save: |
|
296 on_saveButton_clicked(); |
|
297 break; /* Saved and then Quit */ |
|
298 case QMessageBox::Discard: |
|
299 break; /* Quit without Save */ |
|
300 case QMessageBox::Cancel: |
|
301 return; /* Return to the editor page */ |
|
302 } |
|
303 } |
|
304 |
|
305 this->close(); |
|
306 this->setResult(1); |
|
307 } |
|
308 |