<window id="dailyproduction">
	<reporttitle>Production:->Daily Production Report (Detailed)</reporttitle>
	<layout type="vertical">
		<layout type="horizontal">
			<label>Date:</label>
			<calendar id="reportdate" />
			<label>Weight Unit:</label>
			<sqldrop id="unit" />
			<label>Temperature Unit:</label>
			<sqldrop id="tempunit" />
			<stretch />
		</layout>
		<webview id="report" />
	</layout>
	<menu name="File">
		<item id="print" shortcut="Ctrl+P">Print</item>
	</menu>
	<program>
		<![CDATA[
			this.windowTitle = "Typica - Daily Production Report";
			var dateField = findChildObject(this, 'reportdate');
			var view = findChildObject(this, 'report');
			var printMenu = findChildObject(this, 'print');
			printMenu.triggered.connect(function() {
				view.print();
			});
			var unitBox = findChildObject(this, 'unit');
			unitBox.addItem("Kg");
			unitBox.addItem("Lb");
			unitBox.currentIndex = QSettings.value("script/report_unit", 1);
			unitBox['currentIndexChanged(int)'].connect(function() {
				QSettings.setValue("script/report_unit", unitBox.currentIndex);
				refresh();
			});
			var tempUnit = findChildObject(this, 'tempunit');
			tempUnit.addItem("Celsius");
			tempUnit.addItem("Fahrenheit");
			tempUnit.currentIndex = QSettings.value("script/report_temperature", 1);
			tempUnit['currentIndexChanged(int)'].connect(function() {
				QSettings.setValue("script/report_temperature", tempUnit.currentIndex);
				refresh();
			});
			function refresh() {
				var buffer = new QBuffer;
				buffer.open(3);
				var output = new XmlWriter(buffer);
				output.writeStartDocument("1.0");
				output.writeDTD('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg.dtd">');
				output.writeStartElement("html");
				output.writeAttribute("xmlns", "http://www.w3.org/1999/xhtml");
				output.writeStartElement("head");
				output.writeTextElement("title", TTR("dailyproduction", "Daily Production Report"));
				output.writeEndElement();
				output.writeStartElement("body");
				var dateString = "" + dateField.year() + "-" + dateField.month() + "-" + dateField.day();
				output.writeTextElement("h1", TTR("dailyproduction", "Daily Production Report: ") + dateString);
				output.writeTextElement("h2", TTR("dailyproduction", "Batches Roasted"));
				var query = new QSqlQuery();
				var q = "SELECT time, machine, (SELECT name FROM machine WHERE id = machine), (SELECT name FROM items WHERE id = roasted_id), unroasted_id, unroasted_quantity, unroasted_total_quantity, roasted_id, roasted_quantity, annotation, duration, files, (SELECT loss FROM roasting_specification WHERE item = roasted_id AND time = (SELECT max(time) FROM roasting_specification WHERE time <= roasting_log.time AND item = roasted_id)), (SELECT tolerance FROM roasting_specification WHERE item = roasted_id AND time = (SELECT max(time) FROM roasting_specification WHERE time <= roasting_log.time AND item = roasted_id)), (SELECT notes FROM roasting_specification WHERE item = roasted_id AND time = (SELECT max(time) FROM roasting_specification WHERE time <= roasting_log.time AND item = roasted_id)), approval FROM roasting_log WHERE time > '" + dateString + "' AND time < ('" + dateString + "'::date + integer '1') ORDER BY time";
				query.exec(q);
				var times = new Array();
				var machines = new Array();
				output.writeStartElement("table");
				output.writeAttribute("rules", "groups");
				output.writeAttribute("cellpadding", "3px");
				output.writeStartElement("thead");
				output.writeStartElement("tr");
                                output.writeAttribute("valign", "bottom");
				output.writeTextElement("th", TTR("dailyproduction", "Time"));
				output.writeTextElement("th", TTR("dailyproduction", "Machine"));
				output.writeTextElement("th", TTR("dailyproduction", "Batch ID"));
				switch(unitBox.currentIndex)
				{
					case 0:
						output.writeTextElement("th", TTR("dailyproduction", "Green Weights (Kg)"));
						break;
					case 1:
						output.writeTextElement("th", TTR("dailyproduction", "Green Weights (Lb)"));
						break;
				}
				output.writeTextElement("th", "Green Coffees");
				switch(unitBox.currentIndex)
				{
					case 0:
						output.writeTextElement("th", TTR("dailyproduction", "Roasted Weight (Kg)"));
						break;
					case 1:
						output.writeTextElement("th", TTR("dailyproduction", "Roasted Weight (Lb)"));
						break;
				}
				output.writeTextElement("th", TTR("dailyproduction", "Roasted Coffee"));
				output.writeTextElement("th", TTR("dailyproduction", "% Weight Loss"));
				output.writeTextElement("th", TTR("dailyproduction", "Duration"));
				output.writeEndElement();
				output.writeEndElement();
				output.writeStartElement("tbody");
                                output.writeAttribute("valign", "top");
				while(query.next())
				{
					times.push(query.value(0));
					machines.push(query.value(1));
					output.writeStartElement("tr");
					output.writeTextElement("td", String(query.value(0)).split("T")[1]);
					output.writeTextElement("td", query.value(2));
					output.writeStartElement("td");
					output.writeStartElement("a");
					output.writeAttribute("href", "typica://script/p" + query.value(11).slice(1,-1));
					output.writeCDATA(query.value(11));
					output.writeEndElement();
					output.writeEndElement();
					var unroastedWeightsList = sqlToArray(query.value(5));
					output.writeStartElement("td");
					for(var i = 0; i < unroastedWeightsList.length; i++)
					{
						if(i != 0)
						{
							output.writeEmptyElement("br");
						}
						switch(unitBox.currentIndex)
						{
							case 0:
								output.writeCDATA((unroastedWeightsList[i]/2.2).toFixed(unroastedWeightsList[i].split('.').length > 1 ? unroastedWeightsList[i].split('.')[1].length : 0));
								break;
							case 1:
								output.writeCDATA(unroastedWeightsList[i]);
								break;
						}
					}
					if(unroastedWeightsList.length > 1)
					{
						output.writeCDATA("Total: ");
						switch(unitBox.currentIndex)
						{
							case 0:
								output.writeCDATA((query.value(6)/2.2).toFixed(query.value(6).split('.').length > 1 ? query.value(6).split('.')[1].length : 0));
								break;
							case 1:
								output.writeCDATA(query.value(6));
								break;
						}
					}
					output.writeEndElement();
					var unroastedList = sqlToArray(query.value(4));
					output.writeStartElement("td");
					var greensQuery = new QSqlQuery();
					greensQuery.prepare("SELECT name, reference FROM coffees WHERE id = :id");
					for(var i = 0;  i < unroastedList.length; i++)
					{	
						greensQuery.bind(":id", Number(unroastedList[i]));
						greensQuery.exec();
						if(i != 0)
						{
							output.writeEmptyElement("br");
						}
						greensQuery.next();
						output.writeCDATA(greensQuery.value(0) + " (" + unroastedList[i] + ")" + (greensQuery.value(1) == "" ? "" : " ref: " + greensQuery.value(1)));
					}
					greensQuery = greensQuery.invalidate();
					output.writeEndElement();
					switch(unitBox.currentIndex)
					{
						case 0:
							output.writeCDATA((query.value(8)/2.2).toFixed(query.value(8).split('.').length > 1 ? query.value(8).split('.')[1].length : 0));
							break;
						case 1:
							output.writeCDATA(query.value(8));
							break;
					}
                                        output.writeStartElement("td");
                                        output.writeStartElement("span");
                                        if(query.value(15) == "false") {
                                            output.writeAttribute("style", "color:#FF0000");
                                        }
                                        output.writeCharacters(query.value(3) + " (" + query.value(7) + ")");
                                        output.writeEndElement();
                                        output.writeEndElement();
					if(Number(query.value(6)) > 0) {
						var loss = (Number(query.value(6)) - Number(query.value(8)))/Number(query.value(6));
                                                var lossMin;
                                                var lossMax;
                                                var lossColor;
                                                var useLoss;
                                                if(query.value(12) > 0) {
                                                    useLoss = true;
                                                    lossMin = Number(query.value(12)) - Number(query.value(13));
                                                    lossMax = Number(query.value(12)) + Number(query.value(13));
                                                    if(loss >= lossMin && loss <= lossMax) {
                                                        lossColor = '#00FF00';
                                                    } else {
                                                        lossColor = '#FF0000';
                                                    }
                                                } else {
                                                    lossColor = '#000000';
                                                    useLoss = false;
                                                }
						loss *= 100;
                                                var lossSpec = Number(query.value(12)) * 100;
                                                var lossTol = Number(query.value(13)) * 100;
                                                output.writeStartElement("td");
                                                output.writeStartElement("span");
                                                output.writeAttribute("style", "color:"+lossColor);
                                                if(useLoss) {
                                                    output.writeAttribute("title", lossSpec.toFixed(2) + "+/-" + lossTol.toFixed(2) + "%");
                                                }
                                                output.writeCharacters(loss.toFixed(2) + "%");
                                                output.writeEndElement();
                                                output.writeEndElement();
					} else {
						output.writeTextElement("td", "Undefined");
					}
					output.writeTextElement("td", query.value(10));
					output.writeEndElement();
					if(query.value(9) != "")
					{
						output.writeStartElement("tr");
						output.writeEmptyElement("td");
						output.writeStartElement("td");
						output.writeAttribute("colspan", "8");
                                                var noteArray = query.value(9).split("\n");
                                                for(var i = 0; i < noteArray.length; i++) {
                                                    output.writeStartElement("p");
                                                    output.writeAttribute("style", "margin-top: 0; margin-bottom: 0");
                                                    output.writeCharacters(noteArray[i]);
                                                    output.writeEndElement();
                                                }
						output.writeEndElement();
						output.writeEndElement();
					}
					var files = sqlToArray(query.value(11));
					var annotations = annotationFromRecord(files[0]);
					output.writeStartElement("tr");
					output.writeStartElement("td");
					output.writeAttribute("colspan", "5");
					output.writeTextElement("strong", TTR("dailyproduction", "Profile Summary"));
					var buffer2 = new QBuffer("<points>"+annotations+"</points>");
					buffer2.open(1);
					var colQuery = new XQuery;
					colQuery.bind("profile", buffer2);
					colQuery.setQuery('for $i in doc($profile)//tuple[1]/temperature/@series return (string($i), ";")');
					var result = colQuery.exec();
					buffer2.close();
					var seriesHeaders = new Array();
					seriesHeaders.push(TTR("dailyproduction", "Time"));
					var records = result.split(";");
					for(var i = 0; i < records.length - 1; i++) {
						seriesHeaders.push(records[i].replace(/^\s+|\s+$/g,""));
					}
					seriesHeaders.push(TTR("dailyproduction", "Note"));
					output.writeStartElement("table");
					output.writeStartElement("thead");
					output.writeStartElement("tr");
					for(var i = 0; i < seriesHeaders.length; i++) {
						if(i > 0 && i < seriesHeaders.length - 1) {
							switch(tempUnit.currentIndex)
							{
								case 0:
									output.writeTextElement("th", seriesHeaders[i] + " (°C)");
									break;
								case 1:
									output.writeTextElement("th", seriesHeaders[i] + " (°F)");
									break;
							}
						} else {
							output.writeTextElement("th", seriesHeaders[i]);
						}
					}
					output.writeEndElement();
					output.writeEndElement();
					buffer2.open(1);
					var rq = 'for $t in doc($profile) //tuple return (string($t/time), ";", ';
					for(var i = 0; i < seriesHeaders.length - 2; i++) {
						rq = rq + 'string($t/temperature[' + Number(i+1) + ']), ";", ';
					}
					rq = rq + 'string($t/annotation), "~")';
					colQuery.setQuery(rq);
					var annotationData = colQuery.exec();
					buffer2.close();
					output.writeStartElement("tbody");
					var annotationRecords = annotationData.split("~");
					for(var i = 0; i < annotationRecords.length - 1; i++) {
						output.writeStartElement("tr");
						var annotationRow = annotationRecords[i].split(";");
						for(var j = 0; j < annotationRow.length; j++) {
							output.writeStartElement("td");
							output.writeAttribute("style", "border-left: 1px solid #000000");
							if(j > 0) {
								output.writeAttribute("align", "center");
							}
							if(j > 0 && j < annotationRow.length - 1) {
								switch(tempUnit.currentIndex)
								{
									case 0:
										output.writeCharacters(((Number(annotationRow[j].replace(/^\s+|\s+$/g,""))-32)*5/9).toFixed(2));
										break;
									case 1:
										output.writeCharacters(Number(annotationRow[j].replace(/^\s+|\s+$/g,"")).toFixed(2));
										break;
								}
							}
							else {
								output.writeCharacters(annotationRow[j].replace(/^\s+|\s+$/g,""));
							}
							output.writeEndElement();
						}
						output.writeEndElement();
					}
					output.writeEndElement();
					output.writeEndElement();	
					output.writeEndElement();
                    output.writeStartElement("td");
                    output.writeAttribute("colspan", "4");
                    if(query.value(14)) {
                        output.writeTextElement("strong", "Roast Specification Notes");
                        var specArray = query.value(14).split("\n");
                        for(var i = 0; i < specArray.length; i++) {
                            output.writeStartElement("p");
                            output.writeAttribute("style", "margin-top: 0; margin-bottom: 0");
                            output.writeCharacters(specArray[i]);
                            output.writeEndElement();
                        }                                            
                    }
                    output.writeEndElement();
					output.writeEndElement();
				}
				output.writeEndElement();
				output.writeStartElement("tfoot");
				output.writeStartElement("tr");
				output.writeEmptyElement("td");
				output.writeEmptyElement("td");
				output.writeStartElement("td");
				output.writeTextElement("strong", TTR("dailyproduction", "Totals:"));
				output.writeEndElement();
				q = "SELECT sum(unroasted_total_quantity), sum(roasted_quantity), sum(duration) FROM roasting_log WHERE time > '" + dateString + "' AND time < ('" + dateString + "'::date + integer '1')";
				query.exec(q);
				query.next();
				switch(unitBox.currentIndex)
				{
					case 0:
						output.writeTextElement("td", (query.value(0)/2.2).toFixed(query.value(0).split('.').length > 1 ? query.value(0).split('.')[1].length : 0));
						break;
					case 1:
						output.writeTextElement("td", query.value(0));
						break;
				}
				output.writeEmptyElement("td");
				switch(unitBox.currentIndex)
				{
					case 0:
						output.writeTextElement("td", (query.value(1)/2.2).toFixed(query.value(1).split('.').length > 1 ? query.value(1).split('.')[1].length : 0));
						break;
					case 1:
						output.writeTextElement("td", query.value(1));
						break;
				}
				output.writeEmptyElement("td");
				output.writeEmptyElement("td"); 
				output.writeTextElement("td", query.value(2));
				output.writeEndElement();
				output.writeEndElement(); //tfoot
				output.writeEndElement(); //table
				output.writeTextElement("h2", TTR("dailyproduction", "Inventory"));
				output.writeStartElement("table");
				output.writeAttribute("rules", "groups");
				output.writeAttribute("cellpadding", "3px");
				output.writeStartElement("thead");
				output.writeStartElement("tr");
				output.writeTextElement("th", TTR("dailyproduction", "Green Coffee"));
				output.writeTextElement("th", TTR("dailyproduction", "Starting Inventory"));
				output.writeTextElement("th", TTR("dailyproduction", "Ending Inventory"));
				output.writeTextElement("th", TTR("dailyproduction", "Change"));
				output.writeTextElement("th", TTR("dailyproduction", "Availability"));
				output.writeEndElement();
				output.writeEndElement();
				output.writeStartElement("tbody");
				q = "SELECT DISTINCT item, (SELECT name FROM items WHERE id = item) AS name, (SELECT out FROM coffee_history WHERE id = item) FROM all_transactions WHERE time >= '" + dateString + "' AND time < '" + dateString + "'::date + integer '1' ORDER BY name ASC";
				query.exec(q)
				var subQuery = new QSqlQuery();
				var qq;
				while(query.next())
				{
					var validRow = true;
					var td1 = query.value(1);
					var td2 = 0;
					var td3 = 0;
					var td4 = 0;
					var td5 = query.value(2);
					qq = "SELECT balance FROM item_history(" + query.value(0) + ") WHERE time = (SELECT max(time) FROM all_transactions WHERE time <= '" + dateString + "' AND item = " + query.value(0) + ") OR time = (SELECT max(time) FROM all_transactions WHERE time < '" + dateString + "'::date + integer '1' AND item = " + query.value(0) + ") ORDER BY time ASC";
					subQuery.exec(qq);
					var startValue = "0.0";
					var endValue = "0.0";
					if(subQuery.next())
					{
						switch(unitBox.currentIndex)
						{
							case 0:
								td2 = (subQuery.value(0)/2.2).toFixed(subQuery.value(0).split('.').length > 1 ? subQuery.value(0).split('.')[1].length : 0);
								break;
							case 1:
								td2 = subQuery.value(0);
								break;
						}
						startValue = subQuery.value(0);
					}
					else
					{
						/* This should never happen. */
						validRow = false;
					}
					if(subQuery.next())
					{
						switch(unitBox.currentIndex)
						{
							case 0:
								td3 = (subQuery.value(0)/2.2).toFixed(subQuery.value(0).split('.').length > 1 ? subQuery.value(0).split('.')[1].length : 0);
								break;
							case 1:
								td3 = subQuery.value(0);
								break;
						}
						endValue = subQuery.value(0);
					}
					else
					{
						/* If only one transaction exists for the current query
						   this is a purchase transaction. Until something is
						   done with the coffee, it should not appear in this
						   section of the report. */
						endValue = startValue;
						validRow = false;
					}
					var startPrec = startValue.split('.').length > 1 ? startValue.split('.')[1].length : 0;
					var endPrec = endValue.split('.').length > 1 ? endValue.split('.')[1].length : 0;
					switch(unitBox.currentIndex)
					{
						case 0:
							td4 = (Number(endValue/2.2) - Number(startValue/2.2)).toFixed(Math.max(startPrec, endPrec));
							break;
						case 1:
							td4 = (Number(endValue) - Number(startValue)).toFixed(Math.max(startPrec, endPrec));
							break;
					}
					if(validRow) {
						output.writeStartElement("tr");
						output.writeTextElement("td", td1);
						output.writeTextElement("td", td2);
						output.writeTextElement("td", td3);
						output.writeTextElement("td", td4);
						output.writeTextElement("td", td5);
						output.writeEndElement();
					}
				}
				query = query.invalidate();
				subQuery = subQuery.invalidate();
				output.writeEndElement();
				output.writeStartElement("tfoot");
				
				output.writeEndElement();
				output.writeEndElement();//End of inventory table
				
				output.writeEndElement();
				output.writeEndElement();
				output.writeEndDocument();
				view.setContent(buffer);
				buffer.close();
			}
			refresh();
			dateField.dateChanged.connect(function() {
				refresh();
			});
			
			view.scriptLinkClicked.connect(function(url) {
				var arg = url.slice(1, url.length);
				var details = createWindow("batchDetails");
				var fakeTable = new Object;
				fakeTable.holding = new Array(7);
				fakeTable.data = function(r, c) {
					return this.holding[c];
				};
				var query = new QSqlQuery();
				query.exec("SELECT time, machine, (SELECT name FROM items WHERE id = roasted_id) AS name, unroasted_total_quantity AS green, roasted_quantity AS roasted, ((unroasted_total_quantity - roasted_quantity) / unroasted_total_quantity * 100::numeric)::numeric(12,2) AS weight_loss, duration, annotation FROM roasting_log WHERE files = '{" + arg + "}'");
				query.next();
				for(var i = 0; i < 8; i++) {
					fakeTable.holding[i] = query.value(i);
				}
				query = query.invalidate();
				details.loadData(fakeTable, 0);
			});
		]]>
	</program>
</window>
