Tablas Centrales: Productos y Categorías
La tabla products es la base. Los campos incluyen product_id (PK), sku (unidad de mantenimiento de stock única), barcode, product_name, description, category_id (FK), brand, unit_price, cost_price, tax_rate, unit_type (pieza/kg/litro), is_active, e image_url. La tabla categories organiza los productos jerárquicamente: category_id (PK), name, parent_category_id (FK autorreferenciado para subcategorías), y sort_order. Un árbol de categorías bien diseñado soporta reportes departamentales.
Inventario y Gestión de Stock
La tabla inventory rastrea los niveles de stock en múltiples ubicaciones: inventory_id (PK), product_id (FK), store_id (FK), quantity_on_hand, quantity_committed (reservado para órdenes abiertas), reorder_point, reorder_quantity, y last_count_date. Una tabla stock_movements registra cada cambio de inventario: movement_id (PK), product_id (FK), store_id (FK), movement_type (recepción/venta/devolución/ajuste/transferencia), quantity, reference_document, movement_date, y performed_by. Esta pista de auditoría es esencial para identificar discrepancias durante conteos físicos de inventario.
Esquema de Transacciones de Venta
El esquema de ventas sigue un patrón de encabezado-detalle. La tabla sales_orders (encabezado) registra: order_id (PK), store_id (FK), customer_id (FK), employee_id (FK — el cajero), order_date, order_time, subtotal, discount_total, tax_total, grand_total, payment_status, y order_status. La tabla sales_order_items (detalle) captura cada línea: order_item_id (PK), order_id (FK), product_id (FK), quantity, unit_price_at_sale, discount_percent, line_total, y returned_quantity. Almacenar unit_price_at_sale es crítico porque los precios de los productos cambian con el tiempo.
Procesamiento de Pagos
La tabla payments maneja múltiples tipos de pago por transacción: payment_id (PK), order_id (FK), payment_method (efectivo/tarjeta/UPI/crédito/voucher), payment_amount, reference_number (para transacciones con tarjeta/UPI), payment_date, y is_verified. Para pagos divididos, múltiples filas se vinculan al mismo order_id. Una tabla separate registers gestiona las operaciones del cajón de efectivo: register_id (PK), store_id (FK), opening_balance, closing_balance, opened_by, closed_by, opening_date, closing_date, expected_cash, y variance.
Gestión de Relaciones con Clientes
La tabla customers almacena: customer_id (PK), first_name, last_name, phone, email, date_of_birth, anniversary_date, loyalty_points, total_spent, registration_date, e is_vip. Una tabla loyalty_transactions rastrea los puntos ganados y canjeados por orden. Para cadenas minoristas, una tabla customer_addresses soporta órdenes de entrega con múltiples direcciones. La tabla customer se integra con el esquema de ventas a través del FK customer_id en sales_orders, permitiendo funciones como historial de compras y ofertas personalizadas.
Arquitectura Multi-Tienda
Para operaciones de cadena, la tabla stores define cada ubicación: store_id (PK), store_name, address, city, state, phone, tax_registration_number, e is_active. Las órdenes de transferencia entre tiendas usan una tabla transfer_orders: transfer_id (PK), from_store_id (FK), to_store_id (FK), product_id (FK), quantity, status (solicitada/aprobada/enviada/recibida), request_date, y completion_date. Esta estructura soporta reportes centralizados mientras permite operaciones descentralizadas.
Mejores Prácticas para Base de Datos POS
Usa transacciones de base de datos para cada venta — si la inserción de cualquier línea falla, toda la orden debe revertirse. Indexa la columna barcode para búsquedas de productos sub-milisegundo en el registro. Implementa bloqueo optimista (columna de número de versión) en tablas de inventario para prevenir sobreventas durante períodos de alta concurrencia. Particiona sales_order_items por order_date para consultas históricas rápidas. Siempre almacena valores monetarios en la unidad monetaria más pequeña (céntimos/paisa) como enteros para evitar errores de redondeo de punto flotante.
AIAZH