|
@@ -18,6 +18,7 @@
|
18
|
18
|
</menu>
|
19
|
19
|
<program>
|
20
|
20
|
<![CDATA[
|
|
21
|
+ var externpath = "file:///home/neal/TCS/";
|
21
|
22
|
this.windowTitle = "Typica - Item Transactions";
|
22
|
23
|
var itemBox = findChildObject(this, 'item');
|
23
|
24
|
var unitBox = findChildObject(this, 'unit');
|
|
@@ -46,6 +47,9 @@
|
46
|
47
|
output.writeAttribute("xmlns", "http://www.w3.org/1999/xhtml");
|
47
|
48
|
output.writeStartElement("head");
|
48
|
49
|
output.writeTextElement("title", "Item Transactions");
|
|
50
|
+ output.writeStartElement("script");
|
|
51
|
+ output.writeAttribute("src", "Scripts/d3.min.js");
|
|
52
|
+ output.writeEndElement();
|
49
|
53
|
output.writeStartElement("style");
|
50
|
54
|
output.writeAttribute("type", "text/css");
|
51
|
55
|
output.writeCDATA("tr.PURCHASE {background-color: #77FF77}");
|
|
@@ -126,7 +130,48 @@
|
126
|
130
|
}
|
127
|
131
|
output.writeEndElement() // table
|
128
|
132
|
|
129
|
|
- query.prepare("SELECT time::date, type, quantity / :c1, balance / :c2 FROM item_history(:item)");
|
|
133
|
+ output.writeStartElement("div");
|
|
134
|
+ output.writeAttribute("id", "chart");
|
|
135
|
+ output.writeEndElement();
|
|
136
|
+
|
|
137
|
+ 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");
|
|
138
|
+ query.bind(":item1", itemBox.currentData());
|
|
139
|
+ query.bind(":item2", itemBox.currentData());
|
|
140
|
+ query.bind(":item3", itemBox.currentData());
|
|
141
|
+ query.bind(":item4", itemBox.currentData());
|
|
142
|
+ query.bind(":item5", itemBox.currentData());
|
|
143
|
+ query.bind(":item6", itemBox.currentData());
|
|
144
|
+ query.bind(":item7", itemBox.currentData());
|
|
145
|
+ query.bind(":item8", itemBox.currentData());
|
|
146
|
+ query.exec();
|
|
147
|
+ var chartData = "var data = [";
|
|
148
|
+ var roastedCoffeeLines = "";
|
|
149
|
+ var adjustmentLines = "";
|
|
150
|
+ var currentInventoryLine = "";
|
|
151
|
+ var conversion = 1;
|
|
152
|
+ if(unitBox.currentIndex == 0) {
|
|
153
|
+ conversion = 2.2;
|
|
154
|
+ }
|
|
155
|
+ while(query.next()) {
|
|
156
|
+ if(Number(query.value(1)) > 0) {
|
|
157
|
+ roastedCoffeeLines += "['" + query.value(0).replace(/\'/g, "\\x27") + "'," + query.value(2) / conversion + "," + query.value(3) + "," + query.value(4) / conversion + "],";
|
|
158
|
+ } else if (query.value(0) == "Current Inventory") {
|
|
159
|
+ currentInventoryLine = "['Current Inventory'," + query.value(2) / conversion + "," + query.value(3) + "," + query.value(4) / conversion + "]";
|
|
160
|
+ } else {
|
|
161
|
+ if(Number(query.value(3)) > 0) {
|
|
162
|
+ adjustmentLines += "['" + query.value(0) + "'," + query.value(2) / conversion + "," + query.value(3) + "," + query.value(4) / conversion + "],";
|
|
163
|
+ }
|
|
164
|
+ }
|
|
165
|
+ }
|
|
166
|
+ chartData = chartData + roastedCoffeeLines + adjustmentLines + currentInventoryLine + "];";
|
|
167
|
+
|
|
168
|
+ output.writeTextElement("script", chartData);
|
|
169
|
+
|
|
170
|
+ output.writeStartElement("script");
|
|
171
|
+ output.writeAttribute("src", "Scripts/greenusechart.js");
|
|
172
|
+ output.writeEndElement();
|
|
173
|
+
|
|
174
|
+ 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))) FROM item_history(:item)");
|
130
|
175
|
switch(unitBox.currentIndex)
|
131
|
176
|
{
|
132
|
177
|
case 0:
|
|
@@ -146,6 +191,7 @@
|
146
|
191
|
output.writeTextElement("th", "Type");
|
147
|
192
|
output.writeTextElement("th", "Quantity");
|
148
|
193
|
output.writeTextElement("th", "Balance");
|
|
194
|
+ output.writeTextElement("th", "Record");
|
149
|
195
|
output.writeEndElement(); // tr
|
150
|
196
|
var prev_balance = "0";
|
151
|
197
|
var prev_prec = 0;
|
|
@@ -175,6 +221,23 @@
|
175
|
221
|
}
|
176
|
222
|
output.writeTextElement("td", query.value(3));
|
177
|
223
|
prev_balance = query.value(3);
|
|
224
|
+ if(query.value(1) == "PURCHASE") {
|
|
225
|
+ output.writeStartElement("td");
|
|
226
|
+ output.writeStartElement("a");
|
|
227
|
+ output.writeAttribute("href", "typica://script/i" + query.value(5));
|
|
228
|
+ output.writeCDATA(query.value(6) + " (" + query.value(5) + ")");
|
|
229
|
+ output.writeEndElement();
|
|
230
|
+ output.writeEndElement();
|
|
231
|
+ } else if(query.value(1) == "USE") {
|
|
232
|
+ output.writeStartElement("td");
|
|
233
|
+ output.writeStartElement("a");
|
|
234
|
+ output.writeAttribute("href", "typica://script/p" + query.value(4).slice(1,-1));
|
|
235
|
+ output.writeCDATA(query.value(7) + " " + query.value(4));
|
|
236
|
+ output.writeEndElement();
|
|
237
|
+ output.writeEndElement();
|
|
238
|
+ } else {
|
|
239
|
+ output.writeTextElement("td", "");
|
|
240
|
+ }
|
178
|
241
|
output.writeEndElement(); // tr
|
179
|
242
|
}
|
180
|
243
|
output.writeEndElement(); // table
|
|
@@ -193,7 +256,59 @@
|
193
|
256
|
buffer.close();
|
194
|
257
|
query = query.invalidate();
|
195
|
258
|
}
|
196
|
|
- refresh();
|
|
259
|
+ if(itemBox.currentData() > 0) {
|
|
260
|
+ refresh();
|
|
261
|
+ }
|
|
262
|
+
|
|
263
|
+ /* Open invoices */
|
|
264
|
+ var openInvoice = function(url) {
|
|
265
|
+ var arg = url.slice(1, url.length);
|
|
266
|
+ var info = createWindow("invoiceinfo");
|
|
267
|
+ info.setInvoiceID(arg);
|
|
268
|
+ var query = new QSqlQuery();
|
|
269
|
+ query.exec("SELECT time, invoice, vendor FROM invoices WHERE id = " + arg);
|
|
270
|
+ query.next();
|
|
271
|
+ var timefield = findChildObject(info, 'date');
|
|
272
|
+ timefield.text = query.value(0);
|
|
273
|
+ var vendorfield = findChildObject(info, 'vendor');
|
|
274
|
+ vendorfield.text = query.value(2);
|
|
275
|
+ var invoicefield = findChildObject(info, 'invoice');
|
|
276
|
+ invoicefield.text = query.value(1);
|
|
277
|
+ var itemtable = findChildObject(info, 'itemtable');
|
|
278
|
+ 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");
|
|
279
|
+ query = query.invalidate();
|
|
280
|
+ };
|
|
281
|
+
|
|
282
|
+ /* Open batch data */
|
|
283
|
+ var openProfile = function(url) {
|
|
284
|
+ var arg = url.slice(1, url.length);
|
|
285
|
+ var details = createWindow("batchDetails");
|
|
286
|
+ var fakeTable = new Object;
|
|
287
|
+ fakeTable.holding = new Array(7);
|
|
288
|
+ fakeTable.data = function(r, c) {
|
|
289
|
+ return this.holding[c];
|
|
290
|
+ };
|
|
291
|
+ var query = new QSqlQuery();
|
|
292
|
+ 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 + "}'");
|
|
293
|
+ query.next();
|
|
294
|
+ for(var i = 0; i < 8; i++) {
|
|
295
|
+ fakeTable.holding[i] = query.value(i);
|
|
296
|
+ }
|
|
297
|
+ query = query.invalidate();
|
|
298
|
+ details.loadData(fakeTable, 0);
|
|
299
|
+ };
|
|
300
|
+
|
|
301
|
+ view.scriptLinkClicked.connect(function(url) {
|
|
302
|
+ var linkType = url[0];
|
|
303
|
+ switch(linkType) {
|
|
304
|
+ case 'i':
|
|
305
|
+ openInvoice(url);
|
|
306
|
+ break;
|
|
307
|
+ case 'p':
|
|
308
|
+ openProfile(url);
|
|
309
|
+ break;
|
|
310
|
+ }
|
|
311
|
+ });
|
197
|
312
|
]]>
|
198
|
313
|
</program>
|
199
|
314
|
</window>
|