Skip to main content

Overview

The Order Management system is the core of Ai Studio’s operations, handling all customer orders from intake through fulfillment. The system supports three order types: pickup, delivery, and dine-in, with intelligent status tracking and payment verification.

Key Benefits

  • Multi-channel Order Intake: Accept orders from admin panel, web assistant (Slice), or WhatsApp bot
  • Real-time Status Tracking: Monitor orders through 10 distinct lifecycle states
  • Payment Verification: Track payment method and approval status before completion
  • Firebase Sync: All orders sync in real-time across devices and interfaces
  • Comprehensive History: Full audit trail with status timestamps

Order Types

The system supports three distinct order types, each with its own workflow:
Customers order ahead and collect at the restaurant.Payment Options: Cash or Credit (customer selects at order time)Typical Flow:
Pending → Confirmed → Preparing → Ready → Completed (Pickup)

Order Data Structure

Order Interface

From types.ts:87-108:
export interface Order {
  id: string;                          // Format: ORD-{timestamp}-{random}
  customer: {
    name: string;
    phone?: string;
    address?: string;                  // Required for delivery
  };
  items: OrderItem[];                  // Products in the order
  total: number;                       // Total price
  status: OrderStatus;                 // Current status
  type: OrderType;                     // pickup | delivery | dine-in
  createdAt: string;                   // ISO timestamp
  statusHistory: StatusHistory[];      // Full audit trail
  finishedAt: string | null;           // When order completed/cancelled
  tableIds?: string[];                 // For dine-in orders
  guests?: number;                     // Number of diners
  paymentMethod: PaymentMethod;        // Cash | Credit | Transfer
  isPaid: boolean;                     // Payment approval status
  paymentProofUrl?: string | null;     // Transfer receipt URL
  reservationId?: string;              // Link to reservation if applicable
  createdBy: CreatedBy;                // Admin | Web Assistant | WhatsApp
}

Order Item Structure

From types.ts:79-85:
export interface OrderItem {
  name: string;            // Product name
  quantity: number;        // How many
  price: number;          // Unit price
  isPromotion: boolean;   // Whether this is a promotion item
  itemId: string;         // Product or Promotion ID
}

Order Statuses

From types.ts:48-59, the system defines 10 order statuses:
export enum OrderStatus {
  PENDING = 'Pendiente',                              // Initial state
  CONFIRMED = 'Confirmado',                           // Order accepted
  PREPARING = 'En Preparación',                       // Kitchen working
  READY = 'Listo para Retirar/Entregar',             // Ready for next step
  DELIVERING = 'En Camino',                           // Delivery in progress
  DINE_IN_PENDING_PAYMENT = 'En Mesa (Pendiente de Pago)',  // Waiting for payment
  COMPLETED_PICKUP = 'Completado (Retirado)',        // Pickup completed
  COMPLETED_DELIVERY = 'Completado (Entregado)',     // Delivery completed
  COMPLETED_DINE_IN = 'Completado (En Mesa)',        // Dine-in completed
  CANCELLED = 'Cancelado',                            // Order cancelled
}
The system tracks finished orders as any status in: COMPLETED_PICKUP, COMPLETED_DELIVERY, COMPLETED_DINE_IN, or CANCELLED.

Payment Methods

From types.ts:67-71:
export enum PaymentMethod {
  CASH = 'Efectivo',
  CREDIT = 'Credito',
  TRANSFER = 'Transferencia',
}

Payment Rules

Critical Payment Validations:
  • Orders cannot be marked as completed unless isPaid: true
  • Delivery orders must use Transfer payment method
  • Pickup orders can use Cash or Credit
  • Dine-in orders accept all payment methods
  • Payment proof URL can be attached for transfers

Core Service Functions

From services/orderService.ts:

Creating Orders

