-- =====================================================
-- SCHEMA: hr
-- PROPOSITO: Human Resources Management
-- MODULOS: MGN-HR (Recursos Humanos)
-- FECHA: 2025-11-24
-- =====================================================

-- Crear schema
CREATE SCHEMA IF NOT EXISTS hr;

-- =====================================================
-- TYPES (ENUMs)
-- =====================================================

CREATE TYPE hr.contract_status AS ENUM (
  'draft',
  'active',
  'expired',
  'terminated',
  'cancelled'
);

CREATE TYPE hr.contract_type AS ENUM (
  'permanent',
  'temporary',
  'contractor',
  'internship',
  'part_time'
);

CREATE TYPE hr.leave_status AS ENUM (
  'draft',
  'submitted',
  'approved',
  'rejected',
  'cancelled'
);

CREATE TYPE hr.leave_type AS ENUM (
  'vacation',
  'sick',
  'personal',
  'maternity',
  'paternity',
  'bereavement',
  'unpaid',
  'other'
);

CREATE TYPE hr.employee_status AS ENUM (
  'active',
  'inactive',
  'on_leave',
  'terminated'
);

-- =====================================================
-- TABLES
-- =====================================================

-- Tabla: departments (Departamentos)
CREATE TABLE hr.departments (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
  company_id UUID NOT NULL REFERENCES auth.companies(id) ON DELETE CASCADE,

  name VARCHAR(100) NOT NULL,
  code VARCHAR(20),
  parent_id UUID REFERENCES hr.departments(id),
  manager_id UUID, -- References employees, set after table creation

  description TEXT,
  color VARCHAR(20),

  active BOOLEAN DEFAULT TRUE,
  created_by UUID REFERENCES auth.users(id),
  created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,

  UNIQUE(tenant_id, company_id, name)
);

-- Tabla: job_positions (Puestos de trabajo)
CREATE TABLE hr.job_positions (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,

  name VARCHAR(100) NOT NULL,
  department_id UUID REFERENCES hr.departments(id),

  description TEXT,
  requirements TEXT,
  responsibilities TEXT,

  min_salary DECIMAL(15, 2),
  max_salary DECIMAL(15, 2),

  active BOOLEAN DEFAULT TRUE,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,

  UNIQUE(tenant_id, name)
);

-- Tabla: employees (Empleados)
CREATE TABLE hr.employees (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
  company_id UUID NOT NULL REFERENCES auth.companies(id) ON DELETE CASCADE,

  -- Identificacion
  employee_number VARCHAR(50) NOT NULL,
  first_name VARCHAR(100) NOT NULL,
  last_name VARCHAR(100) NOT NULL,
  middle_name VARCHAR(100),

  -- Usuario vinculado (opcional)
  user_id UUID REFERENCES auth.users(id),

  -- Informacion personal
  birth_date DATE,
  gender VARCHAR(20),
  marital_status VARCHAR(20),
  nationality VARCHAR(100),
  identification_id VARCHAR(50),
  identification_type VARCHAR(50),
  social_security_number VARCHAR(50),
  tax_id VARCHAR(50),

  -- Contacto
  email VARCHAR(255),
  work_email VARCHAR(255),
  phone VARCHAR(50),
  work_phone VARCHAR(50),
  mobile VARCHAR(50),
  emergency_contact VARCHAR(255),
  emergency_phone VARCHAR(50),

  -- Direccion
  street VARCHAR(255),
  city VARCHAR(100),
  state VARCHAR(100),
  zip VARCHAR(20),
  country VARCHAR(100),

  -- Trabajo
  department_id UUID REFERENCES hr.departments(id),
  job_position_id UUID REFERENCES hr.job_positions(id),
  manager_id UUID REFERENCES hr.employees(id),

  hire_date DATE NOT NULL,
  termination_date DATE,
  status hr.employee_status NOT NULL DEFAULT 'active',

  -- Datos bancarios
  bank_name VARCHAR(100),
  bank_account VARCHAR(50),
  bank_clabe VARCHAR(20),

  -- Foto
  photo_url VARCHAR(500),

  -- Notas
  notes TEXT,

  -- Auditoria
  created_by UUID REFERENCES auth.users(id),
  updated_by UUID REFERENCES auth.users(id),
  created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,

  UNIQUE(tenant_id, employee_number)
);

-- Add manager_id reference to departments
ALTER TABLE hr.departments ADD CONSTRAINT fk_departments_manager
  FOREIGN KEY (manager_id) REFERENCES hr.employees(id);

