src/database/db_product.cpp

changeset 248
1a7a5dffba58
child 256
c136bd15b084
equal deleted inserted replaced
247:a789ceedfe0c 248:1a7a5dffba58
1 /**
2 * db_product.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
18 #include "global.h"
19 #include "db_product.h"
20
21
22 bool DB_product::load(Product *prod, QDialog *dialog, int recno)
23 {
24 QSqlQuery query, yquery;
25
26 query.prepare("SELECT * FROM products WHERE record = :recno");
27 query.bindValue(":recno", recno);
28 query.exec();
29 if (! query.first()) {
30 qDebug() << "loadProduct seek error record" << recno;
31 QMessageBox::warning(dialog, QObject::tr("Database error"), QObject::tr("MySQL error: record %1 not found").arg(recno));
32 dialog->done(QDialog::Rejected); // At this stage, this doesn't work because the dialog is not yet visible.
33 return false;
34 }
35
36 QSqlRecord rec = query.record();
37 for (int i = 0; i < rec.count(); i++)
38 qDebug() << i << rec.fieldName(i) << query.value(i);
39
40 prod->record = query.value("record").toInt();
41 prod->uuid = query.value("uuid").toString();
42 prod->name = query.value("name").toString();
43 prod->code = query.value("code").toString();
44 prod->birth = query.value("birth").toDate();
45 prod->stage = query.value("stage").toInt();
46 prod->notes = query.value("notes").toString();
47 prod->log_brew = query.value("log_brew").toInt() ? true:false;
48 prod->log_fermentation = query.value("log_fermentation").toInt() ? true:false;
49 prod->log_ispindel = query.value("log_ispindel").toInt() ? true:false;
50 prod->log_co2pressure = query.value("log_co2pressure").toInt() ? true:false;
51 prod->inventory_reduced = query.value("inventory_reduced").toInt();
52 prod->locked = query.value("locked").toInt() ? true:false;
53
54 prod->eq_name = query.value("eq_name").toString();
55 prod->eq_notes = query.value("eq_notes").toString();
56 prod->eq_boil_size = query.value("eq_boil_size").toDouble();
57 prod->eq_batch_size = query.value("eq_batch_size").toDouble();
58 prod->eq_tun_volume = query.value("eq_tun_volume").toDouble();
59 prod->eq_tun_weight = query.value("eq_tun_weight").toDouble();
60 prod->eq_tun_specific_heat = query.value("eq_tun_specific_heat").toDouble();
61 prod->eq_tun_material = query.value("eq_tun_material").toInt();
62 prod->eq_tun_height = query.value("eq_tun_height").toDouble();
63 prod->eq_top_up_water = query.value("eq_top_up_water").toDouble();
64 prod->eq_trub_chiller_loss = query.value("eq_trub_chiller_loss").toDouble();
65 prod->eq_evap_rate = query.value("eq_evap_rate").toDouble();
66 prod->eq_boil_time = query.value("eq_boil_time").toDouble();
67 prod->eq_calc_boil_volume = query.value("eq_calc_boil_volume").toInt() ? true:false;
68 prod->eq_top_up_kettle = query.value("eq_top_up_kettle").toDouble();
69 prod->eq_hop_utilization = query.value("eq_hop_utilization").toDouble();
70 prod->eq_lauter_volume = query.value("eq_lauter_volume").toDouble();
71 prod->eq_lauter_height = query.value("eq_lauter_height").toDouble();
72 prod->eq_lauter_deadspace = query.value("eq_lauter_deadspace").toDouble();
73 prod->eq_kettle_volume = query.value("eq_kettle_volume").toDouble();
74 prod->eq_kettle_height = query.value("eq_kettle_height").toDouble();
75 prod->eq_mash_volume = query.value("eq_mash_volume").toDouble();
76 prod->eq_mash_max = query.value("eq_mash_max").toDouble();
77 prod->eq_efficiency = query.value("eq_efficiency").toDouble();
78
79 prod->brew_date_start = query.value("brew_date_start").toDateTime();
80 prod->brew_mash_ph = query.value("brew_mash_ph").toDouble();
81 prod->brew_mash_sg = query.value("brew_mash_sg").toDouble();
82 prod->brew_mash_efficiency = query.value("brew_mash_efficiency").toDouble();
83 prod->brew_sparge_temperature = query.value("brew_sparge_temperature").toDouble();
84 prod->brew_sparge_volume = query.value("brew_sparge_volume").toDouble();
85 prod->brew_sparge_est = query.value("brew_sparge_est").toDouble();
86 prod->brew_sparge_ph = query.value("brew_sparge_ph").toDouble();
87 prod->brew_preboil_volume = query.value("brew_preboil_volume").toDouble();
88 prod->brew_preboil_sg = query.value("brew_preboil_sg").toDouble();
89 prod->brew_preboil_ph = query.value("brew_preboil_ph").toDouble();
90 prod->brew_preboil_efficiency = query.value("brew_preboil_efficiency").toDouble();
91 prod->brew_aboil_volume = query.value("brew_aboil_volume").toDouble();
92 prod->brew_aboil_sg = query.value("brew_aboil_sg").toDouble();
93 prod->brew_aboil_ph = query.value("brew_aboil_ph").toDouble();
94 prod->brew_aboil_efficiency = query.value("brew_aboil_efficiency").toDouble();
95 prod->brew_cooling_method = query.value("brew_cooling_method").toInt();
96 prod->brew_cooling_time = query.value("brew_cooling_time").toDouble();
97 prod->brew_cooling_to = query.value("brew_cooling_to").toDouble();
98 prod->brew_whirlpool9 = query.value("brew_whirlpool9").toDouble();
99 prod->brew_whirlpool7 = query.value("brew_whirlpool7").toDouble();
100 prod->brew_whirlpool6 = query.value("brew_whirlpool6").toDouble();
101 prod->brew_whirlpool2 = query.value("brew_whirlpool2").toDouble();
102 prod->brew_fermenter_volume = query.value("brew_fermenter_volume").toDouble();
103 prod->brew_fermenter_extrawater = query.value("brew_fermenter_extrawater").toDouble();
104 prod->brew_fermenter_tcloss = query.value("brew_fermenter_tcloss").toDouble();
105 prod->brew_aeration_time = query.value("brew_aeration_time").toDouble();
106 prod->brew_aeration_speed = query.value("brew_aeration_speed").toDouble();
107 prod->brew_aeration_type = query.value("brew_aeration_type").toInt();
108 prod->brew_fermenter_sg = query.value("brew_fermenter_sg").toDouble();
109 prod->brew_fermenter_ibu = query.value("brew_fermenter_ibu").toDouble();
110 prod->brew_fermenter_color = query.value("brew_fermenter_color").toDouble();
111 prod->brew_date_end = query.value("brew_date_end").toDateTime();
112
113 prod->og = query.value("og").toDouble();
114 prod->fg = query.value("fg").toDouble();
115 prod->primary_start_temp = query.value("primary_start_temp").toDouble();
116 prod->primary_max_temp = query.value("primary_max_temp").toDouble();
117 prod->primary_end_temp = query.value("primary_end_temp").toDouble();
118 prod->primary_end_sg = query.value("primary_end_sg").toDouble();
119 prod->primary_end_date = query.value("primary_end_date").toDate();
120 prod->secondary_temp = query.value("secondary_temp").toDouble();
121 prod->secondary_end_sg = query.value("secondary_end_sg").toDouble();
122 prod->secondary_end_date = query.value("secondary_end_date").toDate();
123 prod->tertiary_temp = query.value("tertiary_temp").toDouble();
124
125 prod->package_date = query.value("package_date").toDate();
126 prod->package_volume = query.value("package_volume").toDouble();
127 prod->package_infuse_amount = query.value("package_infuse_amount").toDouble();
128 prod->package_infuse_abv = query.value("package_infuse_abv").toDouble();
129 prod->package_infuse_notes = query.value("package_infuse_notes").toString();
130 prod->package_abv = query.value("package_abv").toDouble();
131 prod->package_ph = query.value("package_ph").toDouble();
132
133 prod->bottle_amount = query.value("bottle_amount").toDouble();
134 prod->bottle_carbonation = query.value("bottle_carbonation").toDouble();
135 prod->bottle_priming_sugar = query.value("bottle_priming_sugar").toInt();
136 prod->bottle_priming_amount = query.value("bottle_priming_amount").toDouble();
137 prod->bottle_priming_water = query.value("bottle_priming_water").toDouble();
138 prod->bottle_carbonation_temp = query.value("bottle_carbonation_temp").toDouble();
139
140 prod->keg_amount = query.value("keg_amount").toDouble();
141 prod->keg_carbonation = query.value("keg_carbonation").toDouble();
142 prod->keg_priming_sugar = query.value("keg_priming_sugar").toInt();
143 prod->keg_priming_amount = query.value("keg_priming_amount").toDouble();
144 prod->keg_priming_water = query.value("keg_priming_water").toDouble();
145 prod->keg_carbonation_temp = query.value("keg_carbonation_temp").toDouble();
146 prod->keg_forced_carb = query.value("keg_forced_carb").toInt() ? true:false;
147 prod->keg_pressure = query.value("keg_pressure").toDouble();
148
149 prod->taste_notes = query.value("taste_notes").toString();
150 prod->taste_rate = query.value("taste_rate").toDouble();
151 prod->taste_date = query.value("taste_date").toDate();
152 prod->taste_color = query.value("taste_color").toString();
153 prod->taste_transparency = query.value("taste_transparency").toString();
154 prod->taste_head = query.value("taste_head").toString();
155 prod->taste_aroma = query.value("taste_aroma").toString();
156 prod->taste_taste = query.value("taste_taste").toString();
157 prod->taste_mouthfeel = query.value("taste_mouthfeel").toString();
158 prod->taste_aftertaste = query.value("taste_aftertaste").toString();
159
160 prod->st_name = query.value("st_name").toString();
161 prod->st_letter = query.value("st_letter").toString();
162 prod->st_guide = query.value("st_guide").toString();
163 prod->st_category = query.value("st_category").toString();
164 prod->st_category_number = query.value("st_category_number").toInt();
165 prod->st_type = query.value("st_type").toInt();
166 prod->st_og_min = query.value("st_og_min").toDouble();
167 prod->st_og_max = query.value("st_og_max").toDouble();
168 prod->st_fg_min = query.value("st_fg_min").toDouble();
169 prod->st_fg_max = query.value("st_fg_max").toDouble();
170 prod->st_ibu_min = query.value("st_ibu_min").toDouble();
171 prod->st_ibu_max = query.value("st_ibu_max").toDouble();
172 prod->st_color_min = query.value("st_color_min").toDouble();
173 prod->st_color_max = query.value("st_color_max").toDouble();
174 prod->st_carb_min = query.value("st_carb_min").toDouble();
175 prod->st_carb_max = query.value("st_carb_max").toDouble();
176 prod->st_abv_min = query.value("st_abv_min").toDouble();
177 prod->st_abv_max = query.value("st_abv_max").toDouble();
178
179 prod->type = query.value("type").toInt();
180 prod->batch_size = query.value("batch_size").toDouble();
181 prod->boil_size = query.value("boil_size").toDouble();
182 prod->boil_time = query.value("boil_time").toDouble();
183 prod->efficiency = query.value("efficiency").toDouble();
184 prod->est_og = query.value("est_og").toDouble();
185 prod->est_og3 = query.value("est_og3").toDouble();
186 prod->est_fg = query.value("est_fg").toDouble();
187 prod->est_abv = query.value("est_abv").toDouble();
188 prod->est_color = query.value("est_color").toDouble();
189 prod->color_method = query.value("color_method").toInt();
190 prod->est_ibu = query.value("est_ibu").toDouble();
191 prod->ibu_method = query.value("ibu_method").toInt();
192 prod->est_carb = query.value("est_carb").toDouble();
193
194 prod->sparge_temp = query.value("sparge_temp").toDouble();
195 prod->sparge_ph = query.value("sparge_ph").toDouble();
196 prod->sparge_volume = query.value("sparge_volume").toDouble();
197 prod->sparge_source = query.value("sparge_source").toInt();
198 prod->sparge_acid_type = query.value("sparge_acid_type").toInt();
199 prod->sparge_acid_perc = query.value("sparge_acid_perc").toDouble();
200 prod->sparge_acid_amount = query.value("sparge_acid_amount").toDouble();
201 prod->mash_ph = query.value("mash_ph").toDouble();
202 prod->mash_name = query.value("mash_name").toString();
203 prod->calc_acid = query.value("calc_acid").toInt() ? true:false;
204
205 prod->w1_name = query.value("w1_name").toString();
206 prod->w1_amount = query.value("w1_amount").toDouble();
207 prod->w1_calcium = query.value("w1_calcium").toDouble();
208 prod->w1_sulfate = query.value("w1_sulfate").toDouble();
209 prod->w1_chloride = query.value("w1_chloride").toDouble();
210 prod->w1_sodium = query.value("w1_sodium").toDouble();
211 prod->w1_magnesium = query.value("w1_magnesium").toDouble();
212 prod->w1_total_alkalinity = query.value("w1_total_alkalinity").toDouble();
213 prod->w1_ph = query.value("w1_ph").toDouble();
214 prod->w1_cost = query.value("w1_cost").toDouble();
215 prod->w2_name = query.value("w2_name").toString();
216 prod->w2_amount = query.value("w2_amount").toDouble();
217 prod->w2_calcium = query.value("w2_calcium").toDouble();
218 prod->w2_sulfate = query.value("w2_sulfate").toDouble();
219 prod->w2_chloride = query.value("w2_chloride").toDouble();
220 prod->w2_sodium = query.value("w2_sodium").toDouble();
221 prod->w2_magnesium = query.value("w2_magnesium").toDouble();
222 prod->w2_total_alkalinity = query.value("w2_total_alkalinity").toDouble();
223 prod->w2_ph = query.value("w2_ph").toDouble();
224 prod->w2_cost = query.value("w2_cost").toDouble();
225 prod->wg_amount = query.value("wg_amount").toDouble();
226 prod->wg_calcium = query.value("wg_calcium").toDouble();
227 prod->wg_sulfate = query.value("wg_sulfate").toDouble();
228 prod->wg_chloride = query.value("wg_chloride").toDouble();
229 prod->wg_sodium = query.value("wg_sodium").toDouble();
230 prod->wg_magnesium = query.value("wg_magnesium").toDouble();
231 prod->wg_total_alkalinity = query.value("wg_total_alkalinity").toDouble();
232 prod->wg_ph = query.value("wg_ph").toDouble();
233 prod->wb_calcium = query.value("wb_calcium").toDouble();
234 prod->wb_sulfate = query.value("wb_sulfate").toDouble();
235 prod->wb_chloride = query.value("wb_chloride").toDouble();
236 prod->wb_sodium = query.value("wb_sodium").toDouble();
237 prod->wb_magnesium = query.value("wb_magnesium").toDouble();
238 prod->wb_total_alkalinity = query.value("wb_total_alkalinity").toDouble();
239 prod->wb_ph = query.value("wb_ph").toDouble();
240 prod->wa_acid_name = query.value("wa_acid_name").toInt();
241 prod->wa_acid_perc = query.value("wa_acid_perc").toDouble();
242 prod->wa_base_name = query.value("wa_base_name").toInt();
243
244 prod->starter_enable = query.value("starter_enable").toInt() ? true:false;
245 prod->starter_type = query.value("starter_type").toInt();
246 prod->starter_sg = query.value("starter_sg").toDouble();
247 prod->starter_viability = query.value("starter_viability").toInt();
248 if (query.value("yeast_prod_date").toString().length() == 10)
249 prod->yeast_prod_date = query.value("yeast_prod_date").toDate();
250 else
251 prod->yeast_prod_date = QDate();
252 prod->yeast_pitchrate = query.value("yeast_pitchrate").toDouble();
253 prod->prop_type[0] = query.value("prop1_type").toInt();
254 prod->prop_volume[0] = query.value("prop1_volume").toDouble();
255 prod->prop_type[1] = query.value("prop2_type").toInt();
256 prod->prop_volume[1] = query.value("prop2_volume").toDouble();
257 prod->prop_type[2] = query.value("prop3_type").toInt();
258 prod->prop_volume[2] = query.value("prop3_volume").toDouble();
259 prod->prop_type[3] = query.value("prop4_type").toInt();
260 prod->prop_volume[3] = query.value("prop4_volume").toDouble();
261
262 prod->divide_type = query.value("divide_type").toInt();
263 prod->divide_size = query.value("divide_size").toDouble();
264 prod->divide_factor = query.value("divide_factor").toDouble();
265 prod->divide_parts = query.value("divide_parts").toInt();
266 prod->divide_part = query.value("divide_part").toInt();
267
268 QJsonParseError parseError;
269 const auto& f_json = query.value("json_fermentables").toString();
270 if (!f_json.trimmed().isEmpty()) {
271 const auto& formattedJson = QString("%1").arg(f_json);
272 QJsonDocument fermentables = QJsonDocument::fromJson(formattedJson.toUtf8(), &parseError);
273 if (parseError.error != QJsonParseError::NoError) {
274 qDebug() << "Parse error: " << parseError.errorString() << "at" << parseError.offset ;
275 } else if (fermentables.isArray()) {
276 double percentcheck = 0;
277 for (int i = 0; i < fermentables.array().size(); i++) {
278 QJsonObject obj = fermentables.array().at(i).toObject();
279 //qDebug() << i << obj;
280 Fermentables f;
281 f.f_inventory = 0;
282 f.f_avail = false;
283 f.f_name = obj["f_name"].toString();
284 f.f_origin = obj["f_origin"].toString();
285 f.f_supplier = obj["f_supplier"].toString();
286 f.f_amount = obj["f_amount"].toDouble();
287 f.f_cost = obj["f_cost"].toDouble();
288 f.f_type = obj["f_type"].toInt();
289 f.f_yield = obj["f_yield"].toDouble();
290 f.f_color = obj["f_color"].toDouble();
291 f.f_coarse_fine_diff = obj["f_coarse_fine_diff"].toDouble();
292 f.f_moisture = obj["f_moisture"].toDouble();
293 f.f_diastatic_power = obj["f_diastatic_power"].toDouble();
294 f.f_protein = obj["f_protein"].toDouble();
295 f.f_dissolved_protein = obj["f_dissolved_protein"].toDouble();
296 f.f_max_in_batch = obj["f_max_in_batch"].toDouble();
297 f.f_graintype = obj["f_graintype"].toInt();
298 f.f_added = obj["f_added"].toInt();
299 f.f_recommend_mash = obj["f_recommend_mash"].toInt() ? true:false;
300 f.f_add_after_boil = obj["f_add_after_boil"].toInt() ? true:false;
301 f.f_adjust_to_total_100 = obj["f_adjust_to_total_100"].toInt() ? true:false;
302 f.f_percentage = obj["f_percentage"].toDouble();
303 f.f_di_ph = obj["f_di_ph"].toDouble();
304 f.f_acid_to_ph_57 = obj["f_acid_to_ph_57"].toDouble();
305 if (f.f_adjust_to_total_100)
306 prod->fermentables_use100 = true;
307 percentcheck += f.f_percentage;
308 /* Check and update inventory */
309 yquery.prepare("SELECT inventory FROM inventory_fermentables WHERE name=:name AND supplier=:supplier AND origin=:origin");
310 yquery.bindValue(":name", f.f_name);
311 yquery.bindValue(":supplier", f.f_supplier);
312 yquery.bindValue(":origin", f.f_origin);
313 yquery.exec();
314 if (yquery.first()) {
315 f.f_avail = true;
316 f.f_inventory = yquery.value(0).toDouble();
317 }
318 prod->fermentables.append(f);
319 }
320 qDebug() << "fermentables" << prod->fermentables.size() << percentcheck;
321 if (percentcheck == 0 && prod->fermentables.size()) {
322 /* Missing percentages, fix it. */
323 double total = 0;
324 for (int i = 0; i < prod->fermentables.size(); i++) {
325 if (prod->fermentables.at(i).f_added < 4)
326 total += prod->fermentables.at(i).f_amount;
327 }
328 for (int i = 0; i < prod->fermentables.size(); i++) {
329 if (prod->fermentables.at(i).f_added < 4)
330 prod->fermentables[i].f_percentage = round((prod->fermentables.at(i).f_amount / total) * 10000.0) / 100.0;
331 }
332 qDebug() << " fixed missing percentages";
333 // is_changed();
334 }
335 }
336 } else {
337 qDebug() << "empty fermentables";
338 }
339
340 const auto& h_json = query.value("json_hops").toString();
341 if (!h_json.trimmed().isEmpty()) {
342 const auto& formattedJson = QString("%1").arg(h_json);
343 QJsonDocument hops = QJsonDocument::fromJson(formattedJson.toUtf8(), &parseError);
344 if (parseError.error != QJsonParseError::NoError) {
345 qDebug() << "Parse error: " << parseError.errorString() << "at" << parseError.offset;
346 } else if (hops.isArray()) {
347 for (int i = 0; i < hops.array().size(); i++) {
348 QJsonObject obj = hops.array().at(i).toObject();
349 //qDebug() << i << obj;
350 Hops h;
351 h.h_avail = false;
352 h.h_inventory = 0;
353 h.h_name = obj["h_name"].toString();
354 h.h_origin = obj["h_origin"].toString();
355 h.h_amount = obj["h_amount"].toDouble();
356 h.h_cost = obj["h_cost"].toDouble();
357 h.h_type = obj["h_type"].toInt();
358 h.h_form = obj["h_form"].toInt();
359 h.h_useat = obj["h_useat"].toInt();
360 h.h_time = obj["h_time"].toInt();
361 h.h_alpha = obj["h_alpha"].toDouble();
362 h.h_beta = obj["h_beta"].toDouble();
363 h.h_hsi = obj["h_hsi"].toDouble();
364 h.h_humulene = obj["h_humulene"].toDouble();
365 h.h_caryophyllene = obj["h_caryophyllene"].toDouble();
366 h.h_cohumulone = obj["h_cohumulone"].toDouble();
367 h.h_myrcene = obj["h_myrcene"].toDouble();
368 h.h_total_oil = obj["h_total_oil"].toDouble();
369 /* Check and update inventory */
370 yquery.prepare("SELECT inventory FROM inventory_hops WHERE name=:name AND origin=:origin");
371 yquery.bindValue(":name", h.h_name);
372 yquery.bindValue(":origin", h.h_origin);
373 yquery.exec();
374 if (yquery.first()) {
375 h.h_avail = true;
376 h.h_inventory = yquery.value(0).toDouble();
377 }
378 prod->hops.append(h);
379 }
380 qDebug() << "hops" << prod->hops.size();
381 }
382 } else {
383 qDebug() << "empty hops";
384 }
385
386 const auto& m_json = query.value("json_miscs").toString();
387 if (!m_json.trimmed().isEmpty()) {
388 const auto& formattedJson = QString("%1").arg(m_json);
389 QJsonDocument miscs = QJsonDocument::fromJson(formattedJson.toUtf8(), &parseError);
390 if (parseError.error != QJsonParseError::NoError) {
391 qDebug() << "Parse error: " << parseError.errorString() << "at" << parseError.offset;
392 } else if (miscs.isArray()) {
393 for (int i = 0; i < miscs.array().size(); i++) {
394 QJsonObject obj = miscs.array().at(i).toObject();
395 //qDebug() << i << obj;
396 Miscs m;
397 m.m_avail = false;
398 m.m_inventory = 0;
399 m.m_name = obj["m_name"].toString();
400 m.m_amount = obj["m_amount"].toDouble();
401 m.m_type = obj["m_type"].toInt();
402 m.m_use_use = obj["m_use_use"].toInt();
403 m.m_time = obj["m_time"].toDouble();
404 m.m_amount_is_weight = obj["m_amount_is_weight"].toInt() ? true:false;
405 m.m_cost = obj["m_cost"].toDouble();
406 /* Check and update inventory */
407 yquery.prepare("SELECT inventory FROM inventory_miscs WHERE name=:name");
408 yquery.bindValue(":name", m.m_name);
409 yquery.exec();
410 if (yquery.first()) {
411 m.m_avail = true;
412 m.m_inventory = yquery.value(0).toDouble();
413 }
414 prod->miscs.append(m);
415 }
416 qDebug() << "miscs" << prod->miscs.size();
417 }
418 } else {
419 qDebug() << "empty miscs";
420 }
421
422 const auto& y_json = query.value("json_yeasts").toString();
423 if (!y_json.trimmed().isEmpty()) {
424 const auto& formattedJson = QString("%1").arg(y_json);
425 QJsonDocument yeasts = QJsonDocument::fromJson(formattedJson.toUtf8(), &parseError);
426 if (parseError.error != QJsonParseError::NoError) {
427 qDebug() << "Parse error: " << parseError.errorString() << "at" << parseError.offset ;
428 } else if (yeasts.isArray()) {
429 for (int i = 0; i < yeasts.array().size(); i++) {
430 QJsonObject obj = yeasts.array().at(i).toObject();
431 //qDebug() << i << obj;
432 Yeasts y;
433 /* First some defaults for newer fields. */
434 y.y_tolerance = y.y_harvest_time = y.y_pitch_temperature = y.y_zymocide = 0;
435 y.y_avail = y.y_sta1 = y.y_bacteria = y.y_harvest_top = y.y_pofpos = false;
436 y.y_gr_hl_lo = 50;
437 y.y_sg_lo = 1.04;
438 y.y_gr_hl_hi = 80;
439 y.y_sg_hi = 1.08;
440 /* Now get what we have got */
441 y.y_name = obj["y_name"].toString();
442 y.y_laboratory = obj["y_laboratory"].toString();
443 y.y_product_id = obj["y_product_id"].toString();
444 y.y_amount = obj["y_amount"].toDouble();
445 y.y_type = obj["y_type"].toInt();
446 y.y_form = obj["y_form"].toInt();
447 y.y_min_temperature = obj["y_min_temperature"].toDouble();
448 y.y_max_temperature = obj["y_max_temperature"].toDouble();
449 y.y_flocculation = obj["y_flocculation"].toInt();
450 y.y_attenuation = obj["y_attenuation"].toDouble();
451 y.y_cells = obj["y_cells"].toDouble();
452 y.y_tolerance = obj["y_tolerance"].toDouble();
453 y.y_inventory = obj["y_inventory"].toDouble();
454 y.y_use = obj["y_use"].toInt();
455 y.y_sta1 = obj["y_sta1"].toInt() ? true:false;
456 y.y_bacteria = obj["y_bacteria"].toInt() ? true:false;
457 y.y_harvest_top = obj["y_harvest_top"].toInt() ? true:false;
458 y.y_harvest_time = obj["y_harvest_time"].toInt();
459 y.y_pitch_temperature = obj["y_pitch_temperature"].toDouble();
460 y.y_pofpos = obj["y_pofpos"].toInt() ? true:false;
461 y.y_zymocide = obj["y_zymocide"].toInt();
462 y.y_gr_hl_lo = obj["y_gr_hl_lo"].toInt();
463 y.y_sg_lo = obj["y_sg_lo"].toDouble();
464 y.y_gr_hl_hi = obj["y_gr_hl_hi"].toInt();
465 y.y_sg_hi = obj["y_sg_hi"].toDouble();
466 y.y_cost = obj["y_cost"].toDouble();
467 /*
468 * Possible data upgrade needed.
469 */
470 yquery.prepare("SELECT tolerance,cells,sta1,bacteria,harvest_top,harvest_time,pitch_temperature,"
471 "pofpos,zymocide,gr_hl_lo,sg_lo,gr_hl_hi,sg_hi,inventory "
472 "FROM inventory_yeasts WHERE name=:name AND laboratory=:laboratory AND product_id=:product_id");
473 yquery.bindValue(":name", y.y_name);
474 yquery.bindValue(":laboratory", y.y_laboratory);
475 yquery.bindValue(":product_id", y.y_product_id);
476 yquery.exec();
477 if (yquery.first()) {
478 if (y.y_tolerance == 0 || y.y_cells == 0) {
479 y.y_tolerance = yquery.value(0).toDouble();
480 y.y_cells = yquery.value(1).toDouble();
481 }
482 y.y_sta1 = yquery.value(2).toInt() ? true:false;
483 y.y_bacteria = yquery.value(3).toInt() ? true:false;
484 y.y_harvest_top = yquery.value(4).toInt() ? true:false;
485 y.y_harvest_time = yquery.value(5).toInt();
486 y.y_pitch_temperature = yquery.value(6).toDouble();
487 y.y_pofpos = yquery.value(7).toInt() ? true:false;
488 y.y_zymocide = yquery.value(8).toInt();
489 y.y_gr_hl_lo = yquery.value(9).toInt();
490 y.y_sg_lo = yquery.value(10).toDouble();
491 y.y_gr_hl_hi = yquery.value(11).toInt();
492 y.y_sg_hi = yquery.value(12).toDouble();
493 y.y_inventory = yquery.value(13).toDouble();
494 y.y_avail = true;
495 } else {
496 qDebug() << y.y_name << y.y_product_id << "not found for upgrade";
497 }
498 prod->yeasts.append(y);
499 }
500 qDebug() << "yeasts" << prod->yeasts.size();
501 }
502 } else {
503 qDebug() << "empty yeasts";
504 }
505
506 const auto& ma_json = query.value("json_mashs").toString().trimmed();
507 if (!ma_json.trimmed().isEmpty()) {
508 const auto& formattedJson = QString("%1").arg(ma_json);
509 QJsonDocument mashs = QJsonDocument::fromJson(formattedJson.toUtf8(), &parseError);
510 if (parseError.error != QJsonParseError::NoError) {
511 qDebug() << "Parse error: " << parseError.errorString() << "at" << parseError.offset ;
512 } else if (mashs.isArray()) {
513 for (int i = 0; i < mashs.array().size(); i++) {
514 QJsonObject obj = mashs.array().at(i).toObject();
515 qDebug() << i << obj;
516 Mashs m;
517 m.step_name = obj["step_name"].toString();
518 m.step_type = obj["step_type"].toInt();
519 m.step_volume = obj["step_volume"].toDouble();
520 m.step_infuse_amount = obj["step_infuse_amount"].toDouble();
521 m.step_infuse_temp = obj["step_infuse_temp"].toDouble();
522 m.step_temp = obj["step_temp"].toDouble();
523 m.step_time = obj["step_time"].toDouble();
524 m.ramp_time = obj["ramp_time"].toDouble();
525 m.end_temp = obj["end_temp"].toDouble();
526 m.step_wg_ratio = obj["step_wg_ratio"].toDouble();
527 m.step_ph = obj["step_ph"].toDouble();
528 m.step_sg = obj["step_sg"].toDouble();
529 prod->mashs.append(m);
530 }
531 }
532 } else {
533 qDebug() << "empty mashs";
534 }
535 qDebug() << "mashs" << prod->mashs.size();
536
537 return true;
538 }
539
540
541
542
543 bool DB_product::save(Product *prod, QDialog *dialog)
544 {
545 QSqlQuery query;
546
547 if (prod->record == -1) {
548 query.prepare("INSERT INTO products SET "
549 "name=:name, code=:code, birth=:birth, stage=:stage, notes=:notes, log_brew=:log_brew, "
550 "log_fermentation=:log_fermentation, log_ispindel=:log_ispindel, log_co2pressure=:log_co2pressure, "
551 "inventory_reduced=:inventory_reduced, locked=:locked, "
552 "eq_name=:eq_name, eq_boil_size=:eq_boil_size, eq_efficiency=:eq_efficiency, "
553 "eq_batch_size=:eq_batch_size, eq_tun_volume=:eq_tun_volume, eq_tun_weight=:eq_tun_weight, "
554 "eq_tun_specific_heat=:eq_tun_specific_heat, eq_tun_material=:eq_tun_material, eq_tun_height=:eq_tun_height, "
555 "eq_top_up_water=:eq_top_up_water, eq_trub_chiller_loss=:eq_chiller_loss, eq_evap_rate=:eq_evap_rate, "
556 "eq_boil_time=:eq_boil_time, eq_calc_boil_volume=:eq_calcboil, eq_top_up_kettle=:eq_top_up_kettle, "
557 "eq_hop_utilization=:eq_hopfactor, eq_notes=:eq_notes, eq_lauter_volume=:eq_lauter_volume, "
558 "eq_lauter_height=:eq_lauter_height, eq_lauter_deadspace=:eq_lauter_deadspace, eq_kettle_volume=:eq_kettle_volume, "
559 "eq_kettle_height=:eq_kettle_height, eq_mash_volume=:eq_mash_volume, eq_mash_max=:eq_mash_max, "
560 "brew_date_start=:brew_date_start, brew_mash_ph=:brew_mash_ph, brew_mash_sg=:brew_mash_sg, "
561 "brew_mash_efficiency=:brew_mash_efficiency, brew_sparge_temperature=:brew_sparge_temperature, "
562 "brew_sparge_volume=:brew_sparge_volume, brew_sparge_est=:brew_sparge_est, brew_sparge_ph=:brew_sparge_ph, "
563 "brew_preboil_volume=:brew_preboil_volume, brew_preboil_sg=:brew_preboil_sg, brew_preboil_ph=:brew_preboil_ph, "
564 "brew_preboil_efficiency=:brew_preboil_efficiency, brew_aboil_volume=:brew_aboil_volume, "
565 "brew_aboil_sg=:brew_aboil_sg, brew_aboil_ph=:brew_aboil_ph, brew_aboil_efficiency=:brew_aboil_efficiency, "
566 "brew_cooling_method=:brew_cooling_method, brew_cooling_time=:brew_cooling_time, brew_cooling_to=:brew_cooling_to, "
567 "brew_whirlpool9=:brew_whirlpool9, brew_whirlpool7=:brew_whirlpool7, brew_whirlpool6=:brew_whirlpool6, "
568 "brew_whirlpool2=:brew_whirlpool2, brew_fermenter_volume=:brew_fermenter_volume, "
569 "brew_fermenter_extrawater=:brew_fermenter_extrawater, brew_fermenter_tcloss=:brew_fermenter_tcloss, "
570 "brew_aeration_time=:brew_aeration_time, brew_aeration_speed=:brew_aeration_speed, "
571 "brew_aeration_type=:brew_aeration_type, brew_fermenter_sg=:brew_fermenter_sg, brew_fermenter_ibu=:brew_fermenter_ibu, "
572 "brew_fermenter_color=:brew_fermenter_color, brew_date_end=:brew_date_end, "
573 "og=:og, fg=:fg, primary_start_temp=:primary_start_temp, primary_max_temp=:primary_max_temp, "
574 "primary_end_temp=:primary_end_temp, primary_end_sg=:primary_end_sg, primary_end_date=:primary_end_date, "
575 "secondary_temp=:secondary_temp, secondary_end_sg=:secondary_end_sg, secondary_end_date=:secondary_end_date, "
576 "tertiary_temp=:tertiary_temp, package_date=:package_date, package_volume=:package_volume, "
577 "package_infuse_amount=:package_infuse_amount, package_infuse_abv=:package_infuse_abv, "
578 "package_infuse_notes=:package_infuse_notes, package_abv=:package_abv, package_ph=:package_ph, "
579 "bottle_amount=:bottle_amount, bottle_carbonation=:bottle_carbonation, bottle_priming_sugar=:bottle_priming_sugar, "
580 "bottle_priming_amount=:bottle_priming_amount, bottle_priming_water=:bottle_priming_water, "
581 "bottle_carbonation_temp=:bottle_carbonation_temp, keg_amount=:keg_amount, keg_carbonation=:keg_carbonation, "
582 "keg_priming_sugar=:keg_priming_sugar, keg_priming_amount=:keg_priming_amount, keg_priming_water=:keg_priming_water, "
583 "keg_carbonation_temp=:keg_carbonation_temp, keg_forced_carb=:keg_forced_carb, keg_pressure=:keg_pressure, "
584 "taste_notes=:taste_notes, taste_rate=:taste_rate, taste_date=:taste_date, taste_color=:taste_color, "
585 "taste_transparency=:taste_transparency, taste_head=:taste_head, taste_aroma=:taste_aroma, "
586 "taste_taste=:taste_taste, taste_mouthfeel=:taste_mouthfeel, taste_aftertaste=:taste_aftertaste, "
587 "st_name=:st_name, st_letter=:st_letter, "
588 "st_guide=:st_guide, st_category=:st_category, st_category_number=:st_catnr, st_type=:st_type, "
589 "st_og_min=:st_og_min, st_og_max=:st_og_max, st_fg_min=:st_fg_min, st_fg_max=:st_fg_max, "
590 "st_ibu_min=:st_ibu_min, st_ibu_max=:st_ibu_max, st_color_min=:st_color_min, st_color_max=:st_color_max, "
591 "st_carb_min=:st_carb_min, st_carb_max=:st_carb_max, st_abv_min=:st_abv_min, st_abv_max=:st_abv_max, "
592 "type=:type, batch_size=:batch_size, boil_size=:boil_size, "
593 "boil_time=:boil_time, efficiency=:efficiency, est_og=:est_og, est_og3=:est_og3, est_fg=:est_fg, est_abv=:est_abv, "
594 "est_color=:est_color, color_method=:color_method, est_ibu=:est_ibu, ibu_method=:ibu_method, "
595 "est_carb=:est_carb, sparge_temp=:sparge_temp, sparge_ph=:sparge_ph, "
596 "sparge_volume=:sparge_volume, sparge_source=:sparge_source, sparge_acid_type=:sparge_acid_type, "
597 "sparge_acid_perc=:sparge_acid_perc, sparge_acid_amount=:sparge_acid_amount, mash_ph=:mash_ph, "
598 "mash_name=:mash_name, calc_acid=:calc_acid, "
599 "w1_name=:w1_name, w1_amount=:w1_amount, w1_calcium=:w1_calcium, w1_sulfate=:w1_sulfate, "
600 "w1_chloride=:w1_chloride, w1_sodium=:w1_sodium, w1_magnesium=:w1_magnesium, "
601 "w1_total_alkalinity=:w1_total_alkalinity, w1_ph=:w1_ph, w1_cost=:w1_cost, "
602 "w2_name=:w2_name, w2_amount=:w2_amount, w2_calcium=:w2_calcium, w2_sulfate=:w2_sulfate, "
603 "w2_chloride=:w2_chloride, w2_sodium=:w2_sodium, w2_magnesium=:w2_magnesium, "
604 "w2_total_alkalinity=:w2_total_alkalinity, w2_ph=:w2_ph, w2_cost=:w2_cost, "
605 "wg_amount=:wg_amount, wg_calcium=:wg_calcium, wg_sulfate=:wg_sulfate, "
606 "wg_chloride=:wg_chloride, wg_sodium=:wg_sodium, wg_magnesium=:wg_magnesium, "
607 "wg_total_alkalinity=:wg_total_alkalinity, wg_ph=:wg_ph, "
608 "wb_calcium=:wb_calcium, wb_sulfate=:wb_sulfate, wb_chloride=:wb_chloride, wb_sodium=:wb_sodium, "
609 "wb_magnesium=:wb_magnesium, wb_total_alkalinity=:wb_total_alkalinity, wb_ph=:wb_ph, "
610 "wa_acid_name=:wa_acid_name, wa_acid_perc=:wa_acid_perc, wa_base_name=:wa_base_name, "
611 "starter_enable=:starter_enable, starter_type=:starter_type, starter_sg=:starter_sg, "
612 "starter_viability=:starter_viability, yeast_prod_date=:yeast_prod_date, yeast_pitchrate=:yeast_pitchrate, "
613 "prop1_type=:prop1_type, prop1_volume=:prop1_volume, prop2_type=:prop2_type, prop2_volume=:prop2_volume, "
614 "prop3_type=:prop3_type, prop3_volume=:prop3_volume, prop4_type=:prop4_type, prop4_volume=:prop4_volume, "
615 "divide_type=:divide_type, divide_size=:divide_size, divide_factor=:divide_factor, "
616 "divide_parts=:divide_parts, divide_part=:divide_part, "
617 "json_fermentables=:json_fermentables, json_hops=:json_hops, json_miscs=:json_miscs, "
618 "json_yeasts=:json_yeasts, json_mashs=:json_mashs, uuid=:uuid");
619 } else {
620 query.prepare("UPDATE products SET "
621 "name=:name, code=:code, birth=:birth, stage=:stage, notes=:notes, log_brew=:log_brew, "
622 "log_fermentation=:log_fermentation, log_ispindel=:log_ispindel, log_co2pressure=:log_co2pressure, "
623 "inventory_reduced=:inventory_reduced, locked=:locked, "
624 "eq_name=:eq_name, eq_boil_size=:eq_boil_size, eq_efficiency=:eq_efficiency, "
625 "eq_batch_size=:eq_batch_size, eq_tun_volume=:eq_tun_volume, eq_tun_weight=:eq_tun_weight, "
626 "eq_tun_specific_heat=:eq_tun_specific_heat, eq_tun_material=:eq_tun_material, eq_tun_height=:eq_tun_height, "
627 "eq_top_up_water=:eq_top_up_water, eq_trub_chiller_loss=:eq_chiller_loss, eq_evap_rate=:eq_evap_rate, "
628 "eq_boil_time=:eq_boil_time, eq_calc_boil_volume=:eq_calcboil, eq_top_up_kettle=:eq_top_up_kettle, "
629 "eq_hop_utilization=:eq_hopfactor, eq_notes=:eq_notes, eq_lauter_volume=:eq_lauter_volume, "
630 "eq_lauter_height=:eq_lauter_height, eq_lauter_deadspace=:eq_lauter_deadspace, eq_kettle_volume=:eq_kettle_volume, "
631 "eq_kettle_height=:eq_kettle_height, eq_mash_volume=:eq_mash_volume, eq_mash_max=:eq_mash_max, "
632 "brew_date_start=:brew_date_start, brew_mash_ph=:brew_mash_ph, brew_mash_sg=:brew_mash_sg, "
633 "brew_mash_efficiency=:brew_mash_efficiency, brew_sparge_temperature=:brew_sparge_temperature, "
634 "brew_sparge_volume=:brew_sparge_volume, brew_sparge_est=:brew_sparge_est, brew_sparge_ph=:brew_sparge_ph, "
635 "brew_preboil_volume=:brew_preboil_volume, brew_preboil_sg=:brew_preboil_sg, brew_preboil_ph=:brew_preboil_ph, "
636 "brew_preboil_efficiency=:brew_preboil_efficiency, brew_aboil_volume=:brew_aboil_volume, "
637 "brew_aboil_sg=:brew_aboil_sg, brew_aboil_ph=:brew_aboil_ph, brew_aboil_efficiency=:brew_aboil_efficiency, "
638 "brew_cooling_method=:brew_cooling_method, brew_cooling_time=:brew_cooling_time, brew_cooling_to=:brew_cooling_to, "
639 "brew_whirlpool9=:brew_whirlpool9, brew_whirlpool7=:brew_whirlpool7, brew_whirlpool6=:brew_whirlpool6, "
640 "brew_whirlpool2=:brew_whirlpool2, brew_fermenter_volume=:brew_fermenter_volume, "
641 "brew_fermenter_extrawater=:brew_fermenter_extrawater, brew_fermenter_tcloss=:brew_fermenter_tcloss, "
642 "brew_aeration_time=:brew_aeration_time, brew_aeration_speed=:brew_aeration_speed, "
643 "brew_aeration_type=:brew_aeration_type, brew_fermenter_sg=:brew_fermenter_sg, brew_fermenter_ibu=:brew_fermenter_ibu, "
644 "brew_fermenter_color=:brew_fermenter_color, brew_date_end=:brew_date_end, "
645 "og=:og, fg=:fg, primary_start_temp=:primary_start_temp, primary_max_temp=:primary_max_temp, "
646 "primary_end_temp=:primary_end_temp, primary_end_sg=:primary_end_sg, primary_end_date=:primary_end_date, "
647 "secondary_temp=:secondary_temp, secondary_end_sg=:secondary_end_sg, secondary_end_date=:secondary_end_date, "
648 "tertiary_temp=:tertiary_temp, package_date=:package_date, package_volume=:package_volume, "
649 "package_infuse_amount=:package_infuse_amount, package_infuse_abv=:package_infuse_abv, "
650 "package_infuse_notes=:package_infuse_notes, package_abv=:package_abv, package_ph=:package_ph, "
651 "bottle_amount=:bottle_amount, bottle_carbonation=:bottle_carbonation, bottle_priming_sugar=:bottle_priming_sugar, "
652 "bottle_priming_amount=:bottle_priming_amount, bottle_priming_water=:bottle_priming_water, "
653 "bottle_carbonation_temp=:bottle_carbonation_temp, keg_amount=:keg_amount, keg_carbonation=:keg_carbonation, "
654 "keg_priming_sugar=:keg_priming_sugar, keg_priming_amount=:keg_priming_amount, keg_priming_water=:keg_priming_water, "
655 "keg_carbonation_temp=:keg_carbonation_temp, keg_forced_carb=:keg_forced_carb, keg_pressure=:keg_pressure, "
656 "taste_notes=:taste_notes, taste_rate=:taste_rate, taste_date=:taste_date, taste_color=:taste_color, "
657 "taste_transparency=:taste_transparency, taste_head=:taste_head, taste_aroma=:taste_aroma, "
658 "taste_taste=:taste_taste, taste_mouthfeel=:taste_mouthfeel, taste_aftertaste=:taste_aftertaste, "
659 "st_name=:st_name, st_letter=:st_letter, "
660 "st_guide=:st_guide, st_category=:st_category, st_category_number=:st_catnr, st_type=:st_type, "
661 "st_og_min=:st_og_min, st_og_max=:st_og_max, st_fg_min=:st_fg_min, st_fg_max=:st_fg_max, "
662 "st_ibu_min=:st_ibu_min, st_ibu_max=:st_ibu_max, st_color_min=:st_color_min, st_color_max=:st_color_max, "
663 "st_carb_min=:st_carb_min, st_carb_max=:st_carb_max, st_abv_min=:st_abv_min, st_abv_max=:st_abv_max, "
664 "type=:type, batch_size=:batch_size, boil_size=:boil_size, "
665 "boil_time=:boil_time, efficiency=:efficiency, est_og=:est_og, est_og3=:est_og3, est_fg=:est_fg, est_abv=:est_abv, "
666 "est_color=:est_color, color_method=:color_method, est_ibu=:est_ibu, ibu_method=:ibu_method, "
667 "est_carb=:est_carb, sparge_temp=:sparge_temp, sparge_ph=:sparge_ph, "
668 "sparge_volume=:sparge_volume, sparge_source=:sparge_source, sparge_acid_type=:sparge_acid_type, "
669 "sparge_acid_perc=:sparge_acid_perc, sparge_acid_amount=:sparge_acid_amount, mash_ph=:mash_ph, "
670 "mash_name=:mash_name, calc_acid=:calc_acid, "
671 "w1_name=:w1_name, w1_amount=:w1_amount, w1_calcium=:w1_calcium, w1_sulfate=:w1_sulfate, "
672 "w1_chloride=:w1_chloride, w1_sodium=:w1_sodium, w1_magnesium=:w1_magnesium, "
673 "w1_total_alkalinity=:w1_total_alkalinity, w1_ph=:w1_ph, w1_cost=:w1_cost, "
674 "w2_name=:w2_name, w2_amount=:w2_amount, w2_calcium=:w2_calcium, w2_sulfate=:w2_sulfate, "
675 "w2_chloride=:w2_chloride, w2_sodium=:w2_sodium, w2_magnesium=:w2_magnesium, "
676 "w2_total_alkalinity=:w2_total_alkalinity, w2_ph=:w2_ph, w2_cost=:w2_cost, "
677 "wg_amount=:wg_amount, wg_calcium=:wg_calcium, wg_sulfate=:wg_sulfate, "
678 "wg_chloride=:wg_chloride, wg_sodium=:wg_sodium, wg_magnesium=:wg_magnesium, "
679 "wg_total_alkalinity=:wg_total_alkalinity, wg_ph=:wg_ph, "
680 "wb_calcium=:wb_calcium, wb_sulfate=:wb_sulfate, wb_chloride=:wb_chloride, wb_sodium=:wb_sodium, "
681 "wb_magnesium=:wb_magnesium, wb_total_alkalinity=:wb_total_alkalinity, wb_ph=:wb_ph, "
682 "wa_acid_name=:wa_acid_name, wa_acid_perc=:wa_acid_perc, wa_base_name=:wa_base_name, "
683 "starter_enable=:starter_enable, starter_type=:starter_type, starter_sg=:starter_sg, "
684 "starter_viability=:starter_viability, yeast_prod_date=:yeast_prod_date, yeast_pitchrate=:yeast_pitchrate, "
685 "prop1_type=:prop1_type, prop1_volume=:prop1_volume, prop2_type=:prop2_type, prop2_volume=:prop2_volume, "
686 "prop3_type=:prop3_type, prop3_volume=:prop3_volume, prop4_type=:prop4_type, prop4_volume=:prop4_volume, "
687 "divide_type=:divide_type, divide_size=:divide_size, divide_factor=:divide_factor, "
688 "divide_parts=:divide_parts, divide_part=:divide_part, "
689 "json_fermentables=:json_fermentables, json_hops=:json_hops, json_miscs=:json_miscs, "
690 "json_yeasts=:json_yeasts, json_mashs=:json_mashs WHERE record = :recno");
691 }
692
693 query.bindValue(":name", prod->name);
694 query.bindValue(":code", prod->code);
695 query.bindValue(":birth", prod->birth);
696 query.bindValue(":stage", prod->stage);
697 query.bindValue(":notes", prod->notes);
698 query.bindValue(":log_brew", prod->log_brew ? 1:0);
699 query.bindValue(":log_fermentation", prod->log_fermentation ? 1:0);
700 query.bindValue(":log_ispindel", prod->log_ispindel ? 1:0);
701 query.bindValue(":log_co2pressure", prod->log_co2pressure ? 1:0);
702 query.bindValue(":inventory_reduced", prod->inventory_reduced);
703 query.bindValue(":locked", prod->locked ? 1:0);
704 query.bindValue(":eq_name", prod->eq_name);
705 query.bindValue(":eq_boil_size", round(prod->eq_boil_size * 10) / 10);
706 query.bindValue(":eq_batch_size", round(prod->eq_batch_size * 100) / 100);
707 query.bindValue(":eq_tun_volume", round(prod->eq_tun_volume * 10) / 10);
708 query.bindValue(":eq_tun_weight", round(prod->eq_tun_weight * 10) / 10);
709 query.bindValue(":eq_tun_specific_heat", round(prod->eq_tun_specific_heat * 1000) / 1000);
710 query.bindValue(":eq_tun_material", prod->eq_tun_material);
711 query.bindValue(":eq_tun_height", round(prod->eq_tun_height * 1000) / 1000);
712 query.bindValue(":eq_top_up_water", round(prod->eq_top_up_water * 10) / 10);
713 query.bindValue(":eq_chiller_loss", round(prod->eq_trub_chiller_loss * 10) / 10);
714 query.bindValue(":eq_evap_rate", round(prod->eq_evap_rate * 100) / 100);
715 query.bindValue(":eq_boil_time", round(prod->eq_boil_time));
716 query.bindValue(":eq_calcboil", prod->eq_calc_boil_volume ? 1:0);
717 query.bindValue(":eq_top_up_kettle", round(prod->eq_top_up_kettle * 10) / 10);
718 query.bindValue(":eq_hopfactor", round(prod->eq_hop_utilization));
719 query.bindValue(":eq_notes", prod->eq_notes);
720 query.bindValue(":eq_lauter_volume", round(prod->eq_lauter_volume * 10) / 10);
721 query.bindValue(":eq_lauter_height", round(prod->eq_lauter_height * 1000) / 1000);
722 query.bindValue(":eq_lauter_deadspace", round(prod->eq_lauter_deadspace * 10) / 10);
723 query.bindValue(":eq_kettle_volume", round(prod->eq_kettle_volume * 10) / 10);
724 query.bindValue(":eq_kettle_height", round(prod->eq_kettle_height * 1000) / 1000);
725 query.bindValue(":eq_mash_volume", round(prod->eq_mash_volume * 10) / 10);
726 query.bindValue(":eq_mash_max", round(prod->eq_mash_max * 10) / 10);
727 query.bindValue(":eq_efficiency", round(prod->eq_efficiency * 10) / 10);
728 query.bindValue(":brew_date_start", prod->brew_date_start);
729 query.bindValue(":brew_mash_ph", round(prod->brew_mash_ph * 100) / 100);
730 query.bindValue(":brew_mash_sg", round(prod->brew_mash_sg * 1000) / 1000);
731 query.bindValue(":brew_mash_efficiency", round(prod->brew_mash_efficiency * 10) / 10);
732 query.bindValue(":brew_sparge_temperature", round(prod->brew_sparge_temperature * 10) / 10);
733 query.bindValue(":brew_sparge_volume", round(prod->brew_sparge_volume * 10) / 10);
734 query.bindValue(":brew_sparge_est", round(prod->brew_sparge_est * 10) / 10);
735 query.bindValue(":brew_sparge_ph", round(prod->brew_sparge_ph * 100) / 100);
736 query.bindValue(":brew_preboil_volume", round(prod->brew_preboil_volume * 10) / 10);
737 query.bindValue(":brew_preboil_sg", round(prod->brew_preboil_sg * 1000) / 1000);
738 query.bindValue(":brew_preboil_ph", round(prod->brew_preboil_ph * 100) / 100);
739 query.bindValue(":brew_preboil_efficiency", round(prod->brew_preboil_efficiency * 10) / 10);
740 query.bindValue(":brew_aboil_volume", round(prod->brew_aboil_volume * 10) / 10);
741 query.bindValue(":brew_aboil_sg", round(prod->brew_aboil_sg * 1000) / 1000);
742 query.bindValue(":brew_aboil_ph", round(prod->brew_aboil_ph * 100) / 100);
743 query.bindValue(":brew_aboil_efficiency", round(prod->brew_aboil_efficiency * 10) / 10);
744 query.bindValue(":brew_cooling_method", prod->brew_cooling_method);
745 query.bindValue(":brew_cooling_time", round(prod->brew_cooling_time * 10) / 10);
746 query.bindValue(":brew_cooling_to", round(prod->brew_cooling_to * 10) / 10);
747 query.bindValue(":brew_whirlpool9", round(prod->brew_whirlpool9));
748 query.bindValue(":brew_whirlpool7", round(prod->brew_whirlpool7));
749 query.bindValue(":brew_whirlpool6", round(prod->brew_whirlpool6));
750 query.bindValue(":brew_whirlpool2", round(prod->brew_whirlpool2));
751 query.bindValue(":brew_fermenter_volume", round(prod->brew_fermenter_volume * 10) / 10);
752 query.bindValue(":brew_fermenter_extrawater", round(prod->brew_fermenter_extrawater * 10) / 10);
753 query.bindValue(":brew_fermenter_tcloss", round(prod->brew_fermenter_tcloss * 10) / 10);
754 query.bindValue(":brew_aeration_time", round(prod->brew_aeration_time));
755 query.bindValue(":brew_aeration_speed", round(prod->brew_aeration_speed * 10) / 10);
756 query.bindValue(":brew_aeration_type", prod->brew_aeration_type);
757 query.bindValue(":brew_fermenter_sg", round(prod->brew_fermenter_sg * 1000) / 1000);
758 query.bindValue(":brew_fermenter_ibu", round(prod->brew_fermenter_ibu * 10) / 10);
759 query.bindValue(":brew_fermenter_color", round(prod->brew_fermenter_color * 10) / 10);
760 query.bindValue(":brew_date_end", prod->brew_date_end);
761 query.bindValue(":og", round(prod->og * 1000) / 1000);
762 query.bindValue(":fg", round(prod->fg * 1000) / 1000);
763 query.bindValue(":primary_start_temp", round(prod->primary_start_temp * 10) / 10);
764 query.bindValue(":primary_max_temp", round(prod->primary_max_temp * 10) / 10);
765 query.bindValue(":primary_end_temp", round(prod->primary_end_temp * 10) / 10);
766 query.bindValue(":primary_end_sg", round(prod->primary_end_sg * 1000) / 1000);
767 query.bindValue(":primary_end_date", prod->primary_end_date);
768 query.bindValue(":secondary_temp", round(prod->secondary_temp * 10) / 10);
769 query.bindValue(":secondary_end_sg", round(prod->secondary_end_sg * 1000) / 1000);
770 query.bindValue(":secondary_end_date", prod->secondary_end_date);
771 query.bindValue(":tertiary_temp", round(prod->tertiary_temp * 10) / 10);
772 query.bindValue(":package_date", prod->package_date);
773 query.bindValue(":package_volume", round(prod->package_volume * 10) / 10);
774 query.bindValue(":package_infuse_amount", round(prod->package_infuse_amount * 1000) / 1000);
775 query.bindValue(":package_infuse_abv", round(prod->package_infuse_abv * 100) / 100);
776 query.bindValue(":package_infuse_notes", prod->package_infuse_notes);
777 query.bindValue(":package_abv", round(prod->package_abv * 100) / 100);
778 query.bindValue(":package_ph", round(prod->package_ph * 100) / 100);
779 query.bindValue(":bottle_amount", round(prod->bottle_amount * 10) / 10);
780 query.bindValue(":bottle_carbonation", round(prod->bottle_carbonation * 100) / 100);
781 query.bindValue(":bottle_priming_sugar", prod->bottle_priming_sugar);
782 query.bindValue(":bottle_priming_amount", round(prod->bottle_priming_amount * 10) / 10);
783 query.bindValue(":bottle_priming_water", round(prod->bottle_priming_water * 1000) / 1000);
784 query.bindValue(":bottle_carbonation_temp", round(prod->bottle_carbonation_temp * 10) / 10);
785 query.bindValue(":keg_amount", round(prod->keg_amount * 10) / 10);
786 query.bindValue(":keg_carbonation", round(prod->keg_carbonation * 100) / 100);
787 query.bindValue(":keg_priming_sugar", prod->keg_priming_sugar);
788 query.bindValue(":keg_priming_amount", round(prod->keg_priming_amount * 10) / 10);
789 query.bindValue(":keg_priming_water", round(prod->keg_priming_water * 1000) / 1000);
790 query.bindValue(":keg_carbonation_temp", round(prod->keg_carbonation_temp * 10) / 10);
791 query.bindValue(":keg_forced_carb", prod->keg_forced_carb ? 1:0);
792 query.bindValue(":keg_pressure", round(prod->keg_pressure * 10) / 10);
793 query.bindValue(":taste_notes", prod->taste_notes);
794 query.bindValue(":taste_rate", round(prod->taste_rate * 10) / 10);
795 query.bindValue(":taste_date", prod->taste_date);
796 query.bindValue(":taste_color", prod->taste_color);
797 query.bindValue(":taste_transparency", prod->taste_transparency);
798 query.bindValue(":taste_head", prod->taste_head);
799 query.bindValue(":taste_aroma", prod->taste_aroma);
800 query.bindValue(":taste_taste", prod->taste_taste);
801 query.bindValue(":taste_mouthfeel", prod->taste_mouthfeel);
802 query.bindValue(":taste_aftertaste", prod->taste_aftertaste);
803 query.bindValue(":st_name", prod->st_name);
804 query.bindValue(":st_letter", prod->st_letter);
805 query.bindValue(":st_guide", prod->st_guide);
806 query.bindValue(":st_category", prod->st_category);
807 query.bindValue(":st_catnr", prod->st_category_number);
808 query.bindValue(":st_type", prod->st_type);
809 query.bindValue(":st_og_min", round(prod->st_og_min * 1000) / 1000);
810 query.bindValue(":st_og_max", round(prod->st_og_max * 1000) / 1000);
811 query.bindValue(":st_fg_min", round(prod->st_fg_min * 1000) / 1000);
812 query.bindValue(":st_fg_max", round(prod->st_fg_max * 1000) / 1000);
813 query.bindValue(":st_ibu_min", round(prod->st_ibu_min * 10) / 10);
814 query.bindValue(":st_ibu_max", round(prod->st_ibu_max * 10) / 10);
815 query.bindValue(":st_color_min", round(prod->st_color_min * 10) / 10);
816 query.bindValue(":st_color_max", round(prod->st_color_max * 10) / 10);
817 query.bindValue(":st_carb_min", round(prod->st_carb_min * 10) / 10);
818 query.bindValue(":st_carb_max", round(prod->st_carb_max * 10) / 10);
819 query.bindValue(":st_abv_min", round(prod->st_abv_min * 10) / 10);
820 query.bindValue(":st_abv_max", round(prod->st_abv_max * 10) / 10);
821 query.bindValue(":type", prod->type);
822 query.bindValue(":batch_size", round(prod->batch_size * 10) / 10);
823 query.bindValue(":boil_size", round(prod->boil_size * 10) / 10);
824 query.bindValue(":boil_time", round(prod->boil_time * 10) / 10);
825 query.bindValue(":efficiency", round(prod->efficiency * 10) / 10);
826 query.bindValue(":est_og", round(prod->est_og * 1000) / 1000);
827 query.bindValue(":est_og3", round(prod->est_og3 * 1000) / 1000);
828 query.bindValue(":est_fg", round(prod->est_fg * 1000) / 1000);
829 query.bindValue(":est_abv", round(prod->est_abv * 10) / 10);
830 query.bindValue(":est_color", round(prod->est_color * 10) / 10);
831 query.bindValue(":color_method", prod->color_method);
832 query.bindValue(":est_ibu", round(prod->est_ibu * 10) / 10);
833 query.bindValue(":ibu_method", prod->ibu_method);
834 query.bindValue(":est_carb", round(prod->est_carb * 10) / 10);
835 query.bindValue(":sparge_temp", round(prod->sparge_temp * 10) / 10);
836 query.bindValue(":sparge_ph", round(prod->sparge_ph * 100) / 100);
837 query.bindValue(":sparge_volume", round(prod->sparge_volume * 10) / 10);
838 query.bindValue(":sparge_source", prod->sparge_source);
839 query.bindValue(":sparge_acid_type", prod->sparge_acid_type);
840 query.bindValue(":sparge_acid_perc", round(prod->sparge_acid_perc * 10) / 10);
841 query.bindValue(":sparge_acid_amount", round(prod->sparge_acid_amount * 100000) / 100000);
842 query.bindValue(":mash_ph", round(prod->mash_ph * 100) / 100);
843 query.bindValue(":mash_name", prod->mash_name);
844 query.bindValue(":calc_acid", prod->calc_acid ?1:0);
845 query.bindValue(":w1_name", prod->w1_name);
846 query.bindValue(":w1_amount", round(prod->w1_amount * 10) / 10);
847 query.bindValue(":w1_calcium", round(prod->w1_calcium * 100000) / 100000);
848 query.bindValue(":w1_sulfate", round(prod->w1_sulfate * 100000) / 100000);
849 query.bindValue(":w1_chloride", round(prod->w1_chloride * 100000) / 100000);
850 query.bindValue(":w1_sodium", round(prod->w1_sodium * 100000) / 100000);
851 query.bindValue(":w1_magnesium", round(prod->w1_magnesium * 100000) / 100000);
852 query.bindValue(":w1_total_alkalinity", round(prod->w1_total_alkalinity * 100000) / 100000);
853 query.bindValue(":w1_ph", round(prod->w1_ph * 100) / 100);
854 query.bindValue(":w1_cost", round(prod->w1_cost * 100) / 100);
855 query.bindValue(":w2_name", prod->w2_name);
856 query.bindValue(":w2_amount", round(prod->w2_amount * 10) / 10);
857 query.bindValue(":w2_calcium", round(prod->w2_calcium * 100000) / 100000);
858 query.bindValue(":w2_sulfate", round(prod->w2_sulfate * 100000) / 100000);
859 query.bindValue(":w2_chloride", round(prod->w2_chloride * 100000) / 100000);
860 query.bindValue(":w2_sodium", round(prod->w2_sodium * 100000) / 100000);
861 query.bindValue(":w2_magnesium", round(prod->w2_magnesium * 100000) / 100000);
862 query.bindValue(":w2_total_alkalinity", round(prod->w2_total_alkalinity * 100000) / 100000);
863 query.bindValue(":w2_ph", round(prod->w2_ph * 100) / 100);
864 query.bindValue(":w2_cost", round(prod->w2_cost * 100) / 100);
865 query.bindValue(":wg_amount", round(prod->wg_amount * 10) / 10);
866 query.bindValue(":wg_calcium", round(prod->wg_calcium * 100000) / 100000);
867 query.bindValue(":wg_sulfate", round(prod->wg_sulfate * 100000) / 100000);
868 query.bindValue(":wg_chloride", round(prod->wg_chloride * 100000) / 100000);
869 query.bindValue(":wg_sodium", round(prod->wg_sodium * 100000) / 100000);
870 query.bindValue(":wg_magnesium", round(prod->wg_magnesium * 100000) / 100000);
871 query.bindValue(":wg_total_alkalinity", round(prod->wg_total_alkalinity * 100000) / 100000);
872 query.bindValue(":wg_ph", round(prod->wg_ph * 100) / 100);
873 query.bindValue(":wb_calcium", round(prod->wb_calcium * 100000) / 100000);
874 query.bindValue(":wb_sulfate", round(prod->wb_sulfate * 100000) / 100000);
875 query.bindValue(":wb_chloride", round(prod->wb_chloride * 100000) / 100000);
876 query.bindValue(":wb_sodium", round(prod->wb_sodium * 100000) / 100000);
877 query.bindValue(":wb_magnesium", round(prod->wb_magnesium * 100000) / 100000);
878 query.bindValue(":wb_total_alkalinity", round(prod->wb_total_alkalinity * 100000) / 100000);
879 query.bindValue(":wb_ph", round(prod->wb_ph * 100) / 100);
880 query.bindValue(":wa_acid_name", prod->wa_acid_name);
881 query.bindValue(":wa_acid_perc", round(prod->wa_acid_perc * 10) / 10);
882 query.bindValue(":wa_base_name", prod->wa_base_name);
883 query.bindValue(":starter_enable", prod->starter_enable ? 1:0);
884 query.bindValue(":starter_type", prod->starter_type);
885 query.bindValue(":starter_sg", round(prod->starter_sg * 1000) / 1000);
886 query.bindValue(":starter_viability", prod->starter_viability);
887 query.bindValue(":yeast_prod_date", prod->yeast_prod_date);
888 query.bindValue(":yeast_pitchrate", round(prod->yeast_pitchrate * 1000) / 1000);
889 query.bindValue(":prop1_type", prod->prop_type[0]);
890 query.bindValue(":prop1_volume", round(prod->prop_volume[0] * 1000) / 1000);
891 query.bindValue(":prop2_type", prod->prop_type[1]);
892 query.bindValue(":prop2_volume", round(prod->prop_volume[1] * 1000) / 1000);
893 query.bindValue(":prop3_type", prod->prop_type[2]);
894 query.bindValue(":prop3_volume", round(prod->prop_volume[2] * 1000) / 1000);
895 query.bindValue(":prop4_type", prod->prop_type[3]);
896 query.bindValue(":prop4_volume", round(prod->prop_volume[3] * 1000) / 1000);
897 query.bindValue(":divide_type", prod->divide_type);
898 query.bindValue(":divide_size", round(prod->divide_size * 10) / 10);
899 query.bindValue(":divide_factor", round(prod->divide_factor * 100) / 100);
900 query.bindValue(":divide_parts", prod->divide_parts);
901 query.bindValue(":divide_part", prod->divide_part);
902
903 if (prod->fermentables.size() == 0) {
904 query.bindValue(":json_fermentables", "[]");
905 } else {
906 QJsonArray array;
907 for (int i = 0; i < prod->fermentables.size(); i++) {
908 QJsonObject obj;
909 obj.insert("f_name", prod->fermentables.at(i).f_name);
910 obj.insert("f_origin", prod->fermentables.at(i).f_origin);
911 obj.insert("f_supplier", prod->fermentables.at(i).f_supplier);
912 obj.insert("f_amount", round(prod->fermentables.at(i).f_amount * 100000) / 100000);
913 obj.insert("f_cost", round(prod->fermentables.at(i).f_cost * 1000) / 1000);
914 obj.insert("f_type", prod->fermentables.at(i).f_type);
915 obj.insert("f_yield", round(prod->fermentables.at(i).f_yield * 10) / 10);
916 obj.insert("f_color", round(prod->fermentables.at(i).f_color * 10) / 10);
917 obj.insert("f_coarse_fine_diff", round(prod->fermentables.at(i).f_coarse_fine_diff * 10) / 10);
918 obj.insert("f_moisture", round(prod->fermentables.at(i).f_moisture * 10) / 10);
919 obj.insert("f_diastatic_power", round(prod->fermentables.at(i).f_diastatic_power * 100000) / 100000);
920 obj.insert("f_protein", round(prod->fermentables.at(i).f_protein * 10) / 10);
921 obj.insert("f_dissolved_protein", round(prod->fermentables.at(i).f_dissolved_protein * 10) / 10);
922 obj.insert("f_max_in_batch", prod->fermentables.at(i).f_max_in_batch);
923 obj.insert("f_graintype", prod->fermentables.at(i).f_graintype);
924 obj.insert("f_added", prod->fermentables.at(i).f_added);
925 obj.insert("f_recommend_mash", prod->fermentables.at(i).f_recommend_mash ? 1:0);
926 obj.insert("f_add_after_boil", prod->fermentables.at(i).f_add_after_boil ? 1:0);
927 obj.insert("f_adjust_to_total_100", prod->fermentables.at(i).f_adjust_to_total_100 ? 1:0);
928 obj.insert("f_percentage", round(prod->fermentables.at(i).f_percentage * 10) / 10);
929 obj.insert("f_di_ph", round(prod->fermentables.at(i).f_di_ph * 100000) / 100000);
930 obj.insert("f_acid_to_ph_57", round(prod->fermentables.at(i).f_acid_to_ph_57 * 100000) / 100000);
931 qDebug() << "fermentables_Json" << i << obj;
932 array.append(obj); /* Append this object */
933 }
934 QJsonDocument doc;
935 doc.setArray(array);
936 query.bindValue(":json_fermentables", doc.toJson(QJsonDocument::Compact));
937 }
938
939 if (prod->hops.size() == 0) {
940 query.bindValue(":json_hops", "[]");
941 } else {
942 QJsonArray array;
943 for (int i = 0; i < prod->hops.size(); i++) {
944 QJsonObject obj;
945 obj.insert("h_name", prod->hops.at(i).h_name);
946 obj.insert("h_origin", prod->hops.at(i).h_origin);
947 obj.insert("h_amount", round(prod->hops.at(i).h_amount * 10000) / 10000);
948 obj.insert("h_cost", round(prod->hops.at(i).h_cost * 100) / 100);
949 obj.insert("h_type", prod->hops.at(i).h_type);
950 obj.insert("h_form", prod->hops.at(i).h_form);
951 obj.insert("h_useat", prod->hops.at(i).h_useat);
952 obj.insert("h_time", round(prod->hops.at(i).h_time));
953 obj.insert("h_alpha", round(prod->hops.at(i).h_alpha * 100) / 100);
954 obj.insert("h_beta", round(prod->hops.at(i).h_beta * 100) / 100);
955 obj.insert("h_hsi", round(prod->hops.at(i).h_hsi * 100) / 100);
956 obj.insert("h_humulene", round(prod->hops.at(i).h_humulene * 100) / 100);
957 obj.insert("h_caryophyllene", round(prod->hops.at(i).h_caryophyllene * 100) / 100);
958 obj.insert("h_cohumulone", round(prod->hops.at(i).h_cohumulone * 100) / 100);
959 obj.insert("h_myrcene", round(prod->hops.at(i).h_myrcene * 100) / 100);
960 obj.insert("h_total_oil", round(prod->hops.at(i).h_total_oil * 100) / 100);
961 qDebug() << "hops_Json" << i << obj;
962 array.append(obj); /* Append this object */
963 }
964 QJsonDocument doc;
965 doc.setArray(array);
966 query.bindValue(":json_hops", doc.toJson(QJsonDocument::Compact));
967 }
968
969 if (prod->miscs.size() == 0) {
970 query.bindValue(":json_miscs", "[]");
971 } else {
972 QJsonArray array;
973 for (int i = 0; i < prod->miscs.size(); i++) {
974 QJsonObject obj;
975 obj.insert("m_name", prod->miscs.at(i).m_name);
976 obj.insert("m_amount", round(prod->miscs.at(i).m_amount * 10000) / 10000);
977 obj.insert("m_type", prod->miscs.at(i).m_type);
978 obj.insert("m_use_use", prod->miscs.at(i).m_use_use);
979 obj.insert("m_time", round(prod->miscs.at(i).m_time));
980 obj.insert("m_amount_is_weight", prod->miscs.at(i).m_amount_is_weight ? 1:0);
981 obj.insert("m_cost", round(prod->miscs.at(i).m_cost * 10000) / 10000);
982 qDebug() << "miscs_Json" << i << obj;
983 array.append(obj); /* Append this object */
984 }
985 QJsonDocument doc;
986 doc.setArray(array);
987 query.bindValue(":json_miscs", doc.toJson(QJsonDocument::Compact));
988 }
989
990 if (prod->yeasts.size() == 0) {
991 query.bindValue(":json_yeasts", "[]");
992 } else {
993 QJsonArray array;
994 for (int i = 0; i < prod->yeasts.size(); i++) {
995 QJsonObject obj;
996 obj.insert("y_name", prod->yeasts.at(i).y_name);
997 obj.insert("y_laboratory", prod->yeasts.at(i).y_laboratory);
998 obj.insert("y_product_id", prod->yeasts.at(i).y_product_id);
999 obj.insert("y_amount", round(prod->yeasts.at(i).y_amount * 10000) / 10000);
1000 obj.insert("y_type", prod->yeasts.at(i).y_type);
1001 obj.insert("y_form", prod->yeasts.at(i).y_form);
1002 obj.insert("y_min_temperature", round(prod->yeasts.at(i).y_min_temperature * 10) / 10);
1003 obj.insert("y_max_temperature", round(prod->yeasts.at(i).y_max_temperature * 10) / 10);
1004 obj.insert("y_flocculation", prod->yeasts.at(i).y_flocculation);
1005 obj.insert("y_attenuation", round(prod->yeasts.at(i).y_attenuation * 10) / 10);
1006 obj.insert("y_cells", prod->yeasts.at(i).y_cells);
1007 obj.insert("y_tolerance", round(prod->yeasts.at(i).y_tolerance * 10) / 10);
1008 obj.insert("y_inventory", round(prod->yeasts.at(i).y_inventory * 10000) / 10000);
1009 obj.insert("y_use", prod->yeasts.at(i).y_use);
1010 obj.insert("y_sta1", prod->yeasts.at(i).y_sta1 ? 1:0);
1011 obj.insert("y_bacteria", prod->yeasts.at(i).y_bacteria ? 1:0);
1012 obj.insert("y_harvest_top", prod->yeasts.at(i).y_harvest_top ? 1:0);
1013 obj.insert("y_harvest_time", prod->yeasts.at(i).y_harvest_time);
1014 obj.insert("y_pitch_temperature", round(prod->yeasts.at(i).y_pitch_temperature * 10) / 10);
1015 obj.insert("y_pofpos", prod->yeasts.at(i).y_pofpos ? 1:0);
1016 obj.insert("y_zymocide", prod->yeasts.at(i).y_zymocide);
1017 obj.insert("y_gr_hl_lo", prod->yeasts.at(i).y_gr_hl_lo);
1018 obj.insert("y_sg_lo", round(prod->yeasts.at(i).y_sg_lo * 1000) / 1000);
1019 obj.insert("y_gr_hl_hi", prod->yeasts.at(i).y_gr_hl_hi);
1020 obj.insert("y_sg_hi", round(prod->yeasts.at(i).y_sg_hi * 1000) / 1000);
1021 obj.insert("y_cost", round(prod->yeasts.at(i).y_cost * 1000) / 1000);
1022 qDebug() << "yeasts_Json" << i << obj;
1023 array.append(obj); /* Append this object */
1024 }
1025 QJsonDocument doc;
1026 doc.setArray(array);
1027 query.bindValue(":json_yeasts", doc.toJson(QJsonDocument::Compact));
1028 }
1029
1030 if (prod->mashs.size() == 0) {
1031 query.bindValue(":json_mashs", "[]");
1032 } else {
1033 QJsonArray array;
1034 for (int i = 0; i < prod->mashs.size(); i++) {
1035 QJsonObject obj;
1036 obj.insert("step_name", prod->mashs.at(i).step_name);
1037 obj.insert("step_type", prod->mashs.at(i).step_type);
1038 obj.insert("step_volume", round(prod->mashs.at(i).step_volume * 100) / 100);
1039 obj.insert("step_infuse_amount", round(prod->mashs.at(i).step_infuse_amount * 100) / 100);
1040 obj.insert("step_infuse_temp", round(prod->mashs.at(i).step_infuse_temp * 100) / 100);
1041 obj.insert("step_temp", round(prod->mashs.at(i).step_temp * 100) / 100);
1042 obj.insert("step_time", round(prod->mashs.at(i).step_time * 100) / 100);
1043 obj.insert("ramp_time", round(prod->mashs.at(i).ramp_time * 100) / 100);
1044 obj.insert("end_temp", round(prod->mashs.at(i).end_temp * 100) / 100);
1045 obj.insert("step_wg_ratio", round(prod->mashs.at(i).step_wg_ratio * 100) / 100);
1046 obj.insert("step_ph", round(prod->mashs.at(i).step_ph * 100) / 100);
1047 obj.insert("step_sg", round(prod->mashs.at(i).step_sg * 10000) / 10000);
1048 qDebug() << "mashs_Json" << i << obj;
1049 array.append(obj); /* Append this object */
1050 }
1051 QJsonDocument doc;
1052 doc.setArray(array);
1053 query.bindValue(":json_mashs", doc.toJson(QJsonDocument::Compact));
1054 }
1055
1056 if (prod->record == -1) {
1057 query.bindValue(":uuid", QUuid::createUuid().toString().mid(1, 36));
1058 } else {
1059 query.bindValue(":recno", prod->record);
1060 }
1061 query.exec();
1062 qDebug() << query.lastQuery();
1063 if (query.lastError().isValid()) {
1064 qDebug() << "saveProduct" << query.lastError();
1065 QMessageBox::warning(dialog, QObject::tr("Database error"),
1066 QObject::tr("MySQL error: %1\n%2\n%3")
1067 .arg(query.lastError().nativeErrorCode())
1068 .arg(query.lastError().driverText())
1069 .arg(query.lastError().databaseText()));
1070 return false;
1071 } else {
1072 /*
1073 * If this was a new product, find out what record number we
1074 * have got and set it. So when the user saves this record
1075 * again, it will be updated instead of inserting a new copy.
1076 */
1077 if (prod->record < 0) {
1078 QVariant id = query.lastInsertId();
1079 prod->record = id.toInt();
1080 qDebug() << "saveProduct Inserted record" << prod->record;
1081 } else {
1082 qDebug() << "saveProduct Updated record" << prod->record;
1083 }
1084 }
1085 return true;
1086 }
1087
1088
1089 bool DB_product::dele(QDialog *dialog, int recno)
1090 {
1091 QSqlQuery query;
1092
1093 query.prepare("DELETE FROM products WHERE record = :recno");
1094 query.bindValue(":recno", recno);
1095 query.exec();
1096 if (query.lastError().isValid()) {
1097 qDebug() << "deleteProduct" << query.lastError();
1098 QMessageBox::warning(dialog, QObject::tr("Database error"),
1099 QObject::tr("MySQL error: %1\n%2\n%3")
1100 .arg(query.lastError().nativeErrorCode())
1101 .arg(query.lastError().driverText())
1102 .arg(query.lastError().databaseText()));
1103 return false;
1104 }
1105
1106 qDebug() << "deleteProduct Deleted" << recno;
1107 return true;
1108 }
1109
1110

mercurial