|
@@ -1,78 +1,73 @@
|
1
|
1
|
<window id="navwindow">
|
2
|
|
- <layout type="grid">
|
3
|
|
- <row>
|
4
|
|
- <column>
|
5
|
|
- <button name="Configure Roasters" id="configure" type="push" />
|
6
|
|
- </column>
|
7
|
|
- </row>
|
8
|
|
- <row>
|
9
|
|
- <column>
|
10
|
|
- <sqldrop id="machineselector" />
|
11
|
|
- </column>
|
12
|
|
- <column>
|
13
|
|
- <button name="Roast Coffee" id="roast" type="push" />
|
14
|
|
- </column>
|
15
|
|
- </row>
|
16
|
|
- <row>
|
17
|
|
- <column>
|
18
|
|
- <button name="Purchase Green Coffee" id="green" type="push" />
|
19
|
|
- </column>
|
20
|
|
- </row>
|
21
|
|
- <row>
|
22
|
|
- <column>
|
23
|
|
- <button name="Manage Roasted Coffee Items" id="newroasted" type="push" />
|
24
|
|
- </column>
|
25
|
|
- </row>
|
26
|
|
- <row>
|
27
|
|
- <column>
|
28
|
|
- <button name="Edit Roasting Specification" id="roastspec" type="push" />
|
29
|
|
- </column>
|
30
|
|
- </row>
|
31
|
|
- <row>
|
32
|
|
- <column>
|
33
|
|
- <button name="Update Inventory" id="inventory" type="push" />
|
34
|
|
- </column>
|
35
|
|
- </row>
|
36
|
|
- <row>
|
37
|
|
- <column>
|
38
|
|
- <button name="New Cupping Session" id="createcupping"
|
39
|
|
-type="push" />
|
40
|
|
- </column>
|
41
|
|
- </row>
|
42
|
|
- <row>
|
43
|
|
- <column>
|
44
|
|
- <button name="Join Cupping Session" id="joincupping" type="push"
|
45
|
|
-/>
|
46
|
|
- </column>
|
47
|
|
- </row>
|
48
|
|
- <row>
|
49
|
|
- <column>
|
50
|
|
- <button name="Summarize Cupping Session" id="sumcupping"
|
51
|
|
-type="push" />
|
52
|
|
- </column>
|
53
|
|
- </row>
|
54
|
|
- <row>
|
55
|
|
- <column>
|
56
|
|
- <button name="View Target Roast Profiles" id="profilehistory"
|
57
|
|
- type="push" />
|
58
|
|
- </column>
|
59
|
|
- </row>
|
60
|
|
- <row>
|
61
|
|
- <column>
|
62
|
|
- <button name="Import Target Roast Profiles" id="target"
|
63
|
|
-type="push" />
|
64
|
|
- </column>
|
65
|
|
- </row>
|
66
|
|
- <row>
|
67
|
|
- <column>
|
68
|
|
- <button name="Enter Green Coffee Sales" id="greensales" type="push" />
|
69
|
|
- </column>
|
70
|
|
- </row>
|
71
|
|
- </layout>
|
|
2
|
+ <layout type="grid">
|
|
3
|
+ <row>
|
|
4
|
+ <column>
|
|
5
|
+ <button name="Configure Roasters" id="configure" type="push" />
|
|
6
|
+ </column>
|
|
7
|
+ </row>
|
|
8
|
+ <row>
|
|
9
|
+ <column>
|
|
10
|
+ <sqldrop id="machineselector" />
|
|
11
|
+ </column>
|
|
12
|
+ <column>
|
|
13
|
+ <button name="Roast Coffee" id="roast" type="push" />
|
|
14
|
+ </column>
|
|
15
|
+ </row>
|
|
16
|
+ <row>
|
|
17
|
+ <column>
|
|
18
|
+ <button name="Purchase Green Coffee" id="green" type="push" />
|
|
19
|
+ </column>
|
|
20
|
+ </row>
|
|
21
|
+ <row>
|
|
22
|
+ <column>
|
|
23
|
+ <button name="Manage Roasted Coffee Items" id="newroasted" type="push" />
|
|
24
|
+ </column>
|
|
25
|
+ </row>
|
|
26
|
+ <row>
|
|
27
|
+ <column>
|
|
28
|
+ <button name="Edit Roasting Specification" id="roastspec" type="push" />
|
|
29
|
+ </column>
|
|
30
|
+ </row>
|
|
31
|
+ <row>
|
|
32
|
+ <column>
|
|
33
|
+ <button name="Update Inventory" id="inventory" type="push" />
|
|
34
|
+ </column>
|
|
35
|
+ </row>
|
|
36
|
+ <row>
|
|
37
|
+ <column>
|
|
38
|
+ <button name="New Cupping Session" id="createcupping" type="push" />
|
|
39
|
+ </column>
|
|
40
|
+ </row>
|
|
41
|
+ <row>
|
|
42
|
+ <column>
|
|
43
|
+ <button name="Join Cupping Session" id="joincupping" type="push" />
|
|
44
|
+ </column>
|
|
45
|
+ </row>
|
|
46
|
+ <row>
|
|
47
|
+ <column>
|
|
48
|
+ <button name="Summarize Cupping Session" id="sumcupping" type="push" />
|
|
49
|
+ </column>
|
|
50
|
+ </row>
|
|
51
|
+ <row>
|
|
52
|
+ <column>
|
|
53
|
+ <button name="View Target Roast Profiles" id="profilehistory" type="push" />
|
|
54
|
+ </column>
|
|
55
|
+ </row>
|
|
56
|
+ <row>
|
|
57
|
+ <column>
|
|
58
|
+ <button name="Import Target Roast Profiles" id="target" type="push" />
|
|
59
|
+ </column>
|
|
60
|
+ </row>
|
|
61
|
+ <row>
|
|
62
|
+ <column>
|
|
63
|
+ <button name="Enter Green Coffee Sales" id="greensales" type="push" />
|
|
64
|
+ </column>
|
|
65
|
+ </row>
|
|
66
|
+ </layout>
|
72
|
67
|
<menu name="Reports" type="reports" src="Reports" />
|
73
|
|
- <menu name="Database">
|
74
|
|
- <item id="resetconnection">Forget Connection Details</item>
|
75
|
|
- </menu>
|
|
68
|
+ <menu name="Database">
|
|
69
|
+ <item id="resetconnection">Forget Connection Details</item>
|
|
70
|
+ </menu>
|
76
|
71
|
<program>
|
77
|
72
|
var window = this;
|
78
|
73
|
var navigationwindow = window;
|
|
@@ -165,67 +160,67 @@ type="push" />
|
165
|
160
|
confwindow.show();
|
166
|
161
|
});
|
167
|
162
|
<![CDATA[
|
168
|
|
- var DBCreateBase = function() {
|
169
|
|
- var query = new QSqlQuery();
|
170
|
|
- query.exec("CREATE TABLE IF NOT EXISTS certifications (item bigint NOT NULL, certification text NOT NULL)");
|
171
|
|
- query.exec("CREATE TABLE IF NOT EXISTS cupping_samples (session bigint NOT NULL, sample text NOT NULL, position bigint NOT NULL, type text NOT NULL, \"time\" timestamp without time zone, machine bigint, point text, item bigint)");
|
172
|
|
- query.exec("CREATE TABLE cupping_sessions (id bigserial NOT NULL, event text, name text NOT NULL, \"time\" timestamp without time zone NOT NULL, blind boolean NOT NULL, open boolean NOT NULL, note text)");
|
173
|
|
- query.exec("CREATE TABLE IF NOT EXISTS cuppingforms (session bigint NOT NULL, sample text NOT NULL, position bigint NOT NULL, grader text, finalscore numeric, notes text, serialization text)");
|
174
|
|
- query.exec("CREATE TABLE IF NOT EXISTS cuppingform_t1 (aroma numeric, flavor numeric, aftertaste numeric, acidity numeric, body numeric, uniformity numeric, balance numeric, cleancup numeric, sweetness numeric, overall numeric, total numeric) INHERITS (cuppingforms)");
|
175
|
|
- query.exec("CREATE TABLE IF NOT EXISTS invoices (id bigserial PRIMARY KEY NOT NULL, invoice text, vendor text NOT NULL, \"time\" timestamp without time zone NOT NULL)");
|
176
|
|
- query.exec("CREATE TABLE IF NOT EXISTS invoice_items (invoice_id bigint NOT NULL, record_type text NOT NULL, item_id bigint, description text NOT NULL, cost numeric NOT NULL)");
|
177
|
|
- query.exec("CREATE TABLE IF NOT EXISTS transactions (\"time\" timestamp without time zone NOT NULL, item bigint NOT NULL)");
|
178
|
|
- query.exec("CREATE TABLE IF NOT EXISTS inventory (quantity numeric NOT NULL) INHERITS (transactions)");
|
179
|
|
- query.exec("CREATE TABLE IF NOT EXISTS loss (quantity numeric NOT NULL, reason text) INHERITS (transactions)");
|
180
|
|
- query.exec("CREATE TABLE IF NOT EXISTS make (quantity numeric NOT NULL) INHERITS (transactions)");
|
181
|
|
- query.exec("CREATE TABLE IF NOT EXISTS purchase (quantity numeric NOT NULL, cost numeric NOT NULL, vendor text NOT NULL) INHERITS (transactions)");
|
182
|
|
- query.exec("CREATE TABLE IF NOT EXISTS sale (quantity numeric NOT NULL, customer text) INHERITS (transactions)");
|
183
|
|
- query.exec("CREATE TABLE IF NOT EXISTS use (quantity numeric NOT NULL) INHERITS (transactions)");
|
184
|
|
- query.exec("CREATE VIEW all_transactions AS ((((SELECT purchase.\"time\", purchase.item, purchase.quantity, purchase.cost, purchase.vendor, NULL::unknown AS reason, NULL::unknown AS customer, 'PURCHASE' AS type FROM purchase UNION SELECT use.\"time\", use.item, use.quantity, NULL::unknown AS cost, NULL::unknown AS vendor, NULL::unknown AS reason, NULL::unknown AS customer, 'USE' AS type FROM use) UNION SELECT inventory.\"time\", inventory.item, inventory.quantity, NULL::unknown AS cost, NULL::unknown AS vendor, NULL::unknown AS reason, NULL::unknown AS customer, 'INVENTORY' AS type FROM inventory) UNION SELECT loss.\"time\", loss.item, loss.quantity, NULL::unknown AS cost, NULL::unknown AS vendor, loss.reason, NULL::unknown AS customer, 'LOSS' AS type FROM loss) UNION SELECT make.\"time\", make.item, make.quantity, NULL::unknown AS cost, NULL::unknown AS vendor, NULL::unknown AS reason, NULL::unknown AS customer, 'MAKE' AS type FROM make) UNION SELECT sale.\"time\", sale.item, sale.quantity, NULL::unknown AS cost, NULL::unknown AS vendor, NULL::unknown AS reason, sale.customer, 'SALE' AS type FROM sale");
|
185
|
|
- query.exec("CREATE FUNCTION time_range(bigint) RETURNS integer AS $$ BEGIN IF (SELECT quantity FROM items WHERE id = $1) > 0 THEN RETURN (SELECT current_date - min(time)::date + 1 FROM use WHERE item = $1); ELSE RETURN (SELECT max(time)::date - min(time)::date + 1 FROM use WHERE item = $1); END IF; END; $$ LANGUAGE plpgsql STRICT");
|
186
|
|
- query.exec("CREATE TABLE IF NOT EXISTS items(id bigint NOT NULL, name text NOT NULL, reference text, unit text NOT NULL, quantity numeric DEFAULT 0, category text)");
|
187
|
|
- query.exec("CREATE SEQUENCE items_id_seq INCREMENT BY 1 NO MAXVALUE NO MINVALUE CACHE 1");
|
188
|
|
- query.exec("CREATE TABLE IF NOT EXISTS coffees(origin text NOT NULL, region text, producer text, grade text, milling text, drying text) INHERITS (items)");
|
189
|
|
- query.exec("CREATE VIEW coffee_history AS SELECT coffees.id, coffees.name, coffees.origin, coffees.quantity AS stock, (SELECT sum(use.quantity) AS sum FROM use WHERE (use.item = coffees.id)) AS used, time_range(coffees.id) AS \"interval\", ((SELECT (sum(use.quantity) / (time_range(use.item))::numeric) FROM use WHERE (use.item = coffees.id) GROUP BY use.item))::numeric(10,2) AS rate, (SELECT (('now'::text)::date + ((coffees.quantity / (SELECT (sum(use.quantity) / (time_range(use.item))::numeric) FROM use WHERE (use.item = coffees.id) GROUP BY use.item)))::integer)) AS \"out\" FROM coffees WHERE (coffees.id IN (SELECT use.item FROM use)) ORDER BY coffees.origin");
|
190
|
|
- query.exec("CREATE TABLE IF NOT EXISTS current_items (item bigint NOT NULL)");
|
191
|
|
- query.exec("CREATE TABLE IF NOT EXISTS decaf_coffees (decaf_method text NOT NULL) INHERITS (coffees)");
|
192
|
|
- query.exec("CREATE TABLE IF NOT EXISTS files (id bigint NOT NULL, name text NOT NULL, type text NOT NULL, note text, file bytea NOT NULL)");
|
193
|
|
- query.exec("CREATE TABLE IF NOT EXISTS item_files(\"time\" timestamp without time zone NOT NULL, item bigint NOT NULL, files bigint[] NOT NULL)");
|
194
|
|
- query.exec("CREATE TYPE item_transaction_with_balance AS (\"time\" timestamp without time zone, item bigint, quantity numeric, cost numeric, vendor text, reason text, customer text, type text, balance numeric)");
|
195
|
|
- query.exec("CREATE TABLE IF NOT EXISTS lb_bag_conversion (item bigint NOT NULL, conversion numeric NOT NULL)");
|
196
|
|
- query.exec("CREATE TABLE IF NOT EXISTS machine (id bigint NOT NULL, name text NOT NULL)");
|
197
|
|
- query.exec("CREATE VIEW regular_coffees AS SELECT coffees.id, coffees.name, coffees.reference, coffees.unit, coffees.quantity, coffees.category, coffees.origin, coffees.region, coffees.producer, coffees.grade, coffees.milling, coffees.drying FROM coffees WHERE (NOT (coffees.id IN (SELECT decaf_coffees.id FROM decaf_coffees)))");
|
198
|
|
- query.exec("CREATE TABLE IF NOT EXISTS roasting_log (\"time\" timestamp without time zone NOT NULL, unroasted_id bigint[], unroasted_quantity numeric[], unroasted_total_quantity numeric, roasted_id bigint, roasted_quantity numeric, transaction_type text NOT NULL, annotation text, machine bigint NOT NULL, duration interval, approval boolean, humidity numeric, barometric numeric, indoor_air numeric, outdoor_air numeric, files bigint[])");
|
199
|
|
- query.exec("CREATE VIEW short_log AS SELECT roasting_log.\"time\", (SELECT items.name FROM items WHERE (items.id = roasting_log.roasted_id)) AS name, roasting_log.unroasted_total_quantity, roasting_log.roasted_quantity, ((((roasting_log.unroasted_total_quantity - roasting_log.roasted_quantity) / roasting_log.unroasted_total_quantity) * (100)::numeric))::numeric(12,2) AS weight_loss, roasting_log.duration FROM roasting_log ORDER BY roasting_log.\"time\"");
|
200
|
|
- query.exec("CREATE FUNCTION add_inventory() RETURNS trigger AS $$ BEGIN UPDATE items SET quantity = quantity + NEW.quantity WHERE id = NEW.item; RETURN NEW; END; $$ LANGUAGE plpgsql");
|
201
|
|
- query.exec("CREATE FUNCTION bags_in_stock(bigint) RETURNS numeric AS $_$SELECT quantity / (SELECT conversion FROM lb_bag_conversion WHERE item = id) FROM items WHERE id = $1;$_$ LANGUAGE sql IMMUTABLE STRICT");
|
202
|
|
- query.exec("CREATE FUNCTION log_use() RETURNS trigger AS $$ DECLARE i integer := array_lower(NEW.unroasted_id, 1); u integer := array_upper(NEW.unroasted_id, 1); BEGIN WHILE i <= u LOOP INSERT INTO use VALUES(NEW.time, NEW.unroasted_id[i], NEW.unroasted_quantity[i]); i := i + 1; END LOOP; RETURN NEW; END; $$ LANGUAGE plpgsql");
|
203
|
|
- query.exec("CREATE FUNCTION replace_inventory() RETURNS trigger AS $$ BEGIN UPDATE items SET quantity = NEW.quantity WHERE id = NEW.item; RETURN NEW; END; $$ LANGUAGE plpgsql");
|
204
|
|
- query.exec("CREATE FUNCTION subtract_inventory() RETURNS trigger AS $$ BEGIN UPDATE items SET quantity = quantity - NEW.quantity WHERE id = NEW.item; RETURN NEW; END; $$ LANGUAGE plpgsql");
|
205
|
|
- query.exec("CREATE SEQUENCE files_id_seq START WITH 1 INCREMENT BY 1 NO MAXVALUE NO MINVALUE CACHE 1");
|
206
|
|
- query.exec("ALTER TABLE files ALTER COLUMN id SET DEFAULT nextval('files_id_seq'::regclass)");
|
207
|
|
- query.exec("ALTER TABLE items ALTER COLUMN id SET DEFAULT nextval('items_id_seq'::regclass)");
|
208
|
|
- query.exec("ALTER TABLE ONLY files ADD CONSTRAINT file_pkey PRIMARY KEY (id)");
|
209
|
|
- query.exec("ALTER TABLE ONLY items ADD CONSTRAINT items_pkey PRIMARY KEY (id)");
|
210
|
|
- query.exec("ALTER TABLE ONLY lb_bag_conversion ADD CONSTRAINT lb_bag_conversion_item_key UNIQUE (item)");
|
211
|
|
- query.exec("ALTER TABLE ONLY roasting_log ADD CONSTRAINT roasting_log_pkey PRIMARY KEY (\"time\", machine)");
|
212
|
|
- query.exec("CREATE INDEX itemcategories ON items USING btree (category)");
|
213
|
|
- query.exec("CREATE INDEX itemnames ON items USING btree (name)");
|
214
|
|
- query.exec("CREATE INDEX roasting_log_index ON roasting_log USING btree (\"time\")");
|
215
|
|
- query.exec("CREATE INDEX transactionitems ON transactions USING btree (item)");
|
216
|
|
- query.exec("CREATE INDEX transactiontimes ON transactions USING btree (\"time\")");
|
217
|
|
- query.exec("CREATE TRIGGER add_inventory_trigger AFTER INSERT ON purchase FOR EACH ROW EXECUTE PROCEDURE add_inventory()");
|
218
|
|
- query.exec("CREATE TRIGGER add_inventory_trigger AFTER INSERT ON make FOR EACH ROW EXECUTE PROCEDURE add_inventory()");
|
219
|
|
- query.exec("CREATE TRIGGER log_use_trigger AFTER INSERT ON roasting_log FOR EACH ROW EXECUTE PROCEDURE log_use()");
|
220
|
|
- query.exec("CREATE TRIGGER replace_inventory_trigger AFTER INSERT ON inventory FOR EACH ROW EXECUTE PROCEDURE replace_inventory()");
|
221
|
|
- query.exec("CREATE TRIGGER subtract_inventory_trigger AFTER INSERT ON loss FOR EACH ROW EXECUTE PROCEDURE subtract_inventory()");
|
222
|
|
- query.exec("CREATE TRIGGER subtract_inventory_trigger AFTER INSERT ON sale FOR EACH ROW EXECUTE PROCEDURE subtract_inventory()");
|
223
|
|
- query.exec("CREATE TRIGGER subtract_inventory_trigger AFTER INSERT ON use FOR EACH ROW EXECUTE PROCEDURE subtract_inventory()");
|
224
|
|
- query.exec("ALTER TABLE ONLY item_files ADD CONSTRAINT item_files_item_fkey FOREIGN KEY (item) REFERENCES items(id)");
|
225
|
|
- query.exec("ALTER TABLE ONLY transactions ADD CONSTRAINT transactions_item_fkey FOREIGN KEY (item) REFERENCES items(id)");
|
226
|
|
- query.exec("INSERT INTO TypicaFeatures (feature, enabled, version) VALUES('base-features', TRUE, 1)");
|
227
|
|
- query = query.invalidate();
|
228
|
|
- };
|
|
163
|
+ var DBCreateBase = function() {
|
|
164
|
+ var query = new QSqlQuery();
|
|
165
|
+ query.exec("CREATE TABLE IF NOT EXISTS certifications (item bigint NOT NULL, certification text NOT NULL)");
|
|
166
|
+ query.exec("CREATE TABLE IF NOT EXISTS cupping_samples (session bigint NOT NULL, sample text NOT NULL, position bigint NOT NULL, type text NOT NULL, \"time\" timestamp without time zone, machine bigint, point text, item bigint)");
|
|
167
|
+ query.exec("CREATE TABLE cupping_sessions (id bigserial NOT NULL, event text, name text NOT NULL, \"time\" timestamp without time zone NOT NULL, blind boolean NOT NULL, open boolean NOT NULL, note text)");
|
|
168
|
+ query.exec("CREATE TABLE IF NOT EXISTS cuppingforms (session bigint NOT NULL, sample text NOT NULL, position bigint NOT NULL, grader text, finalscore numeric, notes text, serialization text)");
|
|
169
|
+ query.exec("CREATE TABLE IF NOT EXISTS cuppingform_t1 (aroma numeric, flavor numeric, aftertaste numeric, acidity numeric, body numeric, uniformity numeric, balance numeric, cleancup numeric, sweetness numeric, overall numeric, total numeric) INHERITS (cuppingforms)");
|
|
170
|
+ query.exec("CREATE TABLE IF NOT EXISTS invoices (id bigserial PRIMARY KEY NOT NULL, invoice text, vendor text NOT NULL, \"time\" timestamp without time zone NOT NULL)");
|
|
171
|
+ query.exec("CREATE TABLE IF NOT EXISTS invoice_items (invoice_id bigint NOT NULL, record_type text NOT NULL, item_id bigint, description text NOT NULL, cost numeric NOT NULL)");
|
|
172
|
+ query.exec("CREATE TABLE IF NOT EXISTS transactions (\"time\" timestamp without time zone NOT NULL, item bigint NOT NULL)");
|
|
173
|
+ query.exec("CREATE TABLE IF NOT EXISTS inventory (quantity numeric NOT NULL) INHERITS (transactions)");
|
|
174
|
+ query.exec("CREATE TABLE IF NOT EXISTS loss (quantity numeric NOT NULL, reason text) INHERITS (transactions)");
|
|
175
|
+ query.exec("CREATE TABLE IF NOT EXISTS make (quantity numeric NOT NULL) INHERITS (transactions)");
|
|
176
|
+ query.exec("CREATE TABLE IF NOT EXISTS purchase (quantity numeric NOT NULL, cost numeric NOT NULL, vendor text NOT NULL) INHERITS (transactions)");
|
|
177
|
+ query.exec("CREATE TABLE IF NOT EXISTS sale (quantity numeric NOT NULL, customer text) INHERITS (transactions)");
|
|
178
|
+ query.exec("CREATE TABLE IF NOT EXISTS use (quantity numeric NOT NULL) INHERITS (transactions)");
|
|
179
|
+ query.exec("CREATE VIEW all_transactions AS ((((SELECT purchase.\"time\", purchase.item, purchase.quantity, purchase.cost, purchase.vendor, NULL::unknown AS reason, NULL::unknown AS customer, 'PURCHASE' AS type FROM purchase UNION SELECT use.\"time\", use.item, use.quantity, NULL::unknown AS cost, NULL::unknown AS vendor, NULL::unknown AS reason, NULL::unknown AS customer, 'USE' AS type FROM use) UNION SELECT inventory.\"time\", inventory.item, inventory.quantity, NULL::unknown AS cost, NULL::unknown AS vendor, NULL::unknown AS reason, NULL::unknown AS customer, 'INVENTORY' AS type FROM inventory) UNION SELECT loss.\"time\", loss.item, loss.quantity, NULL::unknown AS cost, NULL::unknown AS vendor, loss.reason, NULL::unknown AS customer, 'LOSS' AS type FROM loss) UNION SELECT make.\"time\", make.item, make.quantity, NULL::unknown AS cost, NULL::unknown AS vendor, NULL::unknown AS reason, NULL::unknown AS customer, 'MAKE' AS type FROM make) UNION SELECT sale.\"time\", sale.item, sale.quantity, NULL::unknown AS cost, NULL::unknown AS vendor, NULL::unknown AS reason, sale.customer, 'SALE' AS type FROM sale");
|
|
180
|
+ query.exec("CREATE FUNCTION time_range(bigint) RETURNS integer AS $$ BEGIN IF (SELECT quantity FROM items WHERE id = $1) > 0 THEN RETURN (SELECT current_date - min(time)::date + 1 FROM use WHERE item = $1); ELSE RETURN (SELECT max(time)::date - min(time)::date + 1 FROM use WHERE item = $1); END IF; END; $$ LANGUAGE plpgsql STRICT");
|
|
181
|
+ query.exec("CREATE TABLE IF NOT EXISTS items(id bigint NOT NULL, name text NOT NULL, reference text, unit text NOT NULL, quantity numeric DEFAULT 0, category text)");
|
|
182
|
+ query.exec("CREATE SEQUENCE items_id_seq INCREMENT BY 1 NO MAXVALUE NO MINVALUE CACHE 1");
|
|
183
|
+ query.exec("CREATE TABLE IF NOT EXISTS coffees(origin text NOT NULL, region text, producer text, grade text, milling text, drying text) INHERITS (items)");
|
|
184
|
+ query.exec("CREATE VIEW coffee_history AS SELECT coffees.id, coffees.name, coffees.origin, coffees.quantity AS stock, (SELECT sum(use.quantity) AS sum FROM use WHERE (use.item = coffees.id)) AS used, time_range(coffees.id) AS \"interval\", ((SELECT (sum(use.quantity) / (time_range(use.item))::numeric) FROM use WHERE (use.item = coffees.id) GROUP BY use.item))::numeric(10,2) AS rate, (SELECT (('now'::text)::date + ((coffees.quantity / (SELECT (sum(use.quantity) / (time_range(use.item))::numeric) FROM use WHERE (use.item = coffees.id) GROUP BY use.item)))::integer)) AS \"out\" FROM coffees WHERE (coffees.id IN (SELECT use.item FROM use)) ORDER BY coffees.origin");
|
|
185
|
+ query.exec("CREATE TABLE IF NOT EXISTS current_items (item bigint NOT NULL)");
|
|
186
|
+ query.exec("CREATE TABLE IF NOT EXISTS decaf_coffees (decaf_method text NOT NULL) INHERITS (coffees)");
|
|
187
|
+ query.exec("CREATE TABLE IF NOT EXISTS files (id bigint NOT NULL, name text NOT NULL, type text NOT NULL, note text, file bytea NOT NULL)");
|
|
188
|
+ query.exec("CREATE TABLE IF NOT EXISTS item_files(\"time\" timestamp without time zone NOT NULL, item bigint NOT NULL, files bigint[] NOT NULL)");
|
|
189
|
+ query.exec("CREATE TYPE item_transaction_with_balance AS (\"time\" timestamp without time zone, item bigint, quantity numeric, cost numeric, vendor text, reason text, customer text, type text, balance numeric)");
|
|
190
|
+ query.exec("CREATE TABLE IF NOT EXISTS lb_bag_conversion (item bigint NOT NULL, conversion numeric NOT NULL)");
|
|
191
|
+ query.exec("CREATE TABLE IF NOT EXISTS machine (id bigint NOT NULL, name text NOT NULL)");
|
|
192
|
+ query.exec("CREATE VIEW regular_coffees AS SELECT coffees.id, coffees.name, coffees.reference, coffees.unit, coffees.quantity, coffees.category, coffees.origin, coffees.region, coffees.producer, coffees.grade, coffees.milling, coffees.drying FROM coffees WHERE (NOT (coffees.id IN (SELECT decaf_coffees.id FROM decaf_coffees)))");
|
|
193
|
+ query.exec("CREATE TABLE IF NOT EXISTS roasting_log (\"time\" timestamp without time zone NOT NULL, unroasted_id bigint[], unroasted_quantity numeric[], unroasted_total_quantity numeric, roasted_id bigint, roasted_quantity numeric, transaction_type text NOT NULL, annotation text, machine bigint NOT NULL, duration interval, approval boolean, humidity numeric, barometric numeric, indoor_air numeric, outdoor_air numeric, files bigint[])");
|
|
194
|
+ query.exec("CREATE VIEW short_log AS SELECT roasting_log.\"time\", (SELECT items.name FROM items WHERE (items.id = roasting_log.roasted_id)) AS name, roasting_log.unroasted_total_quantity, roasting_log.roasted_quantity, ((((roasting_log.unroasted_total_quantity - roasting_log.roasted_quantity) / roasting_log.unroasted_total_quantity) * (100)::numeric))::numeric(12,2) AS weight_loss, roasting_log.duration FROM roasting_log ORDER BY roasting_log.\"time\"");
|
|
195
|
+ query.exec("CREATE FUNCTION add_inventory() RETURNS trigger AS $$ BEGIN UPDATE items SET quantity = quantity + NEW.quantity WHERE id = NEW.item; RETURN NEW; END; $$ LANGUAGE plpgsql");
|
|
196
|
+ query.exec("CREATE FUNCTION bags_in_stock(bigint) RETURNS numeric AS $_$SELECT quantity / (SELECT conversion FROM lb_bag_conversion WHERE item = id) FROM items WHERE id = $1;$_$ LANGUAGE sql IMMUTABLE STRICT");
|
|
197
|
+ query.exec("CREATE FUNCTION log_use() RETURNS trigger AS $$ DECLARE i integer := array_lower(NEW.unroasted_id, 1); u integer := array_upper(NEW.unroasted_id, 1); BEGIN WHILE i <= u LOOP INSERT INTO use VALUES(NEW.time, NEW.unroasted_id[i], NEW.unroasted_quantity[i]); i := i + 1; END LOOP; RETURN NEW; END; $$ LANGUAGE plpgsql");
|
|
198
|
+ query.exec("CREATE FUNCTION replace_inventory() RETURNS trigger AS $$ BEGIN UPDATE items SET quantity = NEW.quantity WHERE id = NEW.item; RETURN NEW; END; $$ LANGUAGE plpgsql");
|
|
199
|
+ query.exec("CREATE FUNCTION subtract_inventory() RETURNS trigger AS $$ BEGIN UPDATE items SET quantity = quantity - NEW.quantity WHERE id = NEW.item; RETURN NEW; END; $$ LANGUAGE plpgsql");
|
|
200
|
+ query.exec("CREATE SEQUENCE files_id_seq START WITH 1 INCREMENT BY 1 NO MAXVALUE NO MINVALUE CACHE 1");
|
|
201
|
+ query.exec("ALTER TABLE files ALTER COLUMN id SET DEFAULT nextval('files_id_seq'::regclass)");
|
|
202
|
+ query.exec("ALTER TABLE items ALTER COLUMN id SET DEFAULT nextval('items_id_seq'::regclass)");
|
|
203
|
+ query.exec("ALTER TABLE ONLY files ADD CONSTRAINT file_pkey PRIMARY KEY (id)");
|
|
204
|
+ query.exec("ALTER TABLE ONLY items ADD CONSTRAINT items_pkey PRIMARY KEY (id)");
|
|
205
|
+ query.exec("ALTER TABLE ONLY lb_bag_conversion ADD CONSTRAINT lb_bag_conversion_item_key UNIQUE (item)");
|
|
206
|
+ query.exec("ALTER TABLE ONLY roasting_log ADD CONSTRAINT roasting_log_pkey PRIMARY KEY (\"time\", machine)");
|
|
207
|
+ query.exec("CREATE INDEX itemcategories ON items USING btree (category)");
|
|
208
|
+ query.exec("CREATE INDEX itemnames ON items USING btree (name)");
|
|
209
|
+ query.exec("CREATE INDEX roasting_log_index ON roasting_log USING btree (\"time\")");
|
|
210
|
+ query.exec("CREATE INDEX transactionitems ON transactions USING btree (item)");
|
|
211
|
+ query.exec("CREATE INDEX transactiontimes ON transactions USING btree (\"time\")");
|
|
212
|
+ query.exec("CREATE TRIGGER add_inventory_trigger AFTER INSERT ON purchase FOR EACH ROW EXECUTE PROCEDURE add_inventory()");
|
|
213
|
+ query.exec("CREATE TRIGGER add_inventory_trigger AFTER INSERT ON make FOR EACH ROW EXECUTE PROCEDURE add_inventory()");
|
|
214
|
+ query.exec("CREATE TRIGGER log_use_trigger AFTER INSERT ON roasting_log FOR EACH ROW EXECUTE PROCEDURE log_use()");
|
|
215
|
+ query.exec("CREATE TRIGGER replace_inventory_trigger AFTER INSERT ON inventory FOR EACH ROW EXECUTE PROCEDURE replace_inventory()");
|
|
216
|
+ query.exec("CREATE TRIGGER subtract_inventory_trigger AFTER INSERT ON loss FOR EACH ROW EXECUTE PROCEDURE subtract_inventory()");
|
|
217
|
+ query.exec("CREATE TRIGGER subtract_inventory_trigger AFTER INSERT ON sale FOR EACH ROW EXECUTE PROCEDURE subtract_inventory()");
|
|
218
|
+ query.exec("CREATE TRIGGER subtract_inventory_trigger AFTER INSERT ON use FOR EACH ROW EXECUTE PROCEDURE subtract_inventory()");
|
|
219
|
+ query.exec("ALTER TABLE ONLY item_files ADD CONSTRAINT item_files_item_fkey FOREIGN KEY (item) REFERENCES items(id)");
|
|
220
|
+ query.exec("ALTER TABLE ONLY transactions ADD CONSTRAINT transactions_item_fkey FOREIGN KEY (item) REFERENCES items(id)");
|
|
221
|
+ query.exec("INSERT INTO TypicaFeatures (feature, enabled, version) VALUES('base-features', TRUE, 1)");
|
|
222
|
+ query = query.invalidate();
|
|
223
|
+ };
|
229
|
224
|
|
230
|
225
|
/* Some changes to the database are required for sample roasting features in
|
231
|
226
|
Typica 1.6 and later. */
|