Offers
Create travel offers by selecting flights from the Dynamic Flight Cache. Offers combine a MarketProduct with a departure airport, date, and price.
Overview
Section titled “Overview”Offers represent bookable travel packages that combine:
- MarketProduct - The travel product (tour, package, etc.)
- Departure Airport - Where the flight departs from
- Departure Date - When the flight departs
- Price - Total offer price
- CUG Type - Closed User Group fare type
Database Schema
Section titled “Database Schema”Table: offers
| Column | Type | Description |
|---|---|---|
id | BIGINT | Primary key |
product_by_market_id | BIGINT | FK to products_by_market |
departure_airport_id | BIGINT | FK to airports |
departure_date | DATE | Flight departure date |
total_price | DECIMAL(10,2) | Offer price |
cug_type | VARCHAR(10) | CUG fare type (ALL, TOP, ETH, CRU) |
created_at | TIMESTAMP | - |
updated_at | TIMESTAMP | - |
Constraints:
- Unique:
(product_by_market_id, departure_airport_id, departure_date, total_price, cug_type) - Foreign keys cascade on delete
Quick Start
Section titled “Quick Start”Basic Usage
Section titled “Basic Usage”use App\Models\Offer;
// Create an offer$offer = Offer::create([ 'product_by_market_id' => 1, 'departure_airport_id' => 10, 'departure_date' => '2026-03-15', 'total_price' => 599.00, 'cug_type' => 'ALL',]);
// Access relationships$offer->productByMarket; // ProductByMarket model$offer->departureAirport; // Airport modelQuery Examples
Section titled “Query Examples”// Query offers by market$offers = Offer::whereHas('productByMarket', function ($query) use ($marketId) { $query->where('market_id', $marketId);})->get();
// Get offers with relationships$offers = Offer::with([ 'productByMarket.productTemplate', 'productByMarket.market', 'departureAirport',])->get();
// Filter by date range$offers = Offer::whereBetween('departure_date', [$startDate, $endDate])->get();Admin Panel
Section titled “Admin Panel”Location: /admin/offers
Create Offers (Bulk from Flight Cache)
Section titled “Create Offers (Bulk from Flight Cache)”- Select Market Product from dropdown
- Select Departure Airport (filtered by product’s flight configs)
- View cached flights in the table
- Use filters: Month, Day of Week, CUG Type, Price Range
- Select multiple rows and click Create Offers
Duplicates are automatically skipped with a notification showing how many were created vs. skipped.
List/View Offers
Section titled “List/View Offers”- View all offers with filters for product, market, airport
- Click to view offer details
- Delete individual offers or bulk delete
Note: Offers are immutable once created (no edit functionality).
Relationships
Section titled “Relationships”class Offer extends Model{ public function productByMarket(): BelongsTo { return $this->belongsTo(ProductByMarket::class); }
public function departureAirport(): BelongsTo { return $this->belongsTo(Airport::class, 'departure_airport_id'); }}protected $casts = [ 'departure_date' => 'date', 'total_price' => 'decimal:2',];CUG Types
Section titled “CUG Types”Closed User Group fare types:
| Type | Description |
|---|---|
ALL | All available fare categories |
TOP | Tour operator fares |
ETH | Ethnic/VFR (Visiting Friends & Relatives) |
CRU | Cruise passenger fares |
Testing
Section titled “Testing”Test File: tests/Feature/Models/OfferTest.php
Coverage (8 tests):
- Model relationships
- Date and decimal casting
- CUG type attribute
- Cascade delete
- Unique constraint (duplicate prevention)
- Different prices allowed for same date
Run Tests:
./vendor/bin/sail artisan test tests/Feature/Models/OfferTest.phpRelated Documentation
Section titled “Related Documentation”- Multi-Market API - API endpoints for offers
- Flight Search - Flight search interface