Overview
The Invoice model represents invoices generated from sales transactions. It supports multiple format types (ticket, letter, route) for different printing scenarios and tracks invoice status throughout its lifecycle.
Namespace: App\Models\Sales\Invoice
Database Table: invoices
Traits: SoftDeletes
Properties
Fillable Attributes
Foreign key to the associated Sale model
Unique invoice number for tracking and reference
Type of invoice (e.g., ‘standard’, ‘credit_note’)
Format for printing: ‘ticket’, ‘letter’, or ‘route’
Current status: ‘active’ or ‘cancelled’
Due date for payment (primarily for credit invoices)
ID of the user who generated the invoice
Constants
Status Constants
const STATUS_ACTIVE = 'active';
const STATUS_CANCELLED = 'cancelled';
Format Type Constants
const FORMAT_TICKET = 'ticket'; // Plant / 80mm
const FORMAT_LETTER = 'letter'; // Office / Credit
const FORMAT_ROUTE = 'route'; // Truck / 58mm
Relationships
sale()
Returns the sale associated with this invoice.
Returns a Sale model instance
$invoice->sale; // Sale object
$invoice->sale->total_amount; // Sale total
$invoice->sale->client; // Access client through sale
Scopes
withIndexRelations()
Eager loads necessary relationships for index pages and list views.
Invoice::withIndexRelations()->get();
This scope loads:
sale (id, number, payment_type, client_id, total_amount)
sale.client (id, name)
Static Methods
getStatuses()
Returns an array of available statuses with their human-readable labels.
Invoice::getStatuses();
// Returns:
// [
// 'active' => 'Vigente',
// 'cancelled' => 'Anulada'
// ]
getFormats()
Returns an array of available format types with their descriptions.
Invoice::getFormats();
// Returns:
// [
// 'ticket' => 'Ticket (80mm)',
// 'letter' => 'Carta (Oficina)',
// 'route' => 'Ruta (58mm)'
// ]
getStatusStyles()
Returns Tailwind CSS classes for status badges in the UI.
Invoice::getStatusStyles();
// Returns:
// [
// 'active' => 'bg-emerald-100 text-emerald-700 border-emerald-200 ring-emerald-500/10',
// 'cancelled' => 'bg-red-100 text-red-700 border-red-200 ring-red-500/10'
// ]
getFormatIcons()
Returns Heroicon class names for format type icons.
Invoice::getFormatIcons();
// Returns:
// [
// 'ticket' => 'heroicon-s-printer',
// 'letter' => 'heroicon-s-document-text',
// 'route' => 'heroicon-s-truck'
// ]
Usage Examples
Creating an Invoice
use App\Models\Sales\Invoice;
$invoice = Invoice::create([
'sale_id' => $sale->id,
'invoice_number' => 'INV-2024-0001',
'type' => 'standard',
'format_type' => Invoice::FORMAT_TICKET,
'status' => Invoice::STATUS_ACTIVE,
'due_date' => now()->addDays(30),
'generated_by' => auth()->id()
]);
Querying Invoices
// Get all active invoices with relationships
$invoices = Invoice::withIndexRelations()
->where('status', Invoice::STATUS_ACTIVE)
->orderBy('created_at', 'desc')
->get();
// Access sale and client information
foreach ($invoices as $invoice) {
echo $invoice->invoice_number;
echo $invoice->sale->number;
echo $invoice->sale->client->name;
echo $invoice->sale->total_amount;
}
Filtering by Format Type
// Get all ticket format invoices
$ticketInvoices = Invoice::where('format_type', Invoice::FORMAT_TICKET)
->get();
// Get letter format invoices for credit sales
$letterInvoices = Invoice::where('format_type', Invoice::FORMAT_LETTER)
->whereHas('sale', function ($query) {
$query->where('payment_type', 'credit');
})
->get();
Working with Invoice Status
// Get status label
$statuses = Invoice::getStatuses();
$statusLabel = $statuses[$invoice->status]; // 'Vigente' or 'Anulada'
// Get CSS classes for status badge
$styles = Invoice::getStatusStyles();
$badgeClass = $styles[$invoice->status];
// Get format icon
$icons = Invoice::getFormatIcons();
$icon = $icons[$invoice->format_type];
Cancelling an Invoice
$invoice->status = Invoice::STATUS_CANCELLED;
$invoice->save();
Finding Invoices by Due Date
// Get overdue invoices
$overdueInvoices = Invoice::where('status', Invoice::STATUS_ACTIVE)
->whereNotNull('due_date')
->where('due_date', '<', now())
->withIndexRelations()
->get();
// Get invoices due this week
$dueThisWeek = Invoice::where('status', Invoice::STATUS_ACTIVE)
->whereBetween('due_date', [now()->startOfWeek(), now()->endOfWeek()])
->get();
Format-Specific Operations
// Generate print data based on format
switch ($invoice->format_type) {
case Invoice::FORMAT_TICKET:
// 80mm thermal printer settings
$width = 80;
break;
case Invoice::FORMAT_LETTER:
// Standard letter size
$width = 216;
break;
case Invoice::FORMAT_ROUTE:
// 58mm portable printer
$width = 58;
break;
}
Generating Invoice Reports
// Monthly invoice summary
$monthlySummary = Invoice::where('status', Invoice::STATUS_ACTIVE)
->whereMonth('created_at', now()->month)
->whereYear('created_at', now()->year)
->withIndexRelations()
->get()
->groupBy('format_type')
->map(function ($group) {
return [
'count' => $group->count(),
'total' => $group->sum('sale.total_amount')
];
});
Format Type Use Cases
Ticket Format (80mm)
Ideal for:
- Point of sale terminals
- Retail counter sales
- Quick customer receipts
- Thermal printers
Letter Format
Ideal for:
- Formal invoices
- Credit sales
- Office documentation
- Archive copies
Route Format (58mm)
Ideal for:
- Mobile sales routes
- Delivery trucks
- Portable printers
- Field sales
Related Models
- Sale - Associated sales transaction
- Client - Customer information (via Sale)
- SaleItem - Line items (via Sale)