Production:->Green Coffees Used for Roasted Coffees Print... '); output.writeStartElement("html"); output.writeAttribute("xmlns", "http://www.w3.org/1999/xhtml"); output.writeStartElement("head"); output.writeTextElement("title", TTR("greenforroasted", "Green Coffees Used for Roasted Coffees")); output.writeEndElement(); //head output.writeStartElement("body"); var cdt = new Date(Date.now()); output.writeTextElement("p", cdt.toLocaleDateString(TTR("reports", "en-US")) + " " + cdt.toLocaleTimeString(TTR("reports", "en-US"))); output.writeTextElement("h1", TTR("greenforroasted", "Green Coffees Used for Roasted Coffees ") + startDate + "-" + endDate); output.writeStartElement("ul"); var query = new QSqlQuery(); query.prepare("WITH q AS (SELECT roasted_id, unroasted_id, (SELECT name FROM items WHERE id = roasted_id) AS rname, generate_subscripts(unroasted_id, 1) AS s, sum(roasted_quantity)/:c1 AS rq, min(time)::date, max(time)::date FROM roasting_log WHERE time >= :sd1 AND time < :ed1 ::date + interval '1 day' GROUP BY roasted_id, unroasted_id) SELECT q.*, (SELECT name FROM items WHERE id = unroasted_id[q.s]) || ' (' || unroasted_id[q.s] || ')' AS gname, (SELECT SUM(unroasted_quantity[q.s])/:c2 AS gq FROM roasting_log WHERE roasted_id = q.roasted_id AND unroasted_id = q.unroasted_id AND time >= :sd2 AND time < :ed2 ::date + interval '1 day') FROM q ORDER BY q.rname ASC, min ASC"); query.bind(":sd1", startDate); query.bind(":sd2", startDate); query.bind(":ed1", endDate); query.bind(":ed2", endDate); query.bind(":c1", conversion); query.bind(":c2", conversion); query.exec(); var prevRid = -1; var prevGid = ""; var first = true; while(query.next()) { if(query.value(0) != prevRid) { // New roasted item if(!first) { output.writeEndElement(); //ul from previous roasted item output.writeEndElement(); //ul from previous roasted item } else { first = false; } output.writeTextElement("li", query.value(2) + " (" + query.value(0) + ")"); output.writeStartElement("ul"); output.writeTextElement("li", query.value(4) + " " + unitText + " roasted between " + query.value(5) + " and " + query.value(6) + " with:"); output.writeStartElement("ul"); output.writeTextElement("li", query.value(8) + " " + unitText + " of " + query.value(7)); } else { // Same roasted item if(query.value(1) != prevGid) { // New set of greens output.writeEndElement(); //ul output.writeTextElement("li", query.value(4) + " " + unitText + " roasted between " + query.value(5) + " and " + query.value(6) + " with:"); output.writeStartElement("ul"); output.writeTextElement("li", query.value(8) + " " + unitText + " of " + query.value(7)); } else { // Same set of greens output.writeTextElement("li", query.value(8) + " " + unitText + " of " + query.value(7)); } } prevRid = query.value(0); prevGid = query.value(1); } output.writeEndElement(); //ul output.writeEndElement(); //body output.writeEndElement(); //html output.writeEndDocument(); report.setContent(buffer); buffer.close(); } refresh(); var notifier = Application.subscribe("roastinglogchange"); notifier.notify.connect(function() { refresh(); }); ]]>