Commit ee5572f6 authored by Powell, Eric's avatar Powell, Eric
Browse files

Moving from old computer

parent a417a44b
Loading
Loading
Loading
Loading
+2087 −0

File added.

Preview size limit exceeded, changes collapsed.

+610 KiB

File added.

No diff preview for this file type.

+2096 −0

File added.

Preview size limit exceeded, changes collapsed.

+585 −0
Original line number Diff line number Diff line
-- core_ii.activities definition

-- Drop table

-- DROP TABLE core_ii.activities;

CREATE TABLE core_ii.activities (
	activity_key int4 DEFAULT nextval('core_ii.newtable_activity_id_seq'::regclass) NOT NULL,
	budget_id int4 NULL,
	activity_id int4 NULL,
	activity_description varchar NULL,
	start_date date NULL,
	end_date date NULL,
	scope varchar null,
	CONSTRAINT newtable_pk PRIMARY KEY (activity_id)
);

-- core_ii.budgets definition

-- Drop table

-- DROP TABLE core_ii.budgets;

CREATE TABLE core_ii.budgets (
	budget_id serial4 NOT NULL,
	budget_name varchar NULL,
	lead_id int4 NULL,
	CONSTRAINT budgets_pk PRIMARY KEY (budget_id)
);

-- core_ii.project_team definition

-- Drop table

-- DROP TABLE core_ii.project_team;

CREATE TABLE core_ii.project_team (
	id serial4 NOT NULL,
	l_name varchar NULL,
	employee_id varchar NULL,
	wage_pool varchar NULL,
	project_team varchar NULL,
	f_name varchar NULL,
	unburdened_rate numeric NULL,
	burdened_rate numeric NULL,
	CONSTRAINT project_team_pk PRIMARY KEY (id)
);

-- core_ii.pto_dates definition

-- Drop table

-- DROP TABLE core_ii.pto_dates;

CREATE TABLE core_ii.pto_dates (
	id serial4 NOT NULL,
	employee_id int4 NOT NULL,
	start_date date NULL,
	end_date date NOT NULL,
	"comment" varchar NULL,
	CONSTRAINT pto_dates_pk PRIMARY KEY (id)
);

-- core_ii.task_details definition

-- Drop table

-- DROP TABLE core_ii.task_details;

CREATE TABLE core_ii.task_details (
	task_key serial4 NOT NULL,
	activity_id int4 NULL,
	task_id varchar NULL,
	task_description varchar NULL,
	labor_rate float8 NULL,
	hours float8 NULL,
	unit_cost float8 NULL,
	unit varchar NULL,
	quantity int4 NULL,
	contingency_percent float8 NULL,
	budget_id int4 NULL,
	assignee_id int4 NULL,
	--burdened_labor_rate float8 NULL,
	CONSTRAINT task_details_pk PRIMARY KEY (task_key)
);

