feat(task): add progress mode handling and update related functions
Introduce a new `progress_mode` field to tasks and projects to support different progress calculation methods (manual, weighted, time, default). Update database migrations, task progress calculation functions, and related handlers to accommodate these changes. This ensures consistent progress tracking across different project management needs. The changes include: - Adding `progress_mode` to the `tasks` table. - Updating progress calculation functions to respect the selected mode. - Adding triggers to reset progress values when the project's progress mode changes. - Enhancing documentation to explain the default progress method.
This commit is contained in:
@@ -1,9 +1,21 @@
|
|||||||
# WorkLenz Task Progress Guide for Users
|
# WorkLenz Task Progress Guide for Users
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
WorkLenz offers three different ways to track and calculate task progress, each designed for different project management needs. This guide explains how each method works and when to use them.
|
WorkLenz offers three different ways to track and calculate task progress, each designed for different project management needs. This guide explains how each method works and when to use them.
|
||||||
|
|
||||||
|
## Default Progress Method
|
||||||
|
|
||||||
|
WorkLenz uses a simple completion-based approach as the default progress calculation method. This method is applied when no special progress methods are enabled.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
If you have a parent task with four subtasks and two of the subtasks are marked complete:
|
||||||
|
- Parent task: Not done
|
||||||
|
- 2 subtasks: Done
|
||||||
|
- 2 subtasks: Not done
|
||||||
|
|
||||||
|
The parent task will show as 40% complete (2 completed out of 5 total tasks).
|
||||||
|
|
||||||
## Available Progress Tracking Methods
|
## Available Progress Tracking Methods
|
||||||
|
|
||||||
WorkLenz provides these progress tracking methods:
|
WorkLenz provides these progress tracking methods:
|
||||||
@@ -150,10 +162,6 @@ The parent task would be approximately 29% complete.
|
|||||||
|
|
||||||
This demonstrates how tasks with longer time estimates (like Subtask C) have more influence on the overall progress calculation. Even though Subtask B is 80% complete, its shorter time estimate means it contributes less to the overall progress than the partially-completed but longer Subtask A.
|
This demonstrates how tasks with longer time estimates (like Subtask C) have more influence on the overall progress calculation. Even though Subtask B is 80% complete, its shorter time estimate means it contributes less to the overall progress than the partially-completed but longer Subtask A.
|
||||||
|
|
||||||
## Default Progress Method
|
|
||||||
|
|
||||||
If none of the special progress methods are enabled, WorkLenz uses a simple completion-based approach:
|
|
||||||
|
|
||||||
### How It Works
|
### How It Works
|
||||||
|
|
||||||
- Tasks are either 0% (not done) or 100% (done)
|
- Tasks are either 0% (not done) or 100% (done)
|
||||||
|
|||||||
@@ -0,0 +1,150 @@
|
|||||||
|
-- Migration: Update socket event handlers to set progress-mode handlers
|
||||||
|
-- Date: 2025-04-26
|
||||||
|
-- Version: 1.0.0
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
-- Create ENUM type for progress modes
|
||||||
|
CREATE TYPE progress_mode_type AS ENUM ('manual', 'weighted', 'time', 'default');
|
||||||
|
|
||||||
|
-- Alter tasks table to use ENUM type
|
||||||
|
ALTER TABLE tasks
|
||||||
|
ALTER COLUMN progress_mode TYPE progress_mode_type
|
||||||
|
USING progress_mode::text::progress_mode_type;
|
||||||
|
|
||||||
|
-- Update the on_update_task_progress function to set progress_mode
|
||||||
|
CREATE OR REPLACE FUNCTION on_update_task_progress(_body json) RETURNS json
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
AS
|
||||||
|
$$
|
||||||
|
DECLARE
|
||||||
|
_task_id UUID;
|
||||||
|
_progress_value INTEGER;
|
||||||
|
_parent_task_id UUID;
|
||||||
|
_project_id UUID;
|
||||||
|
_current_mode progress_mode_type;
|
||||||
|
BEGIN
|
||||||
|
_task_id = (_body ->> 'task_id')::UUID;
|
||||||
|
_progress_value = (_body ->> 'progress_value')::INTEGER;
|
||||||
|
_parent_task_id = (_body ->> 'parent_task_id')::UUID;
|
||||||
|
|
||||||
|
-- Get the project ID and determine the current progress mode
|
||||||
|
SELECT project_id INTO _project_id FROM tasks WHERE id = _task_id;
|
||||||
|
|
||||||
|
IF _project_id IS NOT NULL THEN
|
||||||
|
SELECT
|
||||||
|
CASE
|
||||||
|
WHEN use_manual_progress IS TRUE THEN 'manual'
|
||||||
|
WHEN use_weighted_progress IS TRUE THEN 'weighted'
|
||||||
|
WHEN use_time_progress IS TRUE THEN 'time'
|
||||||
|
ELSE 'default'
|
||||||
|
END
|
||||||
|
INTO _current_mode
|
||||||
|
FROM projects
|
||||||
|
WHERE id = _project_id;
|
||||||
|
ELSE
|
||||||
|
_current_mode := 'default';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- Update the task with progress value and set the progress mode
|
||||||
|
UPDATE tasks
|
||||||
|
SET progress_value = _progress_value,
|
||||||
|
manual_progress = TRUE,
|
||||||
|
progress_mode = _current_mode,
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE id = _task_id;
|
||||||
|
|
||||||
|
-- Return the updated task info
|
||||||
|
RETURN JSON_BUILD_OBJECT(
|
||||||
|
'task_id', _task_id,
|
||||||
|
'progress_value', _progress_value,
|
||||||
|
'progress_mode', _current_mode
|
||||||
|
);
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
-- Update the on_update_task_weight function to set progress_mode when weight is updated
|
||||||
|
CREATE OR REPLACE FUNCTION on_update_task_weight(_body json) RETURNS json
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
AS
|
||||||
|
$$
|
||||||
|
DECLARE
|
||||||
|
_task_id UUID;
|
||||||
|
_weight INTEGER;
|
||||||
|
_parent_task_id UUID;
|
||||||
|
_project_id UUID;
|
||||||
|
BEGIN
|
||||||
|
_task_id = (_body ->> 'task_id')::UUID;
|
||||||
|
_weight = (_body ->> 'weight')::INTEGER;
|
||||||
|
_parent_task_id = (_body ->> 'parent_task_id')::UUID;
|
||||||
|
|
||||||
|
-- Get the project ID
|
||||||
|
SELECT project_id INTO _project_id FROM tasks WHERE id = _task_id;
|
||||||
|
|
||||||
|
-- Update the task with weight value and set progress_mode to 'weighted'
|
||||||
|
UPDATE tasks
|
||||||
|
SET weight = _weight,
|
||||||
|
progress_mode = 'weighted',
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE id = _task_id;
|
||||||
|
|
||||||
|
-- Return the updated task info
|
||||||
|
RETURN JSON_BUILD_OBJECT(
|
||||||
|
'task_id', _task_id,
|
||||||
|
'weight', _weight
|
||||||
|
);
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
-- Create a function to reset progress values when switching project progress modes
|
||||||
|
CREATE OR REPLACE FUNCTION reset_project_progress_values() RETURNS TRIGGER
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
AS
|
||||||
|
$$
|
||||||
|
DECLARE
|
||||||
|
_old_mode progress_mode_type;
|
||||||
|
_new_mode progress_mode_type;
|
||||||
|
_project_id UUID;
|
||||||
|
BEGIN
|
||||||
|
_project_id := NEW.id;
|
||||||
|
|
||||||
|
-- Determine old and new modes
|
||||||
|
_old_mode :=
|
||||||
|
CASE
|
||||||
|
WHEN OLD.use_manual_progress IS TRUE THEN 'manual'
|
||||||
|
WHEN OLD.use_weighted_progress IS TRUE THEN 'weighted'
|
||||||
|
WHEN OLD.use_time_progress IS TRUE THEN 'time'
|
||||||
|
ELSE 'default'
|
||||||
|
END;
|
||||||
|
|
||||||
|
_new_mode :=
|
||||||
|
CASE
|
||||||
|
WHEN NEW.use_manual_progress IS TRUE THEN 'manual'
|
||||||
|
WHEN NEW.use_weighted_progress IS TRUE THEN 'weighted'
|
||||||
|
WHEN NEW.use_time_progress IS TRUE THEN 'time'
|
||||||
|
ELSE 'default'
|
||||||
|
END;
|
||||||
|
|
||||||
|
-- If mode has changed, reset progress values for tasks with the old mode
|
||||||
|
IF _old_mode <> _new_mode THEN
|
||||||
|
-- Reset progress values for tasks that were set in the old mode
|
||||||
|
UPDATE tasks
|
||||||
|
SET progress_value = NULL,
|
||||||
|
progress_mode = NULL
|
||||||
|
WHERE project_id = _project_id
|
||||||
|
AND progress_mode = _old_mode;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
-- Create trigger to reset progress values when project progress mode changes
|
||||||
|
DROP TRIGGER IF EXISTS reset_progress_on_mode_change ON projects;
|
||||||
|
CREATE TRIGGER reset_progress_on_mode_change
|
||||||
|
AFTER UPDATE OF use_manual_progress, use_weighted_progress, use_time_progress
|
||||||
|
ON projects
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE FUNCTION reset_project_progress_values();
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
@@ -1,19 +1,29 @@
|
|||||||
BEGIN;
|
BEGIN;
|
||||||
|
|
||||||
|
-- Create ENUM type for progress modes
|
||||||
|
CREATE TYPE PROGRESS_MODE_TYPE AS ENUM ('manual', 'weighted', 'time', 'default');
|
||||||
|
|
||||||
|
-- Alter tasks table to use ENUM type
|
||||||
|
ALTER TABLE tasks
|
||||||
|
ADD COLUMN IF NOT EXISTS manual_progress BOOLEAN DEFAULT FALSE,
|
||||||
|
ADD COLUMN IF NOT EXISTS progress_value INTEGER DEFAULT NULL,
|
||||||
|
ADD COLUMN IF NOT EXISTS progress_mode PROGRESS_MODE_TYPE DEFAULT 'default',
|
||||||
|
ADD COLUMN IF NOT EXISTS weight INTEGER DEFAULT NULL;
|
||||||
|
|
||||||
-- Add manual progress fields to tasks table
|
-- Add manual progress fields to tasks table
|
||||||
ALTER TABLE tasks
|
ALTER TABLE tasks
|
||||||
ADD COLUMN IF NOT EXISTS manual_progress BOOLEAN DEFAULT FALSE,
|
ADD COLUMN IF NOT EXISTS manual_progress BOOLEAN DEFAULT FALSE,
|
||||||
ADD COLUMN IF NOT EXISTS progress_value INTEGER DEFAULT NULL,
|
ADD COLUMN IF NOT EXISTS progress_value INTEGER DEFAULT NULL,
|
||||||
ADD COLUMN IF NOT EXISTS weight INTEGER DEFAULT NULL;
|
ADD COLUMN IF NOT EXISTS weight INTEGER DEFAULT NULL;
|
||||||
|
|
||||||
-- Add progress-related fields to projects table
|
-- Add progress-related fields to projects table
|
||||||
ALTER TABLE projects
|
ALTER TABLE projects
|
||||||
ADD COLUMN IF NOT EXISTS use_manual_progress BOOLEAN DEFAULT FALSE,
|
ADD COLUMN IF NOT EXISTS use_manual_progress BOOLEAN DEFAULT FALSE,
|
||||||
ADD COLUMN IF NOT EXISTS use_weighted_progress BOOLEAN DEFAULT FALSE,
|
ADD COLUMN IF NOT EXISTS use_weighted_progress BOOLEAN DEFAULT FALSE,
|
||||||
ADD COLUMN IF NOT EXISTS use_time_progress BOOLEAN DEFAULT FALSE;
|
ADD COLUMN IF NOT EXISTS use_time_progress BOOLEAN DEFAULT FALSE;
|
||||||
|
|
||||||
-- Update function to consider manual progress
|
-- Update function to consider manual progress
|
||||||
CREATE OR REPLACE FUNCTION get_task_complete_ratio(_task_id uuid) RETURNS json
|
CREATE OR REPLACE FUNCTION get_task_complete_ratio(_task_id UUID) RETURNS JSON
|
||||||
LANGUAGE plpgsql
|
LANGUAGE plpgsql
|
||||||
AS
|
AS
|
||||||
$$
|
$$
|
||||||
@@ -38,7 +48,8 @@ BEGIN
|
|||||||
INTO _is_manual, _manual_value, _project_id;
|
INTO _is_manual, _manual_value, _project_id;
|
||||||
|
|
||||||
-- Check if the project uses manual progress
|
-- Check if the project uses manual progress
|
||||||
IF _project_id IS NOT NULL THEN
|
IF _project_id IS NOT NULL
|
||||||
|
THEN
|
||||||
SELECT COALESCE(use_manual_progress, FALSE),
|
SELECT COALESCE(use_manual_progress, FALSE),
|
||||||
COALESCE(use_weighted_progress, FALSE),
|
COALESCE(use_weighted_progress, FALSE),
|
||||||
COALESCE(use_time_progress, FALSE)
|
COALESCE(use_time_progress, FALSE)
|
||||||
@@ -48,7 +59,8 @@ BEGIN
|
|||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- If manual progress is enabled and has a value, use it directly
|
-- If manual progress is enabled and has a value, use it directly
|
||||||
IF _is_manual IS TRUE AND _manual_value IS NOT NULL THEN
|
IF _is_manual IS TRUE AND _manual_value IS NOT NULL
|
||||||
|
THEN
|
||||||
RETURN JSON_BUILD_OBJECT(
|
RETURN JSON_BUILD_OBJECT(
|
||||||
'ratio', _manual_value,
|
'ratio', _manual_value,
|
||||||
'total_completed', 0,
|
'total_completed', 0,
|
||||||
@@ -76,7 +88,8 @@ BEGIN
|
|||||||
_total_completed = _parent_task_done + _sub_tasks_done;
|
_total_completed = _parent_task_done + _sub_tasks_done;
|
||||||
_total_tasks = _sub_tasks_count; -- +1 for the parent task
|
_total_tasks = _sub_tasks_count; -- +1 for the parent task
|
||||||
|
|
||||||
IF _total_tasks > 0 THEN
|
IF _total_tasks > 0
|
||||||
|
THEN
|
||||||
_ratio = (_total_completed / _total_tasks) * 100;
|
_ratio = (_total_completed / _total_tasks) * 100;
|
||||||
ELSE
|
ELSE
|
||||||
_ratio = _parent_task_done * 100;
|
_ratio = _parent_task_done * 100;
|
||||||
@@ -92,7 +105,7 @@ END
|
|||||||
$$;
|
$$;
|
||||||
|
|
||||||
-- Update project functions to handle progress-related fields
|
-- Update project functions to handle progress-related fields
|
||||||
CREATE OR REPLACE FUNCTION update_project(_body json) RETURNS json
|
CREATE OR REPLACE FUNCTION update_project(_body JSON) RETURNS JSON
|
||||||
LANGUAGE plpgsql
|
LANGUAGE plpgsql
|
||||||
AS
|
AS
|
||||||
$$
|
$$
|
||||||
@@ -124,10 +137,11 @@ BEGIN
|
|||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- check whether the project name is already in
|
-- check whether the project name is already in
|
||||||
IF EXISTS(
|
IF EXISTS(SELECT name
|
||||||
SELECT name FROM projects WHERE LOWER(name) = LOWER(_project_name)
|
FROM projects
|
||||||
AND team_id = _team_id AND id != (_body ->> 'id')::UUID
|
WHERE LOWER(name) = LOWER(_project_name)
|
||||||
)
|
AND team_id = _team_id
|
||||||
|
AND id != (_body ->> 'id')::UUID)
|
||||||
THEN
|
THEN
|
||||||
RAISE 'PROJECT_EXISTS_ERROR:%', _project_name;
|
RAISE 'PROJECT_EXISTS_ERROR:%', _project_name;
|
||||||
END IF;
|
END IF;
|
||||||
@@ -156,7 +170,9 @@ BEGIN
|
|||||||
AND team_id = _team_id
|
AND team_id = _team_id
|
||||||
RETURNING id INTO _project_id;
|
RETURNING id INTO _project_id;
|
||||||
|
|
||||||
UPDATE project_members SET project_access_level_id = (SELECT id FROM project_access_levels WHERE key = 'MEMBER') WHERE project_id = _project_id;
|
UPDATE project_members
|
||||||
|
SET project_access_level_id = (SELECT id FROM project_access_levels WHERE key = 'MEMBER')
|
||||||
|
WHERE project_id = _project_id;
|
||||||
|
|
||||||
IF NOT (_project_manager_team_member_id IS NULL)
|
IF NOT (_project_manager_team_member_id IS NULL)
|
||||||
THEN
|
THEN
|
||||||
@@ -171,7 +187,7 @@ BEGIN
|
|||||||
END;
|
END;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION create_project(_body json) RETURNS json
|
CREATE OR REPLACE FUNCTION create_project(_body JSON) RETURNS JSON
|
||||||
LANGUAGE plpgsql
|
LANGUAGE plpgsql
|
||||||
AS
|
AS
|
||||||
$$
|
$$
|
||||||
@@ -217,7 +233,8 @@ BEGIN
|
|||||||
|
|
||||||
-- create the project
|
-- create the project
|
||||||
INSERT
|
INSERT
|
||||||
INTO projects (name, key, color_code, start_date, end_date, team_id, notes, owner_id, status_id, health_id, folder_id,
|
INTO projects (name, key, color_code, start_date, end_date, team_id, notes, owner_id, status_id, health_id,
|
||||||
|
folder_id,
|
||||||
category_id, estimated_working_days, estimated_man_days, hours_per_day,
|
category_id, estimated_working_days, estimated_man_days, hours_per_day,
|
||||||
use_manual_progress, use_weighted_progress, use_time_progress, client_id)
|
use_manual_progress, use_weighted_progress, use_time_progress, client_id)
|
||||||
VALUES (_project_name,
|
VALUES (_project_name,
|
||||||
@@ -264,7 +281,8 @@ BEGIN
|
|||||||
PERFORM insert_task_list_columns(_project_id);
|
PERFORM insert_task_list_columns(_project_id);
|
||||||
|
|
||||||
-- add project manager role if exists
|
-- add project manager role if exists
|
||||||
IF NOT is_null_or_empty(_project_manager_team_member_id) THEN
|
IF NOT is_null_or_empty(_project_manager_team_member_id)
|
||||||
|
THEN
|
||||||
PERFORM update_project_manager(_project_manager_team_member_id, _project_id);
|
PERFORM update_project_manager(_project_manager_team_member_id, _project_id);
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
@@ -280,8 +298,152 @@ COMMIT;
|
|||||||
|
|
||||||
BEGIN;
|
BEGIN;
|
||||||
|
|
||||||
-- Update function to use time-based progress for all tasks
|
-- Update the on_update_task_progress function to set progress_mode
|
||||||
CREATE OR REPLACE FUNCTION get_task_complete_ratio(_task_id uuid) RETURNS json
|
CREATE OR REPLACE FUNCTION on_update_task_progress(_body JSON) RETURNS JSON
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
AS
|
||||||
|
$$
|
||||||
|
DECLARE
|
||||||
|
_task_id UUID;
|
||||||
|
_progress_value INTEGER;
|
||||||
|
_parent_task_id UUID;
|
||||||
|
_project_id UUID;
|
||||||
|
_current_mode VARCHAR(20);
|
||||||
|
BEGIN
|
||||||
|
_task_id = (_body ->> 'task_id')::UUID;
|
||||||
|
_progress_value = (_body ->> 'progress_value')::INTEGER;
|
||||||
|
_parent_task_id = (_body ->> 'parent_task_id')::UUID;
|
||||||
|
|
||||||
|
-- Get the project ID and determine the current progress mode
|
||||||
|
SELECT project_id INTO _project_id FROM tasks WHERE id = _task_id;
|
||||||
|
|
||||||
|
IF _project_id IS NOT NULL
|
||||||
|
THEN
|
||||||
|
SELECT CASE
|
||||||
|
WHEN use_manual_progress IS TRUE THEN 'manual'
|
||||||
|
WHEN use_weighted_progress IS TRUE THEN 'weighted'
|
||||||
|
WHEN use_time_progress IS TRUE THEN 'time'
|
||||||
|
ELSE 'default'
|
||||||
|
END
|
||||||
|
INTO _current_mode
|
||||||
|
FROM projects
|
||||||
|
WHERE id = _project_id;
|
||||||
|
ELSE
|
||||||
|
_current_mode := 'default';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- Update the task with progress value and set the progress mode
|
||||||
|
UPDATE tasks
|
||||||
|
SET progress_value = _progress_value,
|
||||||
|
manual_progress = TRUE,
|
||||||
|
progress_mode = _current_mode,
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE id = _task_id;
|
||||||
|
|
||||||
|
-- Return the updated task info
|
||||||
|
RETURN JSON_BUILD_OBJECT(
|
||||||
|
'task_id', _task_id,
|
||||||
|
'progress_value', _progress_value,
|
||||||
|
'progress_mode', _current_mode
|
||||||
|
);
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
-- Update the on_update_task_weight function to set progress_mode when weight is updated
|
||||||
|
CREATE OR REPLACE FUNCTION on_update_task_weight(_body JSON) RETURNS JSON
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
AS
|
||||||
|
$$
|
||||||
|
DECLARE
|
||||||
|
_task_id UUID;
|
||||||
|
_weight INTEGER;
|
||||||
|
_parent_task_id UUID;
|
||||||
|
_project_id UUID;
|
||||||
|
BEGIN
|
||||||
|
_task_id = (_body ->> 'task_id')::UUID;
|
||||||
|
_weight = (_body ->> 'weight')::INTEGER;
|
||||||
|
_parent_task_id = (_body ->> 'parent_task_id')::UUID;
|
||||||
|
|
||||||
|
-- Get the project ID
|
||||||
|
SELECT project_id INTO _project_id FROM tasks WHERE id = _task_id;
|
||||||
|
|
||||||
|
-- Update the task with weight value and set progress_mode to 'weighted'
|
||||||
|
UPDATE tasks
|
||||||
|
SET weight = _weight,
|
||||||
|
progress_mode = 'weighted',
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE id = _task_id;
|
||||||
|
|
||||||
|
-- Return the updated task info
|
||||||
|
RETURN JSON_BUILD_OBJECT(
|
||||||
|
'task_id', _task_id,
|
||||||
|
'weight', _weight
|
||||||
|
);
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
-- Create a function to reset progress values when switching project progress modes
|
||||||
|
CREATE OR REPLACE FUNCTION reset_project_progress_values() RETURNS TRIGGER
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
AS
|
||||||
|
$$
|
||||||
|
DECLARE
|
||||||
|
_old_mode VARCHAR(20);
|
||||||
|
_new_mode VARCHAR(20);
|
||||||
|
_project_id UUID;
|
||||||
|
BEGIN
|
||||||
|
_project_id := NEW.id;
|
||||||
|
|
||||||
|
-- Determine old and new modes
|
||||||
|
_old_mode :=
|
||||||
|
CASE
|
||||||
|
WHEN OLD.use_manual_progress IS TRUE THEN 'manual'
|
||||||
|
WHEN OLD.use_weighted_progress IS TRUE THEN 'weighted'
|
||||||
|
WHEN OLD.use_time_progress IS TRUE THEN 'time'
|
||||||
|
ELSE 'default'
|
||||||
|
END;
|
||||||
|
|
||||||
|
_new_mode :=
|
||||||
|
CASE
|
||||||
|
WHEN NEW.use_manual_progress IS TRUE THEN 'manual'
|
||||||
|
WHEN NEW.use_weighted_progress IS TRUE THEN 'weighted'
|
||||||
|
WHEN NEW.use_time_progress IS TRUE THEN 'time'
|
||||||
|
ELSE 'default'
|
||||||
|
END;
|
||||||
|
|
||||||
|
-- If mode has changed, reset progress values for tasks with the old mode
|
||||||
|
IF _old_mode <> _new_mode
|
||||||
|
THEN
|
||||||
|
-- Reset progress values for tasks that were set in the old mode
|
||||||
|
UPDATE tasks
|
||||||
|
SET progress_value = NULL,
|
||||||
|
progress_mode = NULL
|
||||||
|
WHERE project_id = _project_id
|
||||||
|
AND progress_mode = _old_mode;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
-- Create trigger to reset progress values when project progress mode changes
|
||||||
|
DROP TRIGGER IF EXISTS reset_progress_on_mode_change ON projects;
|
||||||
|
CREATE TRIGGER reset_progress_on_mode_change
|
||||||
|
AFTER UPDATE OF use_manual_progress, use_weighted_progress, use_time_progress
|
||||||
|
ON projects
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE FUNCTION reset_project_progress_values();
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
-- Add progress_mode column to tasks table to track which mode the progress was set in
|
||||||
|
ALTER TABLE tasks
|
||||||
|
ADD COLUMN IF NOT EXISTS progress_mode VARCHAR(20) DEFAULT NULL;
|
||||||
|
|
||||||
|
-- Update function to use time-based progress for all tasks and respect mode changes
|
||||||
|
CREATE OR REPLACE FUNCTION get_task_complete_ratio(_task_id UUID) RETURNS JSON
|
||||||
LANGUAGE plpgsql
|
LANGUAGE plpgsql
|
||||||
AS
|
AS
|
||||||
$$
|
$$
|
||||||
@@ -299,21 +461,24 @@ DECLARE
|
|||||||
_use_weighted_progress BOOLEAN = FALSE;
|
_use_weighted_progress BOOLEAN = FALSE;
|
||||||
_use_time_progress BOOLEAN = FALSE;
|
_use_time_progress BOOLEAN = FALSE;
|
||||||
_task_complete BOOLEAN = FALSE;
|
_task_complete BOOLEAN = FALSE;
|
||||||
|
_progress_mode VARCHAR(20) = NULL;
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Check if manual progress is set for this task
|
-- Check if manual progress is set for this task
|
||||||
SELECT manual_progress, progress_value, project_id,
|
SELECT manual_progress,
|
||||||
EXISTS(
|
progress_value,
|
||||||
SELECT 1
|
project_id,
|
||||||
|
progress_mode,
|
||||||
|
EXISTS(SELECT 1
|
||||||
FROM tasks_with_status_view
|
FROM tasks_with_status_view
|
||||||
WHERE tasks_with_status_view.task_id = tasks.id
|
WHERE tasks_with_status_view.task_id = tasks.id
|
||||||
AND is_done IS TRUE
|
AND is_done IS TRUE) AS is_complete
|
||||||
) AS is_complete
|
|
||||||
FROM tasks
|
FROM tasks
|
||||||
WHERE id = _task_id
|
WHERE id = _task_id
|
||||||
INTO _is_manual, _manual_value, _project_id, _task_complete;
|
INTO _is_manual, _manual_value, _project_id, _progress_mode, _task_complete;
|
||||||
|
|
||||||
-- Check if the project uses manual progress
|
-- Check if the project uses manual progress
|
||||||
IF _project_id IS NOT NULL THEN
|
IF _project_id IS NOT NULL
|
||||||
|
THEN
|
||||||
SELECT COALESCE(use_manual_progress, FALSE),
|
SELECT COALESCE(use_manual_progress, FALSE),
|
||||||
COALESCE(use_weighted_progress, FALSE),
|
COALESCE(use_weighted_progress, FALSE),
|
||||||
COALESCE(use_time_progress, FALSE)
|
COALESCE(use_time_progress, FALSE)
|
||||||
@@ -325,11 +490,13 @@ BEGIN
|
|||||||
-- Get all subtasks
|
-- Get all subtasks
|
||||||
SELECT COUNT(*)
|
SELECT COUNT(*)
|
||||||
FROM tasks
|
FROM tasks
|
||||||
WHERE parent_task_id = _task_id AND archived IS FALSE
|
WHERE parent_task_id = _task_id
|
||||||
|
AND archived IS FALSE
|
||||||
INTO _sub_tasks_count;
|
INTO _sub_tasks_count;
|
||||||
|
|
||||||
-- If task is complete, always return 100%
|
-- If task is complete, always return 100%
|
||||||
IF _task_complete IS TRUE THEN
|
IF _task_complete IS TRUE
|
||||||
|
THEN
|
||||||
RETURN JSON_BUILD_OBJECT(
|
RETURN JSON_BUILD_OBJECT(
|
||||||
'ratio', 100,
|
'ratio', 100,
|
||||||
'total_completed', 1,
|
'total_completed', 1,
|
||||||
@@ -338,11 +505,22 @@ BEGIN
|
|||||||
);
|
);
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Use manual progress value in two cases:
|
-- Determine current active mode
|
||||||
-- 1. When task has manual_progress = TRUE and progress_value is set
|
DECLARE
|
||||||
-- 2. When project has use_manual_progress = TRUE and progress_value is set
|
_current_mode VARCHAR(20) = CASE
|
||||||
IF (_is_manual IS TRUE AND _manual_value IS NOT NULL) OR
|
WHEN _use_manual_progress IS TRUE THEN 'manual'
|
||||||
(_use_manual_progress IS TRUE AND _manual_value IS NOT NULL) THEN
|
WHEN _use_weighted_progress IS TRUE THEN 'weighted'
|
||||||
|
WHEN _use_time_progress IS TRUE THEN 'time'
|
||||||
|
ELSE 'default'
|
||||||
|
END;
|
||||||
|
BEGIN
|
||||||
|
-- Only use manual progress value if it was set in the current active mode
|
||||||
|
-- or if the task is explicitly marked for manual progress
|
||||||
|
IF (_is_manual IS TRUE AND _manual_value IS NOT NULL AND
|
||||||
|
(_progress_mode IS NULL OR _progress_mode = _current_mode)) OR
|
||||||
|
(_use_manual_progress IS TRUE AND _manual_value IS NOT NULL AND
|
||||||
|
(_progress_mode IS NULL OR _progress_mode = 'manual'))
|
||||||
|
THEN
|
||||||
RETURN JSON_BUILD_OBJECT(
|
RETURN JSON_BUILD_OBJECT(
|
||||||
'ratio', _manual_value,
|
'ratio', _manual_value,
|
||||||
'total_completed', 0,
|
'total_completed', 0,
|
||||||
@@ -350,18 +528,22 @@ BEGIN
|
|||||||
'is_manual', TRUE
|
'is_manual', TRUE
|
||||||
);
|
);
|
||||||
END IF;
|
END IF;
|
||||||
|
END;
|
||||||
|
|
||||||
-- If there are no subtasks, just use the parent task's status (unless in time-based mode)
|
-- If there are no subtasks, just use the parent task's status (unless in time-based mode)
|
||||||
IF _sub_tasks_count = 0 THEN
|
IF _sub_tasks_count = 0
|
||||||
|
THEN
|
||||||
-- Use time-based estimation for tasks without subtasks if enabled
|
-- Use time-based estimation for tasks without subtasks if enabled
|
||||||
IF _use_time_progress IS TRUE THEN
|
IF _use_time_progress IS TRUE
|
||||||
|
THEN
|
||||||
-- For time-based tasks without subtasks, we still need some progress calculation
|
-- For time-based tasks without subtasks, we still need some progress calculation
|
||||||
-- If the task is completed, return 100%
|
-- If the task is completed, return 100%
|
||||||
-- Otherwise, use the progress value if set manually, or 0
|
-- Otherwise, use the progress value if set manually in the correct mode, or 0
|
||||||
SELECT
|
SELECT CASE
|
||||||
CASE
|
|
||||||
WHEN _task_complete IS TRUE THEN 100
|
WHEN _task_complete IS TRUE THEN 100
|
||||||
ELSE COALESCE(_manual_value, 0)
|
WHEN _manual_value IS NOT NULL AND (_progress_mode = 'time' OR _progress_mode IS NULL)
|
||||||
|
THEN _manual_value
|
||||||
|
ELSE 0
|
||||||
END
|
END
|
||||||
INTO _ratio;
|
INTO _ratio;
|
||||||
ELSE
|
ELSE
|
||||||
@@ -373,68 +555,60 @@ BEGIN
|
|||||||
END IF;
|
END IF;
|
||||||
ELSE
|
ELSE
|
||||||
-- If project uses manual progress, calculate based on subtask manual progress values
|
-- If project uses manual progress, calculate based on subtask manual progress values
|
||||||
IF _use_manual_progress IS TRUE THEN
|
IF _use_manual_progress IS TRUE
|
||||||
WITH subtask_progress AS (
|
THEN
|
||||||
SELECT
|
WITH subtask_progress AS (SELECT t.id,
|
||||||
t.id,
|
|
||||||
t.manual_progress,
|
t.manual_progress,
|
||||||
t.progress_value,
|
t.progress_value,
|
||||||
EXISTS(
|
t.progress_mode,
|
||||||
SELECT 1
|
EXISTS(SELECT 1
|
||||||
FROM tasks_with_status_view
|
FROM tasks_with_status_view
|
||||||
WHERE tasks_with_status_view.task_id = t.id
|
WHERE tasks_with_status_view.task_id = t.id
|
||||||
AND is_done IS TRUE
|
AND is_done IS TRUE) AS is_complete
|
||||||
) AS is_complete
|
|
||||||
FROM tasks t
|
FROM tasks t
|
||||||
WHERE t.parent_task_id = _task_id
|
WHERE t.parent_task_id = _task_id
|
||||||
AND t.archived IS FALSE
|
AND t.archived IS FALSE),
|
||||||
),
|
subtask_with_values AS (SELECT CASE
|
||||||
subtask_with_values AS (
|
|
||||||
SELECT
|
|
||||||
CASE
|
|
||||||
-- For completed tasks, always use 100%
|
-- For completed tasks, always use 100%
|
||||||
WHEN is_complete IS TRUE THEN 100
|
WHEN is_complete IS TRUE THEN 100
|
||||||
-- For tasks with progress value set, use it regardless of manual_progress flag
|
-- For tasks with progress value set in the correct mode, use it
|
||||||
WHEN progress_value IS NOT NULL THEN progress_value
|
WHEN progress_value IS NOT NULL AND
|
||||||
-- Default to 0 for incomplete tasks with no progress value
|
(progress_mode = 'manual' OR progress_mode IS NULL)
|
||||||
|
THEN progress_value
|
||||||
|
-- Default to 0 for incomplete tasks with no progress value or wrong mode
|
||||||
ELSE 0
|
ELSE 0
|
||||||
END AS progress_value
|
END AS progress_value
|
||||||
FROM subtask_progress
|
FROM subtask_progress)
|
||||||
)
|
|
||||||
SELECT COALESCE(AVG(progress_value), 0)
|
SELECT COALESCE(AVG(progress_value), 0)
|
||||||
FROM subtask_with_values
|
FROM subtask_with_values
|
||||||
INTO _ratio;
|
INTO _ratio;
|
||||||
-- If project uses weighted progress, calculate based on subtask weights
|
-- If project uses weighted progress, calculate based on subtask weights
|
||||||
ELSIF _use_weighted_progress IS TRUE THEN
|
ELSIF _use_weighted_progress IS TRUE
|
||||||
WITH subtask_progress AS (
|
THEN
|
||||||
SELECT
|
WITH subtask_progress AS (SELECT t.id,
|
||||||
t.id,
|
|
||||||
t.manual_progress,
|
t.manual_progress,
|
||||||
t.progress_value,
|
t.progress_value,
|
||||||
EXISTS(
|
t.progress_mode,
|
||||||
SELECT 1
|
EXISTS(SELECT 1
|
||||||
FROM tasks_with_status_view
|
FROM tasks_with_status_view
|
||||||
WHERE tasks_with_status_view.task_id = t.id
|
WHERE tasks_with_status_view.task_id = t.id
|
||||||
AND is_done IS TRUE
|
AND is_done IS TRUE) AS is_complete,
|
||||||
) AS is_complete,
|
|
||||||
COALESCE(t.weight, 100) AS weight
|
COALESCE(t.weight, 100) AS weight
|
||||||
FROM tasks t
|
FROM tasks t
|
||||||
WHERE t.parent_task_id = _task_id
|
WHERE t.parent_task_id = _task_id
|
||||||
AND t.archived IS FALSE
|
AND t.archived IS FALSE),
|
||||||
),
|
subtask_with_values AS (SELECT CASE
|
||||||
subtask_with_values AS (
|
|
||||||
SELECT
|
|
||||||
CASE
|
|
||||||
-- For completed tasks, always use 100%
|
-- For completed tasks, always use 100%
|
||||||
WHEN is_complete IS TRUE THEN 100
|
WHEN is_complete IS TRUE THEN 100
|
||||||
-- For tasks with progress value set, use it regardless of manual_progress flag
|
-- For tasks with progress value set in the correct mode, use it
|
||||||
WHEN progress_value IS NOT NULL THEN progress_value
|
WHEN progress_value IS NOT NULL AND
|
||||||
-- Default to 0 for incomplete tasks with no progress value
|
(progress_mode = 'weighted' OR progress_mode IS NULL)
|
||||||
|
THEN progress_value
|
||||||
|
-- Default to 0 for incomplete tasks with no progress value or wrong mode
|
||||||
ELSE 0
|
ELSE 0
|
||||||
END AS progress_value,
|
END AS progress_value,
|
||||||
weight
|
weight
|
||||||
FROM subtask_progress
|
FROM subtask_progress)
|
||||||
)
|
|
||||||
SELECT COALESCE(
|
SELECT COALESCE(
|
||||||
SUM(progress_value * weight) / NULLIF(SUM(weight), 0),
|
SUM(progress_value * weight) / NULLIF(SUM(weight), 0),
|
||||||
0
|
0
|
||||||
@@ -442,36 +616,32 @@ BEGIN
|
|||||||
FROM subtask_with_values
|
FROM subtask_with_values
|
||||||
INTO _ratio;
|
INTO _ratio;
|
||||||
-- If project uses time-based progress, calculate based on estimated time
|
-- If project uses time-based progress, calculate based on estimated time
|
||||||
ELSIF _use_time_progress IS TRUE THEN
|
ELSIF _use_time_progress IS TRUE
|
||||||
WITH subtask_progress AS (
|
THEN
|
||||||
SELECT
|
WITH subtask_progress AS (SELECT t.id,
|
||||||
t.id,
|
|
||||||
t.manual_progress,
|
t.manual_progress,
|
||||||
t.progress_value,
|
t.progress_value,
|
||||||
EXISTS(
|
t.progress_mode,
|
||||||
SELECT 1
|
EXISTS(SELECT 1
|
||||||
FROM tasks_with_status_view
|
FROM tasks_with_status_view
|
||||||
WHERE tasks_with_status_view.task_id = t.id
|
WHERE tasks_with_status_view.task_id = t.id
|
||||||
AND is_done IS TRUE
|
AND is_done IS TRUE) AS is_complete,
|
||||||
) AS is_complete,
|
|
||||||
COALESCE(t.total_minutes, 0) AS estimated_minutes
|
COALESCE(t.total_minutes, 0) AS estimated_minutes
|
||||||
FROM tasks t
|
FROM tasks t
|
||||||
WHERE t.parent_task_id = _task_id
|
WHERE t.parent_task_id = _task_id
|
||||||
AND t.archived IS FALSE
|
AND t.archived IS FALSE),
|
||||||
),
|
subtask_with_values AS (SELECT CASE
|
||||||
subtask_with_values AS (
|
|
||||||
SELECT
|
|
||||||
CASE
|
|
||||||
-- For completed tasks, always use 100%
|
-- For completed tasks, always use 100%
|
||||||
WHEN is_complete IS TRUE THEN 100
|
WHEN is_complete IS TRUE THEN 100
|
||||||
-- For tasks with progress value set, use it regardless of manual_progress flag
|
-- For tasks with progress value set in the correct mode, use it
|
||||||
WHEN progress_value IS NOT NULL THEN progress_value
|
WHEN progress_value IS NOT NULL AND
|
||||||
-- Default to 0 for incomplete tasks with no progress value
|
(progress_mode = 'time' OR progress_mode IS NULL)
|
||||||
|
THEN progress_value
|
||||||
|
-- Default to 0 for incomplete tasks with no progress value or wrong mode
|
||||||
ELSE 0
|
ELSE 0
|
||||||
END AS progress_value,
|
END AS progress_value,
|
||||||
estimated_minutes
|
estimated_minutes
|
||||||
FROM subtask_progress
|
FROM subtask_progress)
|
||||||
)
|
|
||||||
SELECT COALESCE(
|
SELECT COALESCE(
|
||||||
SUM(progress_value * estimated_minutes) / NULLIF(SUM(estimated_minutes), 0),
|
SUM(progress_value * estimated_minutes) / NULLIF(SUM(estimated_minutes), 0),
|
||||||
0
|
0
|
||||||
@@ -492,7 +662,8 @@ BEGIN
|
|||||||
_total_completed = _parent_task_done + _sub_tasks_done;
|
_total_completed = _parent_task_done + _sub_tasks_done;
|
||||||
_total_tasks = _sub_tasks_count + 1; -- +1 for the parent task
|
_total_tasks = _sub_tasks_count + 1; -- +1 for the parent task
|
||||||
|
|
||||||
IF _total_tasks = 0 THEN
|
IF _total_tasks = 0
|
||||||
|
THEN
|
||||||
_ratio = 0;
|
_ratio = 0;
|
||||||
ELSE
|
ELSE
|
||||||
_ratio = (_total_completed / _total_tasks) * 100;
|
_ratio = (_total_completed / _total_tasks) * 100;
|
||||||
@@ -501,9 +672,11 @@ BEGIN
|
|||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Ensure ratio is between 0 and 100
|
-- Ensure ratio is between 0 and 100
|
||||||
IF _ratio < 0 THEN
|
IF _ratio < 0
|
||||||
|
THEN
|
||||||
_ratio = 0;
|
_ratio = 0;
|
||||||
ELSIF _ratio > 100 THEN
|
ELSIF _ratio > 100
|
||||||
|
THEN
|
||||||
_ratio = 100;
|
_ratio = 100;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
@@ -654,4 +827,144 @@ $$;
|
|||||||
|
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
-- Update the on_update_task_progress function to set progress_mode
|
||||||
|
CREATE OR REPLACE FUNCTION on_update_task_progress(_body JSON) RETURNS JSON
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
AS
|
||||||
|
$$
|
||||||
|
DECLARE
|
||||||
|
_task_id UUID;
|
||||||
|
_progress_value INTEGER;
|
||||||
|
_parent_task_id UUID;
|
||||||
|
_project_id UUID;
|
||||||
|
_current_mode VARCHAR(20);
|
||||||
|
BEGIN
|
||||||
|
_task_id = (_body ->> 'task_id')::UUID;
|
||||||
|
_progress_value = (_body ->> 'progress_value')::INTEGER;
|
||||||
|
_parent_task_id = (_body ->> 'parent_task_id')::UUID;
|
||||||
|
|
||||||
|
-- Get the project ID and determine the current progress mode
|
||||||
|
SELECT project_id INTO _project_id FROM tasks WHERE id = _task_id;
|
||||||
|
|
||||||
|
IF _project_id IS NOT NULL
|
||||||
|
THEN
|
||||||
|
SELECT CASE
|
||||||
|
WHEN use_manual_progress IS TRUE THEN 'manual'
|
||||||
|
WHEN use_weighted_progress IS TRUE THEN 'weighted'
|
||||||
|
WHEN use_time_progress IS TRUE THEN 'time'
|
||||||
|
ELSE 'default'
|
||||||
|
END
|
||||||
|
INTO _current_mode
|
||||||
|
FROM projects
|
||||||
|
WHERE id = _project_id;
|
||||||
|
ELSE
|
||||||
|
_current_mode := 'default';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- Update the task with progress value and set the progress mode
|
||||||
|
UPDATE tasks
|
||||||
|
SET progress_value = _progress_value,
|
||||||
|
manual_progress = TRUE,
|
||||||
|
progress_mode = _current_mode,
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE id = _task_id;
|
||||||
|
|
||||||
|
-- Return the updated task info
|
||||||
|
RETURN JSON_BUILD_OBJECT(
|
||||||
|
'task_id', _task_id,
|
||||||
|
'progress_value', _progress_value,
|
||||||
|
'progress_mode', _current_mode
|
||||||
|
);
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
-- Update the on_update_task_weight function to set progress_mode when weight is updated
|
||||||
|
CREATE OR REPLACE FUNCTION on_update_task_weight(_body JSON) RETURNS JSON
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
AS
|
||||||
|
$$
|
||||||
|
DECLARE
|
||||||
|
_task_id UUID;
|
||||||
|
_weight INTEGER;
|
||||||
|
_parent_task_id UUID;
|
||||||
|
_project_id UUID;
|
||||||
|
BEGIN
|
||||||
|
_task_id = (_body ->> 'task_id')::UUID;
|
||||||
|
_weight = (_body ->> 'weight')::INTEGER;
|
||||||
|
_parent_task_id = (_body ->> 'parent_task_id')::UUID;
|
||||||
|
|
||||||
|
-- Get the project ID
|
||||||
|
SELECT project_id INTO _project_id FROM tasks WHERE id = _task_id;
|
||||||
|
|
||||||
|
-- Update the task with weight value and set progress_mode to 'weighted'
|
||||||
|
UPDATE tasks
|
||||||
|
SET weight = _weight,
|
||||||
|
progress_mode = 'weighted',
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE id = _task_id;
|
||||||
|
|
||||||
|
-- Return the updated task info
|
||||||
|
RETURN JSON_BUILD_OBJECT(
|
||||||
|
'task_id', _task_id,
|
||||||
|
'weight', _weight
|
||||||
|
);
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
-- Create a function to reset progress values when switching project progress modes
|
||||||
|
CREATE OR REPLACE FUNCTION reset_project_progress_values() RETURNS TRIGGER
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
AS
|
||||||
|
$$
|
||||||
|
DECLARE
|
||||||
|
_old_mode VARCHAR(20);
|
||||||
|
_new_mode VARCHAR(20);
|
||||||
|
_project_id UUID;
|
||||||
|
BEGIN
|
||||||
|
_project_id := NEW.id;
|
||||||
|
|
||||||
|
-- Determine old and new modes
|
||||||
|
_old_mode :=
|
||||||
|
CASE
|
||||||
|
WHEN OLD.use_manual_progress IS TRUE THEN 'manual'
|
||||||
|
WHEN OLD.use_weighted_progress IS TRUE THEN 'weighted'
|
||||||
|
WHEN OLD.use_time_progress IS TRUE THEN 'time'
|
||||||
|
ELSE 'default'
|
||||||
|
END;
|
||||||
|
|
||||||
|
_new_mode :=
|
||||||
|
CASE
|
||||||
|
WHEN NEW.use_manual_progress IS TRUE THEN 'manual'
|
||||||
|
WHEN NEW.use_weighted_progress IS TRUE THEN 'weighted'
|
||||||
|
WHEN NEW.use_time_progress IS TRUE THEN 'time'
|
||||||
|
ELSE 'default'
|
||||||
|
END;
|
||||||
|
|
||||||
|
-- If mode has changed, reset progress values for tasks with the old mode
|
||||||
|
IF _old_mode <> _new_mode
|
||||||
|
THEN
|
||||||
|
-- Reset progress values for tasks that were set in the old mode
|
||||||
|
UPDATE tasks
|
||||||
|
SET progress_value = NULL,
|
||||||
|
progress_mode = NULL
|
||||||
|
WHERE project_id = _project_id
|
||||||
|
AND progress_mode = _old_mode;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
-- Create trigger to reset progress values when project progress mode changes
|
||||||
|
DROP TRIGGER IF EXISTS reset_progress_on_mode_change ON projects;
|
||||||
|
CREATE TRIGGER reset_progress_on_mode_change
|
||||||
|
AFTER UPDATE OF use_manual_progress, use_weighted_progress, use_time_progress
|
||||||
|
ON projects
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE FUNCTION reset_project_progress_values();
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { LabelType } from './label.type';
|
|
||||||
import { MemberType } from './member.types';
|
import { MemberType } from './member.types';
|
||||||
import { ProjectType } from './project.types';
|
import { ProjectType } from './project.types';
|
||||||
|
import { ITaskLabel } from './tasks/taskLabel.types';
|
||||||
|
|
||||||
export type TaskStatusType = 'doing' | 'todo' | 'done';
|
export type TaskStatusType = 'doing' | 'todo' | 'done';
|
||||||
export type TaskPriorityType = 'low' | 'medium' | 'high';
|
export type TaskPriorityType = 'low' | 'medium' | 'high';
|
||||||
@@ -13,13 +13,16 @@ export type SubTaskType = {
|
|||||||
subTaskDueDate?: Date;
|
subTaskDueDate?: Date;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ProgressModeType = 'manual' | 'weighted' | 'time' | 'default';
|
||||||
|
|
||||||
export type TaskType = {
|
export type TaskType = {
|
||||||
taskId: string;
|
taskId: string;
|
||||||
|
progress_mode?: ProgressModeType;
|
||||||
task: string;
|
task: string;
|
||||||
description?: string | null;
|
description?: string | null;
|
||||||
progress?: number;
|
progress?: number;
|
||||||
members?: MemberType[];
|
members?: MemberType[];
|
||||||
labels?: LabelType[];
|
labels?: ITaskLabel[];
|
||||||
status: TaskStatusType | string;
|
status: TaskStatusType | string;
|
||||||
priority: TaskPriorityType | string;
|
priority: TaskPriorityType | string;
|
||||||
timeTracking?: number;
|
timeTracking?: number;
|
||||||
|
|||||||
Reference in New Issue
Block a user