src/PrinterDialog.cpp

changeset 386
2e30c9c20d22
parent 379
0f2ce4ebd1b8
child 405
2c828cc3d943
equal deleted inserted replaced
385:09af9f46518f 386:2e30c9c20d22
2139 checkLine(&painter, &y, QString(tr("Add %1 gr `%2`")).arg(product->hops.at(i).amount * 1000 * factor, 1, 'f', 2) 2139 checkLine(&painter, &y, QString(tr("Add %1 gr `%2`")).arg(product->hops.at(i).amount * 1000 * factor, 1, 'f', 2)
2140 .arg(product->hops.at(i).name)); 2140 .arg(product->hops.at(i).name));
2141 } 2141 }
2142 } 2142 }
2143 } 2143 }
2144 } else if (p_job == PR_REP_TOTAL) {
2145
2146 qInfo() << "Print total production";
2147 printHeader(&painter);
2148 y = 120;
2149
2150 /* Report header */
2151 painter.setFont(QFont("Helvetica", 9, QFont::Bold));
2152 painter.setPen(Qt::black);
2153 painter.fillRect( 20, y, 540, 20, c_header);
2154 painter.drawText( 20, y+4, 80, 20, Qt::AlignHCenter, tr("Number"));
2155 painter.drawText(100, y+4, 80, 20, Qt::AlignHCenter, tr("Year"));
2156 painter.drawText(180, y+4, 120, 20, Qt::AlignRight, tr("Brew sessions"));
2157 painter.drawText(300, y+4, 120, 20, Qt::AlignRight, tr("Brew volume"));
2158 painter.drawText(420, y+4, 120, 20, Qt::AlignRight, tr("Average volume"));
2159 y += 20;
2160 painter.setFont(QFont("Helvetica", 9, QFont::Normal));
2161 query.exec("SELECT DISTINCT YEAR(package_date) FROM products WHERE package_date ORDER BY package_date");
2162 query.first();
2163 int regel = 0, brews = 0, total = 0;
2164 double packaged = 0, tvolume = 0, average;
2165 QString year = "";
2166 for (int i = 0 ; i < query.size() ; i++ ) {
2167 if ((y + 20) > painter.device()->height()) {
2168 printer->newPage();
2169 printHeader(&painter);
2170 y = 120;
2171 }
2172
2173 brews = 0;
2174 packaged = 0;
2175 regel++;
2176 year = query.value(0).toString();
2177 QSqlQuery query2;
2178 query2.exec("SELECT package_volume FROM products WHERE package_date AND YEAR(package_date) = '" + year + "'");
2179 while (query2.next()) {
2180 brews++;
2181 total++;
2182 packaged += query2.value(0).toDouble();
2183 tvolume += query2.value(0).toDouble();
2184 }
2185 average = packaged / brews;
2186 painter.fillRect( 20, y, 540, 20, (i % 2) ? c_line1:c_line2);
2187 painter.drawText( 20, y+4, 80, 20, Qt::AlignCenter, QString("%1").arg(regel));
2188 painter.drawText(100, y+4, 100, 20, Qt::AlignCenter, year);
2189 painter.drawText(180, y+4, 120, 20, Qt::AlignRight, QString("%1").arg(brews));
2190 painter.drawText(300, y+4, 120, 20, Qt::AlignRight, QString("%1 L").arg(packaged, 2, 'f', 1, '0'));
2191 painter.drawText(420, y+4, 120, 20, Qt::AlignRight, QString("%1 L").arg(average, 2, 'f', 1, '0'));
2192 query.next();
2193 y += 20;
2194 }
2195 average = tvolume / total;
2196 painter.fillRect(180, y, 360, 20, w_line);
2197 painter.drawText(180, y+4, 120, 20, Qt::AlignRight, QString("%1").arg(total));
2198 painter.drawText(300, y+4, 120, 20, Qt::AlignRight, QString("%1 L").arg(tvolume, 2, 'f', 1, '0'));
2199 painter.drawText(420, y+4, 120, 20, Qt::AlignRight, QString("%1 L").arg(average, 2, 'f', 1, '0'));
2200 y += 20;
2201
2202 } else if (p_job == PR_REP_EFF) {
2203
2204 qInfo() << "Print efficiency";
2205 y = painter.device()->height() + 100;
2206
2207 query.exec("SELECT * FROM products WHERE package_date AND type='2' ORDER BY code");
2208 query.first();
2209 for (int i = 0 ; i < query.size() ; i++ ) {
2210 if ((y + 20) > painter.device()->height()) {
2211 if (i > 0)
2212 printer->newPage();
2213 printHeader(&painter);
2214 y = 120;
2215
2216 /* Report header */
2217 painter.setFont(QFont("Helvetica", 9, QFont::Bold));
2218 painter.setPen(Qt::black);
2219 painter.fillRect( 20, y, 715, 20, c_header);
2220 painter.drawText( 25, y+4, 65, 20, Qt::AlignLeft, tr("Code"));
2221 painter.drawText( 90, y+4, 200, 20, Qt::AlignLeft, tr("Name"));
2222 painter.drawText(290, y+4, 120, 20, Qt::AlignLeft, tr("Beer style"));
2223 painter.drawText(410, y+4, 80, 20, Qt::AlignRight, tr("Max extract"));
2224 painter.drawText(490, y+4, 80, 20, Qt::AlignRight, tr("Mash eff."));
2225 painter.drawText(570, y+4, 80, 20, Qt::AlignRight, tr("Sparge eff"));
2226 painter.drawText(650, y+4, 80, 20, Qt::AlignRight, tr("Boil eff"));
2227 y += 20;
2228 painter.setFont(QFont("Helvetica", 9, QFont::Normal));
2229 }
2230
2231 /*
2232 * Data is not always available, calculate the missing pieces.
2233 */
2234 double mvol = 0, msugars = 0, ssugars = 0;
2235 QJsonParseError parseError;
2236
2237 const auto& ma_json = query.value("json_mashs").toString().trimmed();
2238 if (!ma_json.trimmed().isEmpty()) {
2239 const auto& formattedJson = QString("%1").arg(ma_json);
2240 QJsonDocument mashs = QJsonDocument::fromJson(formattedJson.toUtf8(), &parseError);
2241 if (parseError.error != QJsonParseError::NoError) {
2242 qWarning() << "Parse error: " << parseError.errorString() << "at" << parseError.offset ;
2243 } else if (mashs.isArray()) {
2244 for (int j = 0; j < mashs.array().size(); j++) {
2245 QJsonObject obj = mashs.array().at(j).toObject();
2246 if (obj["step_type"].toInt() == 0)
2247 mvol += obj["step_infuse_amount"].toDouble();
2248 }
2249 }
2250 }
2251
2252 const auto& f_json = query.value("json_fermentables").toString();
2253 if (!f_json.trimmed().isEmpty()) {
2254 const auto& formattedJson = QString("%1").arg(f_json);
2255 QJsonDocument fermentables = QJsonDocument::fromJson(formattedJson.toUtf8(), &parseError);
2256 if (parseError.error != QJsonParseError::NoError) {
2257 qWarning() << "Parse error: " << parseError.errorString() << "at" << parseError.offset ;
2258 } else if (fermentables.isArray()) {
2259 for (int j = 0; j < fermentables.array().size(); j++) {
2260 QJsonObject obj = fermentables.array().at(j).toObject();
2261 if (obj["f_added"].toInt() == 0) {
2262 double d = obj["f_amount"].toDouble() * (obj["f_yield"].toDouble() / 100) * (1 - obj["f_moisture"].toDouble() / 100);
2263 ssugars += obj["f_amount"].toDouble();
2264 mvol += obj["f_amount"].toDouble() * obj["f_moisture"].toDouble() / 100;
2265 msugars += d;
2266 }
2267 }
2268 }
2269 }
2270
2271 double sugardensity = 1.611;
2272 double v = msugars / sugardensity + mvol;
2273 double plato = 1000 * msugars / (v * 10); // deg. Plato
2274 double mash_efficiency = query.value("brew_mash_efficiency").toDouble();
2275 double mash_sg = query.value("brew_mash_sg").toDouble();
2276 if ((mash_efficiency == 0) && (mash_sg > 1)) {
2277 mash_efficiency = 100 * Utils::sg_to_plato(mash_sg) / plato;
2278 }
2279 double mash_extract = 100 * msugars / ssugars;
2280 double preboil_sg = query.value("brew_preboil_sg").toDouble();
2281 double preboil_volume = query.value("brew_preboil_volume").toDouble();
2282 double est_preboil_plato = Utils::sg_to_plato(preboil_sg) * (preboil_volume / 1.04) * preboil_sg * 10 / 1000;
2283 double preboil_efficiency = query.value("brew_preboil_efficiency").toDouble();
2284 if ((msugars > 0) && (preboil_efficiency == 0))
2285 preboil_efficiency = est_preboil_plato / msugars * 100;
2286 if (preboil_efficiency < 0)
2287 preboil_efficiency = 0;
2288 double aboil_efficiency = query.value("brew_aboil_efficiency").toDouble();
2289
2290 painter.fillRect( 20, y, 715, 20, (i % 2) ? c_line1:c_line2);
2291 painter.drawText( 25, y+4, 65, 20, Qt::AlignLeft, query.value("code").toString());
2292 painter.drawText( 90, y+4, 200, 20, Qt::AlignLeft, query.value("name").toString());
2293 painter.drawText(290, y+4, 120, 20, Qt::AlignLeft, query.value("st_name").toString());
2294 painter.drawText(410, y+4, 80, 20, Qt::AlignRight, QString("%1%").arg(mash_extract, 2, 'f', 1, '0'));
2295 painter.drawText(490, y+4, 80, 20, Qt::AlignRight, QString("%1%").arg(mash_efficiency, 2, 'f', 1, '0'));
2296 painter.drawText(570, y+4, 80, 20, Qt::AlignRight, QString("%1%").arg(preboil_efficiency, 2, 'f', 1, '0'));
2297 painter.drawText(650, y+4, 80, 20, Qt::AlignRight, QString("%1%").arg(aboil_efficiency, 2, 'f', 1, '0'));
2298 query.next();
2299 y += 20;
2300 }
2301
2302 } else if (p_job == PR_REP_SVG) {
2303
2304 qInfo() << "Print fermentations";
2305 y = painter.device()->height() + 100;
2306 QString y_name, y_lab, y_product;
2307
2308 /*
2309 * Works from MariaDB 10.6.x and later, MySQL 8.x and later.
2310 * Pick the first yeast record, that should be the one used for primary.
2311 */
2312 query.exec("SELECT code,name,brew_date_end,primary_end_temp,primary_end_date,secondary_temp,secondary_end_date,tertiary_temp,"
2313 "package_date,brew_fermenter_sg,fg,json_yeasts,"
2314 "JSON_EXTRACT(json_yeasts, '$[0].y_laboratory') AS yeastLab,JSON_EXTRACT(json_yeasts, '$[0].y_product_id') AS yeastID "
2315 "FROM products WHERE package_date AND type='2' ORDER BY yeastID");
2316 query.first();
2317
2318 for (int i = 0 ; i < query.size() ; i++ ) {
2319 if ((y + 20) > painter.device()->height()) {
2320 if (i > 0)
2321 printer->newPage();
2322 printHeader(&painter);
2323 y = 120;
2324
2325 /* Report header */
2326 painter.setFont(QFont("Helvetica", 9, QFont::Bold));
2327 painter.setPen(Qt::black);
2328 painter.fillRect( 20, y, 715, 20, c_header);
2329 painter.drawText( 25, y+4, 65, 20, Qt::AlignLeft, tr("Code"));
2330 painter.drawText( 90, y+4, 180, 20, Qt::AlignLeft, tr("Name"));
2331 painter.drawText(270, y+4, 110, 20, Qt::AlignLeft, tr("Yeast"));
2332 painter.drawText(380, y+4, 60, 20, Qt::AlignHCenter, tr("Primary"));
2333 painter.drawText(440, y+4, 60, 20, Qt::AlignHCenter, tr("Secondary"));
2334 painter.drawText(500, y+4, 60, 20, Qt::AlignHCenter, tr("Tertiary"));
2335 painter.drawText(560, y+4, 40, 20, Qt::AlignRight, tr("Days"));
2336 painter.drawText(600, y+4, 40, 20, Qt::AlignRight, tr("OG"));
2337 painter.drawText(640, y+4, 40, 20, Qt::AlignRight, tr("FG"));
2338 painter.drawText(680, y+4, 50, 20, Qt::AlignRight, tr("AA"));
2339 y += 20;
2340 painter.setFont(QFont("Helvetica", 9, QFont::Normal));
2341 }
2342
2343 int primary = query.value("brew_date_end").toDate().daysTo(query.value("primary_end_date").toDate());
2344 int secondary = query.value("primary_end_date").toDate().daysTo(query.value("secondary_end_date").toDate());
2345 int tertiary = query.value("secondary_end_date").toDate().daysTo(query.value("package_date").toDate());
2346 int total = query.value("brew_date_end").toDate().daysTo(query.value("package_date").toDate());
2347 double og = query.value("brew_fermenter_sg").toDouble();
2348 double fg = query.value("fg").toDouble();
2349 double aa = Utils::calc_svg(og, fg);
2350
2351 painter.fillRect( 20, y, 715, 20, (i % 2) ? c_line1:c_line2);
2352 painter.drawText( 25, y+4, 65, 20, Qt::AlignLeft, query.value("code").toString());
2353 painter.drawText( 90, y+4, 180, 20, Qt::AlignLeft, query.value("name").toString());
2354 painter.drawText(270, y+4, 110, 20, Qt::AlignLeft, query.value("yeastID").toString() + " " + query.value("yeastLab").toString());
2355 painter.drawText(380, y+4, 40, 20, Qt::AlignRight, QString("%1°").arg(query.value("primary_end_temp").toDouble(), 2, 'f', 1));
2356 painter.drawText(420, y+4, 20, 20, Qt::AlignRight, QString("%1").arg(primary));
2357 painter.drawText(440, y+4, 40, 20, Qt::AlignRight, QString("%1°").arg(query.value("secondary_temp").toDouble(), 2, 'f', 1));
2358 painter.drawText(480, y+4, 20, 20, Qt::AlignRight, QString("%1").arg(secondary));
2359 painter.drawText(500, y+4, 40, 20, Qt::AlignRight, QString("%1°").arg(query.value("tertiary_temp").toDouble(), 2, 'f', 1));
2360 painter.drawText(540, y+4, 20, 20, Qt::AlignRight, QString("%1").arg(tertiary));
2361 painter.drawText(560, y+4, 40, 20, Qt::AlignRight, QString("%1").arg(total));
2362 painter.drawText(600, y+4, 40, 20, Qt::AlignRight, QString("%1").arg(og, 4, 'f', 3, '0'));
2363 painter.drawText(640, y+4, 40, 20, Qt::AlignRight, QString("%1").arg(fg, 4, 'f', 3, '0'));
2364 painter.drawText(680, y+4, 50, 20, Qt::AlignRight, QString("%1%").arg(aa, 2, 'f', 1, '0'));
2365
2366 query.next();
2367 y += 20;
2368 }
2144 } 2369 }
2145 2370
2146 painter.end(); 2371 painter.end();
2147 } 2372 }
2148 2373
2230 painter->drawText(140, 0, 500, 40, Qt::AlignLeft, tr("Yeastbank") + " " + my_brewery_name); 2455 painter->drawText(140, 0, 500, 40, Qt::AlignLeft, tr("Yeastbank") + " " + my_brewery_name);
2231 } else if (p_job == PR_RECIPE) { 2456 } else if (p_job == PR_RECIPE) {
2232 painter->drawText(140, 0, 500, 40, Qt::AlignLeft, recipe->name); 2457 painter->drawText(140, 0, 500, 40, Qt::AlignLeft, recipe->name);
2233 } else if (p_job == PR_PRODUCT || p_job == PR_CHECKLIST) { 2458 } else if (p_job == PR_PRODUCT || p_job == PR_CHECKLIST) {
2234 painter->drawText(140, 0, 500, 40, Qt::AlignLeft, product->code + " " + product->name); 2459 painter->drawText(140, 0, 500, 40, Qt::AlignLeft, product->code + " " + product->name);
2460 } else if (p_job == PR_REP_TOTAL) {
2461 painter->drawText(140, 0, 500, 40, Qt::AlignLeft, tr("Year production") + " " + my_brewery_name);
2462 } else if (p_job == PR_REP_EFF) {
2463 painter->drawText(140, 0, 500, 40, Qt::AlignLeft, tr("Brew efficiency") + " " + my_brewery_name);
2464 } else if (p_job == PR_REP_SVG) {
2465 painter->drawText(140, 0, 500, 40, Qt::AlignLeft, tr("Fermentations") + " " + my_brewery_name);
2235 } else { 2466 } else {
2236 painter->drawText(140, 0, 500, 40, Qt::AlignLeft, "?? " + my_brewery_name); 2467 painter->drawText(140, 0, 500, 40, Qt::AlignLeft, "?? " + my_brewery_name);
2237 } 2468 }
2238 /* The first normal header line */ 2469 /* The first normal header line */
2239 painter->setFont(QFont("Helvetica",10, QFont::Normal)); 2470 painter->setFont(QFont("Helvetica",10, QFont::Normal));

mercurial