CREATE OR REPLACE FUNCTION set_project_dates(
    p_project_id IN VARCHAR2,    -- (1.PROJECT_ID)
    p_assignment_id IN VARCHAR2  -- (1.ASSIGNMENT_ID)
) RETURN VARCHAR2 IS
    /* 
    * Object Name: PMS_TEAM_ASSIGNMENT
    * Event Type: Field Item Change
    * Form Number: 1
    * Field Name: PROJECT_ID
    * Business Logic: Set project start and end dates as default assignment period
    * Function Name: set_project_dates
    *
    * Purpose: This function retrieves project dates from PMS_PROJECT_MASTER
    * and returns them as default values for team assignment start and end dates
    */
    
    -- Local variables
    v_start_date    DATE;
    v_end_date      DATE;
    v_return_json   VARCHAR2(4000);
    
BEGIN
    -- Initialize variables
    v_start_date := NULL;
    v_end_date := NULL;
    
    -- Get project dates from master table
    BEGIN
        SELECT 
            start_date,
            NVL(actual_end_date, target_end_date) AS end_date
        INTO 
            v_start_date,
            v_end_date
        FROM 
            pms_project_master
        WHERE 
            project_id = p_project_id;
    EXCEPTION
        WHEN NO_DATA_FOUND THEN
            -- Handle case when project is not found
            v_start_date := NULL;
            v_end_date := NULL;
    END;
    
    -- Construct JSON response
    v_return_json := '{
        "data": {
            "START_DATE": "' || TO_CHAR(v_start_date, 'YYYY-MM-DD') || '",
            "END_DATE": "' || TO_CHAR(v_end_date, 'YYYY-MM-DD') || '"
        }
    }';
    
    -- Return JSON string
    RETURN v_return_json;
    
EXCEPTION
    WHEN OTHERS THEN
        -- Handle unexpected errors with empty data structure
        v_return_json := '{
            "data": {
                "START_DATE": null,
                "END_DATE": null
            }
        }';
        RETURN v_return_json;
END set_project_dates;

CREATE OR REPLACE FUNCTION check_allocation(
    p_assignment_id IN VARCHAR2,  --(1.ASSIGNMENT_ID)
    p_emp_code     IN VARCHAR2,  --(1.EMP_CODE)
    p_start_date   IN DATE,      --(1.START_DATE)
    p_end_date     IN DATE,      --(1.END_DATE)
    p_alloc_pct    IN NUMBER     --(1.ALLOCATION_PCT)
) RETURN NUMBER IS
    /* 
    * Object Name: PMS_TEAM_ASSIGNMENT
    * Event Type: Field Validation
    * Form Number: 1
    * Field Name: EMP_CODE
    * Business Logic: Validate total allocation does not exceed 100%
    * Function Name: check_allocation
    *
    * Purpose: This function validates if the total allocation percentage for an employee
    * does not exceed 100% for any given date range considering existing assignments
    * and the new allocation being added/modified.
    */
    
    v_total_allocation NUMBER;
    v_is_valid        NUMBER := 1; -- Default to valid
    
BEGIN
    -- Calculate total allocation for the employee during the date range
    -- excluding current assignment (if exists) to handle updates
    SELECT NVL(SUM(allocation_pct), 0)
    INTO v_total_allocation
    FROM pms_team_assignment
    WHERE emp_code = p_emp_code
    AND assignment_id != NVL(p_assignment_id, 'DUMMY')
    AND ((start_date BETWEEN p_start_date AND p_end_date)
         OR (end_date BETWEEN p_start_date AND p_end_date)
         OR (start_date <= p_start_date AND end_date >= p_end_date));

    -- Add the new allocation percentage
    v_total_allocation := v_total_allocation + NVL(p_alloc_pct, 0);
    
    -- Check if total allocation exceeds 100%
    IF v_total_allocation > 100 THEN
        v_is_valid := 0;
    END IF;
    
    RETURN v_is_valid;
    
EXCEPTION
    WHEN OTHERS THEN
        -- Log error and return invalid
        -- You might want to add proper error logging here
        RETURN 0;
END check_allocation;

