CREATE OR REPLACE FUNCTION v3.add_project_year(p_project_id integer, p_year integer, p_emit_audit boolean DEFAULT true)
 RETURNS TABLE(limit_report_id integer, current_expenses_report_id integer)
 LANGUAGE plpgsql
AS $function$
DECLARE
  v_lim INT;
  v_cur INT;
BEGIN
  IF p_year IS NULL THEN
    RAISE EXCEPTION 'p_year обязателен';
  END IF;
  IF NOT EXISTS (SELECT 1 FROM v3.project WHERE id = p_project_id) THEN
    RAISE EXCEPTION 'project id=% не существует', p_project_id;
  END IF;
  IF EXISTS (SELECT 1 FROM v3.rf_project_report
              WHERE project_id = p_project_id AND year = p_year) THEN
    RAISE EXCEPTION 'год % у проекта id=% уже заведён', p_year, p_project_id;
  END IF;

  INSERT INTO v3.rf_project_report (project_id, year, report_type)
  VALUES (p_project_id, p_year, 'LIMIT')            RETURNING id INTO v_lim;
  INSERT INTO v3.rf_project_report (project_id, year, report_type)
  VALUES (p_project_id, p_year, 'CURRENT_EXPENSES') RETURNING id INTO v_cur;

  -- Snapshot RBAC-фаз (иначе default deny → отчёт read-only)
  PERFORM v3.copy_template_to_report(v_lim);
  PERFORM v3.copy_template_to_report(v_cur);

  -- Фиксированная сетка статей на оба трека
  PERFORM v3.seed_form3_report_lines(v_lim);
  PERFORM v3.seed_form3_report_lines(v_cur);

  IF p_emit_audit THEN
    PERFORM v3.log_event(
      'PROJECT_YEAR_ADD', 'PROJECT',
      jsonb_build_object(
        'project_id',                 p_project_id,
        'year',                       p_year,
        'limit_report_id',            v_lim,
        'current_expenses_report_id', v_cur
      )
    );
  END IF;

  RETURN QUERY SELECT v_lim, v_cur;
END;
$function$
;

