[MAE-015] feat: Add assets schema DDL with 11 tables and 9 ENUMs
- asset_categories: Categorias de activos - assets: Catalogo principal de activos - asset_assignments: Asignaciones a proyectos - maintenance_plans: Planes de mantenimiento preventivo - maintenance_schedules: Programacion de mantenimientos - work_orders: Ordenes de trabajo - work_order_parts: Refacciones utilizadas - maintenance_history: Historial de mantenimientos - asset_costs: Costos TCO - asset_locations: Ubicaciones GPS - fuel_logs: Registro de combustible Includes: RLS, indices, triggers, TCO calculation function Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
3e3d2d6eac
commit
e927cafc90
964
schemas/09-assets-schema-ddl.sql
Normal file
964
schemas/09-assets-schema-ddl.sql
Normal file
@ -0,0 +1,964 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- 09-assets-schema-ddl.sql
|
||||||
|
-- Schema: assets
|
||||||
|
-- ERP Construccion - Modulo Activos, Maquinaria y Mantenimiento (MAE-015)
|
||||||
|
-- ============================================================================
|
||||||
|
-- Descripcion: Gestion de activos fijos y maquinaria incluyendo:
|
||||||
|
-- - Catalogo de activos (maquinaria, equipo, vehiculos)
|
||||||
|
-- - Asignaciones a obras/proyectos
|
||||||
|
-- - Planes de mantenimiento preventivo
|
||||||
|
-- - Ordenes de trabajo de mantenimiento
|
||||||
|
-- - Historial de mantenimientos
|
||||||
|
-- - Costeo TCO (Total Cost of Ownership)
|
||||||
|
-- - Rastreo GPS (IoT)
|
||||||
|
-- ============================================================================
|
||||||
|
-- Autor: Claude-Arquitecto-Orquestador
|
||||||
|
-- Fecha: 2026-01-25
|
||||||
|
-- Version: 1.0.0
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
-- Crear schema si no existe
|
||||||
|
CREATE SCHEMA IF NOT EXISTS assets;
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- ENUMS
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
-- Tipo de activo
|
||||||
|
CREATE TYPE assets.asset_type AS ENUM (
|
||||||
|
'heavy_machinery', -- Maquinaria pesada (excavadoras, gruas)
|
||||||
|
'light_equipment', -- Equipo ligero (compactadoras, mezcladoras)
|
||||||
|
'vehicle', -- Vehiculos (camiones, camionetas)
|
||||||
|
'tool', -- Herramientas (taladros, sierras)
|
||||||
|
'computer', -- Equipo de computo
|
||||||
|
'furniture', -- Mobiliario
|
||||||
|
'other' -- Otro
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Estado del activo
|
||||||
|
CREATE TYPE assets.asset_status AS ENUM (
|
||||||
|
'available', -- Disponible
|
||||||
|
'assigned', -- Asignado a obra
|
||||||
|
'in_maintenance', -- En mantenimiento
|
||||||
|
'in_transit', -- En transito entre obras
|
||||||
|
'inactive', -- Inactivo
|
||||||
|
'retired', -- Dado de baja
|
||||||
|
'sold' -- Vendido
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Tipo de propiedad
|
||||||
|
CREATE TYPE assets.ownership_type AS ENUM (
|
||||||
|
'owned', -- Propio
|
||||||
|
'leased', -- Arrendado
|
||||||
|
'rented', -- Rentado
|
||||||
|
'borrowed' -- Prestamo
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Tipo de mantenimiento
|
||||||
|
CREATE TYPE assets.maintenance_type AS ENUM (
|
||||||
|
'preventive', -- Preventivo
|
||||||
|
'corrective', -- Correctivo
|
||||||
|
'predictive', -- Predictivo
|
||||||
|
'emergency' -- Emergencia
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Frecuencia de mantenimiento
|
||||||
|
CREATE TYPE assets.maintenance_frequency AS ENUM (
|
||||||
|
'daily', -- Diario
|
||||||
|
'weekly', -- Semanal
|
||||||
|
'biweekly', -- Quincenal
|
||||||
|
'monthly', -- Mensual
|
||||||
|
'quarterly', -- Trimestral
|
||||||
|
'semiannual', -- Semestral
|
||||||
|
'annual', -- Anual
|
||||||
|
'by_hours', -- Por horas de operacion
|
||||||
|
'by_kilometers' -- Por kilometros
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Estado de orden de trabajo
|
||||||
|
CREATE TYPE assets.work_order_status AS ENUM (
|
||||||
|
'draft', -- Borrador
|
||||||
|
'scheduled', -- Programada
|
||||||
|
'in_progress', -- En progreso
|
||||||
|
'on_hold', -- En espera
|
||||||
|
'completed', -- Completada
|
||||||
|
'cancelled' -- Cancelada
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Prioridad de orden de trabajo
|
||||||
|
CREATE TYPE assets.work_order_priority AS ENUM (
|
||||||
|
'low', -- Baja
|
||||||
|
'medium', -- Media
|
||||||
|
'high', -- Alta
|
||||||
|
'critical' -- Critica
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Tipo de costo
|
||||||
|
CREATE TYPE assets.cost_type AS ENUM (
|
||||||
|
'maintenance', -- Mantenimiento
|
||||||
|
'repair', -- Reparacion
|
||||||
|
'fuel', -- Combustible
|
||||||
|
'insurance', -- Seguro
|
||||||
|
'tax', -- Impuestos
|
||||||
|
'depreciation', -- Depreciacion
|
||||||
|
'operator', -- Operador
|
||||||
|
'other' -- Otro
|
||||||
|
);
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- TABLAS
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
-- 1. Categorias de Activos
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
CREATE TABLE assets.asset_categories (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
tenant_id UUID NOT NULL,
|
||||||
|
|
||||||
|
-- Informacion basica
|
||||||
|
code VARCHAR(20) NOT NULL,
|
||||||
|
name VARCHAR(100) NOT NULL,
|
||||||
|
description TEXT,
|
||||||
|
|
||||||
|
-- Jerarquia
|
||||||
|
parent_id UUID REFERENCES assets.asset_categories(id),
|
||||||
|
level INTEGER NOT NULL DEFAULT 1,
|
||||||
|
|
||||||
|
-- Configuracion de depreciacion
|
||||||
|
useful_life_years INTEGER,
|
||||||
|
depreciation_method VARCHAR(50), -- straight_line, declining_balance, units_of_production
|
||||||
|
salvage_value_percentage DECIMAL(5,2),
|
||||||
|
|
||||||
|
-- Estado
|
||||||
|
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||||
|
|
||||||
|
-- Metadatos
|
||||||
|
metadata JSONB,
|
||||||
|
|
||||||
|
-- Auditoria
|
||||||
|
created_by UUID,
|
||||||
|
updated_by UUID,
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
deleted_at TIMESTAMPTZ,
|
||||||
|
|
||||||
|
CONSTRAINT uq_asset_categories_tenant_code UNIQUE (tenant_id, code)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
-- 2. Activos (Catalogo Principal)
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
CREATE TABLE assets.assets (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
tenant_id UUID NOT NULL,
|
||||||
|
|
||||||
|
-- Identificacion
|
||||||
|
asset_code VARCHAR(50) NOT NULL,
|
||||||
|
name VARCHAR(255) NOT NULL,
|
||||||
|
description TEXT,
|
||||||
|
|
||||||
|
-- Clasificacion
|
||||||
|
category_id UUID REFERENCES assets.asset_categories(id),
|
||||||
|
asset_type assets.asset_type NOT NULL,
|
||||||
|
status assets.asset_status NOT NULL DEFAULT 'available',
|
||||||
|
ownership_type assets.ownership_type NOT NULL DEFAULT 'owned',
|
||||||
|
|
||||||
|
-- Especificaciones tecnicas
|
||||||
|
brand VARCHAR(100),
|
||||||
|
model VARCHAR(100),
|
||||||
|
serial_number VARCHAR(100),
|
||||||
|
year_manufactured INTEGER,
|
||||||
|
specifications JSONB,
|
||||||
|
|
||||||
|
-- Capacidades
|
||||||
|
capacity VARCHAR(100),
|
||||||
|
power_rating VARCHAR(50),
|
||||||
|
fuel_type VARCHAR(50),
|
||||||
|
fuel_capacity DECIMAL(10,2),
|
||||||
|
fuel_consumption_rate DECIMAL(10,2), -- litros/hora o km/litro
|
||||||
|
|
||||||
|
-- Metricas de uso
|
||||||
|
current_hours DECIMAL(12,2) DEFAULT 0,
|
||||||
|
current_kilometers DECIMAL(12,2) DEFAULT 0,
|
||||||
|
last_usage_update TIMESTAMPTZ,
|
||||||
|
|
||||||
|
-- Ubicacion actual
|
||||||
|
current_project_id UUID,
|
||||||
|
current_location_name VARCHAR(255),
|
||||||
|
current_latitude DECIMAL(10,8),
|
||||||
|
current_longitude DECIMAL(11,8),
|
||||||
|
last_location_update TIMESTAMPTZ,
|
||||||
|
|
||||||
|
-- Informacion financiera
|
||||||
|
purchase_date DATE,
|
||||||
|
purchase_price DECIMAL(18,2),
|
||||||
|
purchase_currency VARCHAR(3) DEFAULT 'MXN',
|
||||||
|
supplier_id UUID,
|
||||||
|
invoice_number VARCHAR(100),
|
||||||
|
|
||||||
|
-- Depreciacion
|
||||||
|
useful_life_years INTEGER,
|
||||||
|
salvage_value DECIMAL(18,2),
|
||||||
|
current_book_value DECIMAL(18,2),
|
||||||
|
accumulated_depreciation DECIMAL(18,2) DEFAULT 0,
|
||||||
|
depreciation_method VARCHAR(50),
|
||||||
|
last_depreciation_date DATE,
|
||||||
|
|
||||||
|
-- Arrendamiento (si aplica)
|
||||||
|
lease_start_date DATE,
|
||||||
|
lease_end_date DATE,
|
||||||
|
lease_monthly_rate DECIMAL(18,2),
|
||||||
|
lease_contract_number VARCHAR(100),
|
||||||
|
lessor_name VARCHAR(255),
|
||||||
|
|
||||||
|
-- Seguro
|
||||||
|
insurance_policy_number VARCHAR(100),
|
||||||
|
insurance_company VARCHAR(255),
|
||||||
|
insurance_expiry_date DATE,
|
||||||
|
insurance_coverage_amount DECIMAL(18,2),
|
||||||
|
|
||||||
|
-- Documentos
|
||||||
|
photo_url VARCHAR(500),
|
||||||
|
manual_url VARCHAR(500),
|
||||||
|
registration_document_url VARCHAR(500),
|
||||||
|
|
||||||
|
-- Proximo mantenimiento
|
||||||
|
next_maintenance_date DATE,
|
||||||
|
next_maintenance_hours DECIMAL(12,2),
|
||||||
|
next_maintenance_kilometers DECIMAL(12,2),
|
||||||
|
|
||||||
|
-- Operador asignado
|
||||||
|
assigned_operator_id UUID,
|
||||||
|
|
||||||
|
-- Notas y metadatos
|
||||||
|
notes TEXT,
|
||||||
|
tags VARCHAR(255)[],
|
||||||
|
metadata JSONB,
|
||||||
|
|
||||||
|
-- Auditoria
|
||||||
|
created_by UUID,
|
||||||
|
updated_by UUID,
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
deleted_at TIMESTAMPTZ,
|
||||||
|
|
||||||
|
CONSTRAINT uq_assets_tenant_code UNIQUE (tenant_id, asset_code)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
-- 3. Asignaciones de Activos a Obras
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
CREATE TABLE assets.asset_assignments (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
tenant_id UUID NOT NULL,
|
||||||
|
|
||||||
|
-- Activo y proyecto
|
||||||
|
asset_id UUID NOT NULL REFERENCES assets.assets(id),
|
||||||
|
project_id UUID NOT NULL,
|
||||||
|
project_code VARCHAR(50),
|
||||||
|
project_name VARCHAR(255),
|
||||||
|
|
||||||
|
-- Periodo de asignacion
|
||||||
|
start_date DATE NOT NULL,
|
||||||
|
end_date DATE,
|
||||||
|
is_current BOOLEAN NOT NULL DEFAULT TRUE,
|
||||||
|
|
||||||
|
-- Ubicacion especifica en obra
|
||||||
|
location_in_project VARCHAR(255),
|
||||||
|
latitude DECIMAL(10,8),
|
||||||
|
longitude DECIMAL(11,8),
|
||||||
|
|
||||||
|
-- Operador asignado
|
||||||
|
operator_id UUID,
|
||||||
|
operator_name VARCHAR(255),
|
||||||
|
|
||||||
|
-- Responsable
|
||||||
|
responsible_id UUID,
|
||||||
|
responsible_name VARCHAR(255),
|
||||||
|
|
||||||
|
-- Metricas al inicio/fin
|
||||||
|
hours_at_start DECIMAL(12,2),
|
||||||
|
hours_at_end DECIMAL(12,2),
|
||||||
|
kilometers_at_start DECIMAL(12,2),
|
||||||
|
kilometers_at_end DECIMAL(12,2),
|
||||||
|
|
||||||
|
-- Tarifas
|
||||||
|
daily_rate DECIMAL(18,2),
|
||||||
|
hourly_rate DECIMAL(18,2),
|
||||||
|
|
||||||
|
-- Razon de transferencia
|
||||||
|
transfer_reason TEXT,
|
||||||
|
transfer_notes TEXT,
|
||||||
|
|
||||||
|
-- Documento de entrega
|
||||||
|
delivery_document_url VARCHAR(500),
|
||||||
|
return_document_url VARCHAR(500),
|
||||||
|
|
||||||
|
-- Metadatos
|
||||||
|
metadata JSONB,
|
||||||
|
|
||||||
|
-- Auditoria
|
||||||
|
created_by UUID,
|
||||||
|
updated_by UUID,
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
-- 4. Planes de Mantenimiento
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
CREATE TABLE assets.maintenance_plans (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
tenant_id UUID NOT NULL,
|
||||||
|
|
||||||
|
-- Identificacion
|
||||||
|
plan_code VARCHAR(50) NOT NULL,
|
||||||
|
name VARCHAR(255) NOT NULL,
|
||||||
|
description TEXT,
|
||||||
|
|
||||||
|
-- Aplica a
|
||||||
|
asset_id UUID REFERENCES assets.assets(id), -- Si es especifico de un activo
|
||||||
|
category_id UUID REFERENCES assets.asset_categories(id), -- Si aplica a categoria
|
||||||
|
asset_type assets.asset_type, -- Si aplica a tipo
|
||||||
|
|
||||||
|
-- Tipo y frecuencia
|
||||||
|
maintenance_type assets.maintenance_type NOT NULL DEFAULT 'preventive',
|
||||||
|
frequency assets.maintenance_frequency NOT NULL,
|
||||||
|
frequency_value INTEGER, -- Cada cuantas unidades (dias, horas, km)
|
||||||
|
|
||||||
|
-- Actividades del plan
|
||||||
|
activities JSONB NOT NULL, -- Array de actividades con checklist
|
||||||
|
|
||||||
|
-- Duracion estimada
|
||||||
|
estimated_duration_hours DECIMAL(5,2),
|
||||||
|
|
||||||
|
-- Recursos necesarios
|
||||||
|
required_parts JSONB, -- Refacciones necesarias
|
||||||
|
required_tools JSONB, -- Herramientas necesarias
|
||||||
|
required_skills VARCHAR(255)[], -- Habilidades requeridas
|
||||||
|
|
||||||
|
-- Costos estimados
|
||||||
|
estimated_labor_cost DECIMAL(18,2),
|
||||||
|
estimated_parts_cost DECIMAL(18,2),
|
||||||
|
estimated_total_cost DECIMAL(18,2),
|
||||||
|
|
||||||
|
-- Estado
|
||||||
|
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||||
|
|
||||||
|
-- Metadatos
|
||||||
|
metadata JSONB,
|
||||||
|
|
||||||
|
-- Auditoria
|
||||||
|
created_by UUID,
|
||||||
|
updated_by UUID,
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
deleted_at TIMESTAMPTZ,
|
||||||
|
|
||||||
|
CONSTRAINT uq_maintenance_plans_tenant_code UNIQUE (tenant_id, plan_code)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
-- 5. Programacion de Mantenimientos
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
CREATE TABLE assets.maintenance_schedules (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
tenant_id UUID NOT NULL,
|
||||||
|
|
||||||
|
-- Activo y plan
|
||||||
|
asset_id UUID NOT NULL REFERENCES assets.assets(id),
|
||||||
|
plan_id UUID REFERENCES assets.maintenance_plans(id),
|
||||||
|
|
||||||
|
-- Programacion
|
||||||
|
scheduled_date DATE NOT NULL,
|
||||||
|
scheduled_hours DECIMAL(12,2), -- Horas del equipo cuando debe hacerse
|
||||||
|
scheduled_kilometers DECIMAL(12,2), -- KM cuando debe hacerse
|
||||||
|
|
||||||
|
-- Estado
|
||||||
|
status VARCHAR(20) NOT NULL DEFAULT 'pending', -- pending, completed, skipped, overdue
|
||||||
|
completed_date DATE,
|
||||||
|
|
||||||
|
-- Orden de trabajo generada
|
||||||
|
work_order_id UUID,
|
||||||
|
|
||||||
|
-- Alertas
|
||||||
|
alert_days_before INTEGER DEFAULT 7,
|
||||||
|
alert_sent BOOLEAN DEFAULT FALSE,
|
||||||
|
alert_sent_at TIMESTAMPTZ,
|
||||||
|
|
||||||
|
-- Notas
|
||||||
|
notes TEXT,
|
||||||
|
|
||||||
|
-- Auditoria
|
||||||
|
created_by UUID,
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
-- 6. Ordenes de Trabajo de Mantenimiento
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
CREATE TABLE assets.work_orders (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
tenant_id UUID NOT NULL,
|
||||||
|
|
||||||
|
-- Identificacion
|
||||||
|
work_order_number VARCHAR(50) NOT NULL,
|
||||||
|
|
||||||
|
-- Activo
|
||||||
|
asset_id UUID NOT NULL REFERENCES assets.assets(id),
|
||||||
|
asset_code VARCHAR(50),
|
||||||
|
asset_name VARCHAR(255),
|
||||||
|
|
||||||
|
-- Tipo y estado
|
||||||
|
maintenance_type assets.maintenance_type NOT NULL,
|
||||||
|
status assets.work_order_status NOT NULL DEFAULT 'draft',
|
||||||
|
priority assets.work_order_priority NOT NULL DEFAULT 'medium',
|
||||||
|
|
||||||
|
-- Origen
|
||||||
|
schedule_id UUID REFERENCES assets.maintenance_schedules(id),
|
||||||
|
plan_id UUID REFERENCES assets.maintenance_plans(id),
|
||||||
|
is_scheduled BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
|
|
||||||
|
-- Descripcion
|
||||||
|
title VARCHAR(255) NOT NULL,
|
||||||
|
description TEXT,
|
||||||
|
problem_reported TEXT,
|
||||||
|
diagnosis TEXT,
|
||||||
|
|
||||||
|
-- Ubicacion
|
||||||
|
project_id UUID,
|
||||||
|
project_name VARCHAR(255),
|
||||||
|
location_description VARCHAR(255),
|
||||||
|
|
||||||
|
-- Fechas
|
||||||
|
requested_date DATE NOT NULL,
|
||||||
|
scheduled_start_date DATE,
|
||||||
|
scheduled_end_date DATE,
|
||||||
|
actual_start_date DATE,
|
||||||
|
actual_end_date DATE,
|
||||||
|
|
||||||
|
-- Metricas del equipo al momento
|
||||||
|
hours_at_work_order DECIMAL(12,2),
|
||||||
|
kilometers_at_work_order DECIMAL(12,2),
|
||||||
|
|
||||||
|
-- Asignacion
|
||||||
|
assigned_to_id UUID,
|
||||||
|
assigned_to_name VARCHAR(255),
|
||||||
|
team_ids UUID[],
|
||||||
|
|
||||||
|
-- Solicitante
|
||||||
|
requested_by_id UUID,
|
||||||
|
requested_by_name VARCHAR(255),
|
||||||
|
|
||||||
|
-- Aprobacion
|
||||||
|
approved_by_id UUID,
|
||||||
|
approved_at TIMESTAMPTZ,
|
||||||
|
|
||||||
|
-- Trabajo realizado
|
||||||
|
work_performed TEXT,
|
||||||
|
findings TEXT,
|
||||||
|
recommendations TEXT,
|
||||||
|
|
||||||
|
-- Checklist de actividades
|
||||||
|
activities_checklist JSONB,
|
||||||
|
|
||||||
|
-- Tiempos
|
||||||
|
estimated_hours DECIMAL(5,2),
|
||||||
|
actual_hours DECIMAL(5,2),
|
||||||
|
|
||||||
|
-- Costos
|
||||||
|
labor_cost DECIMAL(18,2) DEFAULT 0,
|
||||||
|
parts_cost DECIMAL(18,2) DEFAULT 0,
|
||||||
|
external_service_cost DECIMAL(18,2) DEFAULT 0,
|
||||||
|
other_costs DECIMAL(18,2) DEFAULT 0,
|
||||||
|
total_cost DECIMAL(18,2) DEFAULT 0,
|
||||||
|
|
||||||
|
-- Partes utilizadas (detalle en tabla separada)
|
||||||
|
parts_used_count INTEGER DEFAULT 0,
|
||||||
|
|
||||||
|
-- Documentos
|
||||||
|
photos_before JSONB, -- URLs de fotos antes
|
||||||
|
photos_after JSONB, -- URLs de fotos despues
|
||||||
|
documents JSONB, -- URLs de documentos adjuntos
|
||||||
|
|
||||||
|
-- Firma de conformidad
|
||||||
|
completed_by_id UUID,
|
||||||
|
completed_by_name VARCHAR(255),
|
||||||
|
completion_signature_url VARCHAR(500),
|
||||||
|
completion_notes TEXT,
|
||||||
|
|
||||||
|
-- Seguimiento
|
||||||
|
requires_followup BOOLEAN DEFAULT FALSE,
|
||||||
|
followup_notes TEXT,
|
||||||
|
followup_work_order_id UUID,
|
||||||
|
|
||||||
|
-- Notas y metadatos
|
||||||
|
notes TEXT,
|
||||||
|
metadata JSONB,
|
||||||
|
|
||||||
|
-- Auditoria
|
||||||
|
created_by UUID,
|
||||||
|
updated_by UUID,
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
deleted_at TIMESTAMPTZ,
|
||||||
|
|
||||||
|
CONSTRAINT uq_work_orders_tenant_number UNIQUE (tenant_id, work_order_number)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
-- 7. Partes/Refacciones Utilizadas en Ordenes de Trabajo
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
CREATE TABLE assets.work_order_parts (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
tenant_id UUID NOT NULL,
|
||||||
|
|
||||||
|
-- Orden de trabajo
|
||||||
|
work_order_id UUID NOT NULL REFERENCES assets.work_orders(id) ON DELETE CASCADE,
|
||||||
|
|
||||||
|
-- Parte/Refaccion
|
||||||
|
part_id UUID, -- Referencia a inventario si existe
|
||||||
|
part_code VARCHAR(50),
|
||||||
|
part_name VARCHAR(255) NOT NULL,
|
||||||
|
part_description TEXT,
|
||||||
|
|
||||||
|
-- Cantidades
|
||||||
|
quantity_required DECIMAL(10,2) NOT NULL,
|
||||||
|
quantity_used DECIMAL(10,2),
|
||||||
|
|
||||||
|
-- Costos
|
||||||
|
unit_cost DECIMAL(18,2),
|
||||||
|
total_cost DECIMAL(18,2),
|
||||||
|
|
||||||
|
-- Origen
|
||||||
|
from_inventory BOOLEAN DEFAULT FALSE,
|
||||||
|
purchase_order_id UUID, -- Si se compro especificamente
|
||||||
|
|
||||||
|
-- Notas
|
||||||
|
notes TEXT,
|
||||||
|
|
||||||
|
-- Auditoria
|
||||||
|
created_by UUID,
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
-- 8. Historial de Mantenimientos
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
CREATE TABLE assets.maintenance_history (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
tenant_id UUID NOT NULL,
|
||||||
|
|
||||||
|
-- Activo
|
||||||
|
asset_id UUID NOT NULL REFERENCES assets.assets(id),
|
||||||
|
|
||||||
|
-- Orden de trabajo (si aplica)
|
||||||
|
work_order_id UUID REFERENCES assets.work_orders(id),
|
||||||
|
|
||||||
|
-- Fecha y tipo
|
||||||
|
maintenance_date DATE NOT NULL,
|
||||||
|
maintenance_type assets.maintenance_type NOT NULL,
|
||||||
|
|
||||||
|
-- Descripcion
|
||||||
|
description TEXT NOT NULL,
|
||||||
|
work_performed TEXT,
|
||||||
|
|
||||||
|
-- Metricas al momento del mantenimiento
|
||||||
|
hours_at_maintenance DECIMAL(12,2),
|
||||||
|
kilometers_at_maintenance DECIMAL(12,2),
|
||||||
|
|
||||||
|
-- Costos
|
||||||
|
labor_cost DECIMAL(18,2) DEFAULT 0,
|
||||||
|
parts_cost DECIMAL(18,2) DEFAULT 0,
|
||||||
|
total_cost DECIMAL(18,2) DEFAULT 0,
|
||||||
|
|
||||||
|
-- Ejecutor
|
||||||
|
performed_by_id UUID,
|
||||||
|
performed_by_name VARCHAR(255),
|
||||||
|
vendor_name VARCHAR(255), -- Si fue externo
|
||||||
|
|
||||||
|
-- Documentos
|
||||||
|
documents JSONB,
|
||||||
|
|
||||||
|
-- Notas
|
||||||
|
notes TEXT,
|
||||||
|
|
||||||
|
-- Auditoria
|
||||||
|
created_by UUID,
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
-- 9. Costos de Activos
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
CREATE TABLE assets.asset_costs (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
tenant_id UUID NOT NULL,
|
||||||
|
|
||||||
|
-- Activo
|
||||||
|
asset_id UUID NOT NULL REFERENCES assets.assets(id),
|
||||||
|
|
||||||
|
-- Periodo
|
||||||
|
period_start DATE NOT NULL,
|
||||||
|
period_end DATE NOT NULL,
|
||||||
|
fiscal_year INTEGER NOT NULL,
|
||||||
|
fiscal_month INTEGER NOT NULL,
|
||||||
|
|
||||||
|
-- Proyecto (si aplica)
|
||||||
|
project_id UUID,
|
||||||
|
project_code VARCHAR(50),
|
||||||
|
|
||||||
|
-- Tipo de costo
|
||||||
|
cost_type assets.cost_type NOT NULL,
|
||||||
|
|
||||||
|
-- Descripcion
|
||||||
|
description VARCHAR(255),
|
||||||
|
reference_document VARCHAR(100),
|
||||||
|
|
||||||
|
-- Monto
|
||||||
|
amount DECIMAL(18,2) NOT NULL,
|
||||||
|
currency VARCHAR(3) DEFAULT 'MXN',
|
||||||
|
|
||||||
|
-- Uso asociado
|
||||||
|
hours_in_period DECIMAL(12,2),
|
||||||
|
kilometers_in_period DECIMAL(12,2),
|
||||||
|
|
||||||
|
-- Calculo de tarifa
|
||||||
|
cost_per_hour DECIMAL(18,4),
|
||||||
|
cost_per_kilometer DECIMAL(18,4),
|
||||||
|
|
||||||
|
-- Origen
|
||||||
|
source_module VARCHAR(50), -- work_order, fuel_log, invoice, etc.
|
||||||
|
source_id UUID,
|
||||||
|
|
||||||
|
-- Notas
|
||||||
|
notes TEXT,
|
||||||
|
metadata JSONB,
|
||||||
|
|
||||||
|
-- Auditoria
|
||||||
|
created_by UUID,
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
-- 10. Ubicaciones GPS (Historico)
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
CREATE TABLE assets.asset_locations (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
tenant_id UUID NOT NULL,
|
||||||
|
|
||||||
|
-- Activo
|
||||||
|
asset_id UUID NOT NULL REFERENCES assets.assets(id),
|
||||||
|
|
||||||
|
-- Ubicacion
|
||||||
|
latitude DECIMAL(10,8) NOT NULL,
|
||||||
|
longitude DECIMAL(11,8) NOT NULL,
|
||||||
|
altitude DECIMAL(8,2),
|
||||||
|
accuracy DECIMAL(6,2),
|
||||||
|
heading DECIMAL(5,2),
|
||||||
|
speed DECIMAL(6,2),
|
||||||
|
|
||||||
|
-- Timestamp
|
||||||
|
recorded_at TIMESTAMPTZ NOT NULL,
|
||||||
|
|
||||||
|
-- Contexto
|
||||||
|
project_id UUID,
|
||||||
|
location_name VARCHAR(255),
|
||||||
|
address VARCHAR(500),
|
||||||
|
|
||||||
|
-- Telemetria adicional
|
||||||
|
engine_status VARCHAR(20), -- on, off, idle
|
||||||
|
fuel_level DECIMAL(5,2),
|
||||||
|
odometer DECIMAL(12,2),
|
||||||
|
engine_hours DECIMAL(12,2),
|
||||||
|
battery_voltage DECIMAL(5,2),
|
||||||
|
|
||||||
|
-- Dispositivo
|
||||||
|
device_id VARCHAR(100),
|
||||||
|
device_type VARCHAR(50),
|
||||||
|
|
||||||
|
-- Metadatos
|
||||||
|
raw_data JSONB,
|
||||||
|
|
||||||
|
-- Auditoria
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
-- 11. Registro de Combustible
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
CREATE TABLE assets.fuel_logs (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
tenant_id UUID NOT NULL,
|
||||||
|
|
||||||
|
-- Activo
|
||||||
|
asset_id UUID NOT NULL REFERENCES assets.assets(id),
|
||||||
|
|
||||||
|
-- Fecha y ubicacion
|
||||||
|
log_date DATE NOT NULL,
|
||||||
|
log_time TIME,
|
||||||
|
project_id UUID,
|
||||||
|
location VARCHAR(255),
|
||||||
|
|
||||||
|
-- Combustible
|
||||||
|
fuel_type VARCHAR(50) NOT NULL,
|
||||||
|
quantity_liters DECIMAL(10,2) NOT NULL,
|
||||||
|
unit_price DECIMAL(18,4) NOT NULL,
|
||||||
|
total_cost DECIMAL(18,2) NOT NULL,
|
||||||
|
|
||||||
|
-- Metricas al cargar
|
||||||
|
odometer_reading DECIMAL(12,2),
|
||||||
|
hours_reading DECIMAL(12,2),
|
||||||
|
|
||||||
|
-- Rendimiento calculado
|
||||||
|
kilometers_since_last DECIMAL(12,2),
|
||||||
|
hours_since_last DECIMAL(12,2),
|
||||||
|
liters_per_100km DECIMAL(8,2),
|
||||||
|
liters_per_hour DECIMAL(8,2),
|
||||||
|
|
||||||
|
-- Proveedor
|
||||||
|
vendor_name VARCHAR(255),
|
||||||
|
invoice_number VARCHAR(100),
|
||||||
|
|
||||||
|
-- Operador
|
||||||
|
operator_id UUID,
|
||||||
|
operator_name VARCHAR(255),
|
||||||
|
|
||||||
|
-- Notas
|
||||||
|
notes TEXT,
|
||||||
|
|
||||||
|
-- Auditoria
|
||||||
|
created_by UUID,
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- INDICES
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
-- Asset Categories
|
||||||
|
CREATE INDEX idx_asset_categories_tenant ON assets.asset_categories(tenant_id);
|
||||||
|
CREATE INDEX idx_asset_categories_parent ON assets.asset_categories(parent_id);
|
||||||
|
|
||||||
|
-- Assets
|
||||||
|
CREATE INDEX idx_assets_tenant ON assets.assets(tenant_id);
|
||||||
|
CREATE INDEX idx_assets_tenant_type ON assets.assets(tenant_id, asset_type);
|
||||||
|
CREATE INDEX idx_assets_tenant_status ON assets.assets(tenant_id, status);
|
||||||
|
CREATE INDEX idx_assets_tenant_category ON assets.assets(tenant_id, category_id);
|
||||||
|
CREATE INDEX idx_assets_current_project ON assets.assets(tenant_id, current_project_id);
|
||||||
|
CREATE INDEX idx_assets_serial ON assets.assets(tenant_id, serial_number);
|
||||||
|
|
||||||
|
-- Asset Assignments
|
||||||
|
CREATE INDEX idx_asset_assignments_tenant ON assets.asset_assignments(tenant_id);
|
||||||
|
CREATE INDEX idx_asset_assignments_asset ON assets.asset_assignments(tenant_id, asset_id);
|
||||||
|
CREATE INDEX idx_asset_assignments_project ON assets.asset_assignments(tenant_id, project_id);
|
||||||
|
CREATE INDEX idx_asset_assignments_current ON assets.asset_assignments(tenant_id, is_current) WHERE is_current = TRUE;
|
||||||
|
|
||||||
|
-- Maintenance Plans
|
||||||
|
CREATE INDEX idx_maintenance_plans_tenant ON assets.maintenance_plans(tenant_id);
|
||||||
|
CREATE INDEX idx_maintenance_plans_asset ON assets.maintenance_plans(tenant_id, asset_id);
|
||||||
|
CREATE INDEX idx_maintenance_plans_category ON assets.maintenance_plans(tenant_id, category_id);
|
||||||
|
|
||||||
|
-- Maintenance Schedules
|
||||||
|
CREATE INDEX idx_maintenance_schedules_tenant ON assets.maintenance_schedules(tenant_id);
|
||||||
|
CREATE INDEX idx_maintenance_schedules_asset ON assets.maintenance_schedules(tenant_id, asset_id);
|
||||||
|
CREATE INDEX idx_maintenance_schedules_date ON assets.maintenance_schedules(tenant_id, scheduled_date);
|
||||||
|
CREATE INDEX idx_maintenance_schedules_status ON assets.maintenance_schedules(tenant_id, status);
|
||||||
|
|
||||||
|
-- Work Orders
|
||||||
|
CREATE INDEX idx_work_orders_tenant ON assets.work_orders(tenant_id);
|
||||||
|
CREATE INDEX idx_work_orders_asset ON assets.work_orders(tenant_id, asset_id);
|
||||||
|
CREATE INDEX idx_work_orders_status ON assets.work_orders(tenant_id, status);
|
||||||
|
CREATE INDEX idx_work_orders_scheduled_date ON assets.work_orders(tenant_id, scheduled_start_date);
|
||||||
|
CREATE INDEX idx_work_orders_project ON assets.work_orders(tenant_id, project_id);
|
||||||
|
|
||||||
|
-- Work Order Parts
|
||||||
|
CREATE INDEX idx_work_order_parts_work_order ON assets.work_order_parts(work_order_id);
|
||||||
|
|
||||||
|
-- Maintenance History
|
||||||
|
CREATE INDEX idx_maintenance_history_tenant ON assets.maintenance_history(tenant_id);
|
||||||
|
CREATE INDEX idx_maintenance_history_asset ON assets.maintenance_history(tenant_id, asset_id);
|
||||||
|
CREATE INDEX idx_maintenance_history_date ON assets.maintenance_history(tenant_id, maintenance_date);
|
||||||
|
|
||||||
|
-- Asset Costs
|
||||||
|
CREATE INDEX idx_asset_costs_tenant ON assets.asset_costs(tenant_id);
|
||||||
|
CREATE INDEX idx_asset_costs_asset ON assets.asset_costs(tenant_id, asset_id);
|
||||||
|
CREATE INDEX idx_asset_costs_period ON assets.asset_costs(tenant_id, period_start, period_end);
|
||||||
|
CREATE INDEX idx_asset_costs_type ON assets.asset_costs(tenant_id, cost_type);
|
||||||
|
CREATE INDEX idx_asset_costs_project ON assets.asset_costs(tenant_id, project_id);
|
||||||
|
|
||||||
|
-- Asset Locations
|
||||||
|
CREATE INDEX idx_asset_locations_tenant ON assets.asset_locations(tenant_id);
|
||||||
|
CREATE INDEX idx_asset_locations_asset ON assets.asset_locations(tenant_id, asset_id);
|
||||||
|
CREATE INDEX idx_asset_locations_recorded ON assets.asset_locations(tenant_id, recorded_at);
|
||||||
|
CREATE INDEX idx_asset_locations_geo ON assets.asset_locations USING gist (
|
||||||
|
ST_SetSRID(ST_MakePoint(longitude, latitude), 4326)
|
||||||
|
) WHERE longitude IS NOT NULL AND latitude IS NOT NULL;
|
||||||
|
|
||||||
|
-- Fuel Logs
|
||||||
|
CREATE INDEX idx_fuel_logs_tenant ON assets.fuel_logs(tenant_id);
|
||||||
|
CREATE INDEX idx_fuel_logs_asset ON assets.fuel_logs(tenant_id, asset_id);
|
||||||
|
CREATE INDEX idx_fuel_logs_date ON assets.fuel_logs(tenant_id, log_date);
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- ROW LEVEL SECURITY (RLS)
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
ALTER TABLE assets.asset_categories ENABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE assets.assets ENABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE assets.asset_assignments ENABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE assets.maintenance_plans ENABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE assets.maintenance_schedules ENABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE assets.work_orders ENABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE assets.work_order_parts ENABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE assets.maintenance_history ENABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE assets.asset_costs ENABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE assets.asset_locations ENABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE assets.fuel_logs ENABLE ROW LEVEL SECURITY;
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- TRIGGERS DE AUDITORIA
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION assets.set_updated_at()
|
||||||
|
RETURNS TRIGGER AS $$
|
||||||
|
BEGIN
|
||||||
|
NEW.updated_at = NOW();
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
CREATE TRIGGER trg_asset_categories_updated_at
|
||||||
|
BEFORE UPDATE ON assets.asset_categories
|
||||||
|
FOR EACH ROW EXECUTE FUNCTION assets.set_updated_at();
|
||||||
|
|
||||||
|
CREATE TRIGGER trg_assets_updated_at
|
||||||
|
BEFORE UPDATE ON assets.assets
|
||||||
|
FOR EACH ROW EXECUTE FUNCTION assets.set_updated_at();
|
||||||
|
|
||||||
|
CREATE TRIGGER trg_asset_assignments_updated_at
|
||||||
|
BEFORE UPDATE ON assets.asset_assignments
|
||||||
|
FOR EACH ROW EXECUTE FUNCTION assets.set_updated_at();
|
||||||
|
|
||||||
|
CREATE TRIGGER trg_maintenance_plans_updated_at
|
||||||
|
BEFORE UPDATE ON assets.maintenance_plans
|
||||||
|
FOR EACH ROW EXECUTE FUNCTION assets.set_updated_at();
|
||||||
|
|
||||||
|
CREATE TRIGGER trg_maintenance_schedules_updated_at
|
||||||
|
BEFORE UPDATE ON assets.maintenance_schedules
|
||||||
|
FOR EACH ROW EXECUTE FUNCTION assets.set_updated_at();
|
||||||
|
|
||||||
|
CREATE TRIGGER trg_work_orders_updated_at
|
||||||
|
BEFORE UPDATE ON assets.work_orders
|
||||||
|
FOR EACH ROW EXECUTE FUNCTION assets.set_updated_at();
|
||||||
|
|
||||||
|
CREATE TRIGGER trg_work_order_parts_updated_at
|
||||||
|
BEFORE UPDATE ON assets.work_order_parts
|
||||||
|
FOR EACH ROW EXECUTE FUNCTION assets.set_updated_at();
|
||||||
|
|
||||||
|
CREATE TRIGGER trg_asset_costs_updated_at
|
||||||
|
BEFORE UPDATE ON assets.asset_costs
|
||||||
|
FOR EACH ROW EXECUTE FUNCTION assets.set_updated_at();
|
||||||
|
|
||||||
|
CREATE TRIGGER trg_fuel_logs_updated_at
|
||||||
|
BEFORE UPDATE ON assets.fuel_logs
|
||||||
|
FOR EACH ROW EXECUTE FUNCTION assets.set_updated_at();
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- FUNCIONES AUXILIARES
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
-- Funcion para calcular TCO de un activo
|
||||||
|
CREATE OR REPLACE FUNCTION assets.calculate_asset_tco(
|
||||||
|
p_asset_id UUID,
|
||||||
|
p_tenant_id UUID,
|
||||||
|
p_from_date DATE DEFAULT NULL,
|
||||||
|
p_to_date DATE DEFAULT NULL
|
||||||
|
)
|
||||||
|
RETURNS TABLE (
|
||||||
|
total_cost DECIMAL(18,2),
|
||||||
|
maintenance_cost DECIMAL(18,2),
|
||||||
|
fuel_cost DECIMAL(18,2),
|
||||||
|
depreciation_cost DECIMAL(18,2),
|
||||||
|
other_costs DECIMAL(18,2),
|
||||||
|
total_hours DECIMAL(12,2),
|
||||||
|
total_kilometers DECIMAL(12,2),
|
||||||
|
cost_per_hour DECIMAL(18,4),
|
||||||
|
cost_per_kilometer DECIMAL(18,4)
|
||||||
|
) AS $$
|
||||||
|
DECLARE
|
||||||
|
v_from_date DATE;
|
||||||
|
v_to_date DATE;
|
||||||
|
BEGIN
|
||||||
|
v_from_date := COALESCE(p_from_date, '1900-01-01'::DATE);
|
||||||
|
v_to_date := COALESCE(p_to_date, CURRENT_DATE);
|
||||||
|
|
||||||
|
RETURN QUERY
|
||||||
|
SELECT
|
||||||
|
COALESCE(SUM(ac.amount), 0) AS total_cost,
|
||||||
|
COALESCE(SUM(CASE WHEN ac.cost_type IN ('maintenance', 'repair') THEN ac.amount END), 0) AS maintenance_cost,
|
||||||
|
COALESCE(SUM(CASE WHEN ac.cost_type = 'fuel' THEN ac.amount END), 0) AS fuel_cost,
|
||||||
|
COALESCE(SUM(CASE WHEN ac.cost_type = 'depreciation' THEN ac.amount END), 0) AS depreciation_cost,
|
||||||
|
COALESCE(SUM(CASE WHEN ac.cost_type NOT IN ('maintenance', 'repair', 'fuel', 'depreciation') THEN ac.amount END), 0) AS other_costs,
|
||||||
|
COALESCE(SUM(ac.hours_in_period), 0) AS total_hours,
|
||||||
|
COALESCE(SUM(ac.kilometers_in_period), 0) AS total_kilometers,
|
||||||
|
CASE WHEN SUM(ac.hours_in_period) > 0 THEN SUM(ac.amount) / SUM(ac.hours_in_period) ELSE 0 END AS cost_per_hour,
|
||||||
|
CASE WHEN SUM(ac.kilometers_in_period) > 0 THEN SUM(ac.amount) / SUM(ac.kilometers_in_period) ELSE 0 END AS cost_per_kilometer
|
||||||
|
FROM assets.asset_costs ac
|
||||||
|
WHERE ac.asset_id = p_asset_id
|
||||||
|
AND ac.tenant_id = p_tenant_id
|
||||||
|
AND ac.period_start >= v_from_date
|
||||||
|
AND ac.period_end <= v_to_date;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
-- Funcion para actualizar proximo mantenimiento de un activo
|
||||||
|
CREATE OR REPLACE FUNCTION assets.update_next_maintenance()
|
||||||
|
RETURNS TRIGGER AS $$
|
||||||
|
BEGIN
|
||||||
|
-- Actualizar proximo mantenimiento del activo
|
||||||
|
UPDATE assets.assets a
|
||||||
|
SET
|
||||||
|
next_maintenance_date = (
|
||||||
|
SELECT MIN(scheduled_date)
|
||||||
|
FROM assets.maintenance_schedules ms
|
||||||
|
WHERE ms.asset_id = a.id
|
||||||
|
AND ms.status = 'pending'
|
||||||
|
),
|
||||||
|
updated_at = NOW()
|
||||||
|
WHERE a.id = COALESCE(NEW.asset_id, OLD.asset_id);
|
||||||
|
|
||||||
|
RETURN COALESCE(NEW, OLD);
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
CREATE TRIGGER trg_update_next_maintenance
|
||||||
|
AFTER INSERT OR UPDATE OR DELETE ON assets.maintenance_schedules
|
||||||
|
FOR EACH ROW EXECUTE FUNCTION assets.update_next_maintenance();
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- COMENTARIOS DE DOCUMENTACION
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
COMMENT ON SCHEMA assets IS 'Modulo de Activos, Maquinaria y Mantenimiento (MAE-015) - ERP Construccion';
|
||||||
|
|
||||||
|
COMMENT ON TABLE assets.asset_categories IS 'Categorias de activos para clasificacion';
|
||||||
|
COMMENT ON TABLE assets.assets IS 'Catalogo principal de activos (maquinaria, equipo, vehiculos)';
|
||||||
|
COMMENT ON TABLE assets.asset_assignments IS 'Asignaciones de activos a proyectos/obras';
|
||||||
|
COMMENT ON TABLE assets.maintenance_plans IS 'Planes de mantenimiento preventivo';
|
||||||
|
COMMENT ON TABLE assets.maintenance_schedules IS 'Programacion de mantenimientos por activo';
|
||||||
|
COMMENT ON TABLE assets.work_orders IS 'Ordenes de trabajo de mantenimiento';
|
||||||
|
COMMENT ON TABLE assets.work_order_parts IS 'Partes/refacciones utilizadas en ordenes de trabajo';
|
||||||
|
COMMENT ON TABLE assets.maintenance_history IS 'Historial de mantenimientos realizados';
|
||||||
|
COMMENT ON TABLE assets.asset_costs IS 'Costos de operacion y mantenimiento de activos';
|
||||||
|
COMMENT ON TABLE assets.asset_locations IS 'Historial de ubicaciones GPS de activos';
|
||||||
|
COMMENT ON TABLE assets.fuel_logs IS 'Registro de cargas de combustible';
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- FIN DEL SCRIPT
|
||||||
|
-- ============================================================================
|
||||||
Loading…
Reference in New Issue
Block a user