CREATE OR REPLACE FUNCTION validate_project_dates(
    p_project_id IN PMS_TEAM_ASSIGNMENT.PROJECT_ID%TYPE,    -- (1.PROJECT_ID)
    p_start_date IN PMS_TEAM_ASSIGNMENT.START_DATE%TYPE,    -- (1.START_DATE) 
    p_end_date IN PMS_TEAM_ASSIGNMENT.END_DATE%TYPE         -- (1.END_DATE)
) RETURN NUMBER IS
    /* 
    * Object Name: PMS_TEAM_ASSIGNMENT
    * Event Type: Field Validation
    * Form Number: 1
    * Field Name: END_DATE
    * Business Logic: Validates that:
    *   1. Team assignment dates fall within project timeline
    *   2. End date is not before start date
    *   3. Dates are not null
    * Function Name: validate_project_dates
    */
    
    v_proj_start_date   DATE;
    v_proj_end_date     DATE;
    v_status            CHAR(1);
    
BEGIN
    -- Input validation
    IF p_start_date IS NULL OR p_end_date IS NULL THEN
        RETURN 0;  -- Invalid if dates are null
    END IF;
    
    -- Validate start date is not after end date
    IF p_start_date > p_end_date THEN
        RETURN 0;  -- Invalid if start date is after end date
    END IF;
    
    -- Get project timeline details
    SELECT start_date,
           NVL(actual_end_date, target_end_date),
           status
    INTO   v_proj_start_date,
           v_proj_end_date,
           v_status
    FROM   pms_project_master
    WHERE  project_id = p_project_id;
    
    -- Validate project exists and is active
    IF v_status != 'A' THEN
        RETURN 0;  -- Invalid if project is not active
    END IF;
    
    -- Validate assignment dates fall within project timeline
    IF p_start_date < v_proj_start_date OR 
       p_end_date > v_proj_end_date THEN
        RETURN 0;  -- Invalid if dates are outside project timeline
    END IF;
    
    RETURN 1;  -- All validations passed
    
EXCEPTION
    WHEN NO_DATA_FOUND THEN
        RETURN 0;  -- Invalid if project doesn't exist
    WHEN OTHERS THEN
        -- Log error and return invalid
        -- You might want to add proper error logging here
        RETURN 0;
END validate_project_dates;

CREATE OR REPLACE FUNCTION validate_project_dates(
    p_project_id IN PMS_TEAM_ASSIGNMENT.PROJECT_ID%TYPE,    -- (1.PROJECT_ID)
    p_start_date IN PMS_TEAM_ASSIGNMENT.START_DATE%TYPE,    -- (1.START_DATE) 
    p_end_date IN PMS_TEAM_ASSIGNMENT.END_DATE%TYPE         -- (1.END_DATE)
) RETURN NUMBER IS
    /* 
    * Object Name: PMS_TEAM_ASSIGNMENT
    * Event Type: Field Validation
    * Form Number: 1
    * Field Name: START_DATE
    * Business Logic: Validates that team assignment dates fall within project timeline
    * Function Name: validate_project_dates
    */
    
    v_proj_start_date   DATE;
    v_proj_end_date     DATE;
    v_status            CHAR(1);
    v_result            NUMBER := 0;

BEGIN
    -- Get project timeline details
    SELECT START_DATE, 
           NVL(ACTUAL_END_DATE, TARGET_END_DATE),
           STATUS
    INTO   v_proj_start_date,
           v_proj_end_date,
           v_status
    FROM   PMS_PROJECT_MASTER
    WHERE  PROJECT_ID = p_project_id;
    
    -- Validation #1: Check if project exists and is active
    IF v_status != 'A' THEN
        RETURN 0;  -- Invalid if project is not active
    END IF;
    
    -- Validation #2: Check if start date is within project timeline
    IF p_start_date < v_proj_start_date OR 
       p_start_date > v_proj_end_date THEN
        RETURN 0;  -- Invalid if start date outside project timeline
    END IF;
    
    -- Validation #3: Check if end date is within project timeline
    IF p_end_date < v_proj_start_date OR 
       p_end_date > v_proj_end_date THEN
        RETURN 0;  -- Invalid if end date outside project timeline
    END IF;
    
    -- Validation #4: Check if start date is before end date
    IF p_start_date > p_end_date THEN
        RETURN 0;  -- Invalid if start date is after end date
    END IF;
    
    -- All validations passed
    RETURN 1;