/*
-- DROP FUNCTION core_ii.create_pivot_table_dynamic(text);

CREATE OR REPLACE FUNCTION core_ii.create_pivot_table_dynamic(source_table text)
 RETURNS SETOF record
 LANGUAGE plpgsql
AS $function$
DECLARE
    v_sql TEXT;
    v_cols TEXT;
    v_rec RECORD;
    v_dyn_table_name TEXT;
BEGIN
    -- Create a temporary table to store the pivoted data
    v_dyn_table_name := 'pivot_table_' || md5(random()::text); -- Create a unique name

    -- Build dynamic columns based on distinct dates
    v_cols := '';
    FOR v_rec IN EXECUTE format('SELECT DISTINCT the_date FROM %I ORDER BY the_date', source_table) LOOP
        v_cols := v_cols || format('MAX(CASE WHEN the_date = ''%s'' THEN weekly_labor_cost ELSE 0 END) AS %I,', v_rec.the_date, v_rec.the_date);
    END LOOP;
    v_cols := rtrim(v_cols, ',');

    -- Construct the dynamic CREATE TABLE statement
    v_sql := format('
        CREATE TEMP TABLE %I AS
        SELECT employee_name, %s
        FROM %I
        GROUP BY employee_name', v_dyn_table_name, v_cols, source_table);

    EXECUTE v_sql;

    -- Construct the final SELECT statement to return the data
    v_sql := format('SELECT * FROM %I', v_dyn_table_name);

    -- Return the data
    RETURN QUERY EXECUTE v_sql;

    -- Drop the temporary table
    EXECUTE format('DROP TABLE %I', v_dyn_table_name);
END;
$function$
;

-- DROP FUNCTION core_ii.create_pivot_table_dynamic(text, text);

CREATE OR REPLACE FUNCTION core_ii.create_pivot_table_dynamic(source_schema text, source_table text)
 RETURNS void
 LANGUAGE plpgsql
AS $function$
DECLARE
    v_sql TEXT;
    v_cols TEXT;
    v_rec RECORD;
    v_dates TEXT[];
	p_table_name TEXT := 'core_ii.t_staffing_chart';
BEGIN
    -- Get distinct dates and build column expressions
    v_cols := '';
	raise notice 'Inputs: %, %', source_schema, source_table;
    FOR v_rec IN EXECUTE format('SELECT DISTINCT the_date FROM %I.%I ORDER BY the_date', source_schema, source_table) LOOP
        v_cols := v_cols || format('MAX(CASE WHEN the_date = ''%s'' THEN weekly_labor_cost ELSE 0 END),', v_rec.the_date);
        v_dates := array_append(v_dates, v_rec.the_date::TEXT); -- Store dates for array order
    END LOOP;
    v_cols := rtrim(v_cols, ',');

    -- Construct the dynamic SQL statement to aggregate into an array
    v_sql := format('CREATE TABLE %I.%I AS
        SELECT employee_name, unnest(ARRAY[%s])
        FROM %I.%I
        GROUP BY employee_name
        ORDER BY employee_name', source_schema, p_table_name, v_cols, source_schema, source_table);
	EXECUTE format('DROP TABLE IF EXISTS %I.%I', source_schema, p_table_name);
	raise notice 'SQL:%', v_sql;
	EXECUTE v_sql;
    -- Execute the query and return the result
    --RETURN ;
END;
$function$
;

*/

-- DROP FUNCTION core_ii.cumulative_weekly_sum(date, date, text);

CREATE OR REPLACE FUNCTION core_ii.cumulative_weekly_sum(start_date date, end_date date, table_name text)
 RETURNS TABLE(pals_record_date date, weekly_sum numeric, cumulative_sum numeric)
 LANGUAGE plpgsql
AS $function$
DECLARE
    the_date DATE;
    weekly_total NUMERIC := 0;
    cumulative_total NUMERIC := 0;
	query TEXT;
	week_start DATE;
	report_end_date DATE;
	pals_date DATE;
