diff --git a/src/Application/Controller/XMLRPC/Handler.php b/src/Application/Controller/XMLRPC/Handler.php
index 2b36bc0..c49a5be 100644
--- a/src/Application/Controller/XMLRPC/Handler.php
+++ b/src/Application/Controller/XMLRPC/Handler.php
@@ -485,7 +485,7 @@ public function setCommenceTicketState($ticket_id) {
throw new Exception(__FUNCTION__.': ticket is not in initial state!',1304);
}
- $commenceState = ProjectTicketState::getCommenceState($ticket['project_id'], $ticket['ticket_type']);
+ $commenceState = ProjectTicketState::getCommenceState($ticket_id);
if(!$commenceState) {
throw new Exception(__FUNCTION__.': ticket has no commence state!',1305);
}
diff --git a/src/Application/Migrations/01_ticket_states.sql b/src/Application/Migrations/01_ticket_states.sql
index 6dc044c..571123b 100644
--- a/src/Application/Migrations/01_ticket_states.sql
+++ b/src/Application/Migrations/01_ticket_states.sql
@@ -78,59 +78,59 @@ CREATE TRIGGER increment_ticket_state_sort BEFORE INSERT ON tbl_ticket_state FOR
-- meta tickets
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('meta', 'staging', 0, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('meta', 'staged', 50, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('meta', 'closed', 50, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('meta', 'staging', 0, false, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('meta', 'staged', 50, false, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('meta', 'closed', 50, false, false);
-- recording tickets
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('recording', 'locked', 0, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('recording', 'scheduled', 5, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('recording', 'recording', 40, true);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('recording', 'recorded', 5, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('recording', 'preparing', 10, true);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('recording', 'prepared', 5, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('recording', 'cutting', 30, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('recording', 'cut', 5, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('recording', 'finalizing', 10, true);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('recording', 'finalized', 5, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('recording', 'ready to archive', 0, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('recording', 'archiving', 0, true);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('recording', 'archived', 0, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('recording', 'ready to remove', 0, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('recording', 'removing', 0, true);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('recording', 'gone', 0, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('recording', 'locked', 0, false, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('recording', 'scheduled', 5, false, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('recording', 'recording', 40, true, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('recording', 'recorded', 5, false, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('recording', 'preparing', 10, true, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('recording', 'prepared', 5, false, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('recording', 'cutting', 30, false, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('recording', 'cut', 5, false, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('recording', 'finalizing', 10, true, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('recording', 'finalized', 5, false, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('recording', 'ready to archive', 0, false, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('recording', 'archiving', 0, true, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('recording', 'archived', 0, false, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('recording', 'ready to remove', 0, false, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('recording', 'removing', 0, true, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('recording', 'gone', 0, false, false);
-- encoding tickets
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('encoding', 'material needed', 0, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('encoding', 'ready to encode', 5, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('encoding', 'encoding', 50, true);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('encoding', 'encoded', 5, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('encoding', 'postencoding', 10, true);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('encoding', 'postencoded', 5, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('encoding', 'checking', 20, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('encoding', 'checked', 5, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('encoding', 'postprocessing', 10, true);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('encoding', 'postprocessed', 5, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('encoding', 'ready to release', 5, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('encoding', 'releasing', 20, true);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('encoding', 'released', 5, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('encoding', 'ready to remove', 0, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('encoding', 'removing', 0, true);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('encoding', 'gone', 0, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('encoding', 'material needed', 0, false, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('encoding', 'ready to encode', 5, false, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('encoding', 'encoding', 50, true, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('encoding', 'encoded', 5, false, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('encoding', 'postencoding', 10, true, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('encoding', 'postencoded', 5, false, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('encoding', 'checking', 20, false, true);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('encoding', 'checked', 5, false, true);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('encoding', 'postprocessing', 10, true, true);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('encoding', 'postprocessed', 5, false, true);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('encoding', 'ready to release', 5, false, true);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('encoding', 'releasing', 20, true, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('encoding', 'released', 5, false, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('encoding', 'ready to remove', 0, false, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('encoding', 'removing', 0, true, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('encoding', 'gone', 0, false, false);
-- ingest tickets
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('ingest', 'incomplete', 0, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('ingest', 'ready to ingest', 5, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('ingest', 'ingesting', 50, true);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('ingest', 'ingested', 5, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('ingest', 'finalizing', 10, true);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('ingest', 'finalized', 5, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('ingest', 'ready to archive', 5, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('ingest', 'archiving', 30, true);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('ingest', 'archived', 5, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('ingest', 'ready to remove', 5, false);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('ingest', 'removing', 20, true);
-INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable) VALUES ('ingest', 'gone', 5, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('ingest', 'incomplete', 0, false, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('ingest', 'ready to ingest', 5, false, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('ingest', 'ingesting', 50, true, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('ingest', 'ingested', 5, false, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('ingest', 'finalizing', 10, true, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('ingest', 'finalized', 5, false, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('ingest', 'ready to archive', 5, false, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('ingest', 'archiving', 30, true, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('ingest', 'archived', 5, false, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('ingest', 'ready to remove', 5, false, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('ingest', 'removing', 20, true, false);
+INSERT INTO tbl_ticket_state (ticket_type, ticket_state, percent_progress, service_executable, skippable_on_dependent) VALUES ('ingest', 'gone', 5, false, false);
-- mark non-initial states by giving sort <= 0
UPDATE tbl_ticket_state SET sort = 0 where ticket_state = 'locked';
diff --git a/src/Application/Migrations/04_projects.sql b/src/Application/Migrations/04_projects.sql
index cd9037b..8326a34 100644
--- a/src/Application/Migrations/04_projects.sql
+++ b/src/Application/Migrations/04_projects.sql
@@ -50,6 +50,7 @@ CREATE TABLE tbl_project_ticket_state
ticket_type enum_ticket_type NOT NULL,
ticket_state enum_ticket_state NOT NULL,
service_executable boolean NOT NULL DEFAULT false,
+ skip_on_dependent boolean NOT NULL DEFAULT false,
CONSTRAINT tbl_project_ticket_state_pk PRIMARY KEY (project_id, ticket_type, ticket_state),
CONSTRAINT tbl_project_ticket_state_project_fk FOREIGN KEY (project_id)
REFERENCES tbl_project (id) MATCH SIMPLE
diff --git a/src/Application/Migrations/06_tickets.sql b/src/Application/Migrations/06_tickets.sql
index 9d70d57..3a25467 100644
--- a/src/Application/Migrations/06_tickets.sql
+++ b/src/Application/Migrations/06_tickets.sql
@@ -40,7 +40,7 @@ $BODY$
DECLARE
next_state record;
BEGIN
- next_state := ticket_state_next(NEW.project_id, NEW.ticket_type, NEW.ticket_state);
+ next_state := ticket_state_next(NEW.id, NEW.ticket_state);
NEW.ticket_state_next := next_state.ticket_state;
NEW.service_executable := next_state.service_executable;
@@ -95,7 +95,7 @@ $BODY$
(progress, ticket_state_next, service_executable)
= (tp, (n).ticket_state, (n).service_executable)
FROM (
- SELECT id, ticket_state_next(t2.project_id, t2.ticket_type, t2.ticket_state) AS n, ticket_progress(t2.id) as tp
+ SELECT id, ticket_state_next(t2.id) AS n, ticket_progress(t2.id) as tp
FROM tbl_ticket t2
WHERE t2.project_id = param_project_id AND param_project_id IS NOT NULL
) AS x
diff --git a/src/Application/Migrations/15_function_ticket_state.sql b/src/Application/Migrations/15_function_ticket_state.sql
index f72907e..61e9713 100644
--- a/src/Application/Migrations/15_function_ticket_state.sql
+++ b/src/Application/Migrations/15_function_ticket_state.sql
@@ -2,7 +2,7 @@ BEGIN;
SET ROLE TO postgres;
-CREATE OR REPLACE FUNCTION ticket_state_next(param_project_id bigint, param_ticket_type enum_ticket_type, param_ticket_state enum_ticket_state)
+CREATE OR REPLACE FUNCTION ticket_state_next(param_ticket_id bigint, param_ticket_state enum_ticket_state DEFAULT NULL)
RETURNS TABLE(ticket_state enum_ticket_state, service_executable boolean) AS
$$
DECLARE
@@ -11,26 +11,35 @@ BEGIN
SELECT
pts.ticket_state, pts.service_executable
FROM
- tbl_ticket_state ts1
+ tbl_ticket t
JOIN
- tbl_project_ticket_state pts ON pts.ticket_type = ts1.ticket_type AND pts.ticket_state = ts1.ticket_state
+ tbl_ticket_state ts_this ON ts_this.ticket_type = t.ticket_type AND ts_this.ticket_state = COALESCE(param_ticket_state, t.ticket_state)
JOIN
- tbl_ticket_state ts2 ON ts1.ticket_type = ts2.ticket_type AND ts1.sort > ts2.sort
+ tbl_project_ticket_state pts ON pts.project_id = t.project_id AND pts.ticket_type = t.ticket_type
+ JOIN
+ tbl_ticket_state ts_other ON ts_other.ticket_type = pts.ticket_type AND ts_other.ticket_state = pts.ticket_state
WHERE
- pts.project_id = param_project_id AND
- ts2.ticket_type = param_ticket_type AND
- ts2.ticket_state = param_ticket_state
- ORDER BY
- ts1.sort ASC
+ t.id = param_ticket_id AND
+ ts_other.sort > ts_this.sort AND
+ (pts.skip_on_dependent = FALSE OR
+ ( /* is master encoding ticket */
+ SELECT ep.depends_on
+ FROM tbl_ticket t
+ INNER JOIN tbl_encoding_profile_version epv ON epv.id = t.encoding_profile_version_id
+ INNER JOIN tbl_encoding_profile ep ON ep.id = epv.encoding_profile_id
+ WHERE t.id = param_ticket_id
+ ) IS NULL )
+ ORDER BY ts_other.sort ASC
LIMIT 1;
- IF NOT FOUND THEN
- RETURN QUERY SELECT NULL::enum_ticket_state, false;
- END IF;
+
+ IF NOT FOUND THEN
+ RETURN QUERY SELECT NULL::enum_ticket_state, false;
+ END IF;
END
$$
LANGUAGE plpgsql;
-CREATE OR REPLACE FUNCTION ticket_state_previous(param_project_id bigint, param_ticket_type enum_ticket_type, param_ticket_state enum_ticket_state)
+CREATE OR REPLACE FUNCTION ticket_state_previous(param_ticket_id bigint, param_ticket_state enum_ticket_state DEFAULT NULL)
RETURNS TABLE(ticket_state enum_ticket_state, service_executable boolean) AS
$$
DECLARE
@@ -39,21 +48,30 @@ BEGIN
SELECT
pts.ticket_state, pts.service_executable
FROM
- tbl_ticket_state ts1
+ tbl_ticket t
+ JOIN
+ tbl_ticket_state ts_this ON ts_this.ticket_type = t.ticket_type AND ts_this.ticket_state = COALESCE(param_ticket_state, t.ticket_state)
JOIN
- tbl_project_ticket_state pts ON pts.ticket_type = ts1.ticket_type AND pts.ticket_state = ts1.ticket_state
+ tbl_project_ticket_state pts ON pts.project_id = t.project_id AND pts.ticket_type = t.ticket_type
JOIN
- tbl_ticket_state ts2 ON ts1.ticket_type = ts2.ticket_type AND ts1.sort < ts2.sort
+ tbl_ticket_state ts_other ON ts_other.ticket_type = pts.ticket_type AND ts_other.ticket_state = pts.ticket_state
WHERE
- pts.project_id = param_project_id AND
- ts2.ticket_type = param_ticket_type AND
- ts2.ticket_state = param_ticket_state
- ORDER BY
- ts1.sort DESC
+ t.id = param_ticket_id AND
+ ts_other.sort < ts_this.sort AND
+ (pts.skip_on_dependent = FALSE OR
+ ( /* is master encoding ticket */
+ SELECT ep.depends_on
+ FROM tbl_ticket t
+ JOIN tbl_encoding_profile_version epv ON epv.id = t.encoding_profile_version_id
+ JOIN tbl_encoding_profile ep ON ep.id = epv.encoding_profile_id
+ WHERE t.id = param_ticket_id
+ ) IS NULL )
+ ORDER BY ts_other.sort DESC
LIMIT 1;
- IF NOT FOUND THEN
- RETURN QUERY SELECT NULL::enum_ticket_state, false;
- END IF;
+
+ IF NOT FOUND THEN
+ RETURN QUERY SELECT NULL::enum_ticket_state, false;
+ END IF;
END
$$
LANGUAGE plpgsql;
@@ -96,22 +114,31 @@ END
$$
LANGUAGE plpgsql;
-CREATE OR REPLACE FUNCTION ticket_state_commence(param_project_id bigint, param_ticket_type enum_ticket_type)
+CREATE OR REPLACE FUNCTION ticket_state_commence(param_ticket_id bigint)
RETURNS enum_ticket_state AS
$$
DECLARE
+ var_project_id bigint;
+ var_ticket_type enum_ticket_type;
ret enum_ticket_state;
next_state record;
BEGIN
+ SELECT
+ project_id, ticket_type INTO var_project_id, var_ticket_type
+ FROM
+ tbl_ticket t
+ WHERE
+ t.id = param_ticket_id;
+
-- special case: meta ticket, since it has no serviceable states
- IF param_ticket_type = 'meta' THEN
+ IF var_ticket_type = 'meta' THEN
RETURN 'staged'::enum_ticket_state;
END IF;
- ret := (SELECT ticket_state_initial(param_project_id, param_ticket_type));
+ ret := (SELECT ticket_state_initial(var_project_id, var_ticket_type));
WHILE ret IS NOT NULL LOOP
- SELECT * INTO next_state FROM ticket_state_next(param_project_id, param_ticket_type, ret);
+ SELECT * INTO next_state FROM ticket_state_next(param_ticket_id, ret);
IF NOT FOUND THEN
ret := NULL;
EXIT;
@@ -215,4 +242,4 @@ END
$$
LANGUAGE plpgsql;
-COMMIT;
\ No newline at end of file
+COMMIT;
diff --git a/src/Application/Migrations/__2019-09-29_skip_dependent.sql b/src/Application/Migrations/__2019-09-29_skip_dependent.sql
new file mode 100644
index 0000000..074819c
--- /dev/null
+++ b/src/Application/Migrations/__2019-09-29_skip_dependent.sql
@@ -0,0 +1,184 @@
+BEGIN;
+
+SET ROLE TO postgres;
+
+ALTER TABLE tbl_project_ticket_state
+ ADD COLUMN skip_on_dependent boolean NOT NULL DEFAULT false;
+
+ALTER TABLE tbl_ticket_state
+ ADD COLUMN skippable_on_dependent boolean NOT NULL DEFAULT false;
+
+
+UPDATE tbl_ticket_state
+SET skippable_on_dependent = true
+WHERE ticket_type = 'encoding'
+ AND ticket_state IN ('checking', 'checked', 'postprocessing', 'postprocessed', 'ready to release');
+
+DROP FUNCTION IF EXISTS ticket_state_next(bigint);
+DROP FUNCTION IF EXISTS ticket_state_next(bigint, enum_ticket_type);
+DROP FUNCTION IF EXISTS ticket_state_next(bigint, enum_ticket_type, enum_ticket_state);
+
+DROP FUNCTION IF EXISTS ticket_state_previous(bigint);
+DROP FUNCTION IF EXISTS ticket_state_previous(bigint, enum_ticket_type);
+DROP FUNCTION IF EXISTS ticket_state_previous(bigint, enum_ticket_type, enum_ticket_state);
+
+DROP FUNCTION IF EXISTS ticket_state_commence(bigint, enum_ticket_type);
+DROP FUNCTION IF EXISTS ticket_state_commence(bigint);
+
+
+CREATE OR REPLACE FUNCTION update_ticket_next_state()
+ RETURNS trigger AS
+$BODY$
+ DECLARE
+ next_state record;
+ BEGIN
+ next_state := ticket_state_next(NEW.id, NEW.ticket_state);
+
+ NEW.ticket_state_next := next_state.ticket_state;
+ NEW.service_executable := next_state.service_executable;
+
+ RETURN NEW;
+ END
+$BODY$
+LANGUAGE plpgsql VOLATILE;
+
+
+CREATE OR REPLACE FUNCTION update_all_tickets_progress_and_next_state(param_project_id bigint)
+ RETURNS VOID AS
+$BODY$
+ BEGIN
+
+ UPDATE tbl_ticket t SET
+ (progress, ticket_state_next, service_executable)
+ = (tp, (n).ticket_state, (n).service_executable)
+ FROM (
+ SELECT id, ticket_state_next(t2.id) AS n, ticket_progress(t2.id) as tp
+ FROM tbl_ticket t2
+ WHERE t2.project_id = param_project_id AND param_project_id IS NOT NULL
+ ) AS x
+ WHERE t.id = x.id;
+
+ END;
+$BODY$
+LANGUAGE plpgsql VOLATILE;
+
+
+CREATE OR REPLACE FUNCTION ticket_state_next(param_ticket_id bigint, param_ticket_state enum_ticket_state DEFAULT NULL)
+ RETURNS TABLE(ticket_state enum_ticket_state, service_executable boolean) AS
+ $$
+DECLARE
+BEGIN
+ RETURN QUERY
+ SELECT
+ pts.ticket_state, pts.service_executable
+ FROM
+ tbl_ticket t
+ JOIN
+ tbl_ticket_state ts_this ON ts_this.ticket_type = t.ticket_type AND ts_this.ticket_state = COALESCE(param_ticket_state, t.ticket_state)
+ JOIN
+ tbl_project_ticket_state pts ON pts.project_id = t.project_id AND pts.ticket_type = t.ticket_type
+ JOIN
+ tbl_ticket_state ts_other ON ts_other.ticket_type = pts.ticket_type AND ts_other.ticket_state = pts.ticket_state
+ WHERE
+ t.id = param_ticket_id AND
+ ts_other.sort > ts_this.sort AND
+ (pts.skip_on_dependent = FALSE OR
+ ( /* is master encoding ticket */
+ SELECT ep.depends_on
+ FROM tbl_ticket t
+ INNER JOIN tbl_encoding_profile_version epv ON epv.id = t.encoding_profile_version_id
+ INNER JOIN tbl_encoding_profile ep ON ep.id = epv.encoding_profile_id
+ WHERE t.id = param_ticket_id
+ ) IS NULL )
+ ORDER BY ts_other.sort ASC
+ LIMIT 1;
+
+ IF NOT FOUND THEN
+ RETURN QUERY SELECT NULL::enum_ticket_state, false;
+ END IF;
+END
+$$
+LANGUAGE plpgsql;
+
+CREATE OR REPLACE FUNCTION ticket_state_previous(param_ticket_id bigint, param_ticket_state enum_ticket_state DEFAULT NULL)
+ RETURNS TABLE(ticket_state enum_ticket_state, service_executable boolean) AS
+ $$
+DECLARE
+BEGIN
+ RETURN QUERY
+ SELECT
+ pts.ticket_state, pts.service_executable
+ FROM
+ tbl_ticket t
+ JOIN
+ tbl_ticket_state ts_this ON ts_this.ticket_type = t.ticket_type AND ts_this.ticket_state = COALESCE(param_ticket_state, t.ticket_state)
+ JOIN
+ tbl_project_ticket_state pts ON pts.project_id = t.project_id AND pts.ticket_type = t.ticket_type
+ JOIN
+ tbl_ticket_state ts_other ON ts_other.ticket_type = pts.ticket_type AND ts_other.ticket_state = pts.ticket_state
+ WHERE
+ t.id = param_ticket_id AND
+ ts_other.sort < ts_this.sort AND
+ (pts.skip_on_dependent = FALSE OR
+ ( /* is master encoding ticket */
+ SELECT ep.depends_on
+ FROM tbl_ticket t
+ JOIN tbl_encoding_profile_version epv ON epv.id = t.encoding_profile_version_id
+ JOIN tbl_encoding_profile ep ON ep.id = epv.encoding_profile_id
+ WHERE t.id = param_ticket_id
+ ) IS NULL )
+ ORDER BY ts_other.sort DESC
+ LIMIT 1;
+
+ IF NOT FOUND THEN
+ RETURN QUERY SELECT NULL::enum_ticket_state, false;
+ END IF;
+END
+$$
+LANGUAGE plpgsql;
+
+
+CREATE OR REPLACE FUNCTION ticket_state_commence(param_ticket_id bigint)
+ RETURNS enum_ticket_state AS
+$$
+DECLARE
+ var_project_id bigint;
+ var_ticket_type enum_ticket_type;
+ ret enum_ticket_state;
+ next_state record;
+BEGIN
+ SELECT
+ project_id, ticket_type INTO var_project_id, var_ticket_type
+ FROM
+ tbl_ticket t
+ WHERE
+ t.id = param_ticket_id;
+
+ -- special case: meta ticket, since it has no serviceable states
+ IF var_ticket_type = 'meta' THEN
+ RETURN 'staged'::enum_ticket_state;
+ END IF;
+
+ ret := (SELECT ticket_state_initial(var_project_id, var_ticket_type));
+
+ WHILE ret IS NOT NULL LOOP
+ SELECT * INTO next_state FROM ticket_state_next(param_ticket_id, ret);
+ IF NOT FOUND THEN
+ ret := NULL;
+ EXIT;
+ END IF;
+
+ -- exit, if serviceable state is found
+ EXIT WHEN next_state.service_executable IS TRUE;
+
+ -- otherwise set current state as possible commence state
+ ret := next_state.ticket_state;
+ END LOOP;
+
+ RETURN ret;
+END
+$$
+LANGUAGE plpgsql;
+
+
+COMMIT;
diff --git a/src/Application/Model/ProjectTicketState.php b/src/Application/Model/ProjectTicketState.php
index 89226f9..3e55781 100644
--- a/src/Application/Model/ProjectTicketState.php
+++ b/src/Application/Model/ProjectTicketState.php
@@ -20,31 +20,10 @@ class ProjectTicketState extends Model {
]
];
- // TODO: use Ticket::queryNextState / queryPreviousState?
- public static function getNextState($project, $type, $state) {
+ public static function getCommenceState($ticket) {
$handle = Database::$Instance->query(
- 'SELECT * FROM ticket_state_next(?, ?, ?)',
- [$project, $type, $state]
- );
- $row = $handle->fetch();
-
- return ($row === false)? null : $row;
- }
-
- public static function getPreviousState($project, $type, $state) {
- $handle = Database::$Instance->query(
- 'SELECT * FROM ticket_state_previous(?, ?, ?)',
- [$project, $type, $state]
- );
-
- $row = $handle->fetch();
- return ($row === false)? null : $row;
- }
-
- public static function getCommenceState($project, $type) {
- $handle = Database::$Instance->query(
- 'SELECT ticket_state_commence(?, ?)',
- [$project, $type]
+ 'SELECT ticket_state_commence(?)',
+ [$ticket]
);
return $handle->fetch()['ticket_state_commence'];
diff --git a/src/Application/Model/Ticket.php b/src/Application/Model/Ticket.php
index 2678f1f..29d1e7a 100644
--- a/src/Application/Model/Ticket.php
+++ b/src/Application/Model/Ticket.php
@@ -904,13 +904,9 @@ public function queryPreviousState($state = null) {
return (new Database_Query(''))
->select('ticket_state')
->from(
- 'ticket_state_previous(?, ?, ?)',
+ 'ticket_state_previous(?)',
'previous_state',
- [
- $this['project_id'],
- $this['ticket_type'],
- ($state === null)? $this['ticket_state'] : $state
- ]
+ [$this['id']]
);
}
@@ -918,16 +914,12 @@ public function queryNextState($state = null) {
return (new Database_Query(''))
->select('ticket_state')
->from(
- 'ticket_state_next(?, ?, ?)',
+ 'ticket_state_next(?)',
'next_state',
- [
- $this['project_id'],
- $this['ticket_type'],
- ($state === null)? $this['ticket_state'] : $state
- ]
+ [$this['id']]
);
}
-
+
public function findNextForAction($state) {
$next = null;
diff --git a/src/Application/Model/TicketState.php b/src/Application/Model/TicketState.php
index 8d195cb..dccc0f7 100644
--- a/src/Application/Model/TicketState.php
+++ b/src/Application/Model/TicketState.php
@@ -9,7 +9,9 @@ class TicketState extends Model {
public $hasOne = [
'ProjectTicketState' => [
'foreign_key' => ['ticket_type', 'ticket_state'],
- 'select' => '(ticket_state IS NOT NULL) AS project_enabled, service_executable AS project_service_executable'
+ 'select' => '(ticket_state IS NOT NULL) AS project_enabled,' .
+ 'service_executable AS project_service_executable,' .
+ 'skip_on_dependent AS project_skip_on_dependent'
]
];
diff --git a/src/Application/View/projects/settings/states.html.php b/src/Application/View/projects/settings/states.html.php
index 4b231c7..6a7b3fa 100644
--- a/src/Application/View/projects/settings/states.html.php
+++ b/src/Application/View/projects/settings/states.html.php
@@ -2,7 +2,7 @@
= $this->render('projects/settings/_header'); ?>
+$first = false; ?>
= $f = $stateForm(['disabled' => $project['read_only']]); ?>
@@ -17,54 +17,74 @@
$encodingStates, (!empty($project))? $project['dependee_ticket_trigger_state'] : null) ?>
- $state): ?>
- 1):
- $typeRows = 0; ?>
-
-
-
-
-
-
-
-
- Type |
- State |
- Service |
-
-
-
-
+
+
+
- = h(mb_ucfirst($type)); ?> |
-
+ Type |
+ State |
+ Service |
+
+
+
+ $state) {
+ if ($state['ticket_type'] === 'encoding') {
+ continue;
+ }
+
+ if ($type !== $state['ticket_type']) {
+ $type = $state['ticket_type'];
+ $first = true;
+ } else {
+ $first = false;
+ }
+
+
+ echo $this->render('projects/settings/states/_state', [
+ 'f' => $f,
+ 'first' => $first,
+ 'index' => $index,
+ 'state' => $state
+ ]);
+ } ?>
+
+
+
+
+
+
- |
-
- =
- $f->checkbox(
- 'States[' . $index . '][ticket_state]',
- $state['ticket_state'],
- $state['project_enabled'],
- ['value' => $state['ticket_state']] +
- (($state['project_enabled'])?
- ['data-association-destroy' => 'States[' . $index . '][_destroy]'] :
- []),
- false
- ) .
- $f->hidden('States[' . $index . '][ticket_type]', $state['ticket_type']);
- ?> |
- checkbox('States[' . $index . '][service_executable]', null, $state['project_service_executable'], [], false);
- } ?> |
-
- register('States[' . $index . '][_destroy]'); ?>
-
+ Type |
+ State |
+ Service |
+
+ Skip
+ |
+
+
+
+ $state) {
+ if ($state['ticket_type'] !== 'encoding') {
+ continue;
+ }
+
+ if ($type !== $state['ticket_type']) {
+ $type = $state['ticket_type'];
+ $first = true;
+ } else {
+ $first = false;
+ }
+
+
+ echo $this->render('projects/settings/states/_state', [
+ 'f' => $f,
+ 'first' => $first,
+ 'index' => $index,
+ 'state' => $state,
+ 'skip' => true
+ ]);
+ } ?>
diff --git a/src/Application/View/projects/settings/states/_state.html.php b/src/Application/View/projects/settings/states/_state.html.php
new file mode 100644
index 0000000..b8a1f41
--- /dev/null
+++ b/src/Application/View/projects/settings/states/_state.html.php
@@ -0,0 +1,30 @@
+
+
+ = h(mb_ucfirst($state['ticket_type'])); ?> |
+
+
+ |
+
+ =
+ $f->checkbox(
+ 'States[' . $index . '][ticket_state]',
+ $state['ticket_state'],
+ $state['project_enabled'],
+ ['value' => $state['ticket_state']] +
+ (($state['project_enabled'])?
+ ['data-association-destroy' => 'States[' . $index . '][_destroy]'] :
+ []),
+ false
+ ) .
+ $f->hidden('States[' . $index . '][ticket_type]', $state['ticket_type']);
+ ?> |
+ checkbox('States[' . $index . '][service_executable]', null, $state['project_service_executable'], [], false);
+ } ?> |
+
+ checkbox('States[' . $index . '][skip_on_dependent]', null, $state['project_skip_on_dependent'], ['title' => 'This state will be skipped in dependent encoding profiles'], false);
+ } ?> |
+
+
+register('States[' . $index . '][_destroy]'); ?>