1 -- @tag: requirement_specs
2 -- @description: Pflichtenhefte
3 -- @depends: release_3_0_0
5 -- Nur für Entwicklungszwecke:
7 -- DELETE FROM schema_info WHERE tag = 'requirement_specs';
10 -- DROP TABLE requirement_spec_item_dependencies;
11 -- DROP TABLE requirement_spec_items;
12 -- DROP TABLE requirement_spec_text_blocks;
13 -- DROP TABLE requirement_specs;
14 -- DROP TABLE requirement_spec_versions;
15 -- DROP TABLE requirement_spec_predefined_texts;
16 -- DROP TABLE requirement_spec_types;
17 -- DROP TABLE requirement_spec_statuses;
18 -- DROP TABLE requirement_spec_risks;
19 -- DROP TABLE requirement_spec_complexities;
20 -- DROP TABLE requirement_spec_acceptance_statuses;
21 -- ALTER TABLE customer DROP COLUMN hourly_rate;
22 -- ALTER TABLE defaults DROP COLUMN requirement_spec_section_number_format;
23 -- ALTER TABLE defaults DROP COLUMN requirement_spec_function_block_number_format;
25 CREATE TABLE requirement_spec_acceptance_statuses (
29 position INTEGER NOT NULL,
30 itime TIMESTAMP DEFAULT now(),
34 UNIQUE (name, description)
36 CREATE TRIGGER mtime_requirement_spec_acceptance_statuses BEFORE UPDATE ON requirement_spec_acceptance_statuses FOR EACH ROW EXECUTE PROCEDURE set_mtime();
38 INSERT INTO requirement_spec_acceptance_statuses (name, description, position) VALUES ('accepted', 'Abgenommen', 1);
39 INSERT INTO requirement_spec_acceptance_statuses (name, description, position) VALUES ('accepted_with_defects', 'Mit Mängeln abgenommen', 2);
40 INSERT INTO requirement_spec_acceptance_statuses (name, description, position) VALUES ('accepted_with_defects_to_be_fixed', 'Mit noch zu behebenden Mängeln abgenommen', 3);
41 INSERT INTO requirement_spec_acceptance_statuses (name, description, position) VALUES ('not_accepted', 'Nicht abgenommen', 4);
45 CREATE TABLE requirement_spec_complexities (
47 description TEXT NOT NULL,
48 position INTEGER NOT NULL,
49 itime TIMESTAMP DEFAULT now(),
55 CREATE TRIGGER mtime_requirement_spec_complexities BEFORE UPDATE ON requirement_spec_complexities FOR EACH ROW EXECUTE PROCEDURE set_mtime();
57 INSERT INTO requirement_spec_complexities (description, position) VALUES ('nicht bewertet', 1);
58 INSERT INTO requirement_spec_complexities (description, position) VALUES ('nur Anforderung', 2);
59 INSERT INTO requirement_spec_complexities (description, position) VALUES ('gering', 3);
60 INSERT INTO requirement_spec_complexities (description, position) VALUES ('mittel', 4);
61 INSERT INTO requirement_spec_complexities (description, position) VALUES ('hoch', 5);
65 CREATE TABLE requirement_spec_risks (
67 description TEXT NOT NULL,
68 position INTEGER NOT NULL,
69 itime TIMESTAMP DEFAULT now(),
75 CREATE TRIGGER mtime_requirement_spec_risks BEFORE UPDATE ON requirement_spec_risks FOR EACH ROW EXECUTE PROCEDURE set_mtime();
77 INSERT INTO requirement_spec_risks (description, position) VALUES ('nicht bewertet', 1);
78 INSERT INTO requirement_spec_risks (description, position) VALUES ('nur Anforderung', 2);
79 INSERT INTO requirement_spec_risks (description, position) VALUES ('gering', 3);
80 INSERT INTO requirement_spec_risks (description, position) VALUES ('mittel', 4);
81 INSERT INTO requirement_spec_risks (description, position) VALUES ('hoch', 5);
85 CREATE TABLE requirement_spec_statuses (
88 description TEXT NOT NULL,
89 position INTEGER NOT NULL,
90 itime TIMESTAMP DEFAULT now(),
94 UNIQUE (name, description)
96 CREATE TRIGGER mtime_requirement_spec_statuses BEFORE UPDATE ON requirement_spec_statuses FOR EACH ROW EXECUTE PROCEDURE set_mtime();
98 INSERT INTO requirement_spec_statuses (name, description, position) VALUES ('planning', 'In Planung', 1);
99 INSERT INTO requirement_spec_statuses (name, description, position) VALUES ('running', 'In Bearbeitung', 2);
100 INSERT INTO requirement_spec_statuses (name, description, position) VALUES ('done', 'Fertiggestellt', 3);
104 CREATE TABLE requirement_spec_types (
106 description TEXT NOT NULL,
107 position INTEGER NOT NULL,
108 itime TIMESTAMP DEFAULT now(),
114 CREATE TRIGGER mtime_requirement_spec_types BEFORE UPDATE ON requirement_spec_types FOR EACH ROW EXECUTE PROCEDURE set_mtime();
116 INSERT INTO requirement_spec_types (description, position) VALUES ('Pflichtenheft', 1);
117 INSERT INTO requirement_spec_types (description, position) VALUES ('Konzept', 2);
121 CREATE TABLE requirement_spec_predefined_texts (
123 description TEXT NOT NULL,
126 position INTEGER NOT NULL,
127 itime TIMESTAMP DEFAULT now(),
133 CREATE TRIGGER mtime_requirement_spec_predefined_texts BEFORE UPDATE ON requirement_spec_predefined_texts FOR EACH ROW EXECUTE PROCEDURE set_mtime();
137 CREATE TABLE requirement_spec_versions (
139 version_number INTEGER,
140 description TEXT NOT NULL,
145 itime TIMESTAMP DEFAULT now(),
149 FOREIGN KEY (order_id) REFERENCES oe (id)
151 CREATE TRIGGER mtime_requirement_spec_versions BEFORE UPDATE ON requirement_spec_versions FOR EACH ROW EXECUTE PROCEDURE set_mtime();
155 CREATE TABLE requirement_specs (
157 type_id INTEGER NOT NULL,
158 status_id INTEGER NOT NULL,
160 customer_id INTEGER NOT NULL,
163 hourly_rate NUMERIC(8, 2) NOT NULL DEFAULT 0,
164 net_sum NUMERIC(12, 2) NOT NULL DEFAULT 0,
165 working_copy_id INTEGER,
166 previous_section_number INTEGER NOT NULL,
167 previous_fb_number INTEGER NOT NULL,
168 is_template BOOLEAN DEFAULT FALSE,
169 itime TIMESTAMP DEFAULT now(),
173 FOREIGN KEY (type_id) REFERENCES requirement_spec_types (id),
174 FOREIGN KEY (status_id) REFERENCES requirement_spec_statuses (id),
175 FOREIGN KEY (version_id) REFERENCES requirement_spec_versions (id),
176 FOREIGN KEY (working_copy_id) REFERENCES requirement_specs (id),
177 FOREIGN KEY (customer_id) REFERENCES customer (id),
178 FOREIGN KEY (project_id) REFERENCES project (id)
180 CREATE TRIGGER mtime_requirement_specs BEFORE UPDATE ON requirement_specs FOR EACH ROW EXECUTE PROCEDURE set_mtime();
184 CREATE TABLE requirement_spec_text_blocks (
186 requirement_spec_id INTEGER NOT NULL,
189 position INTEGER NOT NULL,
190 output_position INTEGER NOT NULL DEFAULT 1,
191 is_flagged BOOLEAN NOT NULL DEFAULT FALSE,
192 itime TIMESTAMP NOT NULL DEFAULT now(),
196 FOREIGN KEY (requirement_spec_id) REFERENCES requirement_specs (id)
198 CREATE TRIGGER mtime_requirement_spec_text_blocks BEFORE UPDATE ON requirement_spec_text_blocks FOR EACH ROW EXECUTE PROCEDURE set_mtime();
201 CREATE TABLE requirement_spec_items (
203 requirement_spec_id INTEGER NOT NULL,
204 item_type TEXT NOT NULL,
206 position INTEGER NOT NULL,
207 fb_number TEXT NOT NULL,
210 complexity_id INTEGER,
212 time_estimation NUMERIC(12, 2) NOT NULL DEFAULT 0,
213 net_sum NUMERIC(12, 2) NOT NULL DEFAULT 0,
214 is_flagged BOOLEAN NOT NULL DEFAULT FALSE,
215 acceptance_status_id INTEGER,
216 acceptance_text TEXT,
217 itime TIMESTAMP NOT NULL DEFAULT now(),
221 FOREIGN KEY (requirement_spec_id) REFERENCES requirement_specs (id),
222 FOREIGN KEY (parent_id) REFERENCES requirement_spec_items (id),
223 FOREIGN KEY (complexity_id) REFERENCES requirement_spec_complexities (id),
224 FOREIGN KEY (risk_id) REFERENCES requirement_spec_risks (id),
225 FOREIGN KEY (acceptance_status_id) REFERENCES requirement_spec_acceptance_statuses (id),
227 CONSTRAINT valid_item_type CHECK ((item_type = 'section') OR (item_type = 'function-block') OR (item_type = 'sub-function-block')),
228 CONSTRAINT valid_parent_id_for_item_type CHECK (CASE
229 WHEN (item_type = 'section') THEN parent_id IS NULL
230 ELSE parent_id IS NOT NULL
233 CREATE TRIGGER mtime_requirement_spec_items BEFORE UPDATE ON requirement_spec_items FOR EACH ROW EXECUTE PROCEDURE set_mtime();
237 CREATE TABLE requirement_spec_item_dependencies (
238 depending_item_id INTEGER NOT NULL,
239 depended_item_id INTEGER NOT NULL,
241 PRIMARY KEY (depending_item_id, depended_item_id),
242 FOREIGN KEY (depending_item_id) REFERENCES requirement_spec_items (id),
243 FOREIGN KEY (depended_item_id) REFERENCES requirement_spec_items (id)
246 ALTER TABLE customer ADD COLUMN hourly_rate NUMERIC(8, 2);
249 CREATE TABLE trigger_information (
250 id SERIAL PRIMARY KEY,
257 -- Trigger for updating time_estimation of function blocks from their
258 -- children (not for sections, not for sub function blocks).
259 CREATE OR REPLACE FUNCTION update_requirement_spec_item_time_estimation(item_id INTEGER) RETURNS BOOLEAN AS $$
263 IF item_id IS NULL THEN
264 RAISE DEBUG 'updateRSIE: item_id IS NULL';
270 FROM trigger_information
271 WHERE (key = 'deleting_requirement_spec_item')
272 AND (value = CAST(item_id AS TEXT))
275 RAISE DEBUG 'updateRSIE: item_id % is about to be deleted; do not update', item_id;
279 SELECT * INTO item FROM requirement_spec_items WHERE id = item_id;
280 RAISE DEBUG 'updateRSIE: item_id % item_type %', item_id, item.item_type;
282 IF (item.item_type = 'sub-function-block') THEN
283 -- Don't do anything for sub-function-blocks.
284 RAISE DEBUG 'updateRSIE: this is a sub-function-block, not updating.';
288 RAISE DEBUG 'updateRSIE: will do stuff now';
290 UPDATE requirement_spec_items
291 SET time_estimation = COALESCE((
292 SELECT SUM(time_estimation)
293 FROM requirement_spec_items
294 WHERE parent_id = item_id
302 CREATE OR REPLACE FUNCTION requirement_spec_item_time_estimation_updater_trigger() RETURNS trigger AS $$
306 RAISE DEBUG 'updateRSITE op %', TG_OP;
307 IF ((TG_OP = 'UPDATE') OR (TG_OP = 'DELETE')) THEN
308 RAISE DEBUG 'UPDATE trigg op % OLD.id % OLD.parent_id %', TG_OP, OLD.id, OLD.parent_id;
309 PERFORM update_requirement_spec_item_time_estimation(OLD.parent_id);
310 RAISE DEBUG 'UPDATE trigg op % END %', TG_OP, OLD.id;
314 IF (TG_OP = 'UPDATE') THEN
315 do_new = OLD.parent_id <> NEW.parent_id;
318 IF (do_new OR (TG_OP = 'INSERT')) THEN
319 RAISE DEBUG 'UPDATE trigg op % NEW.id % NEW.parent_id %', TG_OP, NEW.id, NEW.parent_id;
320 PERFORM update_requirement_spec_item_time_estimation(NEW.parent_id);
321 RAISE DEBUG 'UPDATE trigg op % END %', TG_OP, NEW.id;
328 DROP TRIGGER IF EXISTS update_requirement_spec_item_time_estimation ON requirement_spec_items;
329 CREATE TRIGGER update_requirement_spec_item_time_estimation
330 AFTER INSERT OR UPDATE OR DELETE ON requirement_spec_items
331 FOR EACH ROW EXECUTE PROCEDURE requirement_spec_item_time_estimation_updater_trigger();
334 -- Trigger for deleting depending stuff if a requirement spec item is deleted.
335 CREATE OR REPLACE FUNCTION requirement_spec_item_before_delete_trigger() RETURNS trigger AS $$
337 RAISE DEBUG 'delete trig RSitem old id %', OLD.id;
338 INSERT INTO trigger_information (key, value) VALUES ('deleting_requirement_spec_item', CAST(OLD.id AS TEXT));
339 DELETE FROM requirement_spec_item_dependencies WHERE (depending_item_id = OLD.id) OR (depended_item_id = OLD.id);
340 DELETE FROM requirement_spec_items WHERE (parent_id = OLD.id);
341 DELETE FROM trigger_information WHERE (key = 'deleting_requirement_spec_item') AND (value = CAST(OLD.id AS TEXT));
342 RAISE DEBUG 'delete trig END %', OLD.id;
347 DROP TRIGGER IF EXISTS delete_requirement_spec_item_dependencies ON requirement_spec_items;
348 CREATE TRIGGER delete_requirement_spec_item_dependencies
349 BEFORE DELETE ON requirement_spec_items
350 FOR EACH ROW EXECUTE PROCEDURE requirement_spec_item_before_delete_trigger();
353 -- Trigger for deleting depending stuff if a requirement spec is deleted.
354 CREATE OR REPLACE FUNCTION requirement_spec_delete_trigger() RETURNS trigger AS $$
358 tname := 'tmp_delete_reqspec' || OLD.id;
360 IF TG_WHEN = 'AFTER' THEN
361 RAISE DEBUG 'after trigger on %; deleting from versions', OLD.id;
362 EXECUTE 'DELETE FROM requirement_spec_versions ' ||
363 'WHERE id IN (SELECT version_id FROM ' || tname || ')';
365 RAISE DEBUG ' dropping table';
366 EXECUTE 'DROP TABLE ' || tname;
371 RAISE DEBUG 'before delete trigger on %', OLD.id;
373 EXECUTE 'CREATE TEMPORARY TABLE ' || tname || ' AS ' ||
374 'SELECT DISTINCT version_id ' ||
375 'FROM requirement_specs ' ||
376 'WHERE (version_id IS NOT NULL) ' ||
377 ' AND ((id = ' || OLD.id || ') OR (working_copy_id = ' || OLD.id || '))';
379 RAISE DEBUG ' Updating version_id and items for %', OLD.id;
380 UPDATE requirement_specs SET version_id = NULL WHERE (id <> OLD.id) AND (working_copy_id = OLD.id);
381 UPDATE requirement_spec_items SET item_type = 'section', parent_id = NULL WHERE requirement_spec_id = OLD.id;
383 RAISE DEBUG ' Deleting stuff for %', OLD.id;
385 DELETE FROM requirement_spec_text_blocks WHERE (requirement_spec_id = OLD.id);
386 DELETE FROM requirement_spec_items WHERE (requirement_spec_id = OLD.id);
387 DELETE FROM requirement_specs WHERE (working_copy_id = OLD.id);
389 RAISE DEBUG ' And we out for %', OLD.id;
395 DROP TRIGGER IF EXISTS delete_requirement_spec_dependencies ON requirement_specs;
396 CREATE TRIGGER delete_requirement_spec_dependencies
397 BEFORE DELETE ON requirement_specs
398 FOR EACH ROW EXECUTE PROCEDURE requirement_spec_delete_trigger();
400 DROP TRIGGER IF EXISTS after_delete_requirement_spec_dependencies ON requirement_specs;
401 CREATE TRIGGER after_delete_requirement_spec_dependencies
402 AFTER DELETE ON requirement_specs
403 FOR EACH ROW EXECUTE PROCEDURE requirement_spec_delete_trigger();
406 -- Add formats for section/function block numbers to defaults
407 ALTER TABLE defaults ADD COLUMN requirement_spec_section_number_format TEXT;
408 ALTER TABLE defaults ALTER COLUMN requirement_spec_section_number_format SET DEFAULT 'A00';
409 ALTER TABLE defaults ADD COLUMN requirement_spec_function_block_number_format TEXT;
410 ALTER TABLE defaults ALTER COLUMN requirement_spec_function_block_number_format SET DEFAULT 'FB000';
412 UPDATE defaults SET requirement_spec_section_number_format = 'A00';
413 UPDATE defaults SET requirement_spec_function_block_number_format = 'FB000';
415 ALTER TABLE defaults ALTER COLUMN requirement_spec_section_number_format SET NOT NULL;
416 ALTER TABLE defaults ALTER COLUMN requirement_spec_function_block_number_format SET NOT NULL;