Files
Autoparts-DB/pos/migrations/v4.4_workshop.sql
consultoria-as ce66212223 feat(pos/workshop): add lightweight workshop/taller module
- Add DB migration v4.4_workshop.sql (sale_id, service_catalog,
  reserved_quantity, SO_RESERVE/SO_RELEASE operation types).
- Extend service_order_engine with inventory reservation, release,
  convert-to-sale, mechanic assignment, and service catalog CRUD.
- Extend service_order_bp with /reserve, /convert-to-sale,
  /assign-mechanic, and /service-catalog endpoints.
- Create workshop Kanban UI: workshop.html, workshop.js, workshop.css.
- Add /pos/workshop route and sidebar navigation (sidebar.js + inline
  templates).
- Add 11 unit tests with mocked cursors.
- Update FASES_IMPLEMENTADAS.md with FASE 9 documentation.

Tests: 92 passing (61 console + 20 Facturapi + 11 workshop).
2026-06-15 05:34:35 +00:00

67 lines
4.2 KiB
PL/PgSQL

-- v4.4 Workshop Lite
-- Extends service orders with inventory reservation, sale linking and a labor catalog.
-- ═════════════════════════════════════════════════════════════════════════════
-- 1. SERVICE_ORDERS: link to the sale generated from the order
-- ═════════════════════════════════════════════════════════════════════════════
ALTER TABLE service_orders
ADD COLUMN IF NOT EXISTS sale_id INTEGER REFERENCES sales(id);
COMMENT ON COLUMN service_orders.sale_id IS 'Sale/invoice generated from this service order';
CREATE INDEX IF NOT EXISTS idx_service_orders_sale_id ON service_orders(sale_id);
-- ═════════════════════════════════════════════════════════════════════════════
-- 2. SERVICE_CATALOG: reusable labor/work concepts for mechanics
-- ═════════════════════════════════════════════════════════════════════════════
CREATE TABLE IF NOT EXISTS service_catalog (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL,
name VARCHAR(200) NOT NULL,
description TEXT,
suggested_hours NUMERIC(6,2) DEFAULT 0,
suggested_rate NUMERIC(12,2) DEFAULT 0,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_service_catalog_tenant ON service_catalog(tenant_id);
CREATE INDEX IF NOT EXISTS idx_service_catalog_active ON service_catalog(is_active);
COMMENT ON TABLE service_catalog IS 'Reusable labor concepts for workshop service orders';
-- Trigger to auto-update updated_at on service_catalog
CREATE OR REPLACE FUNCTION update_service_catalog_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS trg_service_catalog_updated_at ON service_catalog;
CREATE TRIGGER trg_service_catalog_updated_at
BEFORE UPDATE ON service_catalog
FOR EACH ROW
EXECUTE FUNCTION update_service_catalog_updated_at();
-- ═════════════════════════════════════════════════════════════════════════════
-- 3. SERVICE_ORDER_ITEMS: track reserved quantity separately
-- ═════════════════════════════════════════════════════════════════════════════
ALTER TABLE service_order_items
ADD COLUMN IF NOT EXISTS reserved_quantity NUMERIC(10,2) DEFAULT 0;
COMMENT ON COLUMN service_order_items.reserved_quantity IS 'Quantity currently reserved from inventory';
-- ═════════════════════════════════════════════════════════════════════════════
-- 4. INVENTORY_OPERATIONS: new operation types for service orders
-- ═════════════════════════════════════════════════════════════════════════════
-- operation_type is VARCHAR(20) without a constraint, so no ALTER is needed.
-- New types used by the workshop module:
-- SO_RESERVE : negative quantity, reserves stock when item is added to SO
-- SO_RELEASE : positive quantity, releases a previous reservation
-- SO_CONSUME : negative quantity, final deduction when SO is converted to sale
COMMENT ON COLUMN inventory_operations.operation_type IS
'SALE, PURCHASE, RETURN, ADJUST, TRANSFER, INITIAL, QUOTE_RESERVE, QUOTE_RELEASE, SO_RESERVE, SO_RELEASE, SO_CONSUME';