Typica is a free program for professional coffee roasters. https://typica.us
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

auco.xml 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. <window id="useandcostreport">
  2. <reporttitle>Production:->Average Use and Cost by Origin</reporttitle>
  3. <layout type="vertical">
  4. <layout type="horizontal">
  5. <daterange id="dates" initial="23" /><!-- Lifetime -->
  6. <label>Sort Order:</label>
  7. <sqldrop id="sort" />
  8. <label>Weight Unit:</label>
  9. <sqldrop id="unit" />
  10. <stretch />
  11. </layout>
  12. <webview id="report" />
  13. </layout>
  14. <menu name="File">
  15. <item id="print" shortcut="Ctrl+P">Print...</item>
  16. </menu>
  17. <program>
  18. <![CDATA[
  19. this.windowTitle = TTR("useandcostreport", "Typica - Average Use and Cost by Origin");
  20. var report = findChildObject(this, 'report');
  21. var printMenu = findChildObject(this, 'print');
  22. printMenu.triggered.connect(function() {
  23. report.print();
  24. });
  25. var sortBox = findChildObject(this, 'sort');
  26. sortBox.addItem(TTR("useandcostreport","Origin A-Z"));
  27. sortBox.addItem(TTR("useandcostreport", "Origin Z-A"));
  28. sortBox.addItem(TTR("useandcostreport", "Avg. Rate Ascending"));
  29. sortBox.addItem(TTR("useandcostreport", "Avg. Rate Descending"));
  30. sortBox.addItem(TTR("useandcostreport", "Avg. Cost Ascending"));
  31. sortBox.addItem(TTR("useandcostreport", "Avg. Cost Descending"));
  32. sortBox.currentIndex = QSettings.value("auco_sort", 0);
  33. var unitBox = findChildObject(this, 'unit');
  34. unitBox.addItem(TTR("useandcostreport", "Kg"));
  35. unitBox.addItem(TTR("useandcostreport", "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;
  57. function refresh() {
  58. rowData.length = 0;
  59. var dateRange = dateSelect.currentRange();
  60. var startDate = dateRange[0];
  61. var endDate = dateRange[dateRange.length - 1];
  62. rowIndex = 0;
  63. var buffer = new QBuffer;
  64. buffer.open(3);
  65. var output = new XmlWriter(buffer);
  66. output.writeStartDocument("1.0");
  67. 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">');
  68. output.writeStartElement("html");
  69. output.writeAttribute("xmlns", "http://www.w3.org/1999/xhtml");
  70. output.writeStartElement("head");
  71. output.writeTextElement("title", TTR("useandcostreport", "Recent Use and Cost by Origin"));
  72. output.writeEndElement();
  73. output.writeStartElement("body");
  74. var cdt = new Date(Date.now());
  75. output.writeTextElement("p", cdt.toLocaleDateString(TTR("reports", "en-US")) + " " + cdt.toLocaleTimeString(TTR("reports", "en-US")));
  76. output.writeTextElement("h1", TTR("useandcostreport", "Average Use and Cost by Origin ") + startDate + " - " + endDate);
  77. switch(unitBox.currentIndex)
  78. {
  79. case 0:
  80. output.writeTextElement("p", TTR("useandcostreport", "This is a report of average rate of use in kilograms per day and cost of unroasted coffee."));
  81. break;
  82. case 1:
  83. output.writeTextElement("p", TTR("useandcostreport", "This is a report of average rate of use in pounds per day and cost of unroasted coffee."));
  84. break;
  85. }
  86. output.writeStartElement("table");
  87. output.writeAttribute("rules", "groups");
  88. output.writeAttribute("cellpadding", "3px");
  89. output.writeStartElement("thead");
  90. output.writeStartElement("tr");
  91. output.writeStartElement("th");
  92. output.writeAttribute("colspan", "9");
  93. output.writeCharacters(TTR("useandcostreport", "Regular Coffees"));
  94. output.writeEndElement();
  95. output.writeEndElement();
  96. output.writeStartElement("tr");
  97. output.writeTextElement("th", TTR("useandcostreport", "Origin"));
  98. output.writeTextElement("th", TTR("useandcostreport", "Avg. Rate"));
  99. output.writeTextElement("th", TTR("useandcostreport", "Avg. Cost"));
  100. output.writeTextElement("th", TTR("useandcostreport", "Last Cost"));
  101. output.writeTextElement("th", TTR("useandcostreport", "Last Purchase Date"));
  102. output.writeTextElement("th", TTR("useandcostreport", "Bag Size (min)"));
  103. output.writeTextElement("th", TTR("useandcostreport", "Bag Size (max)"));
  104. output.writeTextElement("th", TTR("useandcostreport", "Bag Size (mean)"));
  105. output.writeTextElement("th", TTR("useandcostreport", "Purchases"));
  106. output.writeEndElement();
  107. output.writeEndElement();
  108. output.writeStartElement("tbody");
  109. var query = new QSqlQuery();
  110. var conversion = 1;
  111. if(unitBox.currentIndex == 0) {
  112. conversion = 2.2;
  113. }
  114. var orderClause;
  115. switch(sortBox.currentIndex)
  116. {
  117. case 0:
  118. orderClause = "origin ASC";
  119. break;
  120. case 1:
  121. orderClause = "origin DESC";
  122. break;
  123. case 2:
  124. orderClause = "rate ASC";
  125. break;
  126. case 3:
  127. orderClause = "rate DESC";
  128. break;
  129. case 4:
  130. orderClause = "cost ASC";
  131. break;
  132. case 5:
  133. orderClause = "cost DESC";
  134. break;
  135. }
  136. 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);
  137. query.bind(":c1", conversion);
  138. query.bind(":c2", conversion);
  139. query.bind(":c3", conversion);
  140. query.bind(":c4", conversion);
  141. query.bind(":startDate", startDate);
  142. query.bind(":endDate", endDate);
  143. query.exec();
  144. while(query.next())
  145. {
  146. output.writeStartElement("tr");
  147. output.writeAttribute("id", "r" + rowIndex);
  148. output.writeStartElement("td");
  149. output.writeStartElement("a");
  150. output.writeAttribute("href", "typica://script/r" + rowIndex);
  151. rowIndex++;
  152. rowData.push(query.value(0));
  153. output.writeCharacters(query.value(0));
  154. output.writeEndElement();
  155. output.writeEndElement();
  156. output.writeTextElement("td", query.value(1));
  157. output.writeTextElement("td", query.value(2));
  158. output.writeTextElement("td", query.value(3));
  159. output.writeTextElement("td", query.value(4));
  160. output.writeTextElement("td", query.value(5));
  161. output.writeTextElement("td", query.value(6));
  162. output.writeTextElement("td", query.value(7));
  163. output.writeTextElement("td", query.value(8));
  164. output.writeEndElement();
  165. }
  166. output.writeStartElement("tr");
  167. output.writeStartElement("th");
  168. output.writeAttribute("colspan", "9");
  169. output.writeCharacters(TTR("useandcostreport", "Decaffeinated Coffees"));
  170. output.writeEndElement();
  171. output.writeEndElement();
  172. 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);
  173. query.bind(":c1", conversion);
  174. query.bind(":c2", conversion);
  175. query.bind(":c3", conversion);
  176. query.bind(":c4", conversion);
  177. query.bind(":startDate", startDate);
  178. query.bind(":endDate", endDate);
  179. query.exec();
  180. while(query.next())
  181. {
  182. output.writeStartElement("tr");
  183. output.writeAttribute("id", "d" + rowIndex);
  184. output.writeStartElement("td");
  185. output.writeStartElement("a");
  186. output.writeAttribute("href", "typica://script/d" + rowIndex);
  187. rowIndex++;
  188. rowData.push(query.value(0));
  189. output.writeCharacters(query.value(0));
  190. output.writeEndElement();
  191. output.writeEndElement();
  192. output.writeTextElement("td", query.value(1));
  193. output.writeTextElement("td", query.value(2));
  194. output.writeTextElement("td", query.value(3));
  195. output.writeTextElement("td", query.value(4));
  196. output.writeTextElement("td", query.value(5));
  197. output.writeTextElement("td", query.value(6));
  198. output.writeTextElement("td", query.value(7));
  199. output.writeTextElement("td", query.value(8));
  200. output.writeEndElement();
  201. }
  202. query = query.invalidate();
  203. output.writeEndElement();
  204. output.writeEndElement();
  205. output.writeEndElement();
  206. output.writeEndElement();
  207. output.writeEndDocument();
  208. report.setContent(buffer);
  209. buffer.close();
  210. }
  211. refresh();
  212. sortBox['currentIndexChanged(int)'].connect(function() {
  213. QSettings.setValue("auco_sort", sortBox.currentIndex);
  214. refresh();
  215. });
  216. report.scriptLinkClicked.connect(function(url) {
  217. if(url[0] == 'i') {
  218. url = url.slice(1, url.length);
  219. var itemReport = createReport("itemtransactions.xml");
  220. var sIB = findChildObject(itemReport, 'item');
  221. sIB.currentIndex = sIB.findData(url);
  222. return;
  223. }
  224. var element = new WebElement(report.findFirstElement("#" + url));
  225. var regular = url[0] == 'r';
  226. var index = url.slice(1, url.length);
  227. var tableref;
  228. if(regular) {
  229. tableref = "regular_coffees";
  230. } else {
  231. tableref = "decaf_coffees";
  232. }
  233. var origin = rowData[Number(url.slice(1, url.length))];
  234. var details = '<tr><td /><td colspan="6"><table><tr><th>' +
  235. TTR("useandcostreport", "Id") + '</th><th>' +
  236. TTR("useandcostreport", "Name") + '</th><th>' +
  237. TTR("useandcostreport", "Rate") + '</th><th>' +
  238. TTR("useandcostreport", "Cost") + '</th><th>' +
  239. TTR("useandcostreport", "Inventory") + '</th><th>' +
  240. TTR("useandcostreport", "First Use") + '</th><th>' +
  241. TTR("useandcostreport", "Last Use") + '</th></tr>';
  242. var query = new QSqlQuery();
  243. 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");
  244. var conversion = 1;
  245. if(unitBox.currentIndex == 0) {
  246. conversion = 2.2;
  247. }
  248. var dateRange = dateSelect.currentRange();
  249. var startDate = dateRange[0];
  250. var endDate = dateRange[dateRange.length - 1];
  251. query.bind(":conversion1", conversion);
  252. query.bind(":conversion2", conversion);
  253. query.bind(":conversion3", conversion);
  254. query.bind(":origin", origin);
  255. query.bind(":startDate", startDate);
  256. query.bind(":endDate", endDate);
  257. query.exec();
  258. while(query.next()) {
  259. details += "<tr>";
  260. details += '<td><a href="typica://script/i' + query.value(0) + '">' + query.value(0) + "</a></td>";
  261. for(var i = 1; i < 7; i++) {
  262. details += "<td>" + query.value(i) + "</td>";
  263. }
  264. details += "</tr>";
  265. }
  266. query = query.invalidate();
  267. details += "</table></td></tr>";
  268. element.appendOutside(details);
  269. });
  270. ]]>
  271. </program>
  272. </window>