EXCEPTION
    WHEN NO_DATA_FOUND THEN
        -- Project not found
        RETURN 0;
    WHEN OTHERS THEN
        -- Handle unexpected errors
        RETURN 0;
END validate_project_dates;

CREATE OR REPLACE FUNCTION project_info(
    p_project_id IN VARCHAR2,    -- (1.PROJECT_ID)
    p_assignment_id IN VARCHAR2  -- (1.ASSIGNMENT_ID)
) RETURN VARCHAR2 IS
    /* 
    * Object Name: PMS_TEAM_ASSIGNMENT
    * Event Type: Field Item Change
    * Form Number: 1
    * Field Name: PROJECT_ID
    * Business Logic: Set project start and end dates as default assignment period
    * Function Name: project_info
    *
    * Purpose: This function retrieves project dates from PMS_PROJECT_MASTER
    * and returns them as default values for team assignment start and end dates
    */
    
    -- Local variables
    v_start_date    DATE;
    v_end_date      DATE;
    v_return_json   VARCHAR2(4000);
    
BEGIN
    -- Initialize variables
    v_start_date := NULL;
    v_end_date := NULL;
    
    -- Get project dates from master table
    BEGIN
        SELECT 
            start_date,
            NVL(actual_end_date, target_end_date) AS end_date
        INTO 
            v_start_date,
            v_end_date
        FROM 
            pms_project_master
        WHERE 
            project_id = p_project_id;
    EXCEPTION
        WHEN NO_DATA_FOUND THEN
            -- Handle case when project is not found
            v_start_date := NULL;
            v_end_date := NULL;
    END;
    
    -- Construct JSON response
    v_return_json := '{
        "data": {
            "START_DATE": "' || TO_CHAR(v_start_date, 'YYYY-MM-DD') || '",
            "END_DATE": "' || TO_CHAR(v_end_date, 'YYYY-MM-DD') || '"
        }
    }';
    
    -- Return JSON string
    RETURN v_return_json;
    
EXCEPTION
    WHEN OTHERS THEN
        -- Handle unexpected errors with empty data structure
        v_return_json := '{
            "data": {
                "START_DATE": null,
                "END_DATE": null
            }
        }';
        RETURN v_return_json;
END project_info;

CREATE OR REPLACE FUNCTION project_details(
    p_project_id IN VARCHAR2,    -- (1.PROJECT_ID)
    p_assignment_id IN VARCHAR2  -- (1.ASSIGNMENT_ID)
) RETURN VARCHAR2 IS
    /* 
    * Object Name: PMS_TEAM_ASSIGNMENT
    * Event Type: Field Item Change
    * Form Number: 1
    * Field Name: PROJECT_ID
    * Business Logic: Set project start and end dates as default assignment period
    * Function Name: project_details
    *
    * Purpose: This function retrieves project dates from PMS_PROJECT_MASTER
    * and returns them as default values for team assignment start and end dates
    */
    
    -- Local variables
    v_start_date    DATE;
    v_end_date      DATE;
    v_return_json   VARCHAR2(4000);
    
BEGIN
    -- Initialize variables
    v_start_date := NULL;
    v_end_date := NULL;
    
    -- Get project dates from master table
    BEGIN
        SELECT 
            start_date,
            NVL(actual_end_date, target_end_date) AS end_date
        INTO 
            v_start_date,
            v_end_date
        FROM 
            pms_project_master
        WHERE 
            project_id = p_project_id;
    EXCEPTION
        WHEN NO_DATA_FOUND THEN
            -- Handle case when project is not found
            v_start_date := NULL;
            v_end_date := NULL;
    END;
    
    -- Construct JSON response
    v_return_json := '{
        "data": {
            "START_DATE": "' || TO_CHAR(v_start_date, 'YYYY-MM-DD') || '",
            "END_DATE": "' || TO_CHAR(v_end_date, 'YYYY-MM-DD') || '"
        }
    }';
    
    -- Return JSON string
    RETURN v_return_json;
    
EXCEPTION
    WHEN OTHERS THEN
        -- Handle unexpected errors with empty data structure
        v_return_json := '{
            "data": {
                "START_DATE": null,
                "END_DATE": null
            }
        }';
        RETURN v_return_json;
END project_details;
