1 -- @tag: requirement_specs
2 -- @description: Pflichtenhefte
3 -- @depends: release_3_0_0
6 -- Nur für Entwicklungszwecke:
8 -- DELETE FROM schema_info WHERE tag = 'requirement_specs';
11 -- DROP TABLE requirement_spec_item_dependencies;
12 -- DROP TABLE requirement_spec_items;
13 -- DROP TABLE requirement_spec_text_blocks;
14 -- DROP TABLE requirement_specs;
15 -- DROP TABLE requirement_spec_versions;
16 -- DROP TABLE requirement_spec_predefined_texts;
17 -- DROP TABLE requirement_spec_types;
18 -- DROP TABLE requirement_spec_statuses;
19 -- DROP TABLE requirement_spec_risks;
20 -- DROP TABLE requirement_spec_complexities;
21 -- DROP TABLE requirement_spec_acceptance_statuses;
22 -- ALTER TABLE customer DROP COLUMN hourly_rate;
23 -- ALTER TABLE defaults DROP COLUMN requirement_spec_section_number_format;
24 -- ALTER TABLE defaults DROP COLUMN requirement_spec_function_block_number_format;
26 CREATE TABLE requirement_spec_acceptance_statuses (
30 position INTEGER NOT NULL,
31 itime TIMESTAMP DEFAULT now(),
35 UNIQUE (name, description)
37 CREATE TRIGGER mtime_requirement_spec_acceptance_statuses BEFORE UPDATE ON requirement_spec_acceptance_statuses FOR EACH ROW EXECUTE PROCEDURE set_mtime();
39 INSERT INTO requirement_spec_acceptance_statuses (name, description, position) VALUES ('accepted', 'Abgenommen', 1);
40 INSERT INTO requirement_spec_acceptance_statuses (name, description, position) VALUES ('accepted_with_defects', 'Mit Mängeln abgenommen', 2);
41 INSERT INTO requirement_spec_acceptance_statuses (name, description, position) VALUES ('accepted_with_defects_to_be_fixed', 'Mit noch zu behebenden Mängeln abgenommen', 3);
42 INSERT INTO requirement_spec_acceptance_statuses (name, description, position) VALUES ('not_accepted', 'Nicht abgenommen', 4);
46 CREATE TABLE requirement_spec_complexities (
48 description TEXT NOT NULL,
49 position INTEGER NOT NULL,
50 itime TIMESTAMP DEFAULT now(),
56 CREATE TRIGGER mtime_requirement_spec_complexities BEFORE UPDATE ON requirement_spec_complexities FOR EACH ROW EXECUTE PROCEDURE set_mtime();
58 INSERT INTO requirement_spec_complexities (description, position) VALUES ('nicht bewertet', 1);
59 INSERT INTO requirement_spec_complexities (description, position) VALUES ('nur Anforderung', 2);
60 INSERT INTO requirement_spec_complexities (description, position) VALUES ('gering', 3);
61 INSERT INTO requirement_spec_complexities (description, position) VALUES ('mittel', 4);
62 INSERT INTO requirement_spec_complexities (description, position) VALUES ('hoch', 5);
66 CREATE TABLE requirement_spec_risks (
68 description TEXT NOT NULL,
69 position INTEGER NOT NULL,
70 itime TIMESTAMP DEFAULT now(),
76 CREATE TRIGGER mtime_requirement_spec_risks BEFORE UPDATE ON requirement_spec_risks FOR EACH ROW EXECUTE PROCEDURE set_mtime();
78 INSERT INTO requirement_spec_risks (description, position) VALUES ('nicht bewertet', 1);
79 INSERT INTO requirement_spec_risks (description, position) VALUES ('nur Anforderung', 2);
80 INSERT INTO requirement_spec_risks (description, position) VALUES ('gering', 3);
81 INSERT INTO requirement_spec_risks (description, position) VALUES ('mittel', 4);
82 INSERT INTO requirement_spec_risks (description, position) VALUES ('hoch', 5);
86 CREATE TABLE requirement_spec_statuses (
89 description TEXT NOT NULL,
90 position INTEGER NOT NULL,
91 itime TIMESTAMP DEFAULT now(),
95 UNIQUE (name, description)
97 CREATE TRIGGER mtime_requirement_spec_statuses BEFORE UPDATE ON requirement_spec_statuses FOR EACH ROW EXECUTE PROCEDURE set_mtime();
99 INSERT INTO requirement_spec_statuses (name, description, position) VALUES ('planning', 'In Planung', 1);
100 INSERT INTO requirement_spec_statuses (name, description, position) VALUES ('running', 'In Bearbeitung', 2);
101 INSERT INTO requirement_spec_statuses (name, description, position) VALUES ('done', 'Fertiggestellt', 3);
105 CREATE TABLE requirement_spec_types (
107 description TEXT NOT NULL,
108 position INTEGER NOT NULL,
109 itime TIMESTAMP DEFAULT now(),
115 CREATE TRIGGER mtime_requirement_spec_types BEFORE UPDATE ON requirement_spec_types FOR EACH ROW EXECUTE PROCEDURE set_mtime();
117 INSERT INTO requirement_spec_types (description, position) VALUES ('Pflichtenheft', 1);
118 INSERT INTO requirement_spec_types (description, position) VALUES ('Konzept', 2);
122 CREATE TABLE requirement_spec_predefined_texts (
124 description TEXT NOT NULL,
127 position INTEGER NOT NULL,
128 itime TIMESTAMP DEFAULT now(),
134 CREATE TRIGGER mtime_requirement_spec_predefined_texts BEFORE UPDATE ON requirement_spec_predefined_texts FOR EACH ROW EXECUTE PROCEDURE set_mtime();
138 CREATE TABLE requirement_spec_versions (
140 version_number INTEGER,
141 description TEXT NOT NULL,
146 itime TIMESTAMP DEFAULT now(),
150 FOREIGN KEY (order_id) REFERENCES oe (id)
152 CREATE TRIGGER mtime_requirement_spec_versions BEFORE UPDATE ON requirement_spec_versions FOR EACH ROW EXECUTE PROCEDURE set_mtime();
156 CREATE TABLE requirement_specs (
158 type_id INTEGER NOT NULL,
159 status_id INTEGER NOT NULL,
161 customer_id INTEGER NOT NULL,
164 hourly_rate NUMERIC(8, 2) NOT NULL DEFAULT 0,
165 net_sum NUMERIC(12, 2) NOT NULL DEFAULT 0,
166 working_copy_id INTEGER,
167 previous_section_number INTEGER NOT NULL,
168 previous_fb_number INTEGER NOT NULL,
169 is_template BOOLEAN DEFAULT FALSE,
170 itime TIMESTAMP DEFAULT now(),
174 FOREIGN KEY (type_id) REFERENCES requirement_spec_types (id),
175 FOREIGN KEY (status_id) REFERENCES requirement_spec_statuses (id),
176 FOREIGN KEY (version_id) REFERENCES requirement_spec_versions (id),
177 FOREIGN KEY (working_copy_id) REFERENCES requirement_specs (id),
178 FOREIGN KEY (customer_id) REFERENCES customer (id),
179 FOREIGN KEY (project_id) REFERENCES project (id)
181 CREATE TRIGGER mtime_requirement_specs BEFORE UPDATE ON requirement_specs FOR EACH ROW EXECUTE PROCEDURE set_mtime();
185 CREATE TABLE requirement_spec_text_blocks (
187 requirement_spec_id INTEGER NOT NULL,
190 position INTEGER NOT NULL,
191 output_position INTEGER NOT NULL DEFAULT 1,
192 is_flagged BOOLEAN NOT NULL DEFAULT FALSE,
193 itime TIMESTAMP NOT NULL DEFAULT now(),
197 FOREIGN KEY (requirement_spec_id) REFERENCES requirement_specs (id)
199 CREATE TRIGGER mtime_requirement_spec_text_blocks BEFORE UPDATE ON requirement_spec_text_blocks FOR EACH ROW EXECUTE PROCEDURE set_mtime();
202 CREATE TABLE requirement_spec_items (
204 requirement_spec_id INTEGER NOT NULL,
205 item_type TEXT NOT NULL,
207 position INTEGER NOT NULL,
208 fb_number TEXT NOT NULL,
211 complexity_id INTEGER,
213 time_estimation NUMERIC(12, 2) NOT NULL DEFAULT 0,
214 net_sum NUMERIC(12, 2) NOT NULL DEFAULT 0,
215 is_flagged BOOLEAN NOT NULL DEFAULT FALSE,
216 acceptance_status_id INTEGER,
217 acceptance_text TEXT,
218 itime TIMESTAMP NOT NULL DEFAULT now(),
222 FOREIGN KEY (requirement_spec_id) REFERENCES requirement_specs (id),
223 FOREIGN KEY (parent_id) REFERENCES requirement_spec_items (id),
224 FOREIGN KEY (complexity_id) REFERENCES requirement_spec_complexities (id),
225 FOREIGN KEY (risk_id) REFERENCES requirement_spec_risks (id),
226 FOREIGN KEY (acceptance_status_id) REFERENCES requirement_spec_acceptance_statuses (id),
228 CONSTRAINT valid_item_type CHECK ((item_type = 'section') OR (item_type = 'function-block') OR (item_type = 'sub-function-block')),
229 CONSTRAINT valid_parent_id_for_item_type CHECK (CASE
230 WHEN (item_type = 'section') THEN parent_id IS NULL
231 ELSE parent_id IS NOT NULL
234 CREATE TRIGGER mtime_requirement_spec_items BEFORE UPDATE ON requirement_spec_items FOR EACH ROW EXECUTE PROCEDURE set_mtime();
238 CREATE TABLE requirement_spec_item_dependencies (
239 depending_item_id INTEGER NOT NULL,
240 depended_item_id INTEGER NOT NULL,
242 PRIMARY KEY (depending_item_id, depended_item_id),
243 FOREIGN KEY (depending_item_id) REFERENCES requirement_spec_items (id),
244 FOREIGN KEY (depended_item_id) REFERENCES requirement_spec_items (id)
247 ALTER TABLE customer ADD COLUMN hourly_rate NUMERIC(8, 2);
250 CREATE TABLE trigger_information (
251 id SERIAL PRIMARY KEY,
258 -- Trigger for updating time_estimation of function blocks from their
259 -- children (not for sections, not for sub function blocks).
260 CREATE OR REPLACE FUNCTION update_requirement_spec_item_time_estimation(item_id INTEGER) RETURNS BOOLEAN AS $$
264 IF item_id IS NULL THEN
265 RAISE DEBUG 'updateRSIE: item_id IS NULL';
271 FROM trigger_information
272 WHERE (key = 'deleting_requirement_spec_item')
273 AND (value = CAST(item_id AS TEXT))
276 RAISE DEBUG 'updateRSIE: item_id % is about to be deleted; do not update', item_id;
280 SELECT * INTO item FROM requirement_spec_items WHERE id = item_id;
281 RAISE DEBUG 'updateRSIE: item_id % item_type %', item_id, item.item_type;
283 IF (item.item_type = 'section') OR (item.item_type = 'sub-function-block') THEN
284 -- Don't do anything for sections and sub-function-blocks.
285 RAISE DEBUG 'updateRSIE: this is a section/sub-function-block, not updating.';
289 RAISE DEBUG 'updateRSIE: will do stuff now';
291 UPDATE requirement_spec_items
292 SET time_estimation = COALESCE((
293 SELECT SUM(time_estimation)
294 FROM requirement_spec_items
295 WHERE parent_id = item_id
303 CREATE OR REPLACE FUNCTION requirement_spec_item_time_estimation_updater_trigger() RETURNS trigger AS $$
307 RAISE DEBUG 'updateRSITE op %', TG_OP;
308 IF ((TG_OP = 'UPDATE') OR (TG_OP = 'DELETE')) THEN
309 RAISE DEBUG 'UPDATE trigg op % OLD.id % OLD.parent_id %', TG_OP, OLD.id, OLD.parent_id;
310 PERFORM update_requirement_spec_item_time_estimation(OLD.parent_id);
311 RAISE DEBUG 'UPDATE trigg op % END %', TG_OP, OLD.id;
315 IF (TG_OP = 'UPDATE') THEN
316 do_new = OLD.parent_id <> NEW.parent_id;
319 IF (do_new OR (TG_OP = 'INSERT')) THEN
320 RAISE DEBUG 'UPDATE trigg op % NEW.id % NEW.parent_id %', TG_OP, NEW.id, NEW.parent_id;
321 PERFORM update_requirement_spec_item_time_estimation(NEW.parent_id);
322 RAISE DEBUG 'UPDATE trigg op % END %', TG_OP, NEW.id;
329 DROP TRIGGER IF EXISTS update_requirement_spec_item_time_estimation ON requirement_spec_items;
330 CREATE TRIGGER update_requirement_spec_item_time_estimation
331 AFTER INSERT OR UPDATE OR DELETE ON requirement_spec_items
332 FOR EACH ROW EXECUTE PROCEDURE requirement_spec_item_time_estimation_updater_trigger();
335 -- Trigger for deleting depending stuff if a requirement spec item is deleted.
336 CREATE OR REPLACE FUNCTION requirement_spec_item_before_delete_trigger() RETURNS trigger AS $$
338 RAISE DEBUG 'delete trig RSitem old id %', OLD.id;
339 INSERT INTO trigger_information (key, value) VALUES ('deleting_requirement_spec_item', CAST(OLD.id AS TEXT));
340 DELETE FROM requirement_spec_item_dependencies WHERE (depending_item_id = OLD.id) OR (depended_item_id = OLD.id);
341 DELETE FROM requirement_spec_items WHERE (parent_id = OLD.id);
342 DELETE FROM trigger_information WHERE (key = 'deleting_requirement_spec_item') AND (value = CAST(OLD.id AS TEXT));
343 RAISE DEBUG 'delete trig END %', OLD.id;
348 DROP TRIGGER IF EXISTS delete_requirement_spec_item_dependencies ON requirement_spec_items;
349 CREATE TRIGGER delete_requirement_spec_item_dependencies
350 BEFORE DELETE ON requirement_spec_items
351 FOR EACH ROW EXECUTE PROCEDURE requirement_spec_item_before_delete_trigger();
354 -- Trigger for deleting depending stuff if a requirement spec is deleted.
355 CREATE OR REPLACE FUNCTION requirement_spec_delete_trigger() RETURNS trigger AS $$
359 tname := 'tmp_delete_reqspec' || OLD.id;
361 IF TG_WHEN = 'AFTER' THEN
362 RAISE DEBUG 'after trigger on %; deleting from versions', OLD.id;
363 EXECUTE 'DELETE FROM requirement_spec_versions ' ||
364 'WHERE id IN (SELECT version_id FROM ' || tname || ')';
366 RAISE DEBUG ' dropping table';
367 EXECUTE 'DROP TABLE ' || tname;
372 RAISE DEBUG 'before delete trigger on %', OLD.id;
374 EXECUTE 'CREATE TEMPORARY TABLE ' || tname || ' AS ' ||
375 'SELECT DISTINCT version_id ' ||
376 'FROM requirement_specs ' ||
377 'WHERE (version_id IS NOT NULL) ' ||
378 ' AND ((id = ' || OLD.id || ') OR (working_copy_id = ' || OLD.id || '))';
380 RAISE DEBUG ' Updating version_id and items for %', OLD.id;
381 UPDATE requirement_specs SET version_id = NULL WHERE (id <> OLD.id) AND (working_copy_id = OLD.id);
382 UPDATE requirement_spec_items SET item_type = 'section', parent_id = NULL WHERE requirement_spec_id = OLD.id;
384 RAISE DEBUG ' Deleting stuff for %', OLD.id;
386 DELETE FROM requirement_spec_text_blocks WHERE (requirement_spec_id = OLD.id);
387 DELETE FROM requirement_spec_items WHERE (requirement_spec_id = OLD.id);
388 DELETE FROM requirement_specs WHERE (working_copy_id = OLD.id);
390 RAISE DEBUG ' And we out for %', OLD.id;
396 DROP TRIGGER IF EXISTS delete_requirement_spec_dependencies ON requirement_specs;
397 CREATE TRIGGER delete_requirement_spec_dependencies
398 BEFORE DELETE ON requirement_specs
399 FOR EACH ROW EXECUTE PROCEDURE requirement_spec_delete_trigger();
401 DROP TRIGGER IF EXISTS after_delete_requirement_spec_dependencies ON requirement_specs;
402 CREATE TRIGGER after_delete_requirement_spec_dependencies
403 AFTER DELETE ON requirement_specs
404 FOR EACH ROW EXECUTE PROCEDURE requirement_spec_delete_trigger();
407 -- Add formats for section/function block numbers to defaults
408 ALTER TABLE defaults ADD COLUMN requirement_spec_section_number_format TEXT;
409 ALTER TABLE defaults ALTER COLUMN requirement_spec_section_number_format SET DEFAULT 'A00';
410 ALTER TABLE defaults ADD COLUMN requirement_spec_function_block_number_format TEXT;
411 ALTER TABLE defaults ALTER COLUMN requirement_spec_function_block_number_format SET DEFAULT 'FB000';
413 UPDATE defaults SET requirement_spec_section_number_format = 'A00';
414 UPDATE defaults SET requirement_spec_function_block_number_format = 'FB000';
416 ALTER TABLE defaults ALTER COLUMN requirement_spec_section_number_format SET NOT NULL;
417 ALTER TABLE defaults ALTER COLUMN requirement_spec_function_block_number_format SET NOT NULL;