Overview
The PAE Inventory System uses PostgreSQL stored procedures exposed as RPC functions through Supabase. These functions handle complex transactional operations with built-in permission checks and audit logging.aprobar_guia
Approves a pending entry guide (guía de entrada) and updates inventory stock atomically.Signature
Parameters
The ID of the guide to approve
Optional comments about the approval
Return Type
Returns a JSON object with the following structure:Behavior
- Permission Check: Only users with role Director (1) or Desarrollador (4) can approve guides
- Validation: Verifies the guide exists and is in ‘Pendiente’ (Pending) state
- Transaction: Updates guide status to ‘Aprobada’ and increments stock for all associated products
- Audit: Creates an audit log entry with approval details
Error Conditions
Raised when user doesn’t have Director or Desarrollador role
Raised when the specified guide ID doesn’t exist
Raised when the guide is not in ‘Pendiente’ state
Usage Example
rechazar_guia
Rejects a pending entry guide without updating inventory.Signature
Parameters
The ID of the guide to reject
Required reason for rejection
Return Type
Returns a JSON object:Behavior
- Permission Check: Only Director (1) or Desarrollador (4) can reject guides
- Validation: Requires non-empty rejection reason, verifies guide is pending
- Update: Sets guide status to ‘Rechazada’ with rejection reason
- Audit: Logs rejection with motivo in audit_log
Error Conditions
Raised when user lacks required permissions
Raised when p_motivo is NULL or empty
Raised when guide state is not ‘Pendiente’
Usage Example
get_lotes_por_vencer
Retrieves batches (lotes) that are expiring within a specified number of days.Signature
Parameters
Number of days to look ahead for expiring batches
Return Columns
| Column | Type | Description |
|---|---|---|
id_product | INTEGER | Product ID |
product_name | TEXT | Product name |
stock | NUMERIC(10,2) | Current total stock |
unit_measure | TEXT | Unit of measure (kg, lt, unidades) |
category_name | TEXT | Product category |
fecha_vencimiento | DATE | Batch expiration date |
cantidad_lote | NUMERIC(10,2) | Quantity in this batch |
dias_restantes | INTEGER | Days until expiration |
Behavior
- Queries JSONB
lotes_detallefrom approved guides - Filters batches expiring within
p_diasdays - Orders by expiration date (FIFO - First In, First Out)
- Only includes batches from approved guides
Usage Example
procesar_operacion_diaria
Processes a daily operation (meal service) with FIFO batch consumption and automatic stock updates.Signature
Parameters
Date of the operation
Meal shift: ‘Desayuno’, ‘Almuerzo’, or ‘Merienda’
Total student attendance for this meal
Array of product IDs (rubros) used in this meal
Return Type
Returns a JSON object:Behavior
This is the most complex RPC function, implementing full FIFO (First-Expire, First-Out) logic:- Permission Check: Requires Director (1), Madre Procesadora (2), or Desarrollador (4) role
- Create Record: Inserts into
registro_diariotable - For each rubro:
- Retrieves
rendimiento_por_unidad(yield/portion) fromreceta_porcion - Calculates required quantity:
asistencia / rendimiento - Locks relevant batch rows using
SELECT FOR UPDATE - Consumes batches in FIFO order (earliest expiration first)
- Updates JSONB batch quantities
- Creates output record (triggers automatic stock deduction)
- Retrieves
- Audit: Logs operation details to
audit_log
FIFO Implementation
Batches are consumed in order of:- Expiration date (ascending)
- Input ID (ascending, for same-date batches)
- Locks all relevant batches to prevent race conditions
- Consumes partial batches when necessary
- Updates JSONB quantities atomically
- Validates sufficient stock before committing
Error Conditions
User lacks required role (must be 1, 2, or 4)
A product in p_rubros lacks a receta_porcion entry or has invalid yield
Not enough batch quantities available to fulfill the operationFormat:
Lotes insuficientes para "[Product]". Faltan X unidades.Raised by trigger_update_stock_output if overall stock is insufficient
Usage Example
Permissions
All RPC functions are granted to theauthenticated role:
get_user_role() against the users table.
Security
All functions are defined withSECURITY DEFINER, meaning they execute with the privileges of the function creator rather than the caller. This allows:
- Controlled access to sensitive operations
- Consistent audit logging via
auth.uid() - Enforcement of business rules regardless of RLS policies