saveOrder(
  orderData: Omit<Order, 'id' | 'status' | 'createdAt' | 'statusHistory' | 'finishedAt' | 'isPaid'>
): Promise<Order>
Example Usage:
import { saveOrder } from './services/orderService';
import { OrderType, PaymentMethod, CreatedBy } from './types';

const newOrder = await saveOrder({
  customer: {
    name: 'Juan Pérez',
    phone: '1234567890',
    address: 'Calle Falsa 123'
  },
  items: [
    {
      name: 'Pizza Muzzarella',
      quantity: 2,
      price: 9200,
      isPromotion: false,
      itemId: 'PROD-123'
    }
  ],
  total: 18400,
  type: OrderType.DELIVERY,
  paymentMethod: PaymentMethod.TRANSFER,
  createdBy: CreatedBy.ADMIN,
});

// Returns order with:
// - Auto-generated ID (ORD-{timestamp}-{random})
// - status: PENDING
// - isPaid: false (unless paymentProofUrl provided)
// - statusHistory initialized

Updating Order Status

updateOrderStatus(
  orderId: string,
  status: OrderStatus
): Promise<Order>
Example:
import { updateOrderStatus } from './services/orderService';
import { OrderStatus } from './types';

// Move order to next stage
const updatedOrder = await updateOrderStatus(
  'ORD-1234567890-abc',
  OrderStatus.PREPARING
);

// System automatically:
// - Adds status to statusHistory with timestamp
// - Sets finishedAt if moving to completed/cancelled status
// - Creates notification for status change
// - Syncs to Firebase
Status Transition Rules:
  • Cannot change status of already-finished orders
  • Cannot complete order unless isPaid: true
  • Completing order automatically sets isPaid: true (except for cancelled)

Managing Payment Status

markOrderAsPaid(
  orderId: string,
  paymentMethod: PaymentMethod,
  paymentProofUrl?: string | null
): Promise<Order>
Example:
import { markOrderAsPaid } from './services/orderService';
import { PaymentMethod } from './types';

// Record payment for delivery order
const paidOrder = await markOrderAsPaid(
  'ORD-1234567890-abc',
  PaymentMethod.TRANSFER,
  'https://storage.example.com/receipt123.jpg'
);

// For dine-in orders at DINE_IN_PENDING_PAYMENT:
// - Automatically transitions to COMPLETED_DINE_IN
// - Adds completion to statusHistory

Retrieving Orders

// Get all orders from cache (sorted newest first)
getOrdersFromCache(): Order[]

// Fetch latest from Firebase and update cache
fetchAndCacheOrders(): Promise<Order[]>

// Check if order is finished
isOrderFinished(status: OrderStatus): boolean

User Workflows

Admin Creating an Order

1

Navigate to Orders Panel

From the admin sidebar, click “Orders” to view the OrdersPanel.
2

Click 'Nuevo Pedido'

Opens order creation form with fields for customer, items, and order details.
3

Select Order Type

Choose Pickup, Delivery, or Dine-In. This determines:
  • Required fields (address for delivery, tables for dine-in)
  • Available payment methods
  • Status workflow
4

Add Items

Select products from the menu, specify quantities. System calculates total automatically.
5

Enter Customer Details

Name, phone, and address (if delivery). System may auto-suggest from customer database.
6

Select Payment Method

Based on order type:
  • Delivery: Transfer (can upload payment proof)
  • Pickup: Cash or Credit
  • Dine-In: Any method (paid later)
7

Submit Order

Order created with status PENDING. Notification sent. Firebase sync immediate.

Processing Orders Through Kitchen

1

Confirm Order

Admin reviews order, clicks “Confirmar” → Status: CONFIRMED
2

Start Preparation

Kitchen begins work, admin updates → Status: PREPARING
3

Mark as Ready

Order complete, admin marks ready → Status: READY
4

Final Step (varies by type)

  • Pickup: Customer arrives → COMPLETED_PICKUP
  • Delivery: Driver dispatched → DELIVERING → COMPLETED_DELIVERY
  • Dine-In: Customer finishes → DINE_IN_PENDING_PAYMENT → (after payment) → COMPLETED_DINE_IN

