- Add CONTEXT-MAP.yml and ENVIRONMENT-INVENTORY.yml - Add propagacion-fase8 directory - Update CONTEXTO-PROYECTO.md and DEPENDENCIAS-SHARED.yml 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
182 lines
6.7 KiB
SQL
182 lines
6.7 KiB
SQL
-- ============================================================================
|
|
-- HR EXTENSIONS - FASE 8 ERP-Core
|
|
-- ERP Vidrio Templado
|
|
-- ============================================================================
|
|
|
|
CREATE SCHEMA IF NOT EXISTS hr;
|
|
|
|
DO $$ BEGIN
|
|
CREATE TYPE hr.expense_status AS ENUM ('draft', 'submitted', 'approved', 'posted', 'paid', 'rejected');
|
|
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
END $$;
|
|
|
|
DO $$ BEGIN
|
|
CREATE TYPE hr.payslip_status AS ENUM ('draft', 'verify', 'done', 'cancel');
|
|
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
END $$;
|
|
|
|
-- Ubicaciones (áreas de producción)
|
|
CREATE TABLE IF NOT EXISTS hr.work_locations (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
name VARCHAR(100) NOT NULL,
|
|
-- Extensiones vidrio
|
|
tipo_area VARCHAR(50), -- 'corte', 'pulido', 'templado', 'almacen', 'instalacion'
|
|
capacidad_m2 NUMERIC(10,2),
|
|
tiene_horno BOOLEAN DEFAULT false,
|
|
temperatura_max INTEGER,
|
|
active BOOLEAN DEFAULT true,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- Tipos de habilidad
|
|
CREATE TABLE IF NOT EXISTS hr.skill_types (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
name VARCHAR(100) NOT NULL,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- Habilidades
|
|
CREATE TABLE IF NOT EXISTS hr.skills (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
skill_type_id UUID REFERENCES hr.skill_types(id),
|
|
name VARCHAR(100) NOT NULL,
|
|
-- Extensiones vidrio
|
|
tipo_proceso VARCHAR(50), -- 'corte', 'biselado', 'templado', 'instalacion'
|
|
maquina_habilitado VARCHAR(100),
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- Niveles
|
|
CREATE TABLE IF NOT EXISTS hr.skill_levels (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
skill_type_id UUID REFERENCES hr.skill_types(id),
|
|
name VARCHAR(100) NOT NULL,
|
|
level INTEGER DEFAULT 1,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- Habilidades de empleado
|
|
CREATE TABLE IF NOT EXISTS hr.employee_skills (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
employee_id UUID NOT NULL,
|
|
skill_id UUID REFERENCES hr.skills(id),
|
|
skill_level_id UUID REFERENCES hr.skill_levels(id),
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- Gastos
|
|
CREATE TABLE IF NOT EXISTS hr.expense_sheets (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
employee_id UUID NOT NULL,
|
|
name VARCHAR(100) NOT NULL,
|
|
state hr.expense_status DEFAULT 'draft',
|
|
total_amount NUMERIC(12,2) DEFAULT 0,
|
|
proyecto_id UUID,
|
|
obra_id UUID,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS hr.expenses (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
sheet_id UUID REFERENCES hr.expense_sheets(id) ON DELETE CASCADE,
|
|
employee_id UUID NOT NULL,
|
|
name VARCHAR(200) NOT NULL,
|
|
date DATE DEFAULT CURRENT_DATE,
|
|
total_amount NUMERIC(12,2) NOT NULL,
|
|
state hr.expense_status DEFAULT 'draft',
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- Nómina
|
|
CREATE TABLE IF NOT EXISTS hr.payslip_structures (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
name VARCHAR(100) NOT NULL,
|
|
code VARCHAR(20) NOT NULL,
|
|
tipo_pago VARCHAR(50),
|
|
active BOOLEAN DEFAULT true,
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
CONSTRAINT uq_payslip_structures_code UNIQUE(tenant_id, code)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS hr.payslips (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
employee_id UUID NOT NULL,
|
|
structure_id UUID REFERENCES hr.payslip_structures(id),
|
|
date_from DATE NOT NULL,
|
|
date_to DATE NOT NULL,
|
|
state hr.payslip_status DEFAULT 'draft',
|
|
gross NUMERIC(12,2) DEFAULT 0,
|
|
net NUMERIC(12,2) DEFAULT 0,
|
|
area_id UUID REFERENCES hr.work_locations(id),
|
|
metros_producidos NUMERIC(10,2),
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS hr.payslip_lines (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
payslip_id UUID REFERENCES hr.payslips(id) ON DELETE CASCADE,
|
|
name VARCHAR(100) NOT NULL,
|
|
code VARCHAR(20),
|
|
amount NUMERIC(12,2) DEFAULT 0,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- Índices
|
|
CREATE INDEX IF NOT EXISTS idx_work_locations_tenant ON hr.work_locations(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_skill_types_tenant ON hr.skill_types(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_skills_tenant ON hr.skills(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_expense_sheets_tenant ON hr.expense_sheets(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_payslips_tenant ON hr.payslips(tenant_id);
|
|
|
|
-- RLS
|
|
ALTER TABLE hr.work_locations ENABLE ROW LEVEL SECURITY;
|
|
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;
|
|
ALTER TABLE hr.expense_sheets ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE hr.expenses ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE hr.payslip_structures ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE hr.payslips ENABLE ROW LEVEL SECURITY;
|
|
|
|
DROP POLICY IF EXISTS tenant_isolation_work_locations ON hr.work_locations;
|
|
CREATE POLICY tenant_isolation_work_locations ON hr.work_locations
|
|
USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
|
|
|
|
DROP POLICY IF EXISTS tenant_isolation_skill_types ON hr.skill_types;
|
|
CREATE POLICY tenant_isolation_skill_types ON hr.skill_types
|
|
USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
|
|
|
|
DROP POLICY IF EXISTS tenant_isolation_skills ON hr.skills;
|
|
CREATE POLICY tenant_isolation_skills ON hr.skills
|
|
USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
|
|
|
|
DROP POLICY IF EXISTS tenant_isolation_skill_levels ON hr.skill_levels;
|
|
CREATE POLICY tenant_isolation_skill_levels ON hr.skill_levels
|
|
USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
|
|
|
|
DROP POLICY IF EXISTS tenant_isolation_expense_sheets ON hr.expense_sheets;
|
|
CREATE POLICY tenant_isolation_expense_sheets ON hr.expense_sheets
|
|
USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
|
|
|
|
DROP POLICY IF EXISTS tenant_isolation_expenses ON hr.expenses;
|
|
CREATE POLICY tenant_isolation_expenses ON hr.expenses
|
|
USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
|
|
|
|
DROP POLICY IF EXISTS tenant_isolation_payslip_structures ON hr.payslip_structures;
|
|
CREATE POLICY tenant_isolation_payslip_structures ON hr.payslip_structures
|
|
USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
|
|
|
|
DROP POLICY IF EXISTS tenant_isolation_payslips ON hr.payslips;
|
|
CREATE POLICY tenant_isolation_payslips ON hr.payslips
|
|
USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
|