123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496 |
- <window id="manualLogEntry">
- <menu name="File">
- <plugins id="pluginMenu" title="Import" src="ImportFilters" preRun="pluginContext.preRun();" postRun="pluginContext.postRun();"/>
- <separator />
- <item id="quitItem" shortcut="ctrl+Q">Quit</item>
- </menu>
- <menu name="Log">
- <item id="clear" shortcut="Ctrl+L">Clear Log</item>
- <separator />
- <item id="ms">Millisecond View</item>
- <item id="1s">1 Second View</item>
- <item id="5s">5 Second View</item>
- <item id="10s">10 Second View</item>
- <item id="15s">15 Second View</item>
- <item id="30s">30 Second View</item>
- <item id="1m">1 Minute View</item>
- <separator />
- <item id="showC">Display Celsius</item>
- <item id="showF">Display Fahrenheit</item>
- </menu>
- <layout type="vertical">
- <tabbar id="tabs"/>
- <layout type="stack" id="pages">
- <page>
- <layout type="vertical">
- <layout type="horizontal">
- <label>Batch Type:</label>
- <sqldrop id="batchType" />
- <label>Machine:</label>
- <sqldrop id="machineSelector" />
- <stretch />
- </layout>
- <label>Green Coffee:</label>
- <layout type="stack" id="greenInfoLayout">
- <page id="sampleGreen">
- <layout type="vertical">
- <layout type="grid">
- <row>
- <column><label>Name:</label></column>
- <column><line id="sampleGreenName" /></column>
- </row>
- <row>
- <column><label>Weight:</label></column>
- <column><line id="sampleGreenWeight" validator="numeric">0.0</line></column>
- <column><sqldrop id="sampleGreenUnit" /></column>
- </row>
- <row>
- <column><label>Vendor:</label></column>
- <column><line id="sampleGreenVendor" /></column>
- </row>
- <row>
- <column><label>Arrival Date:</label></column>
- <column><calendar id="sampleGreenArrivalDate" /></column>
- </row>
- </layout>
- <label>Additional Details:</label>
- <sqltablearray columns="2" id="attributes">
- <column name="Attribute" />
- <column name="Value" />
- </sqltablearray>
- </layout>
- </page>
- <page id="productionGreen">
- <layout type="vertical">
- <layout type="horizontal">
- <label>Unit:</label>
- <sqldrop id="productionGreenUnit" />
- <stretch />
- </layout>
- <sqltablearray columns="2" id="productionGreenTable">
- <column name="Coffee" delegate="sql" showdata="true" null="true" nulltext="Delete" nulldata="delete" data="0" display="1">
- <![CDATA[SELECT id, name FROM coffees WHERE quantity <> 0 ORDER BY name]]>
- </column>
- <column name="Weight" delegate="numeric" />
- </sqltablearray>
- </layout>
- </page>
- </layout>
- <label>Roasting Details:</label>
- <layout type="grid">
- <row>
- <column><label>Item:</label></column>
- <column>
- <sqldrop data="0" display="1" showdata="true" id="roastedItem">
- <null />
- <query>SELECT id, name FROM items WHERE category = 'Coffee: Roasted' AND id IN (SELECT item FROM current_items) ORDER BY name</query>
- </sqldrop>
- </column>
- </row>
- <row>
- <column><label>Weight:</label></column>
- <column><line id="roastedWeight" validator="numeric">0.0</line></column>
- </row>
- <row>
- <column><label>Time:</label></column>
- <column><calendar id="roastTime" time="true"/></column>
- </row>
- <row>
- <column><label>Duration:</label></column>
- <column><timeedit id="roastDuration" /></column>
- </row>
- <row>
- <column><label>Notes:</label></column>
- <column><textarea id="notes" /></column>
- </row>
- </layout>
- </layout>
- </page>
- <page>
- <layout type="vertical">
- <layout type="horizontal">
- <label>Time Increment (s):</label>
- <line id="timeincrement" validator="numeric">30</line>
- <stretch />
- <label>Time:</label>
- <timeedit id="currenttime" />
- <stretch />
- <label>Temperature:</label>
- <line id="currenttemperature" validator="numeric" />
- <label>Note:</label>
- <line id="currentnote" />
- <button name="Add Measurement" id="addmeasurement" type="push" />
- </layout>
- <splitter type="horizontal" id="roastdatasplit">
- <measurementtable id="log" />
- <graph id="graph" />
- </splitter>
- </layout>
- </page>
- </layout>
- <layout type="horizontal">
- <stretch />
- <button name="Submit" id="submit" type="push" />
- </layout>
- </layout>
- <program>
- <![CDATA[
- var window = this;
- this.windowTitle = TTR("manualLogEntry", "Typica - Manual Log Entry");
- window.windowReady.connect(function() {
- if(machineModel.rowCount() == 0) {
- displayError(TTR("manualLogEntry", "Configuration Required"),
- TTR("manualLogEntry", "Please configure a roaster."));
- window.close();
- }
- });
- quitItem = findChildObject(this, 'quitItem');
- quitItem.triggered.connect(function() {
- Application.quit();
- });
- pluginContext = {};
- pluginContext.table = findChildObject(this, 'log');
- pluginContext.table.setHeaderData(1, "Temp");
- pluginContext.table.addOutputTemperatureColumn(1);
- pluginContext.table.setHeaderData(2, "Note");
- pluginContext.table.addOutputAnnotationColumn(2);
- pluginContext.graph = findChildObject(this, 'graph');
- pluginContext.preRun = function() {
- var filename = QFileDialog.getOpenFileName(window, TTR("manualLogEntry", "Import"), QSettings.value('script/lastDir', '') + '/');
- var file = new QFile(filename);
- if(file.open(1)) {
- pluginContext.data = file.readToString();
- file.close();
- pluginContext.table.clear();
- pluginContext.graph.clear();
- QSettings.setValue("script/lastDir", dir(filename));
- } else {
- throw new Error("Failed to open file, aborting import.");
- }
- };
- pluginContext.postRun = function() {
-
- };
- pluginContext.newMeasurement = function(m, c) {
- pluginContext.table.newMeasurement(m, c);
- pluginContext.graph.newMeasurement(m, c);
- }
- pluginMenu = findChildObject(this, 'pluginMenu');
- pluginMenu.setProperty("activationObject", pluginContext);
- tabs = findChildObject(this, 'tabs');
- tabs.addTab("Batch Data");
- tabs.addTab("Roast Data");
- pages = findChildObject(this, 'pages');
- tabs.currentChanged.connect(function(index) {
- pages.setCurrentIndex(index);
- });
- greenInfoLayout = findChildObject(this, 'greenInfoLayout');
- roastedItem = findChildObject(this, 'roastedItem');
- batchType = findChildObject(this, 'batchType');
- batchType.addItem("Sample");
- batchType.addItem("Production");
- batchType['currentIndexChanged(int)'].connect(function(batchTypeIndex) {
- QSettings.setValue("script/manual_batchType", batchTypeIndex);
- greenInfoLayout.setCurrentIndex(batchTypeIndex);
- roastedItem.enabled = (batchTypeIndex == 1);
- });
- batchType.setCurrentIndex(QSettings.value("script/manual_batchType", 1));
- var machineSelector = findChildObject(this, 'machineSelector');
- var machineModel = new DeviceTreeModel;
- machineSelector.setModel(machineModel);
- machineSelector.currentIndex = QSettings.value("script/manualMachineSelection", 0);
- machineSelector['currentIndexChanged(int)'].connect(function(index) {
- QSettings.setValue("script/manualMachineSelection", index);
- });
- sampleGreenUnit = findChildObject(this, 'sampleGreenUnit');
- sampleGreenUnit.addItem("g");
- sampleGreenUnit.addItem("Kg");
- sampleGreenUnit.addItem("oz");
- sampleGreenUnit.addItem("lb");
- sampleGreenUnit.currentIndex = (QSettings.value("script/manual_unit", sampleGreenUnit.findText("lb")));
- productionGreenUnit = findChildObject(this, 'productionGreenUnit');
- productionGreenUnit.addItem("g");
- productionGreenUnit.addItem("Kg");
- productionGreenUnit.addItem("oz");
- productionGreenUnit.addItem("lb");
- productionGreenUnit.currentIndex = (QSettings.value("script/manual_unit", productionGreenUnit.findText("lb")));
- sampleGreenUnit['currentIndexChanged(int)'].connect(function(greenUnitIndex) {
- QSettings.setValue("script/manual_unit", greenUnitIndex);
- productionGreenUnit.setCurrentIndex(greenUnitIndex);
- });
- productionGreenUnit['currentIndexChanged(int)'].connect(function(greenUnitIndex) {
- QSettings.setValue("script/manual_unit", greenUnitIndex);
- sampleGreenUnit.setCurrentIndex(greenUnitIndex);
- });
- timeincrement = findChildObject(this, 'timeincrement');
- currenttime = findChildObject(this, 'currenttime');
- currenttemperature = findChildObject(this, 'currenttemperature');
- currentnote = findChildObject(this, 'currentnote');
- addmeasurement = findChildObject(this, 'addmeasurement');
- var currentUnit = Units.Fahrenheit;
- var showC = findChildObject(this, 'showC');
- showC.triggered.connect(function() {
- pluginContext.table.setDisplayUnits(Units.Celsius);
- pluginContext.graph.showC();
- QSettings.setValue("temperatureUnit", "C");
- currentUnit = Units.Celsius;
- });
- var showF = findChildObject(this, 'showF');
- showF.triggered.connect(function() {
- pluginContext.table.setDisplayUnits(Units.Fahrenheit);
- pluginContext.graph.showF();
- QSettings.setValue("temperatureUnit", "F");
- currentUnit = Units.Fahrenheit;
- });
- if(QSettings.value("temperatureUnit", "F") == "C") {
- showC.trigger();
- }
- addmeasurement.clicked.connect(function() {
- var fromUnit =
- pluginContext.newMeasurement(new Measurement(Units.convertTemperature(Number(currenttemperature.text), currentUnit, Units.Fahrenheit), currenttime.time), 1);
- if(currentnote.text.length > 0) {
- pluginContext.table.newAnnotation(currentnote.text, 1, 2);
- }
- currentnote.text = "";
- var t = QTime();
- t = t.fromString(currenttime.time, "hh:mm:ss");
- t = t.addSecs(30);
- currenttime.time = t;
- currenttemperature.text = "";
- });
- currenttemperature.returnPressed.connect(addmeasurement.clicked);
- currentnote.returnPressed.connect(addmeasurement.clicked);
- var v1 = findChildObject(this, 'ms');
- v1.triggered.connect(pluginContext.table.LOD_ms);
- var v2 = findChildObject(this, '1s');
- v2.triggered.connect(pluginContext.table.LOD_1s);
- var v3 = findChildObject(this, '5s');
- v3.triggered.connect(pluginContext.table.LOD_5s);
- var v4 = findChildObject(this, '10s');
- v4.triggered.connect(pluginContext.table.LOD_10s);
- var v5 = findChildObject(this, '15s');
- v5.triggered.connect(pluginContext.table.LOD_15s);
- var v6 = findChildObject(this, '30s');
- v6.triggered.connect(pluginContext.table.LOD_30s);
- var v7 = findChildObject(this, '1m');
- v7.triggered.connect(pluginContext.table.LOD_1m);
- var clear = findChildObject(this, 'clear');
- clear.triggered.connect(pluginContext.table.clear);
- clear.triggered.connect(pluginContext.graph.clear);
- clear.triggered.connect(function() {
- currenttime.time = QTime(0, 0, 0, 0);
- currenttemperature.text = "";
- currentnote.text = "";
- pluginContext.table.clearOutputColumns();
- pluginContext.table.addOutputTemperatureColumn(1);
- pluginContext.table.addOutputAnnotationColumn(2);
- });
- var sampleGreenName = findChildObject(this, 'sampleGreenName');
- var sampleGreenWeight = findChildObject(this, 'sampleGreenWeight');
- var productionGreenTable = findChildObject(this, 'productionGreenTable');
- var greenModel = productionGreenTable.model();
- var greenTotal = 0.0;
- var updateGreenTable = function() {
- var deleteRow = -1;
- while((deleteRow = productionGreenTable.findData("delete", 0)) > -1) {
- if(productionGreenTable.data(deleteRow, 0, 0) == "Delete") {
- productionGreenTable.removeRow(productionGreenTable.findData("delete", 0));
- } else {
- break;
- }
- }
- greenTotal = productionGreenTable.columnSum(1, 0);
- productionGreenTable.resizeColumnToContents(0);
- };
- greenModel.dataChanged.connect(updateGreenTable);
- var validateInputs = function() {
- if(batchType.currentIndex == 0) {
- /* Sample batch */
- if(sampleGreenName.text.length == 0) {
- tabs.setCurrentIndex(0);
- displayError(TTR("manualLogEntry", "Data Entry Error"),
- TTR("manualLogEntry", "Please enter a green coffee name."));
- return false;
- }
- if(Number(sampleGreenWeight.text) <= 0 || isNaN(sampleGreenWeight.text)) {
- tabs.setCurrentIndex(0);
- displayError(TTR("manualLogEntry", "Data Entry Error"),
- TTR("manualLogEntry", "Green coffee weight must be a number greater than 0."));
- return false;
- }
- } else {
- /* Production batch */
- var itemArray = productionGreenTable.columnArray(0, 32).split("\\s*,\\s*");
- var weightArray = productionGreenTable.columnArray(1, 0).split("\\s*,\\s*");
- if((itemArray.length != weightArray.length) || (itemArray.length == 0)) {
- tabs.setCurrentIndex(0);
- displayError(TTR("manualLogEntry", "Data Entry Error"),
- TTR("manualLogEntry", "Please check that at least one green coffee has been selected and each green coffee has a valid weight"));
- return false;
- }
- if(Number(greenTotal) <= 0) {
- tabs.setCurrentIndex(0);
- displayError(TTR("manualLogEntry", "DataEntryError"),
- TTR("manualLogEntry", "Total green coffee weight must be a number greater than 0."));
- return false;
- }
- if(roastedItem.currentIndex == 0) {
- tabs.setCurrentIndex(0);
- displayError(TTR("manualLogEntry", "DataEntryError"),
- TTR("manualLogEntry", "Please select a roasted coffee item."));
- return false;
- }
- }
- return true;
- };
- var roastDataExists = function() {
- return (pluginContext.table.rowCount() > 0);
- }
- var roastTime = findChildObject(this, 'roastTime');
- var attributes = findChildObject(this, 'attributes');
- var sampleGreenArrivalDate = findChildObject(this, 'sampleGreenArrivalDate');
- var convertToPounds = function(w, u) {
- switch(u) {
- case "g":
- return w * 0.0022;
- case "oz":
- return w * 0.0625;
- case "Kg":
- return w * 2.2;
- }
- return w;
- };
- var roastedWeight = findChildObject(this, 'roastedWeight');
- var notes = findChildObject(this, 'notes');
- var roastDuration = findChildObject(this, 'roastDuration');
- var doSubmit = function() {
- var fileID = -1;
- var query = new QSqlQuery();
- if(roastDataExists()) {
- var buffer = new QBuffer;
- buffer.open(3);
- pluginContext.table.saveXML(buffer);
- buffer.open(3); /* saveXML closes the buffer */
- var q = "INSERT INTO files (id, name, type, note, file) VALUES (default, :name, 'profile', NULL, :data) RETURNING id";
- query.prepare(q);
- query.bind(":name", roastTime.text + " Manual Entry");
- query.bind(":data", buffer.readToString());
- query.exec();
- query.next();
- fileID = query.value(0);
- buffer.close();
- }
- var rootIndex = machineModel.index(machineSelector.currentIndex, 0);
- var selectedRoasterName = machineModel.data(rootIndex, 0);
- var machineReference = machineModel.referenceElement(machineModel.data(rootIndex, 32));
- var selectedRoasterID = machineReference.databaseid;
- query.exec("SELECT 1 FROM machine WHERE id = " + selectedRoasterID);
- if(!query.next()) {
- query.prepare("INSERT INTO machine (id, name) VALUES (:id, :name)");
- query.bind(":id", selectedRoasterID);
- query.bind(":name", selectedRoasterName);
- query.exec();
- }
- if(batchType.currentIndex == 0) {
- /* Sample roast */
- var attnames = sqlToArray(attributes.columnArray(0, 0));
- for(var i = 0; i < attnames.length; i++) {
- var attname = attnames[i];
- if(attname[0] == '{') {
- attname = attname.substr(1);
- }
- if(attname[0] == ' ') {
- attname = attname.substr(1);
- }
- if(attname[attname.length - 1] == '}') {
- attname = attname.substr(0, attname.length - 1);
- }
- if(attname.length == 0) {
- break;
- }
- query.prepare("SELECT id FROM item_attributes WHERE name = :name");
- query.bind(":name", attname);
- query.exec();
- if(query.next()) {
- attributes.setData(i, 0, query.value(0), 32);
- } else {
- query.prepare("INSERT INTO item_attributes(id, name) VALUES (DEFAULT, :name) RETURNING id");
- query.bind(":name", attname);
- query.exec();
- query.next();
- attributes.setData(i, 0, query.value(0), 32);
- }
- }
- query.prepare("INSERT INTO coffee_sample_items(id, name, reference, unit, quantity, category, arrival, vendor, attribute_ids, attribute_values) VALUES (DEFAULT, :name, NULL, 'lb', 0, 'Coffee: Green Sample', :arrival, :vendor, :attrids, :attrvals) RETURNING id");
- query.bind(":name", sampleGreenName.text);
- query.bind(":arrival", sampleGreenArrivalDate.date);
- query.bind(":attrids", attributes.bindableColumnArray(0, 32));
- query.bind(":attrvals", attributes.bindableQuotedColumnArray(1, 0));
- query.exec();
- query.next();
- var greenId = query.value(0);
- query.prepare("INSERT INTO items (id, name, reference, unit, quantity, category) VALUES (DEFAULT, :name, NULL, 'lb', 0, 'Coffee: Roasted Sample') RETURNING id");
- query.bind(":name", sampleGreenName.text + " Roasted Sample");
- query.exec();
- query.next();
- var roastedId = query.value(0);
- query.prepare("INSERT INTO roasting_log (time, unroasted_id, unroasted_quantity, unroasted_total_quantity, roasted_id, roasted_quantity, transaction_type, annotation, machine, duration, approval, humidity, barometric, indoor_air, outdoor_air, files, person) VALUES (:time, :unroastedids, :greens, :green, :roastedid, :roasted, 'SAMPLEROAST', :note, :machine, :duration, TRUE, NULL, NULL, NULL, NULL, :files, :user)");
- query.bind(":time", roastTime.text);
- query.bind(":unroastedids", "{" + greenId + "}");
- query.bind(":greens", "{" + convertToPounds(parseFloat(sampleGreenWeight.text), sampleGreenUnit.currentText) + "}");
- query.bind(":green", convertToPounds(parseFloat(sampleGreenWeight.text), sampleGreenUnit.currentText));
- query.bind("roastedid", Number(roastedId));
- query.bind("roasted", convertToPounds(parseFloat(roastedWeight.text), sampleGreenUnit.currentText));
- query.bind(":note", notes.plainText);
- query.bind(":machine", Number(selectedRoasterID));
- query.bind(":duration", roastDuration.text);
- if(fileID > 0) {
- query.bind(":files", "{" + fileID + "}");
- } else {
- query.bind(":file", "{}");
- }
- query.bind(":user", Application.currentTypicaUser());
- query.exec();
- } else {
- var q = "INSERT INTO roasting_log (time, unroasted_id, unroasted_quantity, unroasted_total_quantity, roasted_id, roasted_quantity, transaction_type, annotation, machine, duration, approval, humidity, barometric, indoor_air, outdoor_air, files, person) VALUES (:time, ";
- q += productionGreenTable.columnArray(0, 32);
- q += ", ";
- var greenSum = 0.0;
- for(var i = 0; i < productionGreenTable.data(i, 1, 0).value != ""; i++) {
- var greenWt = convertToPounds(parseFloat(productionGreenTable.data(i, 1, 0)), productionGreenUnit.currentText);
- productionGreenTable.setData(i, 1, greenWt, 32);
- greenSum += greenWt;
- }
- q += productionGreenTable.columnArray(1, 32);
- q += ", ";
- q += greenWt;
- q += ", ";
- q += roastedItem.currentData();
- q += ", ";
- q += convertToPounds(parseFloat(roastedWeight.text), productionGreenUnit.currentText);
- q += ", 'ROAST', :annotation, ";
- q += selectedRoasterID;
- q += ", :duration, TRUE, NULL, NULL, NULL, NULL, '{";
- if(fileID > 0) {
- q += fileID;
- }
- q += "}', :user)";
- query.prepare(q);
- query.bind(":time", roastTime.text);
- query.bind(":annotation", notes.plainText);
- query.bind(":duration", roastDuration.text);
- query.bind(":user", Application.currentTypicaUser());
- query.exec();
- }
- query = query.invalidate();
- window.close();
- }
- var submit = findChildObject(this, 'submit');
- submit.clicked.connect(function() {
- if(validateInputs()) {
- doSubmit();
- }
- });
- ]]>
- </program>
- </window>
|