-- Tabla: contracts (Contratos laborales)
CREATE TABLE hr.contracts (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
  company_id UUID NOT NULL REFERENCES auth.companies(id) ON DELETE CASCADE,

  employee_id UUID NOT NULL REFERENCES hr.employees(id) ON DELETE CASCADE,

  -- Identificacion
  name VARCHAR(100) NOT NULL,
  reference VARCHAR(100),

  -- Tipo y estado
  contract_type hr.contract_type NOT NULL,
  status hr.contract_status NOT NULL DEFAULT 'draft',

  -- Puesto
  job_position_id UUID REFERENCES hr.job_positions(id),
  department_id UUID REFERENCES hr.departments(id),

  -- Vigencia
  date_start DATE NOT NULL,
  date_end DATE,
  trial_date_end DATE,

  -- Compensacion
  wage DECIMAL(15, 2) NOT NULL,
  wage_type VARCHAR(20) DEFAULT 'monthly', -- hourly, daily, weekly, monthly, yearly
  currency_id UUID REFERENCES core.currencies(id),

  -- Horas
  resource_calendar_id UUID, -- For future scheduling module
  hours_per_week DECIMAL(5, 2) DEFAULT 40,

  -- Beneficios y deducciones
  vacation_days INTEGER DEFAULT 6,
  christmas_bonus_days INTEGER DEFAULT 15,

  -- Documentos
  document_url VARCHAR(500),

  -- Notas
  notes TEXT,

  -- Auditoria
  created_by UUID REFERENCES auth.users(id),
  updated_by UUID REFERENCES auth.users(id),
  created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

-- Tabla: leave_types (Tipos de ausencia configurables)
CREATE TABLE hr.leave_types (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,

  name VARCHAR(100) NOT NULL,
  code VARCHAR(20),
  leave_type hr.leave_type NOT NULL,

  requires_approval BOOLEAN DEFAULT TRUE,
  max_days INTEGER,
  is_paid BOOLEAN DEFAULT TRUE,

  color VARCHAR(20),

  active BOOLEAN DEFAULT TRUE,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,

  UNIQUE(tenant_id, name)
);

-- Tabla: leaves (Ausencias/Permisos)
CREATE TABLE hr.leaves (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
  company_id UUID NOT NULL REFERENCES auth.companies(id) ON DELETE CASCADE,

  employee_id UUID NOT NULL REFERENCES hr.employees(id) ON DELETE CASCADE,
  leave_type_id UUID NOT NULL REFERENCES hr.leave_types(id),

  -- Solicitud
  name VARCHAR(255),
  date_from DATE NOT NULL,
  date_to DATE NOT NULL,
  number_of_days DECIMAL(5, 2) NOT NULL,

  -- Estado
  status hr.leave_status NOT NULL DEFAULT 'draft',

  -- Descripcion
  description TEXT,

  -- Aprobacion
  approved_by UUID REFERENCES auth.users(id),
  approved_at TIMESTAMP WITH TIME ZONE,
  rejection_reason TEXT,

  -- Auditoria
  created_by UUID REFERENCES auth.users(id),
  updated_by UUID REFERENCES auth.users(id),
  created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

-- =====================================================
-- INDEXES
-- =====================================================

CREATE INDEX idx_departments_tenant ON hr.departments(tenant_id);
CREATE INDEX idx_departments_company ON hr.departments(company_id);
CREATE INDEX idx_departments_parent ON hr.departments(parent_id);

CREATE INDEX idx_job_positions_tenant ON hr.job_positions(tenant_id);
CREATE INDEX idx_job_positions_department ON hr.job_positions(department_id);

CREATE INDEX idx_employees_tenant ON hr.employees(tenant_id);
CREATE INDEX idx_employees_company ON hr.employees(company_id);
CREATE INDEX idx_employees_department ON hr.employees(department_id);
CREATE INDEX idx_employees_manager ON hr.employees(manager_id);
CREATE INDEX idx_employees_user ON hr.employees(user_id);
CREATE INDEX idx_employees_status ON hr.employees(status);
CREATE INDEX idx_employees_number ON hr.employees(employee_number);

CREATE INDEX idx_contracts_tenant ON hr.contracts(tenant_id);
CREATE INDEX idx_contracts_employee ON hr.contracts(employee_id);
CREATE INDEX idx_contracts_status ON hr.contracts(status);
CREATE INDEX idx_contracts_dates ON hr.contracts(date_start, date_end);

CREATE INDEX idx_leave_types_tenant ON hr.leave_types(tenant_id);

CREATE INDEX idx_leaves_tenant ON hr.leaves(tenant_id);
CREATE INDEX idx_leaves_employee ON hr.leaves(employee_id);
CREATE INDEX idx_leaves_status ON hr.leaves(status);
CREATE INDEX idx_leaves_dates ON hr.leaves(date_from, date_to);

-- =====================================================
-- TRIGGERS
-- =====================================================

CREATE TRIGGER update_departments_timestamp
  BEFORE UPDATE ON hr.departments
  FOR EACH ROW EXECUTE FUNCTION core.update_timestamp();

CREATE TRIGGER update_job_positions_timestamp
  BEFORE UPDATE ON hr.job_positions
  FOR EACH ROW EXECUTE FUNCTION core.update_timestamp();

CREATE TRIGGER update_employees_timestamp
  BEFORE UPDATE ON hr.employees
  FOR EACH ROW EXECUTE FUNCTION core.update_timestamp();

CREATE TRIGGER update_contracts_timestamp
  BEFORE UPDATE ON hr.contracts
  FOR EACH ROW EXECUTE FUNCTION core.update_timestamp();

CREATE TRIGGER update_leaves_timestamp
  BEFORE UPDATE ON hr.leaves
  FOR EACH ROW EXECUTE FUNCTION core.update_timestamp();

-- =====================================================
-- ROW LEVEL SECURITY
-- =====================================================

-- Habilitar RLS
ALTER TABLE hr.departments ENABLE ROW LEVEL SECURITY;
ALTER TABLE hr.job_positions ENABLE ROW LEVEL SECURITY;
ALTER TABLE hr.employees ENABLE ROW LEVEL SECURITY;
ALTER TABLE hr.contracts ENABLE ROW LEVEL SECURITY;
ALTER TABLE hr.leave_types ENABLE ROW LEVEL SECURITY;
ALTER TABLE hr.leaves ENABLE ROW LEVEL SECURITY;

-- Políticas de aislamiento por tenant
CREATE POLICY tenant_isolation_departments ON hr.departments
  USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);

CREATE POLICY tenant_isolation_job_positions ON hr.job_positions
  USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);