-- FKs
ALTER TABLE v3.app_user ADD CONSTRAINT app_user_role_fk FOREIGN KEY (role_id) REFERENCES v3."role"(id);
ALTER TABLE v3.audit_log ADD CONSTRAINT audit_log_app_user_fk FOREIGN KEY (user_id) REFERENCES v3.app_user(id);
ALTER TABLE v3.audit_log ADD CONSTRAINT audit_log_org_unit_fk FOREIGN KEY (org_unit_id) REFERENCES v3.org_unit(id);
ALTER TABLE v3.audit_log ADD CONSTRAINT audit_log_budget_form_fk FOREIGN KEY (form_id) REFERENCES v3.budget_form(id);
ALTER TABLE v3.booking ADD CONSTRAINT booking_budget_line_fk FOREIGN KEY (line_id) REFERENCES v3.budget_line(id);
ALTER TABLE v3.budget_form ADD CONSTRAINT budget_form_app_user_fk FOREIGN KEY (created_by) REFERENCES v3.app_user(id);
ALTER TABLE v3.budget_form ADD CONSTRAINT budget_form_app_user_fk_1 FOREIGN KEY (updated_by) REFERENCES v3.app_user(id);
ALTER TABLE v3.budget_form ADD CONSTRAINT budget_form_org_unit_fk FOREIGN KEY (org_unit_id) REFERENCES v3.org_unit(id);
ALTER TABLE v3.budget_line ADD CONSTRAINT budget_line_budget_form_fk FOREIGN KEY (budget_form_id) REFERENCES v3.budget_form(id);
ALTER TABLE v3.budget_line ADD CONSTRAINT budget_line_expense_item_fk FOREIGN KEY (expense_item_id) REFERENCES v3.expense_item(id);
ALTER TABLE v3.budget_line ADD CONSTRAINT budget_line_vsp_fk FOREIGN KEY (vsp_id) REFERENCES v3.vsp(id);
ALTER TABLE v3.budget_line ADD CONSTRAINT budget_line_app_user_fk FOREIGN KEY (created_by) REFERENCES v3.app_user(id);
ALTER TABLE v3.budget_line ADD CONSTRAINT budget_line_app_user_fk_1 FOREIGN KEY (updated_by) REFERENCES v3.app_user(id);
ALTER TABLE v3.budget_line_quarter ADD CONSTRAINT budget_line_quarter_budget_line_fk FOREIGN KEY (line_id) REFERENCES v3.budget_line(id);
ALTER TABLE v3.ckk ADD CONSTRAINT ckk_budget_line_fk FOREIGN KEY (line_id) REFERENCES v3.budget_line(id);
ALTER TABLE v3.collegial_approval ADD CONSTRAINT collegial_approval_budget_line_fk FOREIGN KEY (line_id) REFERENCES v3.budget_line(id);
ALTER TABLE v3.contract_detail ADD CONSTRAINT contract_detail_budget_line_fk FOREIGN KEY (line_id) REFERENCES v3.budget_line(id);
ALTER TABLE v3.contract_summary ADD CONSTRAINT contract_summary_budget_line_fk FOREIGN KEY (line_id) REFERENCES v3.budget_line(id);
ALTER TABLE v3.expense_item ADD CONSTRAINT expense_item_expense_item_fk FOREIGN KEY (parent_id) REFERENCES v3.expense_item(id);
ALTER TABLE v3.expense_item_form_type ADD CONSTRAINT expense_item_form_type_expense_item_fk FOREIGN KEY (expense_item_id) REFERENCES v3.expense_item(id);
ALTER TABLE v3.fixed_asset_report ADD CONSTRAINT fixed_asset_report_budget_form_fk FOREIGN KEY (budget_form_id) REFERENCES v3.budget_form(id);
ALTER TABLE v3.fixed_asset_report ADD CONSTRAINT fixed_asset_report_expense_item_fk FOREIGN KEY (expense_item_id) REFERENCES v3.expense_item(id);
ALTER TABLE v3.form3_phase ADD CONSTRAINT form3_phase_rf_project_report_fk FOREIGN KEY (rf_project_report_id) REFERENCES v3.rf_project_report(id);
ALTER TABLE v3.form_limit ADD CONSTRAINT form_limit_budget_form_fk FOREIGN KEY (budget_form_id) REFERENCES v3.budget_form(id);
ALTER TABLE v3.form_phase ADD CONSTRAINT form_phase_budget_form_fk FOREIGN KEY (budget_form_id) REFERENCES v3.budget_form(id);
ALTER TABLE v3.phase_template ADD CONSTRAINT phase_template_form_type_fk FOREIGN KEY (form_type) REFERENCES v3.form_type(code);
ALTER TABLE v3."plan" ADD CONSTRAINT plan_budget_line_fk FOREIGN KEY (line_id) REFERENCES v3.budget_line(id);
ALTER TABLE v3.project ADD CONSTRAINT project_org_unit_fk FOREIGN KEY (org_unit_id) REFERENCES v3.org_unit(id);
ALTER TABLE v3.rent_detail ADD CONSTRAINT rent_detail_budget_line_fk FOREIGN KEY (line_id) REFERENCES v3.budget_line(id);
ALTER TABLE v3.rent_detail ADD CONSTRAINT rent_detail_vsp_fk FOREIGN KEY (vsp_id) REFERENCES v3.vsp(id);
ALTER TABLE v3.reserve ADD CONSTRAINT reserve_budget_line_fk FOREIGN KEY (line_id) REFERENCES v3.budget_line(id);
ALTER TABLE v3.rf_project_report ADD CONSTRAINT rf_project_report_project_fk FOREIGN KEY (project_id) REFERENCES v3.project(id);
ALTER TABLE v3.rf_project_report ADD CONSTRAINT rf_project_report_app_user_fk FOREIGN KEY (created_by) REFERENCES v3.app_user(id);
ALTER TABLE v3.rf_project_report ADD CONSTRAINT rf_project_report_app_user_fk_1 FOREIGN KEY (updated_by) REFERENCES v3.app_user(id);
ALTER TABLE v3.rf_project_report_line ADD CONSTRAINT rf_project_report_line_rf_project_report_fk FOREIGN KEY (rf_project_report_id) REFERENCES v3.rf_project_report(id);
ALTER TABLE v3.rf_project_report_line ADD CONSTRAINT rf_project_report_line_expense_item_fk FOREIGN KEY (expense_item_id) REFERENCES v3.expense_item(id);
ALTER TABLE v3.rf_project_report_quarter ADD CONSTRAINT rf_project_report_quarter_rf_project_report_line_fk FOREIGN KEY (rf_project_report_line_id) REFERENCES v3.rf_project_report_line(id);
ALTER TABLE v3.security_detail ADD CONSTRAINT security_detail_budget_line_fk FOREIGN KEY (line_id) REFERENCES v3.budget_line(id);
ALTER TABLE v3.security_detail ADD CONSTRAINT security_detail_vsp_fk FOREIGN KEY (vsp_id) REFERENCES v3.vsp(id);
ALTER TABLE v3.sequestration ADD CONSTRAINT sequestration_budget_line_fk FOREIGN KEY (line_id) REFERENCES v3.budget_line(id);
ALTER TABLE v3.user_org ADD CONSTRAINT user_org_app_user_fk FOREIGN KEY (user_id) REFERENCES v3.app_user(id);
ALTER TABLE v3.user_org ADD CONSTRAINT user_org_org_unit_fk FOREIGN KEY (org_unit_id) REFERENCES v3.org_unit(id);
ALTER TABLE v3.utility_detail ADD CONSTRAINT utility_detail_budget_line_fk FOREIGN KEY (line_id) REFERENCES v3.budget_line(id);
ALTER TABLE v3.utility_detail ADD CONSTRAINT utility_detail_vsp_fk FOREIGN KEY (vsp_id) REFERENCES v3.vsp(id);
ALTER TABLE v3.vsp ADD CONSTRAINT vsp_org_unit_fk FOREIGN KEY (branch_id) REFERENCES v3.org_unit(id);
ALTER TABLE v3.vsp ADD CONSTRAINT vsp_app_user_fk FOREIGN KEY (created_by) REFERENCES v3.app_user(id);
ALTER TABLE v3.vsp ADD CONSTRAINT vsp_app_user_fk_1 FOREIGN KEY (updated_by) REFERENCES v3.app_user(id);


