PHPackages                             solution-forest/bookflow - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. solution-forest/bookflow

AbandonedArchivedLibrary[Framework](/categories/framework)

solution-forest/bookflow
========================

Book Flow for Laravel

0.0.2(11mo ago)32MITPHPPHP &gt;=8.3CI passing

Since May 12Pushed 10mo ago2 watchersCompare

[ Source](https://github.com/solutionforest/bookflow)[ Packagist](https://packagist.org/packages/solution-forest/bookflow)[ Docs](https://github.com/solutionforest/bookflow)[ GitHub Sponsors](https://github.com/solution-forest)[ RSS](/packages/solution-forest-bookflow/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)Dependencies (12)Versions (3)Used By (0)

BookFlow
========

[](#bookflow)

[![Latest Version on Packagist](https://camo.githubusercontent.com/0f7fcfc5642dae6d1e87ac4a80c6d69e78c32c9fd91e49aeac060b92067356df/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f736f6c7574696f6e2d666f726573742f626f6f6b666c6f772e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/solution-forest/bookflow)[![GitHub Tests Action Status](https://camo.githubusercontent.com/b26139f10bf2fe5a35098e609dec9b4be3e6317ea52daf1eace520f903c75b8b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f736f6c7574696f6e666f726573742f626f6f6b666c6f772f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/solutionforest/bookflow/actions?query=workflow%3Arun-tests+branch%3Amain)[![GitHub Code Style Action Status](https://camo.githubusercontent.com/ce27d14cb721cd6db0392c55bb037f9a15788b230fd89594fe896447f2438c90/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f736f6c7574696f6e666f726573742f626f6f6b666c6f772f6669782d7068702d636f64652d7374796c652d6973737565732e796d6c3f6272616e63683d6d61696e266c6162656c3d636f64652532307374796c65267374796c653d666c61742d737175617265)](https://github.com/solutionforest/bookflow/actions?query=workflow%3A%22Fix+PHP+code+style+issues%22+branch%3Amain)[![Total Downloads](https://camo.githubusercontent.com/7f9925ef496b30972fbff56228b070c8e010acab5837ea5cd77d4e9f6d913848/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f736f6c7574696f6e2d666f726573742f626f6f6b666c6f772e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/solution-forest/bookflow)

---

Deprecation Notice
------------------

[](#deprecation-notice)

**⚠️ This project is now deprecated and will not receive further development.**

We recommend users to migrate to [laravel-zap](https://github.com/ludoguenet/laravel-zap), which provides a more robust and actively maintained solution for booking and scheduling systems in Laravel.

- [laravel-zap](https://github.com/ludoguenet/laravel-zap)

BookFlow will remain available for reference but is no longer recommended for new projects. Please consider [laravel-zap](https://github.com/ludoguenet/laravel-zap) for your production needs.

---

BookFlow
--------

[](#bookflow-1)

BookFlow is a flexible Laravel package for managing bookings and pricing strategies. It provides a robust foundation for implementing booking systems with customizable pricing calculations.

> ⚠️ **WARNING: DEVELOPMENT STATUS**⚠️
>
> This package is currently under active development and is **NOT READY FOR PRODUCTION USE**.
>
> Features may be incomplete, APIs might change, and there could be breaking changes. Use at your own risk in development environments only.

Features
--------

[](#features)

- Easy booking management with support for one-time and recurring bookings
- **Capacity Management** - Allow multiple bookings per timeslot (default: 1 booking)
- Flexible pricing strategies (Fixed, Hourly, Daily)
- Customizable time-based pricing with configurable units and rounding
- Extensible architecture for custom pricing strategies
- Built-in conflict detection and availability checking with capacity constraints
- Support for multiple service types and rates
- Comprehensive date and time validation
- Laravel Eloquent integration

Capacity Management
-------------------

[](#capacity-management)

BookFlow allows multiple bookings for the same timeslot when capacity is available.

```
// Set capacity for your model
class Room extends Model
{
    use HasBookings;

    public $capacity = 3; // Allow 3 bookings per timeslot
}

// Multiple users can book the same time
$booking1 = Booking::create([...]);  // Uses 1/3 capacity
$booking2 = Booking::create([...]);  // Uses 2/3 capacity
$booking3 = Booking::create([...]);  // Uses 3/3 capacity
// 4th booking would throw BookingException

// Check availability
$available = $room->isAvailable($start, $end, null, $quantity);
```

**Default capacity is 1 booking per timeslot.** You can change this in your model or globally in `config/bookflow.php`:

```
// In config/bookflow.php
'booking' => [
    'default_capacity' => 3, // Change default capacity for all models
]
```

Installation
------------

[](#installation)

> **Requires [PHP 8.3+](https://php.net/releases/), and [Laravel 11.0+](https://laravel.com)**.

You can install the package via composer:

```
composer require solution-forest/bookflow
```

Publish and run the migrations:

```
php artisan vendor:publish --tag="bookflow-migrations"
php artisan migrate
```

Publish the config file:

```
php artisan vendor:publish --tag="bookflow-config"
```

Configuration
-------------

[](#configuration)

After publishing the config file, you can configure the pricing strategies in `config/bookflow.php`:

```
return [
    'pricing' => [
        'strategies' => [
            'fixed' => \SolutionForest\Bookflow\Services\PricingStrategies\FixedPriceStrategy::class,
            'hour' => \SolutionForest\Bookflow\Services\PricingStrategies\TimeBasedPricingStrategy::class,
            'day' => \SolutionForest\Bookflow\Services\PricingStrategies\TimeBasedPricingStrategy::class,
        ],
        'custom_strategies' => [
            // Add your custom strategies here
            // 'group' => \App\Services\PricingStrategies\GroupBookingStrategy::class,
        ],
        'time_based' => [
            'round_up' => true, // Whether to round up partial units
            'minimum_units' => 1, // Minimum number of units to charge
        ],
    ],
];
```

Usage
-----

[](#usage)

### Setting Up Your Models

[](#setting-up-your-models)

First, add the `HasBookings` trait to your bookable model:

```
use SolutionForest\Bookflow\Traits\HasBookings;

class Room extends Model
{
    use HasBookings;

    // Your model implementation
}
```

### Managing Rates

[](#managing-rates)

Create and manage different pricing rates:

```
use SolutionForest\Bookflow\Models\Rate;

// Create a fixed-price rate
$fixedRate = Rate::create([
    'name' => 'Standard Rate',
    'price' => 100,
    'strategy' => 'fixed',
]);

// Create an hourly rate
$hourlyRate = Rate::create([
    'name' => 'Hourly Rate',
    'price' => 50,
    'strategy' => 'hour',
    'minimum_units' => 2, // Minimum 2 hours
]);

// Create a daily rate
$dailyRate = Rate::create([
    'name' => 'Daily Rate',
    'price' => 200,
    'strategy' => 'day',
]);
```

### Basic Booking Operations

[](#basic-booking-operations)

BookFlow provides multiple ways to create bookings. Here's the recommended fluent interface:

```
use SolutionForest\Bookflow\Models\Booking;

// Create a booking using the fluent interface
$booking = Booking::make()
    ->forRate($hourlyRate)
    ->from(now())
    ->to(now()->addHours(3))
    ->forCustomer($customer)
    ->forBookable($room)
    ->withQuantity(2)
    ->withNotes('Special requirements')
    ->save();

// Alternative method using create
$booking = Booking::create([
    'rate_id' => $hourlyRate->id,
    'starts_at' => now(),
    'ends_at' => now()->addHours(3),
    'customer_id' => $customer->id,
    'customer_type' => get_class($customer),
    'bookable_id' => $room->id,
    'bookable_type' => Room::class,
    'quantity' => 1,
]);

// Check booking status
$isPast = $booking->isPast();
$isCurrent = $booking->isCurrent();
$isFuture = $booking->isFuture();
$isCancelled = $booking->isCancelled();

// Get related bookings
$pastBookings = $booking->past();
$currentBookings = $booking->current();
$futureBookings = $booking->future();
$cancelledBookings = $booking->cancelled();
```

### Checking Availability

[](#checking-availability)

```
use SolutionForest\Bookflow\Helpers\BookingHelper;

// Check if a room is available for a specific time period
$room = Room::find(1);
$isAvailable = $room->isAvailable(
    start: now(),
    end: now()->addHours(2)
);

// Get all available rates for a time period
$availableRates = $room->getAvailableRates(
    start: now(),
    end: now()->addHours(2)
);

// Find available time slots
$timeSlots = BookingHelper::findAvailableTimeSlots(
    bookable: $room,
    date: now()->toDateString(),
    duration: 60, // minutes
    rate: $hourlyRate // optional: filter by specific rate
);

// Advanced availability checking
$availability = BookingHelper::checkAvailability(
    bookable: $room,
    start: now(),
    end: now()->addDays(7),
    rate: $hourlyRate,
    quantity: 2 // check if multiple units are available
);

// Get conflicting bookings
$conflicts = $room->getConflictingBookings(
    start: now(),
    end: now()->addHours(2)
);
```

### Recurring Bookings

[](#recurring-bookings)

Create bookings that repeat on specific days:

```
use SolutionForest\Bookflow\Models\RecurringBooking;

$recurringBooking = RecurringBooking::create([
    'rate_id' => $hourlyRate->id,
    'start_time' => '09:00',
    'end_time' => '10:00',
    'days_of_week' => ['monday', 'wednesday', 'friday'],
    'starts_from' => now(),
    'ends_at' => now()->addMonths(3),
    'bookable_id' => $room->id,
    'bookable_type' => Room::class,
    'customer_id' => $customer->id,
]);

// Get all bookings generated from this recurring booking
$generatedBookings = $recurringBooking->bookings;

// Update recurring booking
$recurringBooking->update([
    'days_of_week' => ['tuesday', 'thursday'],
    'ends_at' => now()->addMonths(6),
]);
```

### Custom Pricing Strategies

[](#custom-pricing-strategies)

Create a custom pricing strategy:

```
use SolutionForest\Bookflow\Services\PricingStrategies\PricingStrategy;
use SolutionForest\Bookflow\Models\Booking;

class GroupBookingStrategy implements PricingStrategy
{
    public function calculate(Booking $booking): float
    {
        $basePrice = $booking->rate->price;
        $groupSize = $booking->group_size;

        // Apply group discount
        if ($groupSize >= 10) {
            return $basePrice * $groupSize * 0.8; // 20% discount
        } elseif ($groupSize >= 5) {
            return $basePrice * $groupSize * 0.9; // 10% discount
        }

        return $basePrice * $groupSize;
    }
}
```

Register your custom strategy in `config/bookflow.php`:

```
'custom_strategies' => [
    'group' => \App\Services\PricingStrategies\GroupBookingStrategy::class,
],
```

Use the custom strategy:

```
$groupRate = Rate::create([
    'name' => 'Group Rate',
    'price' => 30,
    'strategy' => 'group',
]);

$booking = Booking::create([
    'rate_id' => $groupRate->id,
    'start_time' => now(),
    'end_time' => now()->addHours(2),
    'group_size' => 8,
    // ... other booking details
]);

$price = $booking->calculatePrice(); // Will use GroupBookingStrategy
```

### Additional Custom Pricing Strategy Example

[](#additional-custom-pricing-strategy-example)

Here's an example of a seasonal pricing strategy that adjusts rates based on peak seasons and special events:

```
use SolutionForest\Bookflow\Services\PricingStrategies\PricingStrategy;
use SolutionForest\Bookflow\Models\Booking;
use Carbon\Carbon;

class SeasonalPricingStrategy implements PricingStrategy
{
    protected array $peakSeasons = [
        ['start' => '06-15', 'end' => '09-15'], // Summer peak
        ['start' => '12-15', 'end' => '01-15'], // Holiday peak
    ];

    protected array $specialEvents = [
        '12-24' => 2.0,  // Christmas Eve: 100% markup
        '12-31' => 2.5,  // New Year's Eve: 150% markup
    ];

    public function calculate(Booking $booking): float
    {
        $basePrice = $booking->rate->price;
        $bookingDate = Carbon::parse($booking->start_time);

        // Check for special event dates
        $eventDate = $bookingDate->format('m-d');
        if (isset($this->specialEvents[$eventDate])) {
            return $basePrice * $this->specialEvents[$eventDate];
        }

        // Check for peak seasons
        foreach ($this->peakSeasons as $season) {
            $seasonStart = Carbon::createFromFormat('m-d', $season['start']);
            $seasonEnd = Carbon::createFromFormat('m-d', $season['end']);

            if ($bookingDate->between($seasonStart, $seasonEnd)) {
                return $basePrice * 1.5; // 50% markup during peak season
            }
        }

        // Regular season price
        return $basePrice;
    }
}
```

Register the seasonal pricing strategy:

```
'custom_strategies' => [
    'group' => \App\Services\PricingStrategies\GroupBookingStrategy::class,
    'seasonal' => \App\Services\PricingStrategies\SeasonalPricingStrategy::class,
],
```

Use the seasonal pricing strategy:

```
$seasonalRate = Rate::create([
    'name' => 'Seasonal Rate',
    'price' => 100, // Base price
    'strategy' => 'seasonal',
]);

$booking = Booking::create([
    'rate_id' => $seasonalRate->id,
    'start_time' => '2024-12-31 20:00:00',
    'end_time' => '2025-01-01 02:00:00',
    // ... other booking details
]);

$price = $booking->calculatePrice(); // Will return 250 (base price * 2.5 for New Year's Eve)
```

### Error Handling

[](#error-handling)

BookFlow provides specific exceptions for different scenarios:

```
use SolutionForest\Bookflow\Exceptions\BookingException;
use SolutionForest\Bookflow\Exceptions\PricingException;

try {
    $booking = Booking::create([
        // ... booking details
    ]);
} catch (BookingException $e) {
    // Handle booking-related errors (conflicts, validation, etc.)
    report($e);
} catch (PricingException $e) {
    // Handle pricing-related errors
    report($e);
}
```

### Command-Line Tools

[](#command-line-tools)

BookFlow provides a command-line tool for checking system configuration and data integrity:

```
# Run all checks
php artisan bookflow:check --all

# Check rate configurations
php artisan bookflow:check --rates

# Check for booking conflicts
php artisan bookflow:check --bookings

# Test pricing calculations
php artisan bookflow:check --pricing
```

This command helps you:

- Validate rate configurations (units, minimum units, etc.)
- Detect booking conflicts and invalid booking periods
- Test pricing calculations for all rates

Testing
-------

[](#testing)

```
composer test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [alan](https://github.com/lam0819)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

30

—

LowBetter than 64% of packages

Maintenance53

Moderate activity, may be stable

Popularity6

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity43

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 90.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~13 days

Total

2

Last Release

356d ago

PHP version history (2 changes)0.0.1PHP ^8.3

0.0.2PHP &gt;=8.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/9499120912b47a170291b3b795ea0255f060d8500bd2988535e4e6faccee5c8d?d=identicon)[solutionforest](/maintainers/solutionforest)

---

Top Contributors

[![lam0819](https://avatars.githubusercontent.com/u/68211972?v=4)](https://github.com/lam0819 "lam0819 (28 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (2 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (1 commits)")

---

Tags

laravelSolution Forestbookflow

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/solution-forest-bookflow/health.svg)

```
[![Health](https://phpackages.com/badges/solution-forest-bookflow/health.svg)](https://phpackages.com/packages/solution-forest-bookflow)
```

###  Alternatives

[laravel/horizon

Dashboard and code-driven configuration for Laravel queues.

4.2k84.2M225](/packages/laravel-horizon)[lunarstorm/laravel-ddd

A Laravel toolkit for Domain Driven Design patterns

17959.0k](/packages/lunarstorm-laravel-ddd)[bezhansalleh/filament-plugin-essentials

A collection of essential traits that streamline Filament plugin development by taking care of the boilerplate, so you can focus on shipping real features faster

27584.7k16](/packages/bezhansalleh-filament-plugin-essentials)[vormkracht10/laravel-mails

Laravel Mails can collect everything you might want to track about the mails that has been sent by your Laravel app.

24149.7k](/packages/vormkracht10-laravel-mails)[jonpurvis/squeaky

A Laravel Validation Rule to Help Catch Profanity.

706.0k](/packages/jonpurvis-squeaky)[blendbyte/filament-title-with-slug

TitleWithSlugInput - Easy Permalink Slugs for the FilamentPHP Form Builder (PHP / Laravel / Livewire)

1322.4k3](/packages/blendbyte-filament-title-with-slug)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