CREATE POLICY tenant_isolation_employees ON hr.employees
  USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);

CREATE POLICY tenant_isolation_contracts ON hr.contracts
  USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);

CREATE POLICY tenant_isolation_leave_types ON hr.leave_types
  USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);

CREATE POLICY tenant_isolation_leaves ON hr.leaves
  USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);

-- =====================================================
-- COMMENTS
-- =====================================================

COMMENT ON TABLE hr.departments IS 'Departamentos de la organizacion';
COMMENT ON TABLE hr.job_positions IS 'Puestos de trabajo/posiciones';
COMMENT ON TABLE hr.employees IS 'Empleados de la organizacion';
COMMENT ON TABLE hr.contracts IS 'Contratos laborales';
COMMENT ON TABLE hr.leave_types IS 'Tipos de ausencia configurables';
COMMENT ON TABLE hr.leaves IS 'Solicitudes de ausencias/permisos';

-- =====================================================
-- COR-026: Employee Attendances
-- Equivalente a hr.attendance de Odoo
-- =====================================================

CREATE TABLE hr.attendances (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
  employee_id UUID NOT NULL REFERENCES hr.employees(id) ON DELETE CASCADE,
  check_in TIMESTAMP WITH TIME ZONE NOT NULL,
  check_out TIMESTAMP WITH TIME ZONE,
  worked_hours DECIMAL(10,4),
  overtime_hours DECIMAL(10,4) DEFAULT 0,
  is_overtime BOOLEAN DEFAULT FALSE,
  notes TEXT,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  CONSTRAINT valid_checkout CHECK (check_out IS NULL OR check_out > check_in)
);

CREATE INDEX idx_attendances_tenant ON hr.attendances(tenant_id);
CREATE INDEX idx_attendances_employee ON hr.attendances(employee_id);
CREATE INDEX idx_attendances_checkin ON hr.attendances(check_in);
CREATE INDEX idx_attendances_date ON hr.attendances(tenant_id, DATE(check_in));

