56 lines
2.0 KiB
PL/PgSQL
56 lines
2.0 KiB
PL/PgSQL
-- Atomic insert that generates a unique task_number and inserts a task in one transaction
|
|
-- Returns: id (uuid), task_number (text)
|
|
|
|
CREATE OR REPLACE FUNCTION insert_task_with_number(
|
|
p_title text,
|
|
p_description text,
|
|
p_office_id text,
|
|
p_ticket_id text,
|
|
p_request_type text,
|
|
p_request_type_other text,
|
|
p_request_category text,
|
|
p_creator_id uuid
|
|
)
|
|
RETURNS TABLE(id uuid, task_number text)
|
|
LANGUAGE plpgsql
|
|
SECURITY DEFINER
|
|
AS $$
|
|
DECLARE
|
|
-- The numbering trigger on `tasks` will set `task_number` before insert.
|
|
-- This RPC inserts the task row and returns the resulting id and task_number.
|
|
BEGIN
|
|
-- atomically increment (or create) the month counter and use it as the task_number
|
|
INSERT INTO task_number_counters(year_month, counter)
|
|
VALUES (to_char(now(), 'YYYY-MM-'), 1)
|
|
ON CONFLICT (year_month) DO UPDATE
|
|
SET counter = task_number_counters.counter + 1
|
|
RETURNING counter INTO seq;
|
|
|
|
-- build the formatted task number
|
|
PERFORM seq; -- ensure seq is set
|
|
new_task_number := to_char(now(), 'YYYY-MM-') || lpad(seq::text, 5, '0');
|
|
|
|
INSERT INTO tasks(
|
|
title, description, office_id, ticket_id,
|
|
request_type, request_type_other, request_category,
|
|
creator_id, created_at, task_number
|
|
) VALUES (
|
|
p_title,
|
|
p_description,
|
|
CASE WHEN p_office_id IS NULL OR p_office_id = '' THEN NULL ELSE p_office_id::uuid END,
|
|
CASE WHEN p_ticket_id IS NULL OR p_ticket_id = '' THEN NULL ELSE p_ticket_id::uuid END,
|
|
CASE WHEN p_request_type IS NULL OR p_request_type = '' THEN NULL ELSE p_request_type::request_type END,
|
|
p_request_type_other,
|
|
CASE WHEN p_request_category IS NULL OR p_request_category = '' THEN NULL ELSE p_request_category::request_category END,
|
|
p_creator_id,
|
|
now(),
|
|
new_task_number
|
|
) RETURNING tasks.id, tasks.task_number INTO id, task_number;
|
|
|
|
RETURN NEXT;
|
|
END;
|
|
$$;
|
|
|
|
-- Grant execute to authenticated so client RPC can call it
|
|
GRANT EXECUTE ON FUNCTION insert_task_with_number(text,text,text,text,text,text,text,uuid) TO authenticated;
|