Files
Autoparts-DB/pos/migrations/v2.5_service_orders.sql
Nexus Dev 9ff3dc4c8b FASE 4-5-6: Infraestructura, CRM, Service Orders, Notificaciones, Ahorro, Logistica, API Publica
FASE 4:
- Redis cache de stock con fallback graceful
- Multi-moneda (MXN/USD) con contabilidad en MXN
- Proveedores y ordenes de compra completo
- Meilisearch 1.5M+ partes indexadas
- Metabase KPIs con dashboard auto-generado

FASE 5:
- CRM mejorado: activities, tags, loyalty program, analytics
- Imagenes de partes: upload, resize, thumbnails WebP
- Ordenes de servicio Kanban: received->diagnosis->repair->ready->delivered
- Garantias/RMA, alertas de reorden, multi-sucursal
- Stubs BNPL (APLAZO) y ERP Sync (Aspel/Contpaqi)

FASE 6:
- Notificaciones automaticas: push/WhatsApp/email/in-app
- Reportes de ahorro vs retail_price
- Logistica + tracking: DHL, FedEx, Estafeta, 99min, Uber
- API Publica: API keys, rate limiting, catalog search

Migraciones: v1.9-v3.0
Tests: 93/93 pasando
Backup: nexus_backup_20260427_045859.tar.gz
2026-04-27 05:23:30 +00:00

91 lines
3.6 KiB
PL/PgSQL

-- v2.5 Service Orders (Kanban) for workshop management
CREATE TABLE IF NOT EXISTS service_orders (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL,
branch_id INTEGER REFERENCES branches(id),
customer_id INTEGER REFERENCES customers(id),
vehicle_id INTEGER REFERENCES fleet_vehicles(id), -- optional link to fleet
order_number VARCHAR(50) UNIQUE, -- human-readable SO-2026-0001
status VARCHAR(30) DEFAULT 'received', -- received, diagnosis, waiting_parts, repair, quality_check, ready, delivered, cancelled
priority VARCHAR(20) DEFAULT 'normal', -- low, normal, high, urgent
reception_notes TEXT,
diagnosis_notes TEXT,
repair_notes TEXT,
delivery_notes TEXT,
estimated_cost NUMERIC(12,2),
final_cost NUMERIC(12,2),
estimated_completion TIMESTAMPTZ,
actual_completion TIMESTAMPTZ,
delivered_at TIMESTAMPTZ,
delivered_by INTEGER REFERENCES employees(id),
employee_id INTEGER REFERENCES employees(id), -- assigned mechanic/technician
mileage_in INTEGER,
mileage_out INTEGER,
fuel_level VARCHAR(20), -- empty, quarter, half, three_quarters, full
created_by INTEGER REFERENCES employees(id),
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_so_status ON service_orders(status);
CREATE INDEX IF NOT EXISTS idx_so_customer ON service_orders(customer_id);
CREATE INDEX IF NOT EXISTS idx_so_branch ON service_orders(branch_id);
CREATE INDEX IF NOT EXISTS idx_so_created ON service_orders(created_at DESC);
-- Service order items (parts needed/used)
CREATE TABLE IF NOT EXISTS service_order_items (
id SERIAL PRIMARY KEY,
service_order_id INTEGER NOT NULL REFERENCES service_orders(id) ON DELETE CASCADE,
inventory_id INTEGER REFERENCES inventory(id),
part_number VARCHAR(50),
name VARCHAR(300),
quantity NUMERIC(10,2) DEFAULT 1,
unit_cost NUMERIC(12,2),
unit_price NUMERIC(12,2),
status VARCHAR(20) DEFAULT 'pending', -- pending, ordered, received, installed, cancelled
notes TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_soi_order ON service_order_items(service_order_id);
-- Service order labor / work items
CREATE TABLE IF NOT EXISTS service_order_labor (
id SERIAL PRIMARY KEY,
service_order_id INTEGER NOT NULL REFERENCES service_orders(id) ON DELETE CASCADE,
description TEXT NOT NULL,
hours NUMERIC(6,2) DEFAULT 0,
hourly_rate NUMERIC(12,2) DEFAULT 0,
total_cost NUMERIC(12,2) DEFAULT 0,
employee_id INTEGER REFERENCES employees(id), -- mechanic who did the work
status VARCHAR(20) DEFAULT 'pending', -- pending, in_progress, completed
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_sol_order ON service_order_labor(service_order_id);
-- Status history for audit trail
CREATE TABLE IF NOT EXISTS service_order_status_history (
id SERIAL PRIMARY KEY,
service_order_id INTEGER NOT NULL REFERENCES service_orders(id) ON DELETE CASCADE,
old_status VARCHAR(30),
new_status VARCHAR(30) NOT NULL,
changed_by INTEGER REFERENCES employees(id),
notes TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_sosh_order ON service_order_status_history(service_order_id);
-- Trigger to auto-update updated_at
CREATE OR REPLACE FUNCTION update_so_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS trg_service_orders_updated_at ON service_orders;
CREATE TRIGGER trg_service_orders_updated_at
BEFORE UPDATE ON service_orders
FOR EACH ROW
EXECUTE FUNCTION update_so_updated_at();