-- Trigger para calcular worked_hours automaticamente
CREATE OR REPLACE FUNCTION hr.calculate_worked_hours()
RETURNS TRIGGER AS $$
BEGIN
  IF NEW.check_out IS NOT NULL THEN
    NEW.worked_hours := EXTRACT(EPOCH FROM (NEW.check_out - NEW.check_in)) / 3600.0;
  END IF;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_attendances_calculate_hours
  BEFORE INSERT OR UPDATE ON hr.attendances
  FOR EACH ROW EXECUTE FUNCTION hr.calculate_worked_hours();

-- RLS
ALTER TABLE hr.attendances ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation_attendances ON hr.attendances
  USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);

COMMENT ON TABLE hr.attendances IS 'COR-026: Employee attendances - Equivalent to hr.attendance';

-- =====================================================
-- COR-027: Leave Allocations
-- Equivalente a hr.leave.allocation de Odoo
-- =====================================================

CREATE TABLE hr.leave_allocations (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
  company_id UUID NOT NULL REFERENCES auth.companies(id) ON DELETE CASCADE,
  employee_id UUID NOT NULL REFERENCES hr.employees(id) ON DELETE CASCADE,
  leave_type_id UUID NOT NULL REFERENCES hr.leave_types(id),
  name VARCHAR(255),
  number_of_days DECIMAL(10,2) NOT NULL,
  date_from DATE,
  date_to DATE,
  status hr.leave_status DEFAULT 'draft',
  allocation_type VARCHAR(20) DEFAULT 'regular',  -- regular, accrual
  notes TEXT,
  approved_by UUID REFERENCES auth.users(id),
  approved_at TIMESTAMP WITH TIME ZONE,
  created_by UUID REFERENCES auth.users(id),
  created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_leave_allocations_tenant ON hr.leave_allocations(tenant_id);
CREATE INDEX idx_leave_allocations_employee ON hr.leave_allocations(employee_id);
CREATE INDEX idx_leave_allocations_type ON hr.leave_allocations(leave_type_id);
CREATE INDEX idx_leave_allocations_status ON hr.leave_allocations(status);

-- RLS
ALTER TABLE hr.leave_allocations ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation_leave_allocations ON hr.leave_allocations
  USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);

COMMENT ON TABLE hr.leave_allocations IS 'COR-027: Leave allocations - Equivalent to hr.leave.allocation';

-- =====================================================
-- COR-061: Employee Additional Fields
-- Campos adicionales para alinear con Odoo hr.employee
-- =====================================================

ALTER TABLE hr.employees
  ADD COLUMN IF NOT EXISTS work_location_id UUID,  -- FK to work_locations
  ADD COLUMN IF NOT EXISTS resource_id UUID,  -- FK future resource.resource
  ADD COLUMN IF NOT EXISTS resource_calendar_id UUID,  -- FK future resource.calendar
  ADD COLUMN IF NOT EXISTS company_country_id UUID REFERENCES core.countries(id),
  ADD COLUMN IF NOT EXISTS private_street VARCHAR(255),
  ADD COLUMN IF NOT EXISTS private_city VARCHAR(100),
  ADD COLUMN IF NOT EXISTS private_state_id UUID,  -- FK to core.states
  ADD COLUMN IF NOT EXISTS private_zip VARCHAR(20),
  ADD COLUMN IF NOT EXISTS private_country_id UUID REFERENCES core.countries(id),
  ADD COLUMN IF NOT EXISTS private_phone VARCHAR(50),
  ADD COLUMN IF NOT EXISTS private_email VARCHAR(255),
  ADD COLUMN IF NOT EXISTS km_home_work INTEGER DEFAULT 0,  -- Distancia casa-trabajo
  ADD COLUMN IF NOT EXISTS children INTEGER DEFAULT 0,
  ADD COLUMN IF NOT EXISTS vehicle VARCHAR(100),
  ADD COLUMN IF NOT EXISTS vehicle_license_plate VARCHAR(50),
  ADD COLUMN IF NOT EXISTS visa_no VARCHAR(50),
  ADD COLUMN IF NOT EXISTS visa_expire DATE,
  ADD COLUMN IF NOT EXISTS work_permit_no VARCHAR(50),
  ADD COLUMN IF NOT EXISTS work_permit_expiration_date DATE,
  ADD COLUMN IF NOT EXISTS certificate VARCHAR(50),  -- Nivel educativo
  ADD COLUMN IF NOT EXISTS study_field VARCHAR(100),
  ADD COLUMN IF NOT EXISTS study_school VARCHAR(255),
  ADD COLUMN IF NOT EXISTS badge_id VARCHAR(100),
  ADD COLUMN IF NOT EXISTS pin VARCHAR(20),  -- PIN para kiosk
  ADD COLUMN IF NOT EXISTS barcode VARCHAR(100),
  ADD COLUMN IF NOT EXISTS color INTEGER DEFAULT 0,
  ADD COLUMN IF NOT EXISTS additional_note TEXT;

