|
@@ -2,11 +2,15 @@
|
2
|
2
|
<reporttitle>Production:->Previous Year Production Comparison</reporttitle>
|
3
|
3
|
<layout type="vertical">
|
4
|
4
|
<layout type="horizontal">
|
5
|
|
- <daterange id="dates" initial="19" /><!-- Current Year to Date -->
|
|
5
|
+ <label>Batch Type: </label>
|
|
6
|
+ <sqldrop id="batchtype" />
|
|
7
|
+ <label>Approval: </label>
|
|
8
|
+ <sqldrop id="approval" />
|
|
9
|
+ <daterange id="dates" initial="19" /><!-- Current Year to Date -->
|
6
|
10
|
<label>Days to Average</label>
|
7
|
11
|
<line validator="integer" id="days">7</line>
|
8
|
|
- <label>Weight Unit:</label>
|
9
|
|
- <sqldrop id="unit" />
|
|
12
|
+ <label>Weight Unit:</label>
|
|
13
|
+ <sqldrop id="unit" />
|
10
|
14
|
<stretch />
|
11
|
15
|
</layout>
|
12
|
16
|
<webview id="report" />
|
|
@@ -17,27 +21,45 @@
|
17
|
21
|
<program>
|
18
|
22
|
<![CDATA[
|
19
|
23
|
this.windowTitle = "Typica - Previous Year Production Comparison";
|
20
|
|
- var dateSelect = findChildObject(this, 'dates');
|
21
|
|
- dateSelect.removeIndex(23); // Remove Lifetime range
|
|
24
|
+ var dateSelect = findChildObject(this, 'dates');
|
|
25
|
+ dateSelect.removeIndex(23); // Remove Lifetime range
|
22
|
26
|
var view = findChildObject(this, 'report');
|
23
|
27
|
var printMenu = findChildObject(this, 'print');
|
24
|
28
|
printMenu.triggered.connect(function() {
|
25
|
29
|
view.print();
|
26
|
30
|
});
|
27
|
31
|
var avgField = findChildObject(this, 'days');
|
28
|
|
- var unitBox = findChildObject(this, 'unit');
|
29
|
|
- unitBox.addItem("Kg");
|
30
|
|
- unitBox.addItem("Lb");
|
31
|
|
- unitBox.currentIndex = QSettings.value("script/report_unit", 1);
|
32
|
|
- unitBox['currentIndexChanged(int)'].connect(function() {
|
33
|
|
- QSettings.setValue("script/report_unit", unitBox.currentIndex);
|
34
|
|
- refresh();
|
35
|
|
- });
|
|
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 batchType = findChildObject(this, 'batchtype');
|
|
41
|
+ batchType.addItem("Any");
|
|
42
|
+ batchType.addItem("Production Roasts");
|
|
43
|
+ batchType.addItem("SampleRoasts");
|
|
44
|
+ batchType.currentIndex = QSettings.value("script/batchtypefilter", 1);
|
|
45
|
+ batchType['currentIndexChanged(int)'].connect(function() {
|
|
46
|
+ QSettings.setValue("script/batchtypefilter", batchType.currentIndex);
|
|
47
|
+ refresh();
|
|
48
|
+ });
|
|
49
|
+ var approval = findChildObject(this, 'approval');
|
|
50
|
+ approval.addItem("Any");
|
|
51
|
+ approval.addItem("Approved");
|
|
52
|
+ approval.addItem("Not Approved");
|
|
53
|
+ approval.currentIndex = QSettings.value("script/approvalfilter", 1);
|
|
54
|
+ approval['currentIndexChanged(int)'].connect(function() {
|
|
55
|
+ QSettings.setValue("script/approvalfilter", approval.currentIndex);
|
|
56
|
+ refresh();
|
|
57
|
+ });
|
36
|
58
|
function refresh() {
|
37
|
|
- var conversion = 1;
|
38
|
|
- if(unitBox.currentIndex == 0) {
|
39
|
|
- conversion = 2.2;
|
40
|
|
- }
|
|
59
|
+ var conversion = 1;
|
|
60
|
+ if(unitBox.currentIndex == 0) {
|
|
61
|
+ conversion = 2.2;
|
|
62
|
+ }
|
41
|
63
|
var buffer = new QBuffer;
|
42
|
64
|
buffer.open(3);
|
43
|
65
|
var output = new XmlWriter(buffer);
|
|
@@ -58,34 +80,58 @@
|
58
|
80
|
output.writeStartElement("thead");
|
59
|
81
|
output.writeStartElement("tr");
|
60
|
82
|
output.writeTextElement("th", "Coffee");
|
61
|
|
- switch(unitBox.currentIndex) {
|
62
|
|
- case 0:
|
63
|
|
- output.writeTextElement("th", "Previous (Kg)");
|
64
|
|
- output.writeTextElement("th", "Current (Kg)");
|
65
|
|
- output.writeTextElement("th", "Change (Kg)");
|
66
|
|
- break;
|
67
|
|
- case 1:
|
68
|
|
- output.writeTextElement("th", "Previous (Lb)");
|
69
|
|
- output.writeTextElement("th", "Current (Lb)");
|
70
|
|
- output.writeTextElement("th", "Change (Lb)");
|
71
|
|
- break;
|
72
|
|
- }
|
|
83
|
+ switch(unitBox.currentIndex) {
|
|
84
|
+ case 0:
|
|
85
|
+ output.writeTextElement("th", "Previous (Kg)");
|
|
86
|
+ output.writeTextElement("th", "Current (Kg)");
|
|
87
|
+ output.writeTextElement("th", "Change (Kg)");
|
|
88
|
+ break;
|
|
89
|
+ case 1:
|
|
90
|
+ output.writeTextElement("th", "Previous (Lb)");
|
|
91
|
+ output.writeTextElement("th", "Current (Lb)");
|
|
92
|
+ output.writeTextElement("th", "Change (Lb)");
|
|
93
|
+ break;
|
|
94
|
+ }
|
73
|
95
|
output.writeEndElement();
|
74
|
96
|
output.writeEndElement();
|
75
|
97
|
output.writeStartElement("tbody");
|
76
|
98
|
var query = new QSqlQuery();
|
77
|
99
|
query.exec("START TRANSACTION");
|
78
|
|
- var dateRange = dateSelect.currentRange();
|
79
|
|
- var curStartDate = "'"+dateRange[0]+"'";
|
80
|
|
- var curEndDate = "'"+dateRange[dateRange.length - 1]+"'";
|
|
100
|
+ var dateRange = dateSelect.currentRange();
|
|
101
|
+ var curStartDate = "'"+dateRange[0]+"'";
|
|
102
|
+ var curEndDate = "'"+dateRange[dateRange.length - 1]+"'";
|
81
|
103
|
query.exec("SELECT "+curStartDate+"::date - interval '1 year', "+curEndDate+"::date - interval '1 year' + interval '1 day', "+curEndDate+"::date + interval '1 day'");
|
82
|
|
- query.next();
|
|
104
|
+ query.next();
|
83
|
105
|
curEndDate = "'"+query.value(2)+"'";
|
84
|
106
|
var prevStartDate = "'"+query.value(0)+"'";
|
85
|
107
|
var prevEndDate = "'"+query.value(1)+"'";
|
86
|
|
- var q = "CREATE TEMPORARY TABLE previous ON COMMIT DROP AS SELECT roasted_id, sum(roasted_quantity) AS p FROM roasting_log WHERE time > "+prevStartDate+" AND time < "+prevEndDate+" AND roasted_id IS NOT NULL GROUP BY roasted_id";
|
|
108
|
+ var transaction_filter;
|
|
109
|
+ var approval_filter;
|
|
110
|
+ switch(batchType.currentIndex) {
|
|
111
|
+ case 0:
|
|
112
|
+ transaction_filter = "";
|
|
113
|
+ break;
|
|
114
|
+ case 1:
|
|
115
|
+ transaction_filter = " AND transaction_type = 'ROAST'";
|
|
116
|
+ break;
|
|
117
|
+ case 2:
|
|
118
|
+ transaction_filter = " AND transaction_type = 'SAMPLEROAST'";
|
|
119
|
+ break;
|
|
120
|
+ }
|
|
121
|
+ switch(approval.currentIndex) {
|
|
122
|
+ case 0:
|
|
123
|
+ approval_filter = "";
|
|
124
|
+ break;
|
|
125
|
+ case 1:
|
|
126
|
+ approval_filter = " AND approval = true";
|
|
127
|
+ break;
|
|
128
|
+ case 2:
|
|
129
|
+ approval_filter = " AND approval = false";
|
|
130
|
+ break;
|
|
131
|
+ }
|
|
132
|
+ var q = "CREATE TEMPORARY TABLE previous ON COMMIT DROP AS SELECT roasted_id, sum(roasted_quantity) AS p FROM roasting_log WHERE time > "+prevStartDate+" AND time < "+prevEndDate+" AND roasted_id IS NOT NULL" + transaction_filter + approval_filter + " GROUP BY roasted_id";
|
87
|
133
|
query.exec(q);
|
88
|
|
- q = "CREATE TEMPORARY TABLE current ON COMMIT DROP AS SELECT roasted_id, sum(roasted_quantity) AS c FROM roasting_log WHERE time > "+curStartDate+" AND time < "+curEndDate+" AND roasted_id IS NOT NULL GROUP BY roasted_id";
|
|
134
|
+ q = "CREATE TEMPORARY TABLE current ON COMMIT DROP AS SELECT roasted_id, sum(roasted_quantity) AS c FROM roasting_log WHERE time > "+curStartDate+" AND time < "+curEndDate+" AND roasted_id IS NOT NULL" + transaction_filter + approval_filter + " GROUP BY roasted_id";
|
89
|
135
|
query.exec(q);
|
90
|
136
|
query.exec("INSERT INTO previous SELECT roasted_id, 0 FROM current WHERE roasted_id NOT IN (SELECT roasted_id FROM previous)");
|
91
|
137
|
query.exec("INSERT INTO current SELECT roasted_id, 0 FROM previous WHERE roasted_id NOT IN (SELECT roasted_id FROM current)");
|
|
@@ -95,9 +141,9 @@
|
95
|
141
|
{
|
96
|
142
|
output.writeStartElement("tr");
|
97
|
143
|
output.writeTextElement("td", query.value(0));
|
98
|
|
- output.writeTextElement("td", (query.value(1) / conversion).toFixed(2));
|
99
|
|
- output.writeTextElement("td", (query.value(2) / conversion).toFixed(2));
|
100
|
|
- output.writeTextElement("td", (query.value(3) / conversion).toFixed(2));
|
|
144
|
+ output.writeTextElement("td", (query.value(1) / conversion).toFixed(2));
|
|
145
|
+ output.writeTextElement("td", (query.value(2) / conversion).toFixed(2));
|
|
146
|
+ output.writeTextElement("td", (query.value(3) / conversion).toFixed(2));
|
101
|
147
|
output.writeEndElement();
|
102
|
148
|
}
|
103
|
149
|
output.writeEndElement();
|
|
@@ -105,14 +151,14 @@
|
105
|
151
|
output.writeTextElement("th", "Totals");
|
106
|
152
|
query.exec("SELECT sum(p), sum(c), sum(c-p) FROM comp");
|
107
|
153
|
query.next();
|
108
|
|
- output.writeTextElement("td", (query.value(0) / conversion).toFixed(2));
|
109
|
|
- output.writeTextElement("td", (query.value(1) / conversion).toFixed(2));
|
110
|
|
- output.writeTextElement("td", (query.value(2) / conversion).toFixed(2));
|
|
154
|
+ output.writeTextElement("td", (query.value(0) / conversion).toFixed(2));
|
|
155
|
+ output.writeTextElement("td", (query.value(1) / conversion).toFixed(2));
|
|
156
|
+ output.writeTextElement("td", (query.value(2) / conversion).toFixed(2));
|
111
|
157
|
output.writeEndElement();
|
112
|
158
|
query.exec("ABORT");
|
113
|
159
|
output.writeEndElement();
|
114
|
|
- output.writeStartElement("p");
|
115
|
|
- output.writeAttribute("style", "page-break-inside: avoid");
|
|
160
|
+ output.writeStartElement("p");
|
|
161
|
+ output.writeAttribute("style", "page-break-inside: avoid");
|
116
|
162
|
output.writeStartElement("svg");
|
117
|
163
|
output.writeAttribute("xmlns", "http://www.w3.org/2000/svg");
|
118
|
164
|
output.writeAttribute("width", "7.5in");
|
|
@@ -158,7 +204,7 @@
|
158
|
204
|
query.exec(q);
|
159
|
205
|
query.next();
|
160
|
206
|
dates[i] = query.value(0);
|
161
|
|
- q = "SELECT sum(roasted_quantity) FROM roasting_log WHERE time > "+curStartDate+" AND time < '"+dates[i]+"'";
|
|
207
|
+ q = "SELECT sum(roasted_quantity) FROM roasting_log WHERE time > "+curStartDate+" AND time < '"+dates[i]+"'" + transaction_filter + approval_filter;
|
162
|
208
|
query.exec(q);
|
163
|
209
|
if(query.next())
|
164
|
210
|
{
|
|
@@ -168,7 +214,7 @@
|
168
|
214
|
{
|
169
|
215
|
curpounds[i] = 0;
|
170
|
216
|
}
|
171
|
|
- q = "SELECT sum(roasted_quantity) FROM roasting_log WHERE time > "+curStartDate+"::date - '1 year'::interval AND time < '"+dates[i]+"'::date - '1 year'::interval";
|
|
217
|
+ q = "SELECT sum(roasted_quantity) FROM roasting_log WHERE time > "+curStartDate+"::date - '1 year'::interval AND time < '"+dates[i]+"'::date - '1 year'::interval" + transaction_filter + approval_filter;
|
172
|
218
|
query.exec(q);
|
173
|
219
|
if(query.next())
|
174
|
220
|
{
|
|
@@ -204,23 +250,23 @@
|
204
|
250
|
avgchange[i] = sum / parseInt(avgField.text);
|
205
|
251
|
}
|
206
|
252
|
}
|
207
|
|
- // Calculate the domain of the primary y axis.
|
|
253
|
+ // Calculate the domain of the primary y axis.
|
208
|
254
|
var maxy1 = 0;
|
209
|
|
- var increment = 100; // Starting increment is 100 Lb.
|
210
|
|
- if(unitBox.currentIndex == 0) {
|
211
|
|
- increment = 110; // Starting increment is 50 Kg if Kg is requested.
|
212
|
|
- }
|
|
255
|
+ var increment = 100; // Starting increment is 100 Lb.
|
|
256
|
+ if(unitBox.currentIndex == 0) {
|
|
257
|
+ increment = 110; // Starting increment is 50 Kg if Kg is requested.
|
|
258
|
+ }
|
213
|
259
|
while(maxy1 < Math.max(curpounds[days - 1], prevpounds[days - 1]))
|
214
|
260
|
{
|
215
|
|
- maxy1 += increment;
|
|
261
|
+ maxy1 += increment;
|
216
|
262
|
}
|
217
|
|
- // Calculate the number of grid lines and loosen spacing if there are too many.
|
218
|
|
- var divisions = maxy1 / increment;
|
219
|
|
- while(divisions > 10) {
|
220
|
|
- increment *= 2;
|
221
|
|
- divisions = maxy1 / increment;
|
222
|
|
- }
|
223
|
|
- // Draw y axis grid lines.
|
|
263
|
+ // Calculate the number of grid lines and loosen spacing if there are too many.
|
|
264
|
+ var divisions = maxy1 / increment;
|
|
265
|
+ while(divisions > 10) {
|
|
266
|
+ increment *= 2;
|
|
267
|
+ divisions = maxy1 / increment;
|
|
268
|
+ }
|
|
269
|
+ // Draw y axis grid lines.
|
224
|
270
|
var pos = 0;
|
225
|
271
|
while(pos <= maxy1)
|
226
|
272
|
{
|
|
@@ -231,7 +277,7 @@
|
231
|
277
|
output.writeAttribute("y2", (450/maxy1)*pos);
|
232
|
278
|
output.writeAttribute("style", "stroke:rgb(0,0,0);stroke-width:1;");
|
233
|
279
|
output.writeEndElement();
|
234
|
|
- pos += increment;
|
|
280
|
+ pos += increment;
|
235
|
281
|
}
|
236
|
282
|
var n = Math.min.apply(Math, change);
|
237
|
283
|
var m = Math.max.apply(Math, change);
|
|
@@ -334,15 +380,15 @@
|
334
|
380
|
output.writeAttribute("x", "0");
|
335
|
381
|
output.writeAttribute("y", -((450/maxy1)*i)+5);
|
336
|
382
|
output.writeAttribute("font-size", "12");
|
337
|
|
- switch(unitBox.currentIndex) {
|
338
|
|
- case 0:
|
339
|
|
- output.writeCharacters((i / 2.2).toFixed(0));
|
340
|
|
- break;
|
341
|
|
- case 1:
|
342
|
|
- default:
|
343
|
|
- output.writeCharacters(i);
|
344
|
|
- break;
|
345
|
|
- }
|
|
383
|
+ switch(unitBox.currentIndex) {
|
|
384
|
+ case 0:
|
|
385
|
+ output.writeCharacters((i / 2.2).toFixed(0));
|
|
386
|
+ break;
|
|
387
|
+ case 1:
|
|
388
|
+ default:
|
|
389
|
+ output.writeCharacters(i);
|
|
390
|
+ break;
|
|
391
|
+ }
|
346
|
392
|
output.writeEndElement();
|
347
|
393
|
i += increment;
|
348
|
394
|
}
|
|
@@ -427,7 +473,7 @@
|
427
|
473
|
i = days - 1;
|
428
|
474
|
}
|
429
|
475
|
}
|
430
|
|
- query = query.invalidate();
|
|
476
|
+ query = query.invalidate();
|
431
|
477
|
output.writeStartElement("rect");
|
432
|
478
|
output.writeAttribute("fill", "rgb(0,0,0)");
|
433
|
479
|
output.writeAttribute("x", "45");
|
|
@@ -439,14 +485,14 @@
|
439
|
485
|
output.writeAttribute("x", "75");
|
440
|
486
|
output.writeAttribute("y", "120");
|
441
|
487
|
output.writeAttribute("font-size", "12");
|
442
|
|
- switch(unitBox.currentIndex) {
|
443
|
|
- case 0:
|
444
|
|
- output.writeCharacters("Previous Year Kg");
|
445
|
|
- break;
|
446
|
|
- case 1:
|
447
|
|
- output.writeCharacters("Previous Year Lb");
|
448
|
|
- break;
|
449
|
|
- }
|
|
488
|
+ switch(unitBox.currentIndex) {
|
|
489
|
+ case 0:
|
|
490
|
+ output.writeCharacters("Previous Year Kg");
|
|
491
|
+ break;
|
|
492
|
+ case 1:
|
|
493
|
+ output.writeCharacters("Previous Year Lb");
|
|
494
|
+ break;
|
|
495
|
+ }
|
450
|
496
|
output.writeEndElement();
|
451
|
497
|
output.writeStartElement("rect");
|
452
|
498
|
output.writeAttribute("fill", "rgb(255,0,0)");
|
|
@@ -459,14 +505,14 @@
|
459
|
505
|
output.writeAttribute("x", "225");
|
460
|
506
|
output.writeAttribute("y", "120");
|
461
|
507
|
output.writeAttribute("font-size", "12");
|
462
|
|
- switch(unitBox.currentIndex) {
|
463
|
|
- case 0:
|
464
|
|
- output.writeCharacters("Current Year Kg");
|
465
|
|
- break;
|
466
|
|
- case 1:
|
467
|
|
- output.writeCharacters("Current Year Lb");
|
468
|
|
- break;
|
469
|
|
- }
|
|
508
|
+ switch(unitBox.currentIndex) {
|
|
509
|
+ case 0:
|
|
510
|
+ output.writeCharacters("Current Year Kg");
|
|
511
|
+ break;
|
|
512
|
+ case 1:
|
|
513
|
+ output.writeCharacters("Current Year Lb");
|
|
514
|
+ break;
|
|
515
|
+ }
|
470
|
516
|
output.writeEndElement();
|
471
|
517
|
output.writeStartElement("rect");
|
472
|
518
|
output.writeAttribute("fill", "rgb(0,255,0)");
|
|
@@ -498,18 +544,18 @@
|
498
|
544
|
output.writeEndElement();
|
499
|
545
|
output.writeEndElement();
|
500
|
546
|
output.writeEndElement();
|
501
|
|
- output.writeEndElement();
|
|
547
|
+ output.writeEndElement();
|
502
|
548
|
output.writeEndDocument();
|
503
|
549
|
view.setContent(buffer);
|
504
|
550
|
buffer.close();
|
505
|
551
|
}
|
506
|
552
|
refresh();
|
507
|
|
- dateSelect.rangeUpdated.connect(function() {
|
508
|
|
- refresh();
|
509
|
|
- });
|
510
|
|
- avgField.editingFinished.connect(function() {
|
511
|
|
- refresh();
|
512
|
|
- });
|
|
553
|
+ dateSelect.rangeUpdated.connect(function() {
|
|
554
|
+ refresh();
|
|
555
|
+ });
|
|
556
|
+ avgField.editingFinished.connect(function() {
|
|
557
|
+ refresh();
|
|
558
|
+ });
|
513
|
559
|
]]>
|
514
|
560
|
</program>
|
515
|
561
|
</window>
|