AI Assistant Order Flow

From components/ChatAssistantModal.tsx and services/geminiService.ts:
1

Customer Opens Chat

Slice AI assistant greets customer, asks if they want to order or make a reservation.
2

Customer Requests Order

System sets actionLock: 'order' to focus conversation on ordering.
3

Gather Order Details

AI collects:
  • Products and quantities from menu
  • Delivery or pickup
  • Customer name and phone
  • Address (if delivery)
  • Payment method (Transfer for delivery, Cash/Credit for pickup)
4

AI Confirms Details

Presents summary, asks for explicit confirmation.
5

Generate Order JSON

After confirmation, AI responds with structured JSON:
{
  "intent": "ORDER",
  "customer": { "name": "...", "phone": "...", "address": "..." },
  "items": [...],
  "total": 9200,
  "type": "delivery",
  "paymentMethod": "Transferencia"
}
6

System Creates Order

saveOrder() called with createdBy: WEB_ASSISTANT. Order appears in admin panel immediately.

Real-Time Synchronization

From components/AdminDashboard.tsx:106-132: Orders sync in real-time via Firebase listeners:
// Admin dashboard subscribes to Orders collection
const unsubOrders = onSnapshot(
  collection(db, 'Orders'),
  (querySnapshot) => {
    const items = querySnapshot.docs.map(doc => doc.data() as Order);
    updateOrdersCache(items);
    setDataTimestamp(Date.now()); // Triggers UI refresh
  }
);
Benefits:
  • Multi-device admin access (changes appear instantly on all devices)
  • AI assistants create orders that appear immediately in admin panel
  • No manual refresh needed
  • Offline-first with localStorage fallback

Notifications

From components/AdminDashboard.tsx:175-187: The system automatically generates notifications for:
  • New Orders: When first order arrives or latest order changes
  • Status Changes: Each status transition creates a notification
// Auto-notification on new order
if (currentOrders[0].id !== lastCheckedOrder.current) {
  addNotification({
    message: `Nuevo pedido de ${currentOrders[0].customer.name} por $${currentOrders[0].total}`,
    type: 'order',
    relatedId: currentOrders[0].id,
  });
}

Order History & Audit Trail

Every status change is recorded in statusHistory:
export interface StatusHistory {
  status: OrderStatus;
  startedAt: string;  // ISO timestamp
}
Example status history:
[
  { "status": "Pendiente", "startedAt": "2026-03-10T14:30:00.000Z" },
  { "status": "Confirmado", "startedAt": "2026-03-10T14:32:15.000Z" },
  { "status": "En Preparación", "startedAt": "2026-03-10T14:35:00.000Z" },
  { "status": "Listo para Retirar/Entregar", "startedAt": "2026-03-10T14:50:00.000Z" },
  { "status": "Completado (Retirado)", "startedAt": "2026-03-10T15:05:00.000Z" }
]

Configuration

Order Type Enum

From types.ts:61-65:
export enum OrderType {
  PICKUP = 'pickup',
  DELIVERY = 'delivery',
  DINE_IN = 'dine-in',
}

Creation Source Tracking

From types.ts:73-77:
export enum CreatedBy {
  ADMIN = 'Admin Panel',
  WEB_ASSISTANT = 'Web Assistant',      // Slice chat
  WHATSAPP_ASSISTANT = 'WhatsApp Assistant',
}

Best Practices

Always Verify Payment

Before marking an order as completed, ensure isPaid: true. The system enforces this rule.

Use Correct Payment Methods

Delivery must use Transfer. Pickup allows Cash/Credit. Dine-in accepts all methods.

Track Order Source

Use createdBy to understand which channel generated the order for analytics.

Leverage Status History

Use statusHistory for analytics, customer service, and performance tracking.

Build docs developers (and LLMs) love