-- =====================================================
-- COR-062: Work Locations
-- Ubicaciones de trabajo (oficina, remoto, etc.)
-- =====================================================

CREATE TABLE hr.work_locations (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
  company_id UUID REFERENCES auth.companies(id) ON DELETE CASCADE,

  name VARCHAR(100) NOT NULL,
  location_type VARCHAR(50) DEFAULT 'office',  -- office, home, other
  address_id UUID REFERENCES core.partners(id),

  -- Control
  is_active BOOLEAN DEFAULT TRUE,

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,

  UNIQUE(tenant_id, name)
);

CREATE INDEX idx_work_locations_tenant ON hr.work_locations(tenant_id);

-- RLS
ALTER TABLE hr.work_locations ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation_work_locations ON hr.work_locations
  USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);

-- Agregar FK a employees
ALTER TABLE hr.employees ADD CONSTRAINT fk_employees_work_location
  FOREIGN KEY (work_location_id) REFERENCES hr.work_locations(id);

COMMENT ON TABLE hr.work_locations IS 'COR-062: Work locations for employees';

-- =====================================================
-- COR-063: Employee Skills
-- Sistema de habilidades de empleados
-- =====================================================

CREATE TABLE hr.skill_types (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
  name VARCHAR(100) NOT NULL,
  skill_levels VARCHAR(50) DEFAULT 'basic',  -- basic, intermediate, advanced, expert
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  UNIQUE(tenant_id, name)
);

CREATE TABLE hr.skills (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
  skill_type_id UUID NOT NULL REFERENCES hr.skill_types(id) ON DELETE CASCADE,
  name VARCHAR(100) NOT NULL,
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  UNIQUE(tenant_id, skill_type_id, name)
);

CREATE TABLE hr.skill_levels (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
  skill_type_id UUID NOT NULL REFERENCES hr.skill_types(id) ON DELETE CASCADE,
  name VARCHAR(50) NOT NULL,
  level INTEGER NOT NULL DEFAULT 1,  -- 1-5 typically
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  UNIQUE(tenant_id, skill_type_id, name)
);

CREATE TABLE hr.employee_skills (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  employee_id UUID NOT NULL REFERENCES hr.employees(id) ON DELETE CASCADE,
  skill_id UUID NOT NULL REFERENCES hr.skills(id) ON DELETE CASCADE,
  skill_level_id UUID REFERENCES hr.skill_levels(id),
  skill_type_id UUID REFERENCES hr.skill_types(id),

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,

  UNIQUE(employee_id, skill_id)
);

CREATE INDEX idx_skill_types_tenant ON hr.skill_types(tenant_id);
CREATE INDEX idx_skills_tenant ON hr.skills(tenant_id);
CREATE INDEX idx_skills_type ON hr.skills(skill_type_id);
CREATE INDEX idx_skill_levels_type ON hr.skill_levels(skill_type_id);
CREATE INDEX idx_employee_skills_employee ON hr.employee_skills(employee_id);
CREATE INDEX idx_employee_skills_skill ON hr.employee_skills(skill_id);

-- RLS
ALTER TABLE hr.skill_types ENABLE ROW LEVEL SECURITY;
ALTER TABLE hr.skills ENABLE ROW LEVEL SECURITY;
ALTER TABLE hr.skill_levels ENABLE ROW LEVEL SECURITY;

CREATE POLICY tenant_isolation_skill_types ON hr.skill_types
  USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);
CREATE POLICY tenant_isolation_skills ON hr.skills
  USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);
CREATE POLICY tenant_isolation_skill_levels ON hr.skill_levels
  USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);

COMMENT ON TABLE hr.skill_types IS 'COR-063: Skill type categories';
COMMENT ON TABLE hr.skills IS 'COR-063: Individual skills';
COMMENT ON TABLE hr.skill_levels IS 'COR-063: Skill proficiency levels';
COMMENT ON TABLE hr.employee_skills IS 'COR-063: Employee skill assignments';

