Files
ContabilidadSaPolar/db/init.sql
T

710 lines
30 KiB
SQL

-- ============================================================
-- SISTEMA DE GESTIÓN DE ALQUILERES "SA POLAR"
-- Script de inicialización de base de datos (MySQL 8)
-- ⚠ NOTA: La gestión de esquemas ahora la realiza Flyway.
-- Este script se mantiene solo como referencia.
-- Para despliegues nuevos, las migraciones están en:
-- backend/src/main/resources/db/migration/
-- ============================================================
CREATE DATABASE IF NOT EXISTS sa_polar
DEFAULT CHARACTER SET utf8mb4
DEFAULT COLLATE utf8mb4_unicode_ci;
USE sa_polar;
-- ============================================================
-- 1. TABLAS DE USUARIOS Y AUTENTICACIÓN
-- ============================================================
CREATE TABLE roles (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(30) NOT NULL UNIQUE,
description VARCHAR(255)
) ENGINE=InnoDB;
CREATE TABLE users (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100) NOT NULL UNIQUE,
password_hash VARCHAR(255) NOT NULL,
full_name VARCHAR(150) NOT NULL,
phone VARCHAR(20),
role_id INT NOT NULL,
active BOOLEAN NOT NULL DEFAULT TRUE,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
last_login DATETIME,
CONSTRAINT fk_user_role FOREIGN KEY (role_id) REFERENCES roles(id)
) ENGINE=InnoDB;
CREATE TABLE user_permissions (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT NOT NULL,
permission VARCHAR(50) NOT NULL,
granted BOOLEAN NOT NULL DEFAULT TRUE,
CONSTRAINT fk_up_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
UNIQUE KEY uq_user_permission (user_id, permission)
) ENGINE=InnoDB;
-- ============================================================
-- 2. TABLAS DE INMUEBLES
-- ============================================================
CREATE TABLE property_types (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL UNIQUE,
description VARCHAR(255)
) ENGINE=InnoDB;
CREATE TABLE property_statuses (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL UNIQUE,
description VARCHAR(255)
) ENGINE=InnoDB;
CREATE TABLE property_groups (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
description TEXT,
address_street VARCHAR(200),
address_number VARCHAR(20),
address_city VARCHAR(100),
address_postal_code VARCHAR(10),
address_province VARCHAR(100),
active BOOLEAN NOT NULL DEFAULT TRUE,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB;
CREATE TABLE properties (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
parent_id BIGINT,
group_id BIGINT,
type_id INT NOT NULL,
status_id INT NOT NULL,
reference VARCHAR(50) UNIQUE,
name VARCHAR(200) NOT NULL,
description TEXT,
address_street VARCHAR(200),
address_number VARCHAR(20),
address_city VARCHAR(100),
address_postal_code VARCHAR(10),
address_province VARCHAR(100),
cadastral_ref VARCHAR(30),
surface_m2 DECIMAL(10,2),
floor VARCHAR(50),
door VARCHAR(50),
rental_amount DECIMAL(12,2),
rented_since DATE,
vacant_since DATE,
occupied_since DATE,
notes TEXT,
active BOOLEAN NOT NULL DEFAULT TRUE,
created_by BIGINT,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
CONSTRAINT fk_prop_parent FOREIGN KEY (parent_id) REFERENCES properties(id) ON DELETE SET NULL,
CONSTRAINT fk_prop_group FOREIGN KEY (group_id) REFERENCES property_groups(id) ON DELETE SET NULL,
CONSTRAINT fk_prop_type FOREIGN KEY (type_id) REFERENCES property_types(id),
CONSTRAINT fk_prop_status FOREIGN KEY (status_id) REFERENCES property_statuses(id),
CONSTRAINT fk_prop_creator FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE SET NULL
) ENGINE=InnoDB;
CREATE TABLE property_status_history (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
property_id BIGINT NOT NULL,
status_id INT NOT NULL,
changed_by BIGINT,
changed_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
notes VARCHAR(500),
CONSTRAINT fk_psh_property FOREIGN KEY (property_id) REFERENCES properties(id) ON DELETE CASCADE,
CONSTRAINT fk_psh_status FOREIGN KEY (status_id) REFERENCES property_statuses(id),
CONSTRAINT fk_psh_user FOREIGN KEY (changed_by) REFERENCES users(id) ON DELETE SET NULL
) ENGINE=InnoDB;
CREATE INDEX idx_properties_parent ON properties(parent_id);
CREATE INDEX idx_properties_group ON properties(group_id);
CREATE INDEX idx_properties_type ON properties(type_id);
CREATE INDEX idx_properties_status ON properties(status_id);
CREATE INDEX idx_properties_active ON properties(active);
CREATE INDEX idx_psh_property_date ON property_status_history(property_id, changed_at);
-- ============================================================
-- 3. TABLAS DE ARRENDATARIOS
-- ============================================================
CREATE TABLE tenant_types (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(30) NOT NULL UNIQUE
) ENGINE=InnoDB;
CREATE TABLE tenants (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
tenant_type_id INT NOT NULL,
fiscal_id VARCHAR(20) NOT NULL UNIQUE COMMENT 'DNI / NIF / CIF',
first_name VARCHAR(100) NOT NULL,
last_name VARCHAR(100) NOT NULL,
document_type VARCHAR(20) DEFAULT 'DNI',
business_name VARCHAR(200) COMMENT 'Solo para personas jurídicas',
email VARCHAR(100),
phone VARCHAR(20),
address VARCHAR(300),
iban VARCHAR(34),
notes TEXT,
active BOOLEAN NOT NULL DEFAULT TRUE,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
CONSTRAINT fk_tenant_type FOREIGN KEY (tenant_type_id) REFERENCES tenant_types(id)
) ENGINE=InnoDB;
CREATE INDEX idx_tenants_fiscal_id ON tenants(fiscal_id);
CREATE INDEX idx_tenants_name ON tenants(first_name, last_name);
CREATE INDEX idx_tenants_active ON tenants(active);
-- Tabla de datos bancarios del inquilino
CREATE TABLE tenant_bank_data (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
tenant_id BIGINT NOT NULL,
alias VARCHAR(100),
iban VARCHAR(34) NOT NULL,
bic VARCHAR(11),
bank_name VARCHAR(200),
account_holder VARCHAR(200),
is_principal BOOLEAN NOT NULL DEFAULT FALSE,
active BOOLEAN NOT NULL DEFAULT TRUE,
notes TEXT,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
CONSTRAINT fk_bank_data_tenant FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE
) ENGINE=InnoDB;
CREATE INDEX idx_tenant_bank_data_tenant ON tenant_bank_data(tenant_id);
CREATE INDEX idx_tenant_bank_data_principal ON tenant_bank_data(tenant_id, is_principal);
-- ============================================================
-- 4. TABLAS DE CONTRATOS
-- ============================================================
CREATE TABLE contract_statuses (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(30) NOT NULL UNIQUE
) ENGINE=InnoDB;
CREATE TABLE payment_periods (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(30) NOT NULL UNIQUE
) ENGINE=InnoDB;
CREATE TABLE contracts (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
property_id BIGINT NOT NULL,
status_id INT NOT NULL,
period_id INT NOT NULL DEFAULT 1,
contract_number VARCHAR(50) UNIQUE,
start_date DATE NOT NULL,
end_date DATE,
renewal_date DATE,
rental_amount DECIMAL(12,2) NOT NULL,
deposit_amount DECIMAL(12,2),
payment_day INT NOT NULL DEFAULT 1 COMMENT 'Día de mes para el pago',
payment_day_end INT DEFAULT NULL COMMENT 'Día final del rango de pago (NULL = día único)',
iban_charge VARCHAR(34) COMMENT 'IBAN para domiciliación',
notes TEXT,
signed_at DATE,
terminated_at DATE,
termination_cause VARCHAR(500),
created_by BIGINT,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
CONSTRAINT fk_contract_property FOREIGN KEY (property_id) REFERENCES properties(id),
CONSTRAINT fk_contract_status FOREIGN KEY (status_id) REFERENCES contract_statuses(id),
CONSTRAINT fk_contract_period FOREIGN KEY (period_id) REFERENCES payment_periods(id),
CONSTRAINT fk_contract_creator FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE SET NULL
) ENGINE=InnoDB;
CREATE INDEX idx_contracts_property ON contracts(property_id);
CREATE INDEX idx_contracts_status ON contracts(status_id);
CREATE INDEX idx_contracts_dates ON contracts(start_date, end_date);
CREATE TABLE contract_tenants (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
contract_id BIGINT NOT NULL,
tenant_id BIGINT NOT NULL,
role VARCHAR(20) NOT NULL DEFAULT 'TITULAR' COMMENT 'TITULAR o CONVIVIENTE',
CONSTRAINT fk_ct_contract FOREIGN KEY (contract_id) REFERENCES contracts(id) ON DELETE CASCADE,
CONSTRAINT fk_ct_tenant FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE,
UNIQUE KEY uq_contract_tenant (contract_id, tenant_id)
) ENGINE=InnoDB;
CREATE INDEX idx_ct_contract ON contract_tenants(contract_id);
CREATE INDEX idx_ct_tenant ON contract_tenants(tenant_id);
-- ============================================================
-- 5. TABLAS DE DOCUMENTOS
-- ============================================================
CREATE TABLE document_types (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL UNIQUE
) ENGINE=InnoDB;
CREATE TABLE documents (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
document_type_id INT NOT NULL,
entity_type VARCHAR(30) NOT NULL COMMENT 'PROPERTY / CONTRACT / TENANT / INCIDENT / INCOME / EXPENSE',
entity_id BIGINT NOT NULL,
original_name VARCHAR(255) NOT NULL,
stored_name VARCHAR(255) NOT NULL,
mime_type VARCHAR(100),
file_size BIGINT,
description VARCHAR(500),
uploaded_by BIGINT,
uploaded_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_doc_type FOREIGN KEY (document_type_id) REFERENCES document_types(id),
CONSTRAINT fk_doc_uploader FOREIGN KEY (uploaded_by) REFERENCES users(id) ON DELETE SET NULL
) ENGINE=InnoDB;
CREATE INDEX idx_documents_entity ON documents(entity_type, entity_id);
CREATE INDEX idx_documents_type ON documents(document_type_id);
-- ============================================================
-- 6. TABLAS DE INGRESOS
-- ============================================================
CREATE TABLE income_categories (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
description VARCHAR(255),
active BOOLEAN NOT NULL DEFAULT TRUE
) ENGINE=InnoDB;
CREATE TABLE income_statuses (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(30) NOT NULL UNIQUE
) ENGINE=InnoDB;
CREATE TABLE income_receipts (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
contract_id BIGINT,
property_id BIGINT NOT NULL,
tenant_id BIGINT,
bank_account_id BIGINT,
is_domiciled BOOLEAN NOT NULL DEFAULT FALSE,
category_id BIGINT,
status_id INT NOT NULL,
period_label VARCHAR(20) COMMENT 'ej: 2026-07',
amount DECIMAL(12,2) NOT NULL,
tax_withheld DECIMAL(12,2) DEFAULT 0.00 COMMENT 'Retención IRPF aplicada',
net_amount DECIMAL(12,2) COMMENT 'Importe neto después de retención',
issue_date DATE NOT NULL,
due_date DATE,
payment_date DATE,
payment_method VARCHAR(30) COMMENT 'TRANSFERENCIA / EFECTIVO / BIZUM / RECIBO / TARJETA',
description VARCHAR(500),
receipt_number VARCHAR(50),
notes TEXT,
created_by BIGINT,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
CONSTRAINT fk_income_receipt_contract FOREIGN KEY (contract_id) REFERENCES contracts(id) ON DELETE SET NULL,
CONSTRAINT fk_income_receipt_property FOREIGN KEY (property_id) REFERENCES properties(id),
CONSTRAINT fk_income_receipt_tenant FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE SET NULL,
CONSTRAINT fk_income_receipt_bank_account FOREIGN KEY (bank_account_id) REFERENCES bank_accounts(id) ON DELETE SET NULL,
CONSTRAINT fk_income_receipt_category FOREIGN KEY (category_id) REFERENCES income_categories(id) ON DELETE SET NULL,
CONSTRAINT fk_income_receipt_status FOREIGN KEY (status_id) REFERENCES income_statuses(id),
CONSTRAINT fk_income_receipt_creator FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE SET NULL
) ENGINE=InnoDB;
CREATE INDEX idx_income_receipts_property ON income_receipts(property_id);
CREATE INDEX idx_income_receipts_contract ON income_receipts(contract_id);
CREATE INDEX idx_income_receipts_tenant ON income_receipts(tenant_id);
CREATE INDEX idx_income_receipts_status ON income_receipts(status_id);
CREATE INDEX idx_income_receipts_period ON income_receipts(period_label);
CREATE INDEX idx_income_receipts_issue_date ON income_receipts(issue_date);
-- ============================================================
-- 7. TABLAS DE GASTOS
-- ============================================================
CREATE TABLE expense_categories (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
description VARCHAR(255),
active BOOLEAN NOT NULL DEFAULT TRUE
) ENGINE=InnoDB;
CREATE TABLE expense_statuses (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(30) NOT NULL UNIQUE
) ENGINE=InnoDB;
CREATE TABLE expense_templates (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
property_id BIGINT DEFAULT NULL,
property_group_id BIGINT DEFAULT NULL,
bank_account_id BIGINT DEFAULT NULL,
is_domiciled BOOLEAN NOT NULL DEFAULT FALSE,
category_id BIGINT,
period_id INT NOT NULL DEFAULT 1,
payment_day INT NOT NULL DEFAULT 1,
supplier_name VARCHAR(200),
supplier_fiscal_id VARCHAR(20),
amount DECIMAL(12,2) COMMENT 'NULL = variable, usuario rellena importe',
tax_amount DECIMAL(12,2),
description VARCHAR(500) NOT NULL,
notes TEXT,
is_variable BOOLEAN NOT NULL DEFAULT FALSE,
active BOOLEAN NOT NULL DEFAULT TRUE,
created_by BIGINT,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
CONSTRAINT fk_expense_template_property FOREIGN KEY (property_id) REFERENCES properties(id) ON DELETE SET NULL,
CONSTRAINT fk_expense_template_group FOREIGN KEY (property_group_id) REFERENCES property_groups(id) ON DELETE SET NULL,
CONSTRAINT fk_expense_template_bank_account FOREIGN KEY (bank_account_id) REFERENCES bank_accounts(id) ON DELETE SET NULL,
CONSTRAINT fk_expense_template_category FOREIGN KEY (category_id) REFERENCES expense_categories(id) ON DELETE SET NULL,
CONSTRAINT fk_expense_template_period FOREIGN KEY (period_id) REFERENCES payment_periods(id),
CONSTRAINT fk_expense_template_creator FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE SET NULL
) ENGINE=InnoDB;
CREATE INDEX idx_expense_templates_property ON expense_templates(property_id);
CREATE INDEX idx_expense_templates_group ON expense_templates(property_group_id);
CREATE INDEX idx_expense_templates_category ON expense_templates(category_id);
CREATE INDEX idx_expense_templates_period ON expense_templates(period_id);
CREATE TABLE expense_receipts (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
template_id BIGINT DEFAULT NULL,
property_id BIGINT DEFAULT NULL,
property_group_id BIGINT DEFAULT NULL,
bank_account_id BIGINT DEFAULT NULL,
is_domiciled BOOLEAN NOT NULL DEFAULT FALSE,
category_id BIGINT,
status_id INT NOT NULL,
supplier_name VARCHAR(200),
supplier_fiscal_id VARCHAR(20),
invoice_number VARCHAR(50),
amount DECIMAL(12,2) NOT NULL DEFAULT 0,
tax_amount DECIMAL(12,2) DEFAULT 0.00,
total_amount DECIMAL(12,2) COMMENT 'Importe total con impuestos',
is_variable BOOLEAN NOT NULL DEFAULT FALSE,
previous_amount DECIMAL(12,2) COMMENT 'Importe del periodo anterior (para variables)',
issue_date DATE NOT NULL,
due_date DATE,
payment_date DATE,
payment_method VARCHAR(30),
description VARCHAR(500) NOT NULL,
notes TEXT,
created_by BIGINT,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
CONSTRAINT fk_expense_receipt_template FOREIGN KEY (template_id) REFERENCES expense_templates(id) ON DELETE SET NULL,
CONSTRAINT fk_expense_receipt_property FOREIGN KEY (property_id) REFERENCES properties(id) ON DELETE SET NULL,
CONSTRAINT fk_expense_receipt_group FOREIGN KEY (property_group_id) REFERENCES property_groups(id) ON DELETE SET NULL,
CONSTRAINT fk_expense_receipt_bank_account FOREIGN KEY (bank_account_id) REFERENCES bank_accounts(id) ON DELETE SET NULL,
CONSTRAINT fk_expense_receipt_category FOREIGN KEY (category_id) REFERENCES expense_categories(id) ON DELETE SET NULL,
CONSTRAINT fk_expense_receipt_status FOREIGN KEY (status_id) REFERENCES expense_statuses(id),
CONSTRAINT fk_expense_receipt_creator FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE SET NULL
) ENGINE=InnoDB;
CREATE INDEX idx_expense_receipts_template ON expense_receipts(template_id);
CREATE INDEX idx_expense_receipts_property ON expense_receipts(property_id);
CREATE INDEX idx_expense_receipts_group ON expense_receipts(property_group_id);
CREATE INDEX idx_expense_receipts_category ON expense_receipts(category_id);
CREATE INDEX idx_expense_receipts_status ON expense_receipts(status_id);
CREATE INDEX idx_expense_receipts_issue_date ON expense_receipts(issue_date);
-- ============================================================
-- 8. TABLAS DE INCIDENCIAS (Fase 2)
-- ============================================================
CREATE TABLE incident_statuses (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL UNIQUE
) ENGINE=InnoDB;
CREATE TABLE incident_priorities (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20) NOT NULL UNIQUE
) ENGINE=InnoDB;
CREATE TABLE incidents (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
property_id BIGINT NOT NULL,
status_id INT NOT NULL,
priority_id INT NOT NULL,
title VARCHAR(200) NOT NULL,
description TEXT NOT NULL,
reported_by BIGINT,
assigned_to BIGINT COMMENT 'Técnico o usuario asignado',
reported_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
scheduled_date DATE COMMENT 'Fecha prevista de reparación',
resolved_at DATETIME,
resolution_notes TEXT,
cost_estimate DECIMAL(12,2),
final_cost DECIMAL(12,2),
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
CONSTRAINT fk_incident_property FOREIGN KEY (property_id) REFERENCES properties(id),
CONSTRAINT fk_incident_status FOREIGN KEY (status_id) REFERENCES incident_statuses(id),
CONSTRAINT fk_incident_priority FOREIGN KEY (priority_id) REFERENCES incident_priorities(id),
CONSTRAINT fk_incident_reporter FOREIGN KEY (reported_by) REFERENCES users(id) ON DELETE SET NULL,
CONSTRAINT fk_incident_assigned FOREIGN KEY (assigned_to) REFERENCES users(id) ON DELETE SET NULL
) ENGINE=InnoDB;
CREATE INDEX idx_incidents_property ON incidents(property_id);
CREATE INDEX idx_incidents_status ON incidents(status_id);
CREATE INDEX idx_incidents_priority ON incidents(priority_id);
CREATE INDEX idx_incidents_reported ON incidents(reported_at);
-- ============================================================
-- 9. TABLAS DE MANTENIMIENTO PROGRAMADO (Fase 2)
-- ============================================================
CREATE TABLE maintenance_periods (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(30) NOT NULL UNIQUE
) ENGINE=InnoDB;
CREATE TABLE scheduled_maintenance (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
property_id BIGINT NOT NULL,
period_id INT NOT NULL,
title VARCHAR(200) NOT NULL,
description TEXT,
estimated_cost DECIMAL(12,2),
last_execution DATE,
next_execution DATE NOT NULL,
reminder_days_before INT NOT NULL DEFAULT 30,
responsible VARCHAR(200),
notes TEXT,
completed BOOLEAN NOT NULL DEFAULT FALSE,
completed_at DATE,
completed_by BIGINT,
created_by BIGINT,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
CONSTRAINT fk_maint_property FOREIGN KEY (property_id) REFERENCES properties(id),
CONSTRAINT fk_maint_period FOREIGN KEY (period_id) REFERENCES maintenance_periods(id),
CONSTRAINT fk_maint_completed FOREIGN KEY (completed_by) REFERENCES users(id) ON DELETE SET NULL,
CONSTRAINT fk_maint_creator FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE SET NULL
) ENGINE=InnoDB;
CREATE INDEX idx_maint_property ON scheduled_maintenance(property_id);
CREATE INDEX idx_maint_next_exec ON scheduled_maintenance(next_execution);
CREATE INDEX idx_maint_completed ON scheduled_maintenance(completed);
-- ============================================================
-- 10. TABLAS DE NOTIFICACIONES (Fase 3)
-- ============================================================
CREATE TABLE notification_types (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL UNIQUE
) ENGINE=InnoDB;
CREATE TABLE notifications (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT NOT NULL,
type_id INT NOT NULL,
title VARCHAR(200) NOT NULL,
body TEXT,
entity_type VARCHAR(30) COMMENT 'INCIDENT / MAINTENANCE / INCOME / CONTRACT',
entity_id BIGINT,
sent_by_email BOOLEAN NOT NULL DEFAULT FALSE,
`read` BOOLEAN NOT NULL DEFAULT FALSE,
read_at DATETIME,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_notif_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
CONSTRAINT fk_notif_type FOREIGN KEY (type_id) REFERENCES notification_types(id)
) ENGINE=InnoDB;
CREATE INDEX idx_notifications_user ON notifications(user_id, `read`);
CREATE INDEX idx_notifications_created ON notifications(created_at);
-- ============================================================
-- DATOS SEMILLA (Seed Data)
-- ============================================================
-- Roles
INSERT INTO roles (id, name, description) VALUES
(1, 'ADMIN', 'Acceso total al sistema'),
(2, 'GERENTE', 'Gestión de propiedades, contratos, inquilinos y finanzas'),
(3, 'CONTABLE', 'Gestión de ingresos, gastos y reportes'),
(4, 'VISUALIZADOR','Solo lectura de la información');
-- Tipos de propiedad
INSERT INTO property_types (id, name, description) VALUES
(1, 'EDIFICIO', 'Edificio completo con varias plantas'),
(2, 'PISO', 'Vivienda en un edificio de pisos'),
(3, 'LOCAL_COMERCIAL','Local comercial'),
(4, 'BAR', 'Bar o restaurante'),
(5, 'NAVE', 'Nave industrial o almacén'),
(6, 'GARAJE', 'Plaza de garaje'),
(7, 'TRASTERO', 'Trastero'),
(8, 'OFICINA', 'Oficina o despacho'),
(9, 'ADOSADO', 'Vivienda unifamiliar adosada'),
(10, 'CHALET', 'Vivienda unifamiliar independiente');
-- Estados de propiedad
INSERT INTO property_statuses (id, name, description) VALUES
(1, 'DISPONIBLE', 'Propiedad disponible para alquilar'),
(2, 'ALQUILADO', 'Actualmente alquilado'),
(3, 'VACIO', 'Vacío, sin inquilino'),
(4, 'ANUNCIADO', 'Anunciado para alquiler'),
(5, 'VENTA', 'Puesto a la venta'),
(6, 'VENDIDO', 'Vendido'),
(7, 'TRASPASADO', 'Traspasado a otro propietario'),
(8, 'OCUPADO', 'Ocupado sin contrato vigente'),
(9, 'MANTENIMIENTO', 'En obras o mantenimiento');
-- Tipos de arrendatario
INSERT INTO tenant_types (id, name) VALUES
(1, 'PERSONA_FISICA'),
(2, 'PERSONA_JURIDICA');
-- Estados de contrato
INSERT INTO contract_statuses (id, name) VALUES
(1, 'ACTIVO'),
(2, 'VENCIDO'),
(3, 'RENOVADO'),
(4, 'RESCINDIDO'),
(5, 'ANULADO');
-- Períodos de pago
INSERT INTO payment_periods (id, name) VALUES
(1, 'MENSUAL'),
(2, 'TRIMESTRAL'),
(3, 'SEMESTRAL'),
(4, 'ANUAL');
-- Tipos de documento
INSERT INTO document_types (id, name) VALUES
(1, 'CONTRATO'),
(2, 'ANEXO_CONTRATO'),
(3, 'DNI_ARRENDATARIO'),
(5, 'FOTO_PROPIEDAD'),
(6, 'FOTO_INCIDENCIA'),
(7, 'FACTURA'),
(8, 'JUSTIFICANTE_PAGO'),
(9, 'CERTIFICADO'),
(10, 'OTRO'),
(11, 'IMAGEN'),
(12, 'PRESUPUESTO');
-- Estados de ingreso
INSERT INTO income_statuses (id, name) VALUES
(1, 'PENDIENTE'),
(2, 'PAGADO'),
(3, 'VENCIDO'),
(4, 'PARCIAL'),
(5, 'ANULADO');
-- Categorías de ingreso
INSERT INTO income_categories (id, name, description) VALUES
(1, 'ALQUILER', 'Pago de renta mensual o periódica'),
(2, 'FIANZA', 'Depósito de garantía'),
(3, 'GASTOS_COMUNIDAD', 'Repercusión de gastos de comunidad'),
(4, 'INTERESES_DEMORA', 'Intereses por pago fuera de plazo'),
(5, 'INDEMNIZACION', 'Indemnización por daños o rescisión'),
(6, 'OTROS_INGRESOS', 'Otros ingresos no clasificados');
-- Estados de gasto
INSERT INTO expense_statuses (id, name) VALUES
(1, 'PENDIENTE'),
(2, 'PAGADO'),
(3, 'VENCIDO'),
(4, 'ANULADO');
-- Categorías de gasto
INSERT INTO expense_categories (id, name, description) VALUES
(1, 'REPARACION', 'Reparaciones y arreglos'),
(2, 'MANTENIMIENTO', 'Mantenimiento preventivo'),
(3, 'COMUNIDAD', 'Gastos de comunidad de propietarios'),
(4, 'IBI', 'Impuesto de Bienes Inmuebles'),
(5, 'BASURA', 'Tasa de basura'),
(6, 'SUMINISTROS', 'Agua, luz, gas, internet'),
(7, 'SEGURO', 'Seguro del inmueble o multirriesgo'),
(8, 'REFORMA', 'Obras de reforma o mejora'),
(9, 'GESTION', 'Gastos de gestión inmobiliaria'),
(10, 'NOTARIA_REGISTRO', 'Gastos notariales y de registro'),
(11, 'PUBLICIDAD', 'Anuncios y marketing'),
(12, 'OTROS_GASTOS', 'Otros gastos no clasificados');
-- Estados de incidencia (Fase 2)
INSERT INTO incident_statuses (id, name) VALUES
(1, 'SIN_REVISAR'),
(2, 'TECNICO_AVISADO'),
(3, 'REPARACION_PREVISTA'),
(4, 'REPARADO'),
(5, 'IGNORADO'),
(6, 'ANULADO');
-- Prioridades de incidencia (Fase 2)
INSERT INTO incident_priorities (id, name) VALUES
(1, 'BAJA'),
(2, 'MEDIA'),
(3, 'ALTA'),
(4, 'URGENTE');
-- Períodos de mantenimiento (Fase 2)
INSERT INTO maintenance_periods (id, name) VALUES
(1, 'UNICA_VEZ'),
(2, 'MENSUAL'),
(3, 'TRIMESTRAL'),
(4, 'SEMESTRAL'),
(5, 'ANUAL'),
(6, 'BIENAL'),
(7, 'TRIENAL'),
(8, 'QUINQUENAL');
-- Tipos de notificación (Fase 3)
INSERT INTO notification_types (id, name) VALUES
(1, 'INCIDENCIA_ABIERTA'),
(2, 'MANTENIMIENTO_PROXIMO'),
(3, 'RECIBO_VENCIDO'),
(4, 'CONTRATO_PROXIMO_VENCER'),
(5, 'CONTRATO_VENCIDO'),
(6, 'SISTEMA');
-- ============================================================
-- 11. TABLAS DE RECIBOS Y FACTURACIÓN (Fase 2)
-- ============================================================
CREATE TABLE receipt_series (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
series_name VARCHAR(50) NOT NULL,
fiscal_year INT NOT NULL,
last_number INT NOT NULL DEFAULT 0,
prefix VARCHAR(20) NOT NULL DEFAULT 'R-',
active BOOLEAN NOT NULL DEFAULT TRUE,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uq_series_year (series_name, fiscal_year)
) ENGINE=InnoDB;
CREATE TABLE email_log (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
income_receipt_id BIGINT,
recipient_email VARCHAR(200) NOT NULL,
subject VARCHAR(300) NOT NULL,
body TEXT,
success BOOLEAN NOT NULL DEFAULT FALSE,
error_message TEXT,
sent_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_email_income (income_receipt_id)
) ENGINE=InnoDB;
-- Serie de recibos para el año actual
INSERT INTO receipt_series (series_name, fiscal_year, last_number, prefix) VALUES
('RECIBOS', YEAR(CURDATE()), 0, CONCAT('R-', YEAR(CURDATE()), '-'));
-- ============================================================
-- USUARIO ADMIN POR DEFECTO
-- Contraseña: admin123 (BCrypt hash)
-- ============================================================
INSERT INTO users (username, email, password_hash, full_name, role_id, active)
VALUES ('admin', 'admin@sapolar.com',
'$2a$10$I9VbpnnqwttwAiKlWAgxRuyQF6IC02wnMO1YoBF/u2QcTJKcZnJBe',
'Administrador del Sistema', 1, TRUE);