BEGIN
    -- Input validation
    IF start_date > end_date THEN
        RAISE EXCEPTION 'Start date must be before or equal to end date.';
    END IF;

    the_date := start_date;
	raise notice 'Start:(%)', the_date;
	report_end_date = core_ii.get_pals_report_date(end_date);
	raise notice 'Reporing End:(%)', report_end_date;

    WHILE the_date <= report_end_date LOOP
        -- Start of the current week (Monday)
        pals_date := core_ii.get_pals_report_date(the_date);
		raise notice 'Reporitng Date:(%)', pals_date;

        -- Calculate the weekly sum (replace with your actual data source)
        -- This example assumes you have a table called 'sales' with 'date' and 'amount' columns.
        query = format('SELECT COALESCE(SUM(budget_amount), 0) 
        FROM core_ii.%I
        WHERE the_date >= DATE ''%s'' AND the_date < DATE ''%s'' + INTERVAL ''7''', table_name, the_date, pals_date);
		raise notice 'Query: %', query;
		EXECUTE query into weekly_total; -- Data within the current week

        cumulative_total := cumulative_total + weekly_total;

        -- Return the result for the current week
        RETURN QUERY SELECT pals_date, weekly_total, cumulative_total;

        -- Move to the next week
        the_date := pals_date + INTERVAL '7 days';
    END LOOP;

    RETURN;
END;
$function$
;

-- DROP FUNCTION core_ii.generate_mondays(date, date);

CREATE OR REPLACE FUNCTION core_ii.generate_mondays(start_date date, end_date date)
 RETURNS TABLE(monday_date date)
 LANGUAGE plpgsql
AS $function$
DECLARE
    the_date DATE;
BEGIN
    IF start_date IS NULL OR end_date IS NULL THEN
        RETURN;
    END IF;

    IF start_date > end_date THEN
        RAISE EXCEPTION 'Start date (%) cannot be after end date (%)', start_date, end_date;
    END IF;

    the_date := start_date + (1 - EXTRACT(DOW FROM start_date))::INTEGER * INTERVAL '1 day';

    WHILE the_date <= end_date LOOP
        monday_date := the_date;
        RETURN NEXT;
        the_date := the_date + INTERVAL '7 days';
    END LOOP;

    RETURN;
END;
$function$
;

-- DROP FUNCTION core_ii.generate_pals_date(date, date);

CREATE OR REPLACE FUNCTION core_ii.generate_pals_date(start_date date, end_date date)
 RETURNS TABLE(monday_date date)
 LANGUAGE plpgsql
AS $function$
DECLARE
    the_date DATE;
BEGIN
    IF start_date IS NULL OR end_date IS NULL THEN
        RETURN;
    END IF;

    IF start_date > end_date THEN
        RAISE EXCEPTION 'Start date (%) cannot be after end date (%)', start_date, end_date;
    END IF;

    the_date := start_date + (0 - EXTRACT(DOW FROM start_date))::INTEGER * INTERVAL '1 day';

    WHILE the_date <= end_date LOOP
        monday_date := the_date;
        RETURN NEXT;
        the_date := the_date + INTERVAL '7 days';
    END LOOP;

    RETURN;
END;
$function$
;

-- DROP FUNCTION core_ii.get_pals_report_date(date);

CREATE OR REPLACE FUNCTION core_ii.get_pals_report_date(start_date date)
 RETURNS date
 LANGUAGE plpgsql
AS $function$
DECLARE
	sunday_date DATE;
	pals_date DATE;
BEGIN
--    IF start_date IS NULL THEN
--        RETURN;
--    END IF;

    sunday_date := start_date + (0 - EXTRACT(DOW FROM start_date))::INTEGER * INTERVAL '1 day';
	pals_date := sunday_date + INTERVAL '7 days';
	raise notice 'Start Date: %', start_date;
	raise notice 'Sunday Date: %', sunday_date;
	raise notice 'PALS Weekend Date: %', pals_date ;

    RETURN pals_date;
END;
$function$
;

-- core_ii.v_project_team source

CREATE OR REPLACE VIEW core_ii.v_project_team
AS SELECT concat(pt.l_name, ', ', pt.f_name) AS name,
    pt.project_team
   FROM core_ii.project_team pt
  ORDER BY pt.project_team;

-- core_ii.v_spend_plan_data source

*/

-- Gernate a table of activities and ftes per employee to support the activity
drop view core_ii.vw_task_lifecycle_ftes cascade;

create or replace view core_ii.vw_task_lifecycle_ftes as
 SELECT concat(vpt.assignee_id, vpt.activity_id, vpt.budget_id) as budgetaskemp_key,
 	pt_1.f_name,
   pt_1.l_name,
   pt_1.id as assignee_id,
   pt_1.id as employee_id,
    vpt.activity_description,
    vpt.activity_id,
    coalesce(nullif(round((sum(vpt.hours) / ((max(vpt.end_date) - min(vpt.start_date)) / 7 * 40)::double precision)::numeric, 1),0), 0.01) AS empl_activity_fte,
    core_ii.get_pals_report_date(min(vpt.start_date)) AS start_date,
    core_ii.get_pals_report_date(max(vpt.end_date)) AS end_date,
    vpt.budget_name,
    vpt.budget_id
   FROM core_ii.project_team pt_1
     JOIN core_ii.vw_project_tasks vpt ON pt_1.id = vpt.assignee_id
  GROUP BY pt_1.l_name, pt_1.f_name, vpt.activity_description, vpt.budget_name, pt_1.id, vpt.activity_id, vpt.budget_id, vpt.assignee_id
  ORDER BY pt_1.l_name;



CREATE OR REPLACE VIEW core_ii.v_spend_plan_data
AS 
select sp.the_date, sp.employee_name, sum(sp.empl_activity_fte) as fte, sum(sp.weekly_labor_cost) as weekly_labor_cost from (
 SELECT core_ii.generate_pals_date(ftes.start_date, ftes.end_date) AS the_date,
    concat(ftes.l_name, ', ', ftes.f_name) AS employee_name,
    ftes.empl_activity_fte,
    (ftes.empl_activity_fte * 40::numeric)::double precision * pt.burdened_rate + (ftes.empl_activity_fte * 40::numeric)::double precision * pt.burdened_rate * td.contingency_percent AS weekly_labor_cost
   FROM core_ii.vw_task_lifecycle_ftes ftes
     JOIN core_ii.task_details td ON td.assignee_id = ftes.assignee_id and td.activity_id = ftes.activity_id
     JOIN core_ii.project_team pt ON ftes.assignee_id = pt.id
  GROUP BY ftes.l_name, ftes.f_name, ftes.empl_activity_fte, pt.burdened_rate, td.contingency_percent, td.budget_id, ftes.start_date, ftes.end_date, ftes.activity_description) sp
where sp.empl_activity_fte >0
group by sp.the_date, sp.employee_name
order by sp.the_date, sp.employee_name;


-- core_ii.vw_activity_costs source

CREATE OR REPLACE VIEW core_ii.vw_activity_costs
as 
with activity_cost AS 
(
 SELECT distinct
 	ftes.budgetaskemp_key,
 	ftes.budget_name,
    ftes.activity_description,
    ((ftes.empl_activity_fte * 40::numeric)::double precision * pt.burdened_rate + 
    (ftes.empl_activity_fte * 40::numeric)::double precision * pt.burdened_rate * td.contingency_percent) *
    ((ftes.end_date - ftes.start_date) / 7)::int AS weekly_labor_cost
   FROM core_ii.vw_task_lifecycle_ftes ftes
     JOIN core_ii.task_details td ON ftes.employee_id = td.assignee_id
     and ftes.activity_id = td.activity_id
     and ftes.budget_id = td.budget_id
     inner join core_ii.project_team pt
     on pt.id::int = td.assignee_id
) 
 SELECT round(sum(activity_cost.weekly_labor_cost)) AS total_cost,
    activity_cost.budget_name,
    activity_cost.activity_description
   FROM activity_cost
group by activity_cost.budget_name, activity_cost.activity_description;




-- core_ii.vw_activity_cost_week source

CREATE OR REPLACE VIEW core_ii.vw_activity_cost_week
AS SELECT round(vac.total_cost / ((a.end_date - a.start_date) / 7)::double precision) AS cost_wk,
    vac.activity_description,
    vac.budget_name,
    a.start_date,
    a.end_date
   FROM core_ii.vw_activity_costs vac
	inner join core_ii.activities a 
	on a.activity_description = vac.activity_description;


-- core_ii.vw_activity_cost_schedule source

CREATE OR REPLACE VIEW core_ii.vw_activity_cost_schedule
AS WITH mondays AS (
         SELECT core_ii.generate_pals_date(a.start_date, a.end_date) + '7 days'::interval AS the_date,
            a.activity_description
           FROM core_ii.activities a
        )
 SELECT m.the_date,
    m.activity_description,
    vacw.cost_wk
   FROM mondays m
     JOIN core_ii.vw_activity_cost_week vacw ON m.activity_description::text = vacw.activity_description::text;


-- core_ii.vw_budget_cost_schedule source

CREATE OR REPLACE VIEW core_ii.vw_budget_cost_schedule
AS WITH mondays AS (
         SELECT DISTINCT core_ii.generate_pals_date(a.start_date, a.end_date) + '7 days'::interval AS the_date,
            b.budget_name,
            a.activity_description
           FROM core_ii.activities a
             JOIN core_ii.budgets b ON b.budget_id = a.budget_id
        )
 SELECT m.the_date,
    m.budget_name,
    sum(vacw.cost_wk) AS budget_amount
   FROM mondays m
     JOIN core_ii.vw_activity_cost_week vacw ON m.activity_description::text = vacw.activity_description::text
  GROUP BY m.the_date, m.budget_name;


-- core_ii.vw_budget_total source

CREATE OR REPLACE VIEW core_ii.vw_budget_total
AS SELECT sum(vac.total_cost) AS sum,
    vac.budget_name
   FROM core_ii.vw_activity_costs vac
  GROUP BY vac.budget_name;

-- core_ii.vw_cummulative_spend_curve source

CREATE OR REPLACE VIEW core_ii.vw_cummulative_spend_curve
AS SELECT cumulative_weekly_sum.pals_record_date,
    cumulative_weekly_sum.weekly_sum,
    cumulative_weekly_sum.cumulative_sum
   FROM cumulative_weekly_sum('2024-10-08'::date, '2025-09-30'::date, 'vw_project_cost_schedule'::text) cumulative_weekly_sum(pals_record_date, weekly_sum, cumulative_sum);

-- core_ii.vw_project_cost_schedule source

CREATE OR REPLACE VIEW core_ii.vw_project_cost_schedule
AS WITH mondays AS (
         SELECT DISTINCT core_ii.generate_pals_date(a.start_date, a.end_date) + '7 days'::interval AS the_date,
            b.budget_name,
            a.activity_description
           FROM core_ii.activities a
             JOIN core_ii.budgets b ON b.budget_id = a.budget_id
        )
 SELECT m.the_date,
    sum(vacw.cost_wk) AS budget_amount
   FROM mondays m
     JOIN core_ii.vw_activity_cost_week vacw ON m.activity_description::text = vacw.activity_description::text
  GROUP BY m.the_date;

-- core_ii.vw_project_tasks source
drop view core_ii.vw_project_tasks cascade;

CREATE OR REPLACE VIEW core_ii.vw_project_tasks
AS SELECT 
	b.budget_id,
	b.budget_name,
	a.scope,
    a.activity_description,
    td.task_id,
    td.task_description,
    a.start_date,
    a.end_date,
    pt.burdened_rate,
    td.hours,
    td.unit_cost,
    td.unit,
    td.quantity,
    a.activity_id,
    td.contingency_percent,
    td.task_key,
    td.assignee_id,
    td.hours*pt.burdened_rate+(td.hours*pt.burdened_rate)*td.contingency_percent as task_cost
   FROM core_ii.budgets b
     LEFT JOIN core_ii.activities a ON a.budget_id = b.budget_id
     LEFT JOIN core_ii.task_details td ON td.activity_id = a.activity_id AND td.budget_id = a.budget_id
	left join core_ii.project_team pt on pt.id::int = td.assignee_id;


create or replace view core_ii.vw_activites_by_budget as
select activity_description, start_date, end_date, budget_name 
from core_ii.activities a 
inner join core_ii.budgets b
on a.budget_id = b.budget_id; 


-- Gernate a table of activities and ftes per employee to support the activity
drop view core_ii.vw_task_lifecycle_ftes cascade;

create or replace view core_ii.vw_task_lifecycle_ftes as
 SELECT concat(vpt.assignee_id, vpt.activity_id, vpt.budget_id) as budgetaskemp_key,
 	pt_1.f_name,
   pt_1.l_name,
   pt_1.id as employee_id,
    vpt.activity_description,
    vpt.activity_id,
    coalesce(nullif(round((sum(vpt.hours) / ((max(vpt.end_date) - min(vpt.start_date)) / 7 * 40)::double precision)::numeric, 1),0), 0.01) AS empl_activity_fte,
    core_ii.get_pals_report_date(min(vpt.start_date)) AS start_date,
    core_ii.get_pals_report_date(max(vpt.end_date)) AS end_date,
    vpt.budget_name,
    vpt.budget_id
   FROM core_ii.project_team pt_1
     JOIN core_ii.vw_project_tasks vpt ON pt_1.id = vpt.assignee_id
  GROUP BY pt_1.l_name, pt_1.f_name, vpt.activity_description, vpt.budget_name, pt_1.id, vpt.activity_id, vpt.budget_id, vpt.assignee_id
  ORDER BY pt_1.l_name;
	          

--Export the Spend Plan Details
create or replace view core_ii.vw_spendplan_details as
select * from core_ii.v_spend_plan_data vspd 
where the_date > '2025-09-01'::date
and vspd.weekly_labor_cost > 0;


--Genrate a list of activity costs by activity scope
create or replace view core_ii.v_post_poc_activty_budget as
select b.budget_name,  vpt.activity_description , start_date, end_date, sum(task_cost) as activity_cost 
from core_ii.vw_project_tasks vpt 
inner join core_ii.budgets b on b.budget_id = vpt.budget_id
where vpt.scope like '%Ex%'
group by vpt.activity_description, vpt.start_date , vpt.end_date, b.budget_name
order by b.budget_name ;

create or replace view core_ii.v_closeout_activty_budget as
select b.budget_name,  vpt.activity_description , start_date, end_date, sum(task_cost) as activity_cost 
from core_ii.vw_project_tasks vpt 
inner join core_ii.budgets b on b.budget_id = vpt.budget_id
where vpt.scope like '%CLOS%'
group by vpt.activity_description, vpt.start_date , vpt.end_date, b.budget_name
order by b.budget_name ;

--Get a table of names and rates
select distinct f_name, l_name, burdened_rate from
core_ii.project_team pt 
inner join core_ii.task_details td 
on pt.id = td.assignee_id 


select max(td.task_key) from core_ii.task_details td 

-- Genertae the Spend Plan per person / week from current week forward
create or replace view core_ii.vw_spend_plan_current as
select * from core_ii.v_spend_plan_data vspd 
where vspd.the_date >= core_ii.get_pals_report_date(now()::date)-7;

-- Genertae the Spend Plan per person / week from current week forward
create or replace view core_ii.vw_spend_plan_current_hours_wk as
select the_date, employee_name, round(fte*40,0) hours_wk, weekly_labor_cost from core_ii.v_spend_plan_data vspd 
where vspd.the_date >= core_ii.get_pals_report_date(now()::date)-7;

-- Data Check section ----
-----------------------------
select a.activity_description, td.task_description , a.start_date, a.end_date 
from core_ii.activities a inner join
core_ii.task_details td 
on a.budget_id = td.budget_id
and a.activity_id =td.activity_id;




-- Get the most recent PALs report date
select core_ii.get_pals_report_date(now()::date)-7;



--Set contingency to 5%
update core_ii.task_details td set contingency_percent = 0.05;


+12.5 KiB

File added.

No diff preview for this file type.

Loading