-- =====================================================
-- COR-064: Expense Reports
-- Reporte de gastos de empleados
-- =====================================================

CREATE TYPE hr.expense_status AS ENUM (
  'draft',
  'submitted',
  'approved',
  'posted',
  'paid',
  'rejected'
);

CREATE TABLE hr.expense_sheets (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
  company_id UUID NOT NULL REFERENCES auth.companies(id) ON DELETE CASCADE,
  employee_id UUID NOT NULL REFERENCES hr.employees(id),

  name VARCHAR(255) NOT NULL,
  state hr.expense_status DEFAULT 'draft',

  -- Montos
  total_amount DECIMAL(20,6) DEFAULT 0,
  untaxed_amount DECIMAL(20,6) DEFAULT 0,
  total_amount_taxes DECIMAL(20,6) DEFAULT 0,

  -- Cuenta contable
  journal_id UUID,  -- FK to financial.journals
  account_move_id UUID,  -- FK to financial.journal_entries

  -- Aprobacion
  user_id UUID REFERENCES auth.users(id),  -- Responsable
  approved_by UUID REFERENCES auth.users(id),
  approved_date TIMESTAMP WITH TIME ZONE,

  -- Fechas
  accounting_date DATE,

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created_by UUID REFERENCES auth.users(id),
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE hr.expenses (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
  company_id UUID NOT NULL REFERENCES auth.companies(id) ON DELETE CASCADE,
  employee_id UUID NOT NULL REFERENCES hr.employees(id),

  name VARCHAR(255) NOT NULL,
  sheet_id UUID REFERENCES hr.expense_sheets(id) ON DELETE SET NULL,

  -- Producto/Categoria de gasto
  product_id UUID REFERENCES inventory.products(id),

  -- Montos
  unit_amount DECIMAL(20,6) NOT NULL,
  quantity DECIMAL(20,6) DEFAULT 1,
  total_amount DECIMAL(20,6) NOT NULL,
  untaxed_amount DECIMAL(20,6),
  total_amount_taxes DECIMAL(20,6),
  currency_id UUID REFERENCES core.currencies(id),

  -- Impuestos
  tax_ids UUID[] DEFAULT '{}',

  -- Fechas
  date DATE NOT NULL DEFAULT CURRENT_DATE,

  -- Documentacion
  description TEXT,
  reference VARCHAR(255),

  -- Analitica
  analytic_account_id UUID REFERENCES analytics.analytic_accounts(id),

  -- Estado
  state hr.expense_status DEFAULT 'draft',
  payment_mode VARCHAR(50) DEFAULT 'own_account',  -- own_account, company_account

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created_by UUID REFERENCES auth.users(id),
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_expense_sheets_tenant ON hr.expense_sheets(tenant_id);
CREATE INDEX idx_expense_sheets_employee ON hr.expense_sheets(employee_id);
CREATE INDEX idx_expense_sheets_state ON hr.expense_sheets(state);
CREATE INDEX idx_expenses_tenant ON hr.expenses(tenant_id);
CREATE INDEX idx_expenses_employee ON hr.expenses(employee_id);
CREATE INDEX idx_expenses_sheet ON hr.expenses(sheet_id);
CREATE INDEX idx_expenses_date ON hr.expenses(date);

-- RLS
ALTER TABLE hr.expense_sheets ENABLE ROW LEVEL SECURITY;
ALTER TABLE hr.expenses ENABLE ROW LEVEL SECURITY;

CREATE POLICY tenant_isolation_expense_sheets ON hr.expense_sheets
  USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);
CREATE POLICY tenant_isolation_expenses ON hr.expenses
  USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);

COMMENT ON TABLE hr.expense_sheets IS 'COR-064: Expense reports';
COMMENT ON TABLE hr.expenses IS 'COR-064: Individual expense lines';

-- =====================================================
-- COR-065: Employee Resume Lines
-- Historial de experiencia y educacion
-- =====================================================

CREATE TYPE hr.resume_line_type AS ENUM (
  'experience',
  'education',
  'certification',
  'internal'
);

