Skip to main content

Overview

The Sale model represents a sales transaction in the system. It handles both cash and credit sales, tracks payment information, manages sale items, and integrates with invoicing and NCF (tax document numbering) systems. Namespace: App\Models\Sales\Sale Database Table: sales Traits: SoftDeletes

Properties

Fillable Attributes

document_type_id
integer
ID of the document type associated with the sale
number
string
Sale number/identifier for tracking
client_id
integer
required
Foreign key to the Client model
warehouse_id
integer
required
Foreign key to the Warehouse model where the sale originated
user_id
integer
required
Foreign key to the User who created the sale
sale_date
datetime
required
Date and time when the sale was made
total_amount
decimal
required
Total amount of the sale in the system currency
payment_type
string
required
Type of payment: ‘cash’ or ‘credit’
tipo_pago_id
integer
Foreign key to the TipoPago (payment type configuration) model
cash_received
decimal
Amount of cash received from customer (for cash payments)
cash_change
decimal
Change returned to customer (for cash payments)
status
string
required
Current status: ‘completed’ or ‘canceled’
notes
text
Additional notes or comments about the sale

Constants

Status Constants

const STATUS_COMPLETED = 'completed';
const STATUS_CANCELED  = 'canceled';

Payment Type Constants

const PAYMENT_CASH   = 'cash';
const PAYMENT_CREDIT = 'credit';

Relationships

items()

Returns all line items of the sale.
items
HasMany
Returns a collection of SaleItem models
$sale->items; // Collection of SaleItem objects

client()

Returns the client associated with the sale.
client
BelongsTo
Returns a Client model instance
$sale->client; // Client object
$sale->client->name; // Client name

user()

Returns the user who created the sale.
user
BelongsTo
Returns a User model instance
$sale->user; // User object
$sale->user->name; // User name

warehouse()

Returns the warehouse where the sale originated.
warehouse
BelongsTo
Returns a Warehouse model instance
$sale->warehouse; // Warehouse object
$sale->warehouse->name; // Warehouse name

tipoPago()

Returns the payment type configuration.
tipoPago
BelongsTo
Returns a TipoPago model instance
$sale->tipoPago; // TipoPago object
$sale->tipoPago->nombre; // Payment type name

invoice()

Returns the invoice associated with the sale (if exists).
invoice
HasOne
Returns an Invoice model instance or null
$sale->invoice; // Invoice object or null

ncfLog()

Returns the NCF (tax document number) log for the sale.
ncfLog
HasOne
Returns an NcfLog model instance or null
$sale->ncfLog; // NcfLog object or null
$sale->ncfLog->full_ncf; // Full NCF number

Accessors

ncf

Convenience accessor to get the full NCF number directly.
$sale->ncf; // Returns $sale->ncfLog?->full_ncf

Scopes

withIndexRelations()

Eager loads all necessary relationships for index pages and exports.
Sale::withIndexRelations()->get();
This scope loads:
  • client (id, name, tax_id)
  • user (id, name)
  • warehouse (id, name)
  • tipoPago (id, nombre)
  • items (all fields)
  • items.product (id, name, sku)

Static Methods

getStatuses()

Returns an array of available statuses with their labels.
Sale::getStatuses();
// Returns:
// [
//   'completed' => 'Completada',
//   'canceled' => 'Anulada'
// ]

getPaymentTypes()

Returns an array of available payment types with their labels.
Sale::getPaymentTypes();
// Returns:
// [
//   'cash' => 'Contado',
//   'credit' => 'Crédito'
// ]

getStatusStyles()

Returns Tailwind CSS classes for status badges.
Sale::getStatusStyles();
// Returns:
// [
//   'completed' => 'bg-emerald-100 text-emerald-700 border-emerald-200 ring-emerald-500/10',
//   'canceled' => 'bg-red-100 text-red-700 border-red-200 ring-red-500/10'
// ]

getPaymentTypeStyles()

Returns Tailwind CSS classes for payment type badges.
Sale::getPaymentTypeStyles();
// Returns:
// [
//   'cash' => 'bg-blue-100 text-blue-700 border-blue-200 ring-blue-500/10',
//   'credit' => 'bg-amber-100 text-amber-700 border-amber-200 ring-amber-500/10'
// ]

getPaymentTypeIcons()

Returns Heroicon class names for payment type icons.
Sale::getPaymentTypeIcons();
// Returns:
// [
//   'cash' => 'heroicon-s-banknotes',
//   'credit' => 'heroicon-s-credit-card'
// ]

Usage Examples

Creating a Sale

use App\Models\Sales\Sale;

$sale = Sale::create([
    'client_id' => 1,
    'warehouse_id' => 1,
    'user_id' => auth()->id(),
    'sale_date' => now(),
    'total_amount' => 1500.00,
    'payment_type' => Sale::PAYMENT_CASH,
    'cash_received' => 2000.00,
    'cash_change' => 500.00,
    'status' => Sale::STATUS_COMPLETED,
    'notes' => 'Regular sale'
]);

Querying Sales with Relationships

// Get all completed sales with relationships
$sales = Sale::withIndexRelations()
    ->where('status', Sale::STATUS_COMPLETED)
    ->orderBy('sale_date', 'desc')
    ->get();

foreach ($sales as $sale) {
    echo $sale->client->name;
    echo $sale->total_amount;
    echo $sale->ncf; // Access NCF directly
    
    foreach ($sale->items as $item) {
        echo $item->product->name;
        echo $item->quantity;
    }
}

Filtering by Payment Type

// Get all credit sales
$creditSales = Sale::where('payment_type', Sale::PAYMENT_CREDIT)
    ->with('client')
    ->get();

// Get cash sales from today
$todayCashSales = Sale::where('payment_type', Sale::PAYMENT_CASH)
    ->whereDate('sale_date', today())
    ->sum('total_amount');

Working with Sale Status

// Get status label
$statuses = Sale::getStatuses();
$statusLabel = $statuses[$sale->status]; // 'Completada' or 'Anulada'

// Get CSS classes for badge
$styles = Sale::getStatusStyles();
$badgeClass = $styles[$sale->status];

Build docs developers (and LLMs) love