瀏覽代碼

Add date range selector to item transactions report

Neal Wilson 8 年之前
父節點
當前提交
4f1292dd50
共有 1 個文件被更改,包括 367 次插入354 次删除
  1. 367
    354
      config/Reports/itemtransactions.xml

+ 367
- 354
config/Reports/itemtransactions.xml 查看文件

@@ -1,356 +1,369 @@
1 1
 <window id="item_transactions">
2
-	<reporttitle>Inventory:->Item Transactions</reporttitle>
3
-	<layout type="vertical">
4
-		<layout type="horizontal">
5
-			<label>Item:</label>
6
-			<sqldrop id="item" data="0" display="1" showdata="true">
7
-				<null />
8
-				<query>SELECT id, name FROM items WHERE category = 'Coffee: Unroasted' ORDER BY name</query>
9
-			</sqldrop>
10
-			<label>Weight Unit:</label>
11
-			<sqldrop id="unit" />
12
-			<stretch />
13
-		</layout>
14
-		<webview id="report" />
15
-	</layout>
16
-	<menu name="File">
17
-		<item id="print" shortcut="Ctrl+P">Print</item>
18
-	</menu>
19
-	<program>
20
-		<![CDATA[
21
-			this.windowTitle = TTR("item_transactions", "Typica - Item Transactions");
22
-			var itemBox = findChildObject(this, 'item');
23
-			var unitBox = findChildObject(this, 'unit');
24
-			unitBox.addItem(TTR("item_transactions", "Kg"));
25
-			unitBox.addItem(TTR("item_transactions", "Lb"));
26
-			unitBox.currentIndex = QSettings.value("script/report_unit", 1);
27
-			unitBox['currentIndexChanged(int)'].connect(function() {
28
-				QSettings.setValue("script/report_unit", unitBox.currentIndex);
29
-				refresh();
30
-			});
31
-			var view = findChildObject(this, 'report');
32
-			var printMenu = findChildObject(this, 'print');
33
-			printMenu.triggered.connect(function() {
34
-				view.print();
35
-			});
36
-			itemBox['currentIndexChanged(int)'].connect(function() {
37
-				refresh();
38
-			});
39
-			function refresh() {
40
-				var buffer = new QBuffer;
41
-				buffer.open(3);
42
-				var output = new XmlWriter(buffer);
43
-				output.writeStartDocument("1.0");
44
-				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">');
45
-				output.writeStartElement("html");
46
-				output.writeAttribute("xmlns", "http://www.w3.org/1999/xhtml");
47
-				output.writeStartElement("head");
48
-				output.writeTextElement("title", TTR("item_transactions", "Item Transactions"));
49
-				output.writeStartElement("script");
50
-				var scriptFile = new QFile(QSettings.value("config") + "/Scripts/d3.min.js");
51
-				scriptFile.open(1);
52
-				output.writeCDATA(scriptFile.readToString());
53
-				scriptFile.close();
54
-				output.writeEndElement();
55
-				output.writeStartElement("style");
56
-				output.writeAttribute("type", "text/css");
57
-				output.writeCDATA("tr.PURCHASE {background-color: #77FF77}");
58
-				output.writeCDATA("tr.USE {background-color: #FFFFFF}");
59
-				output.writeCDATA("tr.INVENTORY {background-color: #7777FF}");
60
-				output.writeCDATA("tr.SALE {background-color: #FF77FF}");
61
-				output.writeCDATA("tr.LOSS {background-color: #FF7777}");
62
-				output.writeCDATA("tr.MAKE {background-color: #FFFF77}");
63
-				output.writeEndElement(); // style
64
-				
65
-				output.writeEndElement();
66
-				output.writeStartElement("body");
67
-				output.writeTextElement("h1", TTR("item_transactions", "Item Transactions:"));
68
-				output.writeStartElement("table");
69
-				output.writeStartElement("tr");
70
-				output.writeStartElement("td");
71
-				output.writeTextElement("strong", "Item: ")
72
-				output.writeTextElement("span", itemBox.currentText);
73
-				output.writeEndElement(); // td
74
-				var query = new QSqlQuery();
75
-				query.prepare("SELECT reference, category FROM items WHERE id = :item");
76
-				query.bind(":item", itemBox.currentData());
77
-				query.exec();
78
-				if(query.next()) {
79
-					output.writeStartElement("td");
80
-					output.writeTextElement("strong", TTR("item_transactions", "Reference: "));
81
-					output.writeTextElement("span", query.value(0));
82
-					output.writeEndElement(); // td
83
-					output.writeStartElement("td");
84
-					output.writeTextElement("strong", TTR("item_transactions", "Category: "));
85
-					output.writeTextElement("span", query.value(1));
86
-					output.writeEndElement(); //td
87
-					output.writeEndElement(); //tr
88
-					query.prepare("SELECT origin, region, producer, grade, milling, drying FROM coffees WHERE id = :item");
89
-					query.bind(":item", itemBox.currentData());
90
-					query.exec();
91
-					if(query.next()) {
92
-						output.writeStartElement("tr");
93
-						output.writeStartElement("td");
94
-						output.writeTextElement("strong", TTR("item_transactions", "Origin: "));
95
-						output.writeTextElement("span", query.value(0));
96
-						output.writeEndElement(); // td
97
-						output.writeStartElement("td");
98
-						output.writeTextElement("strong", TTR("item_transactions", "Region: "));
99
-						output.writeTextElement("span", query.value(1));
100
-						output.writeEndElement(); // td
101
-						output.writeStartElement("td");
102
-						output.writeTextElement("strong", TTR("item_transactions", "Producer: "));
103
-						output.writeTextElement("span", query.value(2));
104
-						output.writeEndElement(); // td
105
-						output.writeEndElement(); // tr
106
-						output.writeStartElement("tr");
107
-						output.writeStartElement("td");
108
-						output.writeTextElement("strong", TTR("item_transactions", "Grade: "));
109
-						output.writeTextElement("span", query.value(3));
110
-						output.writeEndElement(); // td
111
-						output.writeStartElement("td");
112
-						output.writeTextElement("strong", TTR("item_transactions", "Milling: "));
113
-						output.writeTextElement("span", query.value(4));
114
-						output.writeEndElement(); // td
115
-						output.writeStartElement("td");
116
-						output.writeTextElement("strong", TTR("item_transactions", "Drying: "));
117
-						output.writeTextElement("span", query.value(5));
118
-						output.writeEndElement(); // td
119
-						output.writeEndElement(); // tr
120
-						query.prepare("SELECT decaf_method FROM decaf_coffees WHERE id = :item");
121
-						query.bind(":item", itemBox.currentData());
122
-						query.exec();
123
-						if(query.next()) {
124
-							output.writeStartElement("tr");
125
-							output.writeStartElement("td");
126
-							output.writeAttribute("colspan", "3");
127
-							output.writeTextElement("strong", TTR("item_transactions", "Decaffeination Method: "));
128
-							output.writeTextElement("span", query.value(0));
129
-							output.writeEndElement(); // td
130
-							output.writeEndElement(); // tr
131
-						}
132
-					}
133
-					output.writeEndElement() // table
134
-					
135
-					output.writeStartElement("div");
136
-					output.writeAttribute("id", "chart");
137
-					output.writeEndElement();
138
-					
139
-					query.prepare("WITH q AS (SELECT roasted_id, unroasted_id, unroasted_quantity, unroasted_total_quantity, roasted_quantity, generate_subscripts(unroasted_quantity, 1) AS s FROM roasting_log) SELECT (SELECT name FROM items WHERE id = roasted_id) AS name, roasted_id, SUM(unroasted_quantity[s]) AS total, COUNT(unroasted_quantity[s]), SUM((unroasted_quantity[s]/unroasted_total_quantity)*roasted_quantity)::numeric(12,3) AS roast_proportion FROM q WHERE unroasted_id[s] = :item1 GROUP BY roasted_id UNION SELECT 'Green Sales', NULL, SUM(quantity), COUNT(1), NULL FROM sale WHERE item = :item2 UNION SELECT 'Inventory Adjustment', NULL, ((SELECT SUM(quantity) FROM purchase WHERE item = :item3) - (SELECT quantity FROM items WHERE id = :item4) - (SELECT SUM(quantity) FROM all_transactions WHERE type != 'PURCHASE' AND type != 'INVENTORY' AND item = :item5)), (SELECT COUNT(1) FROM inventory WHERE item = :item6), NULL UNION SELECT 'Loss', NULL, SUM(quantity), COUNT(1), NULL FROM loss WHERE item = :item7 UNION SELECT 'Current Inventory', NULL, (SELECT quantity FROM items WHERE id = :item8), NULL, NULL ORDER BY total DESC");
140
-					query.bind(":item1", itemBox.currentData());
141
-					query.bind(":item2", itemBox.currentData());
142
-					query.bind(":item3", itemBox.currentData());
143
-					query.bind(":item4", itemBox.currentData());
144
-					query.bind(":item5", itemBox.currentData());
145
-					query.bind(":item6", itemBox.currentData());
146
-					query.bind(":item7", itemBox.currentData());
147
-					query.bind(":item8", itemBox.currentData());
148
-					query.exec();
149
-					var chartData = "var data = [";
150
-					var roastedCoffeeLines = "";
151
-					var adjustmentLines = "";
152
-					var currentInventoryLine = "";
153
-					var conversion = 1;
154
-					if(unitBox.currentIndex == 0) {
155
-						conversion = 2.2;
156
-					}
157
-					while(query.next()) {
158
-						if(Number(query.value(1)) > 0) {
159
-							roastedCoffeeLines += "['" + query.value(0).replace(/\'/g, "\\x27") + "'," + query.value(2) / conversion + "," + query.value(3) + "," + query.value(4) / conversion + "],";
160
-						} else if (query.value(0) == "Current Inventory") {
161
-							currentInventoryLine = "['Current Inventory'," + query.value(2) / conversion + "," + query.value(3) + "," + query.value(4) / conversion + "]";
162
-						} else {
163
-							if(Number(query.value(3)) > 0) {
164
-								adjustmentLines += "['" + query.value(0) + "'," + query.value(2) / conversion + "," + query.value(3) + "," + query.value(4) / conversion + "],";
165
-							}
166
-						}
167
-					}
168
-					chartData = chartData + roastedCoffeeLines + adjustmentLines + currentInventoryLine + "];";
169
-					
170
-					output.writeTextElement("script", chartData);
171
-					
172
-					output.writeStartElement("script");
173
-					scriptFile = new QFile(QSettings.value("config") + "/Scripts/greenusechart.js");
174
-					scriptFile.open(1);
175
-					output.writeCDATA(scriptFile.readToString());
176
-					scriptFile.close();
177
-					output.writeEndElement();
178
-
179
-                                        eval(chartData);
180
-                                        output.writeStartElement("table");
181
-                                        output.writeStartElement("tr");
182
-                                        output.writeTextElement("th", "Item");
183
-                                        output.writeTextElement("th", "Green");
184
-                                        output.writeTextElement("th", "Roasted");
185
-                                        output.writeTextElement("th", "Transactions");
186
-                                        output.writeEndElement();
187
-                                        for(var r = 0; r < data.length; r++)
188
-                                        {
189
-                                            output.writeStartElement("tr");
190
-                                            output.writeTextElement("td", data[r][0]);
191
-                                            output.writeTextElement("td", data[r][1]);
192
-                                            output.writeTextElement("td", data[r][3]);
193
-                                            output.writeTextElement("td", data[r][2]);
194
-                                            output.writeEndElement();
195
-                                        }
196
-                                        output.writeStartElement("tr");
197
-                                        output.writeTextElement("th", "Totals:");
198
-                                        output.writeTextElement("td", data.reduce(function(prev, current){
199
-                                            return +(current[1]) + prev;
200
-                                        }, 0));
201
-                                        output.writeTextElement("td", data.reduce(function(prev, current){
202
-                                            return +(current[3]) + prev;
203
-                                        }, 0));
204
-                                        output.writeTextElement("td", data.reduce(function(prev, current){
205
-                                            return +(current[2]) + prev;
206
-                                        }, 0));
207
-                                        output.writeEndElement();
208
-                                        output.writeEndElement();
209
-					
210
-					query.prepare("SELECT time::date, type, quantity / :c1, balance / :c2, (SELECT files FROM roasting_log WHERE roasting_log.time = item_history.time AND item = ANY(unroasted_id)), (SELECT invoice_id FROM invoice_items WHERE item = item_id AND item_history.type = 'PURCHASE'), (SELECT vendor || ' ' || invoice FROM invoices WHERE id = (SELECT invoice_id FROM invoice_items WHERE item = item_id AND item_history.type = 'PURCHASE')), (SELECT name FROM items WHERE id = (SELECT roasted_id FROM roasting_log WHERE roasting_log.time = item_history.time AND item = ANY(unroasted_id))), customer, reason FROM item_history(:item)");
211
-					switch(unitBox.currentIndex)
212
-					{
213
-						case 0:
214
-							query.bind(":c1", 2.2);
215
-							query.bind(":c2", 2.2);
216
-							break;
217
-						case 1:
218
-							query.bind(":c1", 1);
219
-							query.bind(":c2", 1);
220
-							break;
221
-					}
222
-					query.bind(":item", itemBox.currentData());
223
-					query.exec();
224
-					output.writeStartElement("table");
225
-					output.writeStartElement("tr");
226
-					output.writeTextElement("th", TTR("item_transactions", "Date"));
227
-					output.writeTextElement("th", TTR("item_transactions", "Type"));
228
-					output.writeTextElement("th", TTR("item_transactions", "Quantity"));
229
-					output.writeTextElement("th", TTR("item_transactions", "Balance"));
230
-					output.writeTextElement("th", TTR("item_transactions", "Record"));
231
-					output.writeEndElement(); // tr
232
-					var prev_balance = "0";
233
-					var prev_prec = 0;
234
-					var cur_prec = 0;
235
-                                        var max_prec = 3;
236
-					while(query.next()) {
237
-						output.writeStartElement("tr");
238
-						output.writeAttribute("class", query.value(1));
239
-						output.writeTextElement("td", query.value(0));
240
-						output.writeTextElement("td", query.value(1));
241
-                                                var split = prev_balance.split('.');
242
-                                                if(split.length > 1) {
243
-                                                    prev_prec = split[1].length;
244
-                                                } else {
245
-                                                    prev_prec = 0;
246
-                                                }
247
-                                                split = query.value(2).split('.');
248
-                                                if(split.length > 1) {
249
-                                                    cur_prec = split[1].length;
250
-                                                } else {
251
-                                                    cur_prec = 0;
252
-                                                }
253
-                                                var prec = prev_prec > cur_prec ? prev_prec : cur_prec;
254
-                                                var prec = (prec > max_prec ? max_prec : prec);
255
-						if(query.value(1) == "INVENTORY") {
256
-                                                    output.writeTextElement("td", (Number(query.value(2)) - Number(prev_balance)).toFixed(prec));
257
-						} else {
258
-                                                    output.writeTextElement("td", (Number(query.value(2)).toFixed(prec)));
259
-						}
260
-						output.writeTextElement("td", (Number(query.value(3)).toFixed(prec)));
261
-						prev_balance = query.value(3);
262
-						if(query.value(1) == "PURCHASE") {
263
-							output.writeStartElement("td");
264
-							output.writeStartElement("a");
265
-							output.writeAttribute("href", "typica://script/i" + query.value(5));
266
-							output.writeCDATA(query.value(6) + " (" + query.value(5) + ")");
267
-							output.writeEndElement();
268
-							output.writeEndElement();
269
-						} else if(query.value(1) == "USE") {
270
-							output.writeStartElement("td");
271
-							output.writeStartElement("a");
272
-							output.writeAttribute("href", "typica://script/p" + query.value(4).slice(1,-1));
273
-							output.writeCDATA(query.value(7) + " " + query.value(4));
274
-							output.writeEndElement();
275
-							output.writeEndElement();
276
-                                                } else if(query.value(1) == "LOSS") {
277
-                                                    output.writeTextElement("td", query.value(9));
278
-                                                } else if(query.value(1) == "SALE") {
279
-                                                    output.writeTextElement("td", query.value(8));
280
-						} else {
281
-							output.writeTextElement("td", "");
282
-						}
283
-						output.writeEndElement(); // tr
284
-					}
285
-					output.writeEndElement(); // table
286
-					/* Put the rest of the report here. No sense running queries if
287
-					   the item doesn't exist. */
288
-				} else {
289
-					/* Close tags if item data not found. */
290
-					output.writeEndElement(); // tr
291
-					output.writeEndElement(); // table
292
-				}
293
-				
294
-				output.writeEndElement(); // body
295
-				output.writeEndElement(); // html
296
-				output.writeEndDocument();
297
-				view.setContent(buffer);
298
-				buffer.close();
299
-				query = query.invalidate();
300
-			}
301
-			if(itemBox.currentData() > 0) {
302
-				refresh();
303
-			}
304
-			
305
-			/* Open invoices */
306
-			var openInvoice = function(url) {
307
-				var arg = url.slice(1, url.length);
308
-				var info = createWindow("invoiceinfo");
309
-				info.setInvoiceID(arg);
310
-				var query = new QSqlQuery();
311
-				query.exec("SELECT time, invoice, vendor FROM invoices WHERE id = " + arg);
312
-				query.next();
313
-				var timefield = findChildObject(info, 'date');
314
-				timefield.text = query.value(0);
315
-				var vendorfield = findChildObject(info, 'vendor');
316
-				vendorfield.text = query.value(2);
317
-				var invoicefield = findChildObject(info, 'invoice');
318
-				invoicefield.text = query.value(1);
319
-				var itemtable = findChildObject(info, 'itemtable');
320
-				itemtable.setQuery("SELECT record_type, item_id, description, (SELECT reference FROM items WHERE id = item_id) AS reference, (SELECT cost FROM purchase WHERE item = item_id) AS unit_cost, (SELECT quantity FROM purchase WHERE item = item_id) AS quantity, ((SELECT quantity FROM purchase WHERE item = item_id)/(SELECT conversion FROM lb_bag_conversion WHERE item = item_id))::numeric(12,2) AS sacks, cost FROM invoice_items WHERE invoice_id = " + arg + " AND record_type = 'PURCHASE' UNION SELECT record_type, NULL, description, NULL, NULL, NULL, NULL, cost FROM invoice_items WHERE invoice_id = " + arg + " AND record_type = 'FEE' ORDER BY item_id");
321
-				query = query.invalidate();
322
-			};
323
-			
324
-			/* Open batch data */
325
-			var openProfile = function(url) {
326
-				var arg = url.slice(1, url.length);
327
-				var details = createWindow("batchDetails");
328
-				var fakeTable = new Object;
329
-				fakeTable.holding = new Array(7);
330
-				fakeTable.data = function(r, c) {
331
-					return this.holding[c];
332
-				};
333
-				var query = new QSqlQuery();
334
-				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 + "}'");
335
-				query.next();
336
-				for(var i = 0; i < 8; i++) {
337
-					fakeTable.holding[i] = query.value(i);
338
-				}
339
-				query = query.invalidate();
340
-				details.loadData(fakeTable, 0);
341
-			};
342
-			
343
-			view.scriptLinkClicked.connect(function(url) {
344
-				var linkType = url[0];
345
-				switch(linkType) {
346
-					case 'i':
347
-						openInvoice(url);
348
-						break;
349
-					case 'p':
350
-						openProfile(url);
351
-						break;
352
-				}
353
-			});
354
-		]]>
355
-	</program>
2
+    <reporttitle>Inventory:->Item Transactions</reporttitle>
3
+    <layout type="vertical">
4
+        <layout type="horizontal">
5
+            <daterange id="dates" initial="23" /><!-- Lifetime-->
6
+            <label>Item:</label>
7
+            <sqldrop id="item" data="0" display="1" showdata="true">
8
+            <null />
9
+            <query>SELECT id, name FROM items WHERE category = 'Coffee: Unroasted' ORDER BY name</query>
10
+            </sqldrop>
11
+            <label>Weight Unit:</label>
12
+            <sqldrop id="unit" />
13
+            <stretch />
14
+        </layout>
15
+        <webview id="report" />
16
+    </layout>
17
+    <menu name="File">
18
+        <item id="print" shortcut="Ctrl+P">Print</item>
19
+    </menu>
20
+    <program>
21
+        <![CDATA[
22
+            this.windowTitle = TTR("item_transactions", "Typica - Item Transactions");
23
+            var dateSelect = findChildObject(this, 'dates');
24
+            var dateQuery = new QSqlQuery();
25
+            dateQuery.exec("SELECT time::date FROM transactions WHERE time = (SELECT min(time) FROM transactions) OR time = (SELECT max(time) FROM transactions) ORDER BY time ASC");
26
+            dateQuery.next();
27
+            var lifetimeStartDate = dateQuery.value(0);
28
+            var lifetimeEndDate;
29
+            if(dateQuery.next()) {
30
+                lifetimeEndDate = dateQuery.value(0);
31
+            } else {
32
+                lifetimeEndDate = lifetimeStartDate;
33
+            }
34
+            dateSelect.setLifetimeRange(lifetimeStartDate, lifetimeEndDate);
35
+            dateQuery = dateQuery.invalidate();
36
+            dateSelect.rangeUpdated.connect(function() {
37
+                refresh();
38
+            });
39
+            var itemBox = findChildObject(this, 'item');
40
+            var unitBox = findChildObject(this, 'unit');
41
+            unitBox.addItem(TTR("item_transactions", "Kg"));
42
+            unitBox.addItem(TTR("item_transactions", "Lb"));
43
+            unitBox.currentIndex = QSettings.value("script/report_unit", 1);
44
+            unitBox['currentIndexChanged(int)'].connect(function() {
45
+                QSettings.setValue("script/report_unit", unitBox.currentIndex);
46
+                refresh();
47
+            });
48
+            var view = findChildObject(this, 'report');
49
+            var printMenu = findChildObject(this, 'print');
50
+            printMenu.triggered.connect(function() {
51
+                view.print();
52
+            });
53
+            itemBox['currentIndexChanged(int)'].connect(function() {
54
+                refresh();
55
+            });
56
+            function refresh() {
57
+                var dateRange = dateSelect.currentRange();
58
+                var startDate = dateRange[0];
59
+                var endDate = dateRange[dateRange.length - 1];
60
+                var buffer = new QBuffer;
61
+                buffer.open(3);
62
+                var output = new XmlWriter(buffer);
63
+                output.writeStartDocument("1.0");
64
+                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">');
65
+                output.writeStartElement("html");
66
+                output.writeAttribute("xmlns", "http://www.w3.org/1999/xhtml");
67
+                output.writeStartElement("head");
68
+                output.writeTextElement("title", TTR("item_transactions", "Item Transactions"));
69
+                output.writeStartElement("script");
70
+                var scriptFile = new QFile(QSettings.value("config") + "/Scripts/d3.min.js");
71
+                scriptFile.open(1);
72
+                output.writeCDATA(scriptFile.readToString());
73
+                scriptFile.close();
74
+                output.writeEndElement();
75
+                output.writeStartElement("style");
76
+                output.writeAttribute("type", "text/css");
77
+                output.writeCDATA("tr.PURCHASE {background-color: #77FF77}");
78
+                output.writeCDATA("tr.USE {background-color: #FFFFFF}");
79
+                output.writeCDATA("tr.INVENTORY {background-color: #7777FF}");
80
+                output.writeCDATA("tr.SALE {background-color: #FF77FF}");
81
+                output.writeCDATA("tr.LOSS {background-color: #FF7777}");
82
+                output.writeCDATA("tr.MAKE {background-color: #FFFF77}");
83
+                output.writeEndElement(); // style
84
+                output.writeEndElement();
85
+                output.writeStartElement("body");
86
+                output.writeTextElement("h1", TTR("item_transactions", "Item Transactions:"));
87
+                output.writeStartElement("table");
88
+                output.writeStartElement("tr");
89
+                output.writeStartElement("td");
90
+                output.writeTextElement("strong", "Item: ")
91
+                output.writeTextElement("span", itemBox.currentText);
92
+                output.writeEndElement(); // td
93
+                var query = new QSqlQuery();
94
+                query.prepare("SELECT reference, category FROM items WHERE id = :item");
95
+                query.bind(":item", itemBox.currentData());
96
+                query.exec();
97
+                if(query.next()) {
98
+                    output.writeStartElement("td");
99
+                    output.writeTextElement("strong", TTR("item_transactions", "Reference: "));
100
+                    output.writeTextElement("span", query.value(0));
101
+                    output.writeEndElement(); // td
102
+                    output.writeStartElement("td");
103
+                    output.writeTextElement("strong", TTR("item_transactions", "Category: "));
104
+                    output.writeTextElement("span", query.value(1));
105
+                    output.writeEndElement(); //td
106
+                    output.writeEndElement(); //tr
107
+                    query.prepare("SELECT origin, region, producer, grade, milling, drying FROM coffees WHERE id = :item");
108
+                    query.bind(":item", itemBox.currentData());
109
+                    query.exec();
110
+                    if(query.next()) {
111
+                        output.writeStartElement("tr");
112
+                        output.writeStartElement("td");
113
+                        output.writeTextElement("strong", TTR("item_transactions", "Origin: "));
114
+                        output.writeTextElement("span", query.value(0));
115
+                        output.writeEndElement(); // td
116
+                        output.writeStartElement("td");
117
+                        output.writeTextElement("strong", TTR("item_transactions", "Region: "));
118
+                        output.writeTextElement("span", query.value(1));
119
+                        output.writeEndElement(); // td
120
+                        output.writeStartElement("td");
121
+                        output.writeTextElement("strong", TTR("item_transactions", "Producer: "));
122
+                        output.writeTextElement("span", query.value(2));
123
+                        output.writeEndElement(); // td
124
+                        output.writeEndElement(); // tr
125
+                        output.writeStartElement("tr");
126
+                        output.writeStartElement("td");
127
+                        output.writeTextElement("strong", TTR("item_transactions", "Grade: "));
128
+                        output.writeTextElement("span", query.value(3));
129
+                        output.writeEndElement(); // td
130
+                        output.writeStartElement("td");
131
+                        output.writeTextElement("strong", TTR("item_transactions", "Milling: "));
132
+                        output.writeTextElement("span", query.value(4));
133
+                        output.writeEndElement(); // td
134
+                        output.writeStartElement("td");
135
+                        output.writeTextElement("strong", TTR("item_transactions", "Drying: "));
136
+                        output.writeTextElement("span", query.value(5));
137
+                        output.writeEndElement(); // td
138
+                        output.writeEndElement(); // tr
139
+                        query.prepare("SELECT decaf_method FROM decaf_coffees WHERE id = :item");
140
+                        query.bind(":item", itemBox.currentData());
141
+                        query.exec();
142
+                        if(query.next()) {
143
+                            output.writeStartElement("tr");
144
+                            output.writeStartElement("td");
145
+                            output.writeAttribute("colspan", "3");
146
+                            output.writeTextElement("strong", TTR("item_transactions", "Decaffeination Method: "));
147
+                            output.writeTextElement("span", query.value(0));
148
+                            output.writeEndElement(); // td
149
+                            output.writeEndElement(); // tr
150
+                        }
151
+                    }
152
+                    output.writeEndElement() // table
153
+                    output.writeStartElement("div");
154
+                    output.writeAttribute("id", "chart");
155
+                    output.writeEndElement();
156
+                    query.prepare("WITH q AS (SELECT roasted_id, unroasted_id, unroasted_quantity, unroasted_total_quantity, roasted_quantity, generate_subscripts(unroasted_quantity, 1) AS s FROM roasting_log WHERE time >= :sd AND time < :ed ::date + interval '1 day') SELECT (SELECT name FROM items WHERE id = roasted_id) AS name, roasted_id, SUM(unroasted_quantity[s]) AS total, COUNT(unroasted_quantity[s]), SUM((unroasted_quantity[s]/unroasted_total_quantity)*roasted_quantity)::numeric(12,3) AS roast_proportion FROM q WHERE unroasted_id[s] = :item1 GROUP BY roasted_id UNION SELECT 'Green Sales', NULL, SUM(quantity), COUNT(1), NULL FROM sale WHERE item = :item2 UNION SELECT 'Inventory Adjustment', NULL, ((SELECT SUM(quantity) FROM purchase WHERE item = :item3) - (SELECT quantity FROM items WHERE id = :item4) - (SELECT SUM(quantity) FROM all_transactions WHERE type != 'PURCHASE' AND type != 'INVENTORY' AND item = :item5)), (SELECT COUNT(1) FROM inventory WHERE item = :item6), NULL UNION SELECT 'Loss', NULL, SUM(quantity), COUNT(1), NULL FROM loss WHERE item = :item7 UNION SELECT 'Current Inventory', NULL, (SELECT quantity FROM items WHERE id = :item8), NULL, NULL ORDER BY total DESC");
157
+                    query.bind(":sd", startDate);
158
+                    query.bind(":ed", endDate);
159
+                    query.bind(":item1", itemBox.currentData());
160
+                    query.bind(":item2", itemBox.currentData());
161
+                    query.bind(":item3", itemBox.currentData());
162
+                    query.bind(":item4", itemBox.currentData());
163
+                    query.bind(":item5", itemBox.currentData());
164
+                    query.bind(":item6", itemBox.currentData());
165
+                    query.bind(":item7", itemBox.currentData());
166
+                    query.bind(":item8", itemBox.currentData());
167
+                    query.exec();
168
+                    var chartData = "var data = [";
169
+                    var roastedCoffeeLines = "";
170
+                    var adjustmentLines = "";
171
+                    var currentInventoryLine = "";
172
+                    var conversion = 1;
173
+                    if(unitBox.currentIndex == 0) {
174
+                        conversion = 2.2;
175
+                    }
176
+                    while(query.next()) {
177
+                        if(Number(query.value(1)) > 0) {
178
+                            roastedCoffeeLines += "['" + query.value(0).replace(/\'/g, "\\x27") + "'," + query.value(2) / conversion + "," + query.value(3) + "," + query.value(4) / conversion + "],";
179
+                        } else if (query.value(0) == "Current Inventory") {
180
+                            currentInventoryLine = "['Current Inventory'," + query.value(2) / conversion + "," + query.value(3) + "," + query.value(4) / conversion + "]";
181
+                        } else {
182
+                            if(Number(query.value(3)) > 0) {
183
+                                adjustmentLines += "['" + query.value(0) + "'," + query.value(2) / conversion + "," + query.value(3) + "," + query.value(4) / conversion + "],";
184
+                            }
185
+                        }
186
+                    }
187
+                    chartData = chartData + roastedCoffeeLines + adjustmentLines + currentInventoryLine + "];";
188
+                    output.writeTextElement("script", chartData);
189
+                    output.writeStartElement("script");
190
+                    scriptFile = new QFile(QSettings.value("config") + "/Scripts/greenusechart.js");
191
+                    scriptFile.open(1);
192
+                    output.writeCDATA(scriptFile.readToString());
193
+                    scriptFile.close();
194
+                    output.writeEndElement();
195
+                    eval(chartData);
196
+                    output.writeStartElement("table");
197
+                    output.writeStartElement("tr");
198
+                    output.writeTextElement("th", "Item");
199
+                    output.writeTextElement("th", "Green");
200
+                    output.writeTextElement("th", "Roasted");
201
+                    output.writeTextElement("th", "Transactions");
202
+                    output.writeEndElement();
203
+                    for(var r = 0; r < data.length; r++)
204
+                    {
205
+                        output.writeStartElement("tr");
206
+                        output.writeTextElement("td", data[r][0]);
207
+                        output.writeTextElement("td", data[r][1]);
208
+                        output.writeTextElement("td", data[r][3]);
209
+                        output.writeTextElement("td", data[r][2]);
210
+                        output.writeEndElement();
211
+                    }
212
+                    output.writeStartElement("tr");
213
+                    output.writeTextElement("th", "Totals:");
214
+                    output.writeTextElement("td", data.reduce(function(prev, current){
215
+                        return +(current[1]) + prev;
216
+                    }, 0));
217
+                    output.writeTextElement("td", data.reduce(function(prev, current){
218
+                        return +(current[3]) + prev;
219
+                    }, 0));
220
+                    output.writeTextElement("td", data.reduce(function(prev, current){
221
+                        return +(current[2]) + prev;
222
+                    }, 0));
223
+                    output.writeEndElement();
224
+                    output.writeEndElement();
225
+                    query.prepare("SELECT time::date, type, quantity / :c1, balance / :c2, (SELECT files FROM roasting_log WHERE roasting_log.time = item_history.time AND item = ANY(unroasted_id)), (SELECT invoice_id FROM invoice_items WHERE item = item_id AND item_history.type = 'PURCHASE'), (SELECT vendor || ' ' || invoice FROM invoices WHERE id = (SELECT invoice_id FROM invoice_items WHERE item = item_id AND item_history.type = 'PURCHASE')), (SELECT name FROM items WHERE id = (SELECT roasted_id FROM roasting_log WHERE roasting_log.time = item_history.time AND item = ANY(unroasted_id))), customer, reason FROM item_history(:item) WHERE time >= :sd AND time < :ed ::date + interval '1 day'");
226
+                    query.bind(":sd", startDate);
227
+                    query.bind(":ed", endDate);
228
+                    switch(unitBox.currentIndex)
229
+                    {
230
+                        case 0:
231
+                            query.bind(":c1", 2.2);
232
+                            query.bind(":c2", 2.2);
233
+                            break;
234
+                        case 1:
235
+                            query.bind(":c1", 1);
236
+                            query.bind(":c2", 1);
237
+                            break;
238
+                    }
239
+                    query.bind(":item", itemBox.currentData());
240
+                    query.exec();
241
+                    output.writeStartElement("table");
242
+                    output.writeStartElement("tr");
243
+                    output.writeTextElement("th", TTR("item_transactions", "Date"));
244
+                    output.writeTextElement("th", TTR("item_transactions", "Type"));
245
+                    output.writeTextElement("th", TTR("item_transactions", "Quantity"));
246
+                    output.writeTextElement("th", TTR("item_transactions", "Balance"));
247
+                    output.writeTextElement("th", TTR("item_transactions", "Record"));
248
+                    output.writeEndElement(); // tr
249
+                    var prev_balance = "0";
250
+                    var prev_prec = 0;
251
+                    var cur_prec = 0;
252
+                    var max_prec = 3;
253
+                    while(query.next()) {
254
+                        output.writeStartElement("tr");
255
+                        output.writeAttribute("class", query.value(1));
256
+                        output.writeTextElement("td", query.value(0));
257
+                        output.writeTextElement("td", query.value(1));
258
+                        var split = prev_balance.split('.');
259
+                        if(split.length > 1) {
260
+                            prev_prec = split[1].length;
261
+                        } else {
262
+                            prev_prec = 0;
263
+                        }
264
+                        split = query.value(2).split('.');
265
+                        if(split.length > 1) {
266
+                            cur_prec = split[1].length;
267
+                        } else {
268
+                            cur_prec = 0;
269
+                        }
270
+                        var prec = prev_prec > cur_prec ? prev_prec : cur_prec;
271
+                        var prec = (prec > max_prec ? max_prec : prec);
272
+                        if(query.value(1) == "INVENTORY") {
273
+                            output.writeTextElement("td", (Number(query.value(2)) - Number(prev_balance)).toFixed(prec));
274
+                        } else {
275
+                            output.writeTextElement("td", (Number(query.value(2)).toFixed(prec)));
276
+                        }
277
+                        output.writeTextElement("td", (Number(query.value(3)).toFixed(prec)));
278
+                                prev_balance = query.value(3);
279
+                        if(query.value(1) == "PURCHASE") {
280
+                            output.writeStartElement("td");
281
+                            output.writeStartElement("a");
282
+                            output.writeAttribute("href", "typica://script/i" + query.value(5));
283
+                            output.writeCDATA(query.value(6) + " (" + query.value(5) + ")");
284
+                            output.writeEndElement();
285
+                            output.writeEndElement();
286
+                        } else if(query.value(1) == "USE") {
287
+                            output.writeStartElement("td");
288
+                            output.writeStartElement("a");
289
+                            output.writeAttribute("href", "typica://script/p" + query.value(4).slice(1,-1));
290
+                            output.writeCDATA(query.value(7) + " " + query.value(4));
291
+                            output.writeEndElement();
292
+                            output.writeEndElement();
293
+                        } else if(query.value(1) == "LOSS") {
294
+                            output.writeTextElement("td", query.value(9));
295
+                        } else if(query.value(1) == "SALE") {
296
+                            output.writeTextElement("td", query.value(8));
297
+                        } else {
298
+                            output.writeTextElement("td", "");
299
+                        }
300
+                        output.writeEndElement(); // tr
301
+                    }
302
+                    output.writeEndElement(); // table
303
+                    /* Put the rest of the report here. No sense running queries if
304
+                    the item doesn't exist. */
305
+                } else {
306
+                    /* Close tags if item data not found. */
307
+                    output.writeEndElement(); // tr
308
+                    output.writeEndElement(); // table
309
+                }
310
+                output.writeEndElement(); // body
311
+                output.writeEndElement(); // html
312
+                output.writeEndDocument();
313
+                view.setContent(buffer);
314
+                buffer.close();
315
+                query = query.invalidate();
316
+            }
317
+            if(itemBox.currentData() > 0) {
318
+                refresh();
319
+            }
320
+            /* Open invoices */
321
+            var openInvoice = function(url) {
322
+                var arg = url.slice(1, url.length);
323
+                var info = createWindow("invoiceinfo");
324
+                info.setInvoiceID(arg);
325
+                var query = new QSqlQuery();
326
+                query.exec("SELECT time, invoice, vendor FROM invoices WHERE id = " + arg);
327
+                query.next();
328
+                var timefield = findChildObject(info, 'date');
329
+                timefield.text = query.value(0);
330
+                var vendorfield = findChildObject(info, 'vendor');
331
+                vendorfield.text = query.value(2);
332
+                var invoicefield = findChildObject(info, 'invoice');
333
+                invoicefield.text = query.value(1);
334
+                var itemtable = findChildObject(info, 'itemtable');
335
+                itemtable.setQuery("SELECT record_type, item_id, description, (SELECT reference FROM items WHERE id = item_id) AS reference, (SELECT cost FROM purchase WHERE item = item_id) AS unit_cost, (SELECT quantity FROM purchase WHERE item = item_id) AS quantity, ((SELECT quantity FROM purchase WHERE item = item_id)/(SELECT conversion FROM lb_bag_conversion WHERE item = item_id))::numeric(12,2) AS sacks, cost FROM invoice_items WHERE invoice_id = " + arg + " AND record_type = 'PURCHASE' UNION SELECT record_type, NULL, description, NULL, NULL, NULL, NULL, cost FROM invoice_items WHERE invoice_id = " + arg + " AND record_type = 'FEE' ORDER BY item_id");
336
+                query = query.invalidate();
337
+            };
338
+            /* Open batch data */
339
+            var openProfile = function(url) {
340
+                var arg = url.slice(1, url.length);
341
+                var details = createWindow("batchDetails");
342
+                var fakeTable = new Object;
343
+                fakeTable.holding = new Array(7);
344
+                fakeTable.data = function(r, c) {
345
+                    return this.holding[c];
346
+                };
347
+                var query = new QSqlQuery();
348
+                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 + "}'");
349
+                query.next();
350
+                for(var i = 0; i < 8; i++) {
351
+                    fakeTable.holding[i] = query.value(i);
352
+                }
353
+                query = query.invalidate();
354
+                details.loadData(fakeTable, 0);
355
+            };
356
+            view.scriptLinkClicked.connect(function(url) {
357
+                var linkType = url[0];
358
+                switch(linkType) {
359
+                    case 'i':
360
+                        openInvoice(url);
361
+                        break;
362
+                    case 'p':
363
+                        openProfile(url);
364
+                        break;
365
+                }
366
+            });
367
+        ]]>
368
+    </program>
356 369
 </window>

Loading…
取消
儲存