CREATE TABLE hr.employee_resume_lines (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  employee_id UUID NOT NULL REFERENCES hr.employees(id) ON DELETE CASCADE,

  name VARCHAR(255) NOT NULL,
  date_start DATE,
  date_end DATE,
  description TEXT,
  line_type hr.resume_line_type NOT NULL,

  -- Para experiencia laboral
  company_name VARCHAR(255),
  job_title VARCHAR(255),

  -- Para educacion
  institution VARCHAR(255),
  degree VARCHAR(255),
  field_of_study VARCHAR(255),

  -- Para certificaciones
  certification_name VARCHAR(255),
  certification_id VARCHAR(100),
  expiry_date DATE,

  -- Orden
  display_type VARCHAR(50),  -- classic, course

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_employee_resume_lines_employee ON hr.employee_resume_lines(employee_id);
CREATE INDEX idx_employee_resume_lines_type ON hr.employee_resume_lines(line_type);

COMMENT ON TABLE hr.employee_resume_lines IS 'COR-065: Employee resume/CV lines';

-- =====================================================
-- COR-066: Payslip Basics
-- Estructura basica de nomina (sin calculos complejos)
-- =====================================================

CREATE TYPE hr.payslip_status AS ENUM (
  'draft',
  'verify',
  'done',
  'cancel'
);

CREATE TABLE hr.payslip_structures (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
  name VARCHAR(100) NOT NULL,
  code VARCHAR(50),
  is_active BOOLEAN DEFAULT TRUE,
  note TEXT,
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  UNIQUE(tenant_id, code)
);

CREATE TABLE hr.payslips (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
  company_id UUID NOT NULL REFERENCES auth.companies(id) ON DELETE CASCADE,
  employee_id UUID NOT NULL REFERENCES hr.employees(id),
  contract_id UUID REFERENCES hr.contracts(id),

  name VARCHAR(255) NOT NULL,
  number VARCHAR(100),
  state hr.payslip_status DEFAULT 'draft',

  -- Periodo
  date_from DATE NOT NULL,
  date_to DATE NOT NULL,
  date DATE,  -- Fecha de pago

  -- Estructura
  structure_id UUID REFERENCES hr.payslip_structures(id),

  -- Montos
  basic_wage DECIMAL(20,6),
  gross_wage DECIMAL(20,6),
  net_wage DECIMAL(20,6),

  -- Horas
  worked_days DECIMAL(10,2),
  worked_hours DECIMAL(10,2),

  -- Contabilidad
  journal_id UUID,  -- FK to financial.journals
  move_id UUID,  -- FK to financial.journal_entries

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created_by UUID REFERENCES auth.users(id),
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE hr.payslip_lines (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  payslip_id UUID NOT NULL REFERENCES hr.payslips(id) ON DELETE CASCADE,

  name VARCHAR(255) NOT NULL,
  code VARCHAR(50) NOT NULL,  -- BASIC, GROSS, NET, etc.
  sequence INTEGER DEFAULT 10,

  -- Tipo de linea
  category VARCHAR(50),  -- earning, deduction, company_contribution

  -- Montos
  quantity DECIMAL(20,6) DEFAULT 1,
  rate DECIMAL(10,4) DEFAULT 100,
  amount DECIMAL(20,6) NOT NULL DEFAULT 0,
  total DECIMAL(20,6) NOT NULL DEFAULT 0,

  -- Control
  appears_on_payslip BOOLEAN DEFAULT TRUE,

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_payslip_structures_tenant ON hr.payslip_structures(tenant_id);
CREATE INDEX idx_payslips_tenant ON hr.payslips(tenant_id);
CREATE INDEX idx_payslips_employee ON hr.payslips(employee_id);
CREATE INDEX idx_payslips_contract ON hr.payslips(contract_id);
CREATE INDEX idx_payslips_state ON hr.payslips(state);
CREATE INDEX idx_payslips_period ON hr.payslips(date_from, date_to);
CREATE INDEX idx_payslip_lines_payslip ON hr.payslip_lines(payslip_id);

-- RLS
ALTER TABLE hr.payslip_structures ENABLE ROW LEVEL SECURITY;
ALTER TABLE hr.payslips ENABLE ROW LEVEL SECURITY;

CREATE POLICY tenant_isolation_payslip_structures ON hr.payslip_structures
  USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);
CREATE POLICY tenant_isolation_payslips ON hr.payslips
  USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);

COMMENT ON TABLE hr.payslip_structures IS 'COR-066: Payslip structures';
COMMENT ON TABLE hr.payslips IS 'COR-066: Employee payslips';
COMMENT ON TABLE hr.payslip_lines IS 'COR-066: Payslip detail lines';

-- =====================================================
-- FIN DEL SCHEMA HR
-- =====================================================