-- DROP FUNCTION v3.add_project(varchar, int4, int4, varchar, int4, varchar, varchar, varchar, varchar, int4, numeric, varchar);

CREATE OR REPLACE FUNCTION v3.add_project(p_name character varying, p_year integer, p_org_unit_id integer, p_level character varying DEFAULT 'project'::character varying, p_parent_id integer DEFAULT NULL::integer, p_project_type character varying DEFAULT NULL::character varying, p_vsp_format character varying DEFAULT NULL::character varying, p_placement_type character varying DEFAULT NULL::character varying, p_object_address character varying DEFAULT NULL::character varying, p_staff_count integer DEFAULT NULL::integer, p_total_area numeric DEFAULT NULL::numeric, p_system_code character varying DEFAULT NULL::character varying)
 RETURNS TABLE(project_id integer, limit_report_id integer, current_expenses_report_id integer)
 LANGUAGE plpgsql
AS $function$
            DECLARE
            v_pid INT;
            v_lim INT;
            v_cur INT;
            BEGIN
            IF p_name IS NULL OR length(trim(p_name)) = 0 THEN
                RAISE EXCEPTION 'p_name обязателен';
            END IF;
            IF p_year IS NULL THEN
                RAISE EXCEPTION 'p_year обязателен';
            END IF;
            IF p_org_unit_id IS NULL THEN
                RAISE EXCEPTION 'p_org_unit_id обязателен';
            END IF;
            IF NOT EXISTS (SELECT 1 FROM v3.org_unit ou WHERE id = p_org_unit_id AND ou.is_active ) THEN
                RAISE EXCEPTION 'org_unit id=% не существует', p_org_unit_id;
            END IF;
            IF p_parent_id IS NOT NULL AND
                NOT EXISTS (SELECT 1 FROM v3.project WHERE id = p_parent_id AND level = 'program') THEN
                RAISE EXCEPTION 'parent project id=% не существует или не имеет level=program', p_parent_id;
            END IF;

            -- INSERT project (CHECK-ы name/project_type/vsp_format/placement_type
            -- из migrate_form3_v1.sql применятся автоматически).
            INSERT INTO v3.project (
                name, level, parent_id, org_unit_id,
                project_type, vsp_format, placement_type, object_address, staff_count, total_area,
                system_code
            ) VALUES (
                p_name, p_level, p_parent_id, p_org_unit_id,
                p_project_type, p_vsp_format, p_placement_type, p_object_address, p_staff_count, p_total_area,
                p_system_code
            ) RETURNING id INTO v_pid;

            -- Первый год: 2 отчёта (LIMIT + CURRENT_EXPENSES) + snapshot фаз + сетка статей.
            -- p_emit_audit=false — событие года покрыто PROJECT_CREATE ниже. Дальнейшие
            -- годы добавляются отдельно через v3.add_project_year.
            SELECT y.limit_report_id, y.current_expenses_report_id
                INTO v_lim, v_cur
                FROM v3.add_project_year(v_pid, p_year, false) y;

            -- Аудит: PROJECT_CREATE — все заполненные поля + id отчётов
            PERFORM v3.log_event(
                'PROJECT_CREATE', 'PROJECT',
                jsonb_strip_nulls(jsonb_build_object(
                'project_id',     v_pid,
                'name',           p_name,
                'year',           p_year,
                'level',          p_level,
                'parent_id',      p_parent_id,
                'org_unit_id',    p_org_unit_id,
                'project_type',   p_project_type,
                'vsp_format',     p_vsp_format,
                'placement_type', p_placement_type,
                'object_address', p_object_address,
                'system_code',    p_system_code,
                'staff_count',    p_staff_count,
                'total_area',     p_total_area,
                'limit_report_id',            v_lim,
                'current_expenses_report_id', v_cur
                ))
            );

            RETURN QUERY SELECT v_pid, v_lim, v_cur;
            END;
            $function$
;