Browse Source

Add date range selector, count, per item cost, link to item transactions, and bug fix related to not clearing row data on sort change to AUCO report

Neal Wilson 9 years ago
parent
commit
aabcf8b559
1 changed files with 168 additions and 132 deletions
  1. 168
    132
      config/Reports/auco.xml

+ 168
- 132
config/Reports/auco.xml View File

2
 	<reporttitle>Production:->Average Use and Cost by Origin</reporttitle>
2
 	<reporttitle>Production:->Average Use and Cost by Origin</reporttitle>
3
     <layout type="vertical">
3
     <layout type="vertical">
4
         <layout type="horizontal">
4
         <layout type="horizontal">
5
+            <daterange id="dates" initial="23" /><!-- Lifetime -->
5
             <label>Sort Order:</label>
6
             <label>Sort Order:</label>
6
             <sqldrop id="sort" />
7
             <sqldrop id="sort" />
7
 			<label>Weight Unit:</label>
8
 			<label>Weight Unit:</label>
29
             sortBox.addItem("Avg. Cost Ascending");
30
             sortBox.addItem("Avg. Cost Ascending");
30
             sortBox.addItem("Avg. Cost Descending");
31
             sortBox.addItem("Avg. Cost Descending");
31
             sortBox.currentIndex = QSettings.value("auco_sort", 0);
32
             sortBox.currentIndex = QSettings.value("auco_sort", 0);
32
-			var unitBox = findChildObject(this, 'unit');
33
-			unitBox.addItem("Kg");
34
-			unitBox.addItem("Lb");
35
-			unitBox.currentIndex = QSettings.value("script/report_unit", 1);
36
-			unitBox['currentIndexChanged(int)'].connect(function() {
37
-				QSettings.setValue("script/report_unit", unitBox.currentIndex);
38
-				refresh();
39
-			});
40
-			var rowData = new Array();
41
-			var rowIndex;
33
+            var unitBox = findChildObject(this, 'unit');
34
+            unitBox.addItem("Kg");
35
+            unitBox.addItem("Lb");
36
+            unitBox.currentIndex = QSettings.value("script/report_unit", 1);
37
+            unitBox['currentIndexChanged(int)'].connect(function() {
38
+                QSettings.setValue("script/report_unit", unitBox.currentIndex);
39
+                refresh();
40
+            });
41
+            var dateSelect = findChildObject(this, 'dates');
42
+            var dateQuery = new QSqlQuery;
43
+            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");
44
+            dateQuery.next();
45
+            var lifetimeStartDate = dateQuery.value(0);
46
+            var lifetimeEndDate;
47
+            if(dateQuery.next()) {
48
+                lifetimeEndDate = dateQuery.value(0);
49
+            } else {
50
+                lifetimeEndDate = lifetimeStartDate;
51
+            }
52
+            dateSelect.setLifetimeRange(lifetimeStartDate, lifetimeEndDate);
53
+            dateQuery = dateQuery.invalidate();
54
+            dateSelect.rangeUpdated.connect(refresh);
55
+            var rowData = new Array();
56
+            var rowIndex;
42
             function refresh() {
57
             function refresh() {
43
-				rowIndex = 0;
58
+                rowData.length = 0;
59
+                var dateRange = dateSelect.currentRange();
60
+                var startDate = dateRange[0];
61
+                var endDate = dateRange[dateRange.length - 1];
62
+                rowIndex = 0;
44
                 var buffer = new QBuffer;
63
                 var buffer = new QBuffer;
45
                 buffer.open(3);
64
                 buffer.open(3);
46
                 var output = new XmlWriter(buffer);
65
                 var output = new XmlWriter(buffer);
52
                 output.writeTextElement("title", "Recent Use and Cost by Origin");
71
                 output.writeTextElement("title", "Recent Use and Cost by Origin");
53
                 output.writeEndElement();
72
                 output.writeEndElement();
54
                 output.writeStartElement("body");
73
                 output.writeStartElement("body");
55
-                output.writeTextElement("h1", "Average Use and Cost by Origin");
56
-				switch(unitBox.currentIndex)
57
-				{
58
-					case 0:
59
-						output.writeTextElement("p", "This is a report of average rate of use in kilograms per day and cost of unroasted coffee.");
60
-						break;
61
-					case 1:
62
-						output.writeTextElement("p", "This is a report of average rate of use in pounds per day and cost of unroasted coffee.");
63
-						break;
64
-				}
74
+                output.writeTextElement("h1", "Average Use and Cost by Origin " + startDate + " - " + endDate);
75
+                switch(unitBox.currentIndex)
76
+                {
77
+                    case 0:
78
+                        output.writeTextElement("p", "This is a report of average rate of use in kilograms per day and cost of unroasted coffee.");
79
+                            break;
80
+                    case 1:
81
+                        output.writeTextElement("p", "This is a report of average rate of use in pounds per day and cost of unroasted coffee.");
82
+                    break;
83
+                }
65
                 output.writeStartElement("table");
84
                 output.writeStartElement("table");
66
                 output.writeAttribute("rules", "groups");
85
                 output.writeAttribute("rules", "groups");
67
                 output.writeAttribute("cellpadding", "3px");
86
                 output.writeAttribute("cellpadding", "3px");
68
                 output.writeStartElement("thead");
87
                 output.writeStartElement("thead");
69
                 output.writeStartElement("tr");
88
                 output.writeStartElement("tr");
70
                 output.writeStartElement("th");
89
                 output.writeStartElement("th");
71
-                output.writeAttribute("colspan", "8");
90
+                output.writeAttribute("colspan", "9");
72
                 output.writeCharacters("Regular Coffees");
91
                 output.writeCharacters("Regular Coffees");
73
                 output.writeEndElement();
92
                 output.writeEndElement();
74
                 output.writeEndElement();
93
                 output.writeEndElement();
76
                 output.writeTextElement("th", "Origin");
95
                 output.writeTextElement("th", "Origin");
77
                 output.writeTextElement("th", "Avg. Rate");
96
                 output.writeTextElement("th", "Avg. Rate");
78
                 output.writeTextElement("th", "Avg. Cost");
97
                 output.writeTextElement("th", "Avg. Cost");
79
-				output.writeTextElement("th", "Last Cost");
80
-				output.writeTextElement("th", "Last Purchase Date");
81
-				output.writeTextElement("th", "Bag Size (min)");
82
-				output.writeTextElement("th", "Bag Size (max)");
83
-				output.writeTextElement("th", "Bag Size (mean)");
98
+                output.writeTextElement("th", "Last Cost");
99
+                output.writeTextElement("th", "Last Purchase Date");
100
+                output.writeTextElement("th", "Bag Size (min)");
101
+                output.writeTextElement("th", "Bag Size (max)");
102
+                output.writeTextElement("th", "Bag Size (mean)");
103
+                output.writeTextElement("th", "Purchases");
84
                 output.writeEndElement();
104
                 output.writeEndElement();
85
                 output.writeEndElement();
105
                 output.writeEndElement();
86
                 output.writeStartElement("tbody");
106
                 output.writeStartElement("tbody");
87
                 var query = new QSqlQuery();
107
                 var query = new QSqlQuery();
88
-				var conversion = 1;
89
-				if(unitBox.currentIndex == 0) {
90
-					conversion = 2.2;
91
-				}
92
-				var orderClause;
93
-				switch(sortBox.currentIndex)
94
-				{
95
-					case 0:
96
-						orderClause = "origin ASC";
97
-						break;
98
-					case 1:
99
-						orderClause = "origin DESC";
100
-						break;
101
-					case 2:
102
-						orderClause = "rate ASC";
103
-						break;
104
-					case 3:
105
-						orderClause = "rate DESC";
106
-						break;
107
-					case 4:
108
-						orderClause = "cost ASC";
109
-						break;
110
-					case 5:
111
-						orderClause = "cost DESC";
112
-						break;
113
-				}
114
-				query.prepare("SELECT DISTINCT origin, (avg(rate)/:conversion)::numeric(10,2) AS rate, (SELECT avg(cost)*:conversion2 FROM purchase WHERE item IN (SELECT id FROM regular_coffees WHERE origin = coffee_history.origin))::numeric(10,2) AS cost, (SELECT avg(cost)*:conversion3 FROM purchase WHERE item IN (SELECT id FROM regular_coffees WHERE origin = coffee_history.origin) AND time = (SELECT max(time) FROM purchase WHERE item IN (SELECT id FROM regular_coffees WHERE origin = coffee_history.origin))), (SELECT max(time)::date FROM purchase WHERE item IN (SELECT id FROM regular_coffees WHERE origin = coffee_history.origin)), (SELECT min(conversion)/:conversion4 FROM lb_bag_conversion WHERE item IN (SELECT id FROM regular_coffees WHERE origin = coffee_history.origin))::numeric(10,2) AS minbag, (SELECT max(conversion)/:conversion5 FROM lb_bag_conversion WHERE item IN (SELECT id FROM regular_coffees WHERE origin = coffee_history.origin))::numeric(10,2) AS maxbag, (SELECT avg(conversion)/:conversion6 FROM lb_bag_conversion WHERE item IN (SELECT id FROM regular_coffees WHERE origin = coffee_history.origin))::numeric(10,2) AS meanbag FROM coffee_history WHERE id IN (SELECT id FROM regular_coffees) GROUP BY origin ORDER BY " + orderClause);
115
-				query.bind(":conversion", conversion);
116
-				query.bind(":conversion2", conversion);
117
-				query.bind(":conversion3", conversion);
118
-				query.bind(":conversion4", conversion);
119
-				query.bind(":conversion5", conversion);
120
-				query.bind(":conversion6", conversion);
121
-				query.exec();
108
+                var conversion = 1;
109
+                if(unitBox.currentIndex == 0) {
110
+                    conversion = 2.2;
111
+                }
112
+                var orderClause;
113
+                switch(sortBox.currentIndex)
114
+                {
115
+                    case 0:
116
+                        orderClause = "origin ASC";
117
+                        break;
118
+                    case 1:
119
+                        orderClause = "origin DESC";
120
+                        break;
121
+                    case 2:
122
+                        orderClause = "rate ASC";
123
+                        break;
124
+                    case 3:
125
+                        orderClause = "rate DESC";
126
+                        break;
127
+                    case 4:
128
+                        orderClause = "cost ASC";
129
+                        break;
130
+                    case 5:
131
+                        orderClause = "cost DESC";
132
+                        break;
133
+                }
134
+                query.prepare("WITH q AS (SELECT id, origin, rate/:c1 AS rate, (SELECT cost*:c2 FROM purchase WHERE item = id) AS cost, (SELECT min(time) FROM purchase WHERE item = id) AS purchase_time, (SELECT conversion/:c3 FROM lb_bag_conversion WHERE item = id) AS bag_weight FROM coffee_history WHERE id IN (SELECT id FROM regular_coffees) AND id IN (SELECT item FROM transactions WHERE time >= :startDate AND time < :endDate::date + interval '1 day')) SELECT DISTINCT origin, avg(rate)::numeric(10,2) AS rate, avg(cost)::numeric(10,2) AS cost, (SELECT (cost*:c4)::numeric(10,2) FROM purchase WHERE item = max(q.id)) AS last_cost, max(purchase_time)::date AS last_purchase, min(bag_weight)::numeric(10,2) AS min_weight, max(bag_weight)::numeric(10,2) AS max_weight, avg(bag_weight)::numeric(10,2) AS mean_weight, count(1) AS n FROM q GROUP BY origin ORDER BY " + orderClause);
135
+                query.bind(":c1", conversion);
136
+                query.bind(":c2", conversion);
137
+                query.bind(":c3", conversion);
138
+                query.bind(":c4", conversion);
139
+                query.bind(":startDate", startDate);
140
+                query.bind(":endDate", endDate);
141
+                query.exec();
122
                 while(query.next())
142
                 while(query.next())
123
                 {
143
                 {
124
                     output.writeStartElement("tr");
144
                     output.writeStartElement("tr");
125
-					output.writeAttribute("id", "r" + rowIndex);
126
-					output.writeStartElement("td");
127
-					output.writeStartElement("a");
128
-					output.writeAttribute("href", "typica://script/r" + rowIndex);
129
-					rowIndex++;
130
-					rowData.push(query.value(0));
131
-					output.writeCharacters(query.value(0));
132
-					output.writeEndElement();
133
-					output.writeEndElement();
145
+                    output.writeAttribute("id", "r" + rowIndex);
146
+                    output.writeStartElement("td");
147
+                    output.writeStartElement("a");
148
+                    output.writeAttribute("href", "typica://script/r" + rowIndex);
149
+                    rowIndex++;
150
+                    rowData.push(query.value(0));
151
+                    output.writeCharacters(query.value(0));
152
+                    output.writeEndElement();
153
+                    output.writeEndElement();
134
                     output.writeTextElement("td", query.value(1));
154
                     output.writeTextElement("td", query.value(1));
135
                     output.writeTextElement("td", query.value(2));
155
                     output.writeTextElement("td", query.value(2));
136
-					output.writeTextElement("td", query.value(3));
137
-					output.writeTextElement("td", query.value(4));
138
-					output.writeTextElement("td", query.value(5));
139
-					output.writeTextElement("td", query.value(6));
140
-					output.writeTextElement("td", query.value(7));
156
+                    output.writeTextElement("td", query.value(3));
157
+                    output.writeTextElement("td", query.value(4));
158
+                    output.writeTextElement("td", query.value(5));
159
+                    output.writeTextElement("td", query.value(6));
160
+                    output.writeTextElement("td", query.value(7));
161
+                    output.writeTextElement("td", query.value(8));
141
                     output.writeEndElement();
162
                     output.writeEndElement();
142
                 }
163
                 }
143
                 output.writeStartElement("tr");
164
                 output.writeStartElement("tr");
144
                 output.writeStartElement("th");
165
                 output.writeStartElement("th");
145
-                output.writeAttribute("colspan", "8");
166
+                output.writeAttribute("colspan", "9");
146
                 output.writeCharacters("Decaffeinated Coffees");
167
                 output.writeCharacters("Decaffeinated Coffees");
147
                 output.writeEndElement();
168
                 output.writeEndElement();
148
                 output.writeEndElement();
169
                 output.writeEndElement();
149
-				query.prepare("SELECT DISTINCT origin, (avg(rate)/:conversion)::numeric(10,2) AS rate, (SELECT avg(cost)*:conversion2 FROM purchase WHERE item IN (SELECT id FROM decaf_coffees WHERE origin = coffee_history.origin))::numeric(10,2) AS cost, (SELECT avg(cost)*:conversion3 FROM purchase WHERE item IN (SELECT id FROM decaf_coffees WHERE origin = coffee_history.origin) AND time = (SELECT max(time) FROM purchase WHERE item IN (SELECT id FROM decaf_coffees WHERE origin = coffee_history.origin))), (SELECT max(time)::date FROM purchase WHERE item IN (SELECT id FROM decaf_coffees WHERE origin = coffee_history.origin)), (SELECT min(conversion)/:conversion4 FROM lb_bag_conversion WHERE item IN (SELECT id FROM decaf_coffees WHERE origin = coffee_history.origin))::numeric(10,2) AS minbag, (SELECT max(conversion)/:conversion5 FROM lb_bag_conversion WHERE item IN (SELECT id FROM decaf_coffees WHERE origin = coffee_history.origin))::numeric(10,2) AS maxbag, (SELECT avg(conversion)/:conversion6 FROM lb_bag_conversion WHERE item IN (SELECT id FROM decaf_coffees WHERE origin = coffee_history.origin))::numeric(10,2) AS meanbag FROM coffee_history WHERE id IN (SELECT id FROM decaf_coffees) GROUP BY origin ORDER BY " + orderClause);
150
-				query.bind(":conversion", conversion);
151
-				query.bind(":conversion2", conversion);
152
-				query.bind(":conversion3", conversion);
153
-				query.bind(":conversion4", conversion);
154
-				query.bind(":conversion5", conversion);
155
-				query.bind(":conversion6", conversion);
156
-				query.exec();
170
+                query.prepare("WITH q AS (SELECT id, origin, rate/:c1 AS rate, (SELECT cost*:c2 FROM purchase WHERE item = id) AS cost, (SELECT min(time) FROM purchase WHERE item = id) AS purchase_time, (SELECT conversion/:c3 FROM lb_bag_conversion WHERE item = id) AS bag_weight FROM coffee_history WHERE id IN (SELECT id FROM decaf_coffees) AND id IN (SELECT item FROM transactions WHERE time >= :startDate AND time < :endDate::date + interval '1 day')) SELECT DISTINCT origin, avg(rate)::numeric(10,2) AS rate, avg(cost)::numeric(10,2) AS cost, (SELECT (cost*:c4)::numeric(10,2) FROM purchase WHERE item = max(q.id)) AS last_cost, max(purchase_time)::date AS last_purchase, min(bag_weight)::numeric(10,2) AS min_weight, max(bag_weight)::numeric(10,2) AS max_weight, avg(bag_weight)::numeric(10,2) AS mean_weight, count(1) AS n FROM q GROUP BY origin ORDER BY " + orderClause);
171
+                query.bind(":c1", conversion);
172
+                query.bind(":c2", conversion);
173
+                query.bind(":c3", conversion);
174
+                query.bind(":c4", conversion);
175
+                query.bind(":startDate", startDate);
176
+                query.bind(":endDate", endDate);
177
+                query.exec();
157
                 while(query.next())
178
                 while(query.next())
158
                 {
179
                 {
159
                     output.writeStartElement("tr");
180
                     output.writeStartElement("tr");
160
-					output.writeAttribute("id", "d" + rowIndex);
161
-					output.writeStartElement("td");
162
-					output.writeStartElement("a");
163
-					output.writeAttribute("href", "typica://script/d" + rowIndex);
164
-					rowIndex++;
165
-					rowData.push(query.value(0));
166
-					output.writeCharacters(query.value(0));
167
-					output.writeEndElement();
168
-					output.writeEndElement();
181
+                    output.writeAttribute("id", "d" + rowIndex);
182
+                    output.writeStartElement("td");
183
+                    output.writeStartElement("a");
184
+                    output.writeAttribute("href", "typica://script/d" + rowIndex);
185
+                    rowIndex++;
186
+                    rowData.push(query.value(0));
187
+                    output.writeCharacters(query.value(0));
188
+                    output.writeEndElement();
189
+                    output.writeEndElement();
169
                     output.writeTextElement("td", query.value(1));
190
                     output.writeTextElement("td", query.value(1));
170
                     output.writeTextElement("td", query.value(2));
191
                     output.writeTextElement("td", query.value(2));
171
-					output.writeTextElement("td", query.value(3));
172
-					output.writeTextElement("td", query.value(4));
173
-					output.writeTextElement("td", query.value(5));
174
-					output.writeTextElement("td", query.value(6));
175
-					output.writeTextElement("td", query.value(7));
192
+                    output.writeTextElement("td", query.value(3));
193
+                    output.writeTextElement("td", query.value(4));
194
+                    output.writeTextElement("td", query.value(5));
195
+                    output.writeTextElement("td", query.value(6));
196
+                    output.writeTextElement("td", query.value(7));
197
+                    output.writeTextElement("td", query.value(8));
176
                     output.writeEndElement();
198
                     output.writeEndElement();
177
                 }
199
                 }
178
-				query = query.invalidate();
200
+                query = query.invalidate();
179
                 output.writeEndElement();
201
                 output.writeEndElement();
180
                 output.writeEndElement();
202
                 output.writeEndElement();
181
                 output.writeEndElement();
203
                 output.writeEndElement();
189
                 QSettings.setValue("auco_sort", sortBox.currentIndex);
211
                 QSettings.setValue("auco_sort", sortBox.currentIndex);
190
                 refresh();
212
                 refresh();
191
             });
213
             });
192
-			report.scriptLinkClicked.connect(function(url) {
193
-				var element = new WebElement(report.findFirstElement("#" + url));
194
-				var regular = url[0] == 'r';
195
-				var index = url.slice(1, url.length);
196
-				var tableref;
197
-				if(regular) {
198
-					tableref = "regular_coffees";
199
-				} else {
200
-					tableref = "decaf_coffees";
201
-				}
202
-				var origin = rowData[Number(url.slice(1, url.length))];
203
-				var details = '<tr><td /><td colspan="6"><table><tr><th>Id</th><th>Name</th><th>Rate</th><th>Inventory</th><th>First Use</th><th>Last Use</th></tr>';
204
-				var query = new QSqlQuery();
205
-				query.prepare("SELECT id, name, (rate/:conversion1)::numeric(12,3), (stock/:conversion2)::numeric(12,3), (SELECT min(time)::date FROM use WHERE item = id) AS first_use, (SELECT max(time)::date FROM use WHERE item = id) AS last_use FROM coffee_history WHERE origin = :origin AND id IN (SELECT id FROM " + tableref + ") ORDER BY first_use DESC");
206
-				var conversion = 1;
207
-				if(unitBox.currentIndex == 0) {
208
-					conversion = 2.2;
209
-				}
210
-				query.bind(":conversion1", conversion);
211
-				query.bind(":conversion2", conversion);
212
-				query.bind(":origin", origin);
213
-				query.exec();
214
-				while(query.next()) {
215
-					details += "<tr>";
216
-					for(var i = 0; i < 6; i++) {
217
-						details += "<td>" + query.value(i) + "</td>";
218
-					}
219
-					details += "</tr>";
220
-				}
221
-				query = query.invalidate();
222
-				details += "</table></td></tr>";
223
-				element.appendOutside(details);
224
-			});
214
+            report.scriptLinkClicked.connect(function(url) {
215
+                if(url[0] == 'i') {
216
+                    url = url.slice(1, url.length);
217
+                    var itemReport = createReport("itemtransactions.xml");
218
+                    var sIB = findChildObject(itemReport, 'item');
219
+                    sIB.currentIndex = sIB.findData(url);
220
+                    return;
221
+                }
222
+                var element = new WebElement(report.findFirstElement("#" + url));
223
+                var regular = url[0] == 'r';
224
+                var index = url.slice(1, url.length);
225
+                var tableref;
226
+                if(regular) {
227
+                    tableref = "regular_coffees";
228
+                } else {
229
+                    tableref = "decaf_coffees";
230
+                }
231
+                var origin = rowData[Number(url.slice(1, url.length))];
232
+                var details = '<tr><td /><td colspan="6"><table><tr><th>Id</th><th>Name</th><th>Rate</th><th>Cost</th><th>Inventory</th><th>First Use</th><th>Last Use</th></tr>';
233
+                var query = new QSqlQuery();
234
+                query.prepare("SELECT id, name, (rate/:conversion1)::numeric(12,3), (SELECT (cost*:conversion2)::numeric(12,2) FROM purchase WHERE item = id), (stock/:conversion3)::numeric(12,3), (SELECT min(time)::date FROM use WHERE item = id) AS first_use, (SELECT max(time)::date FROM use WHERE item = id) AS last_use FROM coffee_history WHERE origin = :origin AND id IN (SELECT id FROM " + tableref + ") AND id IN (SELECT item FROM transactions WHERE time >= :startDate AND time < :endDate::date + interval '1 day') ORDER BY first_use DESC");
235
+                var conversion = 1;
236
+                if(unitBox.currentIndex == 0) {
237
+                    conversion = 2.2;
238
+                }
239
+                var dateRange = dateSelect.currentRange();
240
+                var startDate = dateRange[0];
241
+                var endDate = dateRange[dateRange.length - 1];
242
+                query.bind(":conversion1", conversion);
243
+                query.bind(":conversion2", conversion);
244
+                query.bind(":conversion3", conversion);
245
+                query.bind(":origin", origin);
246
+                query.bind(":startDate", startDate);
247
+                query.bind(":endDate", endDate);
248
+                query.exec();
249
+                while(query.next()) {
250
+                    details += "<tr>";
251
+                    details += '<td><a href="typica://script/i' + query.value(0) + '">' + query.value(0) + "</a></td>";
252
+                    for(var i = 1; i < 7; i++) {
253
+                        details += "<td>" + query.value(i) + "</td>";
254
+                    }
255
+                    details += "</tr>";
256
+                }
257
+                query = query.invalidate();
258
+                details += "</table></td></tr>";
259
+                element.appendOutside(details);
260
+            });
225
         ]]>
261
         ]]>
226
     </program>
262
     </program>
227
 </window>
263
 </window>

Loading…
Cancel
Save