{"id":1441,"date":"2025-01-04T14:07:42","date_gmt":"2025-01-04T14:07:42","guid":{"rendered":"https:\/\/www.cmsgalaxy.com\/blog\/?p=1441"},"modified":"2025-01-06T13:21:59","modified_gmt":"2025-01-06T13:21:59","slug":"design-a-booking-state-workflow-in-php-laravel","status":"publish","type":"post","link":"https:\/\/www.cmsgalaxy.com\/blog\/design-a-booking-state-workflow-in-php-laravel\/","title":{"rendered":"Design a Booking State Workflow in PHP Laravel"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"595\" src=\"https:\/\/www.cmsgalaxy.com\/blog\/wp-content\/uploads\/2025\/01\/image-1024x595.png\" alt=\"\" class=\"wp-image-1444\" srcset=\"https:\/\/www.cmsgalaxy.com\/blog\/wp-content\/uploads\/2025\/01\/image-1024x595.png 1024w, https:\/\/www.cmsgalaxy.com\/blog\/wp-content\/uploads\/2025\/01\/image-300x174.png 300w, https:\/\/www.cmsgalaxy.com\/blog\/wp-content\/uploads\/2025\/01\/image-768x446.png 768w, https:\/\/www.cmsgalaxy.com\/blog\/wp-content\/uploads\/2025\/01\/image.png 1271w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Certainly! Adding an <strong>automatic cancellation mechanism<\/strong> for scenarios where the <strong>Partner<\/strong> doesn\u2019t confirm a booking within a set time or the <strong>Renter<\/strong> fails to pay on time makes the workflow more robust and user-friendly. Here&#8217;s the updated <strong>Booking State Workflow<\/strong>:<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Updated Booking States Workflow<\/strong><\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th><strong>State<\/strong><\/th><th><strong>Description<\/strong><\/th><\/tr><\/thead><tbody><tr><td><strong>Pending<\/strong><\/td><td>Booking created but awaiting Partner confirmation.<\/td><\/tr><tr><td><strong>Auto-Cancelled<\/strong><\/td><td>Booking automatically cancelled due to Partner\u2019s inaction within 1 hour.<\/td><\/tr><tr><td><strong>Confirmed<\/strong><\/td><td>Partner has confirmed the booking.<\/td><\/tr><tr><td><strong>Awaiting Payment<\/strong><\/td><td>Renter has not completed payment within 1 hour of confirmation. Booking may auto-cancel.<\/td><\/tr><tr><td><strong>Paid<\/strong><\/td><td>Renter has completed payment.  THE MOMENT PARTNER make ORDER as PAID, <strong>Vehicle Ready<\/strong><\/td><\/tr><tr><td><strong>Vehicle Ready<\/strong><\/td><td>Partner has prepared the vehicle for pick-up\/delivery.<\/td><\/tr><tr><td><strong>In Progress<\/strong><\/td><td>Vehicle has been handed over to the Renter.When <strong>Partner<\/strong> click on <strong>Picked up<\/strong> , then imm it would get into In <strong>In Progress<\/strong><\/td><\/tr><tr><td><strong>Completed<\/strong><\/td><td>Booking successfully completed and vehicle returned. When <strong>Partner<\/strong> click on <strong>Returned<\/strong> , then imm it would get into In  <strong>In Progress<\/strong>. Vehicle would ready automatically<\/td><\/tr><tr><td><strong>Cancelled<\/strong><\/td><td>Booking cancelled manually by Renter or Partner.<\/td><\/tr><tr><td><strong>Refunded<\/strong><\/td><td>NA<\/td><\/tr><tr><td><strong>Issue Reported<\/strong><\/td><td>NA<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>State Transitions with Auto-Cancellation<\/strong><\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th><strong>Current State<\/strong><\/th><th><strong>Trigger\/Action<\/strong><\/th><th><strong>Next State<\/strong><\/th><th><strong>Time Constraint<\/strong><\/th><th><strong>Description<\/strong><\/th><\/tr><\/thead><tbody><tr><td><strong>Pending<\/strong><\/td><td>Partner confirms booking<\/td><td>Confirmed<\/td><td>Within 1 hour of creation<\/td><td>Partner must confirm booking within 1 hour.<\/td><\/tr><tr><td>Pending<\/td><td>System checks timeout<\/td><td>Auto-Cancelled<\/td><td>Exceeds 1 hour<\/td><td>Booking is auto-cancelled if not confirmed.<\/td><\/tr><tr><td><strong>Confirmed<\/strong><\/td><td>Renter completes payment<\/td><td>Paid<\/td><td>Within 1 hour of confirmation<\/td><td>Renter must pay within 1 hour of confirmation.<\/td><\/tr><tr><td>Confirmed<\/td><td>System checks timeout<\/td><td>Auto-Cancelled<\/td><td>Exceeds 1 hour<\/td><td>Booking is auto-cancelled if payment isn\u2019t made.<\/td><\/tr><tr><td><strong>Paid<\/strong><\/td><td>Partner marks vehicle ready<\/td><td>Vehicle Ready<\/td><td>N\/A<\/td><td>Vehicle is prepared for handover.<\/td><\/tr><tr><td><strong>Vehicle Ready<\/strong><\/td><td>Renter picks up the vehicle<\/td><td>In Progress<\/td><td>N\/A<\/td><td>The vehicle is handed over to the Renter.<\/td><\/tr><tr><td><strong>In Progress<\/strong><\/td><td>Renter returns the vehicle<\/td><td>Completed<\/td><td>N\/A<\/td><td>Booking is finalized after vehicle return and inspection.<\/td><\/tr><tr><td><strong>Any State<\/strong><\/td><td>Manual cancellation by Renter or Partner<\/td><td>Cancelled<\/td><td>N\/A<\/td><td>Booking is cancelled manually.<\/td><\/tr><tr><td><strong>Cancelled<\/strong><\/td><td>System processes refund<\/td><td>Refunded<\/td><td>N\/A<\/td><td>Refund initiated for eligible cancellations.<\/td><\/tr><tr><td><strong>In Progress<\/strong><\/td><td>Renter or Partner reports an issue<\/td><td>Issue Reported<\/td><td>N\/A<\/td><td>A damage, delay, or other issue is flagged for resolution.<\/td><\/tr><tr><td><strong>Issue Reported<\/strong><\/td><td>Issue is resolved<\/td><td>Completed<\/td><td>N\/A<\/td><td>Booking finalized after issue resolution.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Updated Workflow with Auto-Cancellation<\/strong><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Step 1: Booking Creation<\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>State<\/strong>: <code>Pending<\/code><\/li>\n\n\n\n<li><strong>Trigger<\/strong>: Renter creates a booking.<\/li>\n\n\n\n<li><strong>Time Constraint<\/strong>: If <strong>Partner<\/strong> does not confirm within 1 hour, the booking transitions to <code>Auto-Cancelled<\/code>.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Step 2: Booking Confirmation<\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>State<\/strong>: <code>Confirmed<\/code><\/li>\n\n\n\n<li><strong>Trigger<\/strong>: Partner confirms the booking.<\/li>\n\n\n\n<li><strong>Time Constraint<\/strong>: If <strong>Renter<\/strong> does not pay within 1 hour, the booking transitions to <code>Auto-Cancelled<\/code>.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Step 3: Payment<\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>State<\/strong>: <code>Paid<\/code><\/li>\n\n\n\n<li><strong>Trigger<\/strong>: Renter completes payment.<\/li>\n\n\n\n<li><strong>Transition<\/strong>: The booking progresses to <code>Vehicle Ready<\/code> once the Partner prepares the vehicle.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Step 4: Auto-Cancellation Conditions<\/strong><\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Pending to Auto-Cancelled<\/strong>: No confirmation from the Partner within 1 hour.<\/li>\n\n\n\n<li><strong>Confirmed to Auto-Cancelled<\/strong>: No payment from the Renter within 1 hour.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Implementation Details<\/strong><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Database Changes<\/strong><\/h4>\n\n\n\n<p>Add a column to track auto-cancellation deadlines:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ALTER TABLE bookings ADD COLUMN auto_cancel_at TIMESTAMP NULL;\n<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Auto-Cancellation Logic<\/strong><\/h4>\n\n\n\n<p>Schedule a background task (e.g., <strong>Laravel Scheduler<\/strong>) to handle time-based state transitions.<\/p>\n\n\n\n<p><strong>Example Code for Auto-Cancellation Job:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>namespace App\\Jobs;\n\nuse App\\Models\\Booking;\nuse Illuminate\\Support\\Facades\\Log;\n\nclass AutoCancelBookings extends Job\n{\n    public function handle()\n    {\n        \/\/ Fetch bookings eligible for auto-cancellation\n        $now = now();\n        $bookings = Booking::whereIn('status', &#91;'Pending', 'Confirmed'])\n            -&gt;where('auto_cancel_at', '&lt;=', $now)\n            -&gt;get();\n\n        foreach ($bookings as $booking) {\n            if ($booking-&gt;status === 'Pending') {\n                $booking-&gt;update(&#91;'status' =&gt; 'Auto-Cancelled']);\n                Log::info(\"Booking {$booking-&gt;id} auto-cancelled due to no Partner confirmation.\");\n            }\n\n            if ($booking-&gt;status === 'Confirmed' &amp;&amp; $booking-&gt;payment_status !== 'Paid') {\n                $booking-&gt;update(&#91;'status' =&gt; 'Auto-Cancelled']);\n                Log::info(\"Booking {$booking-&gt;id} auto-cancelled due to no Renter payment.\");\n            }\n        }\n    }\n}\n<\/code><\/pre>\n\n\n\n<p><strong>Schedule the Job in <code>app\/Console\/Kernel.php<\/code>:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>protected function schedule(Schedule $schedule)\n{\n    $schedule-&gt;job(new AutoCancelBookings)-&gt;everyMinute();\n}\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Frontend Updates<\/strong><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>For Renter Dashboard<\/strong>:<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Display Time Remaining<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Show a countdown for payment time if the booking is in <code>Confirmed<\/code> state.<\/li>\n\n\n\n<li>Example: &#8220;Pay within 59 minutes to confirm your booking.&#8221;<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Auto-Cancellation Notification<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Notify the Renter if the booking is auto-cancelled.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>For Partner Dashboard<\/strong>:<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Display Time Remaining<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Show a countdown for confirmation if the booking is in <code>Pending<\/code> state.<\/li>\n\n\n\n<li>Example: &#8220;Confirm this booking within 30 minutes.&#8221;<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Notifications<\/strong><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>For Renter<\/strong>:<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Pending \u2192 Auto-Cancelled<\/strong>: &#8220;Your booking was cancelled because the Partner did not confirm within 1 hour.&#8221;<\/li>\n\n\n\n<li><strong>Confirmed \u2192 Auto-Cancelled<\/strong>: &#8220;Your booking was cancelled because payment was not completed on time.&#8221;<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>For Partner<\/strong>:<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Pending \u2192 Auto-Cancelled<\/strong>: &#8220;The booking request was cancelled as you did not confirm within 1 hour.&#8221;<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Example State Transition Flow<\/strong><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Case 1: Renter Creates Booking<\/strong><\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Initial State<\/strong>: <code>Pending<\/code>.<\/li>\n\n\n\n<li><strong>Partner Confirms in 40 Minutes<\/strong>: Transition to <code>Confirmed<\/code>.<\/li>\n\n\n\n<li><strong>Renter Pays in 20 Minutes<\/strong>: Transition to <code>Paid<\/code>.<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Case 2: No Partner Confirmation<\/strong><\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Initial State<\/strong>: <code>Pending<\/code>.<\/li>\n\n\n\n<li><strong>Timeout (1 Hour)<\/strong>: Transition to <code>Auto-Cancelled<\/code>.<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Case 3: No Renter Payment<\/strong><\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Initial State<\/strong>: <code>Pending<\/code> \u2192 <code>Confirmed<\/code>.<\/li>\n\n\n\n<li><strong>Timeout (1 Hour)<\/strong>: Transition to <code>Auto-Cancelled<\/code>.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>This updated workflow ensures that bookings are not left in limbo, providing a better experience for both Renters and Partners while maintaining operational efficiency for MotoShare.in. Let me know if you&#8217;d like further customization!<\/p>\n\n\n\n<p>To implement a workflow feature like the one described in <strong>Laravel<\/strong>, the best approach is to design a <strong>state machine<\/strong> that tracks the booking&#8217;s state transitions. Here&#8217;s how you can implement it step-by-step:<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>1. State Machine Design in Laravel<\/strong><\/h3>\n\n\n\n<p>A <strong>state machine<\/strong> is a programming paradigm that defines states, transitions, and the rules for moving between states. In Laravel, this can be implemented efficiently using:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>State Pattern<\/strong>: Build your custom state machine classes.<\/li>\n\n\n\n<li><strong>State Machine Packages<\/strong>: Use a Laravel package for managing workflows, such as:\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/github.com\/wix-incubator\/laravel-state-machine\">Laravel State Machine<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/spatie\/laravel-state\">Spatie&#8217;s Laravel State<\/a><\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>2. Database Design for State Management<\/strong><\/h3>\n\n\n\n<p>Add a <code>status<\/code> column and a <code>auto_cancel_at<\/code> column in your <code>bookings<\/code> table to track the booking state and cancellation deadlines.<\/p>\n\n\n\n<p><strong>Example Migration<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Schema::table('bookings', function (Blueprint $table) {\n    $table-&gt;enum('status', &#91;\n        'Pending',\n        'Auto-Cancelled',\n        'Confirmed',\n        'Awaiting Payment',\n        'Paid',\n        'Vehicle Ready',\n        'In Progress',\n        'Completed',\n        'Cancelled',\n        'Refunded',\n        'Issue Reported',\n    ])-&gt;default('Pending');\n\n    $table-&gt;timestamp('auto_cancel_at')-&gt;nullable();\n});\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>3. State Machine Implementation<\/strong><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Option A: Using <strong>Laravel State Machine<\/strong> Package<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Install Laravel State Machine<\/strong>: <code>composer require wix-incubator\/laravel-state-machine<\/code><\/li>\n\n\n\n<li><strong>Define Booking States and Transitions<\/strong>: Create a <code>BookingStateMachine<\/code><\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>namespace App\\StateMachines;\n\nuse Asantibanez\\LaravelEloquentStateMachines\\StateMachines\\StateMachine;\n\nclass BookingStateMachine extends StateMachine\n{\n    public function transitions(): array\n    {\n        return &#91;\n            'Pending' =&gt; &#91;'Confirmed', 'Auto-Cancelled'],\n            'Confirmed' =&gt; &#91;'Paid', 'Auto-Cancelled'],\n            'Paid' =&gt; &#91;'Vehicle Ready'],\n            'Vehicle Ready' =&gt; &#91;'In Progress'],\n            'In Progress' =&gt; &#91;'Completed', 'Issue Reported'],\n            'Cancelled' =&gt; &#91;'Refunded'],\n        ];\n    }\n\n    public function defaultState(): ?string\n    {\n        return 'Pending';\n    }\n}\n<\/code><\/pre>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Attach State Machine to Booking Model<\/strong>: <\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>namespace App\\Models;\n\nuse Asantibanez\\LaravelEloquentStateMachines\\Traits\\HasStateMachines;\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass Booking extends Model\n{\n    use HasStateMachines;\n\n    public $stateMachines = &#91;\n        'status' =&gt; BookingStateMachine::class,\n    ];\n}\n<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Use Transitions in Code<\/strong>: <\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>$booking = Booking::find(1);\n\nif ($booking-&gt;canTransitionTo('Confirmed')) {\n    $booking-&gt;transitionTo('Confirmed');\n}\n\nif ($booking-&gt;status === 'Confirmed' &amp;&amp; now()-&gt;greaterThan($booking-&gt;auto_cancel_at)) {\n    $booking-&gt;transitionTo('Auto-Cancelled');\n}\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Option B: Custom State Machine Without a Package<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Create a State Machine Service<\/strong>: Create a service class to handle state transitions. <\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>namespace App\\Services;\n\nuse App\\Models\\Booking;\n\nclass BookingStateMachine\n{\n    private $transitions = &#91;\n        'Pending' =&gt; &#91;'Confirmed', 'Auto-Cancelled'],\n        'Confirmed' =&gt; &#91;'Paid', 'Auto-Cancelled'],\n        'Paid' =&gt; &#91;'Vehicle Ready'],\n        'Vehicle Ready' =&gt; &#91;'In Progress'],\n        'In Progress' =&gt; &#91;'Completed', 'Issue Reported'],\n        'Cancelled' =&gt; &#91;'Refunded'],\n    ];\n\n    public function canTransition(Booking $booking, string $newState): bool\n    {\n        $currentState = $booking-&gt;status;\n\n        return in_array($newState, $this-&gt;transitions&#91;$currentState] ?? &#91;]);\n    }\n\n    public function transition(Booking $booking, string $newState)\n    {\n        if (!$this-&gt;canTransition($booking, $newState)) {\n            throw new \\Exception(\"Cannot transition from {$booking-&gt;status} to {$newState}\");\n        }\n\n        $booking-&gt;status = $newState;\n        $booking-&gt;save();\n    }\n}\n<\/code><\/pre>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Use the State Machine Service<\/strong>: <\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>$stateMachine = new \\App\\Services\\BookingStateMachine();\n\n$booking = Booking::find(1);\n\nif ($stateMachine-&gt;canTransition($booking, 'Confirmed')) {\n    $stateMachine-&gt;transition($booking, 'Confirmed');\n}\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>4. Implementing Auto-Cancellation<\/strong><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Step 1: Add Logic to Handle Timeouts<\/strong><\/h4>\n\n\n\n<p>Use a <strong>Laravel Scheduled Job<\/strong> to periodically check and auto-cancel bookings.<\/p>\n\n\n\n<p><strong>Create Job<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>namespace App\\Jobs;\n\nuse App\\Models\\Booking;\n\nclass AutoCancelBookings extends Job\n{\n    public function handle()\n    {\n        \/\/ Auto-cancel Pending bookings not confirmed in time\n        Booking::where('status', 'Pending')\n            -&gt;where('auto_cancel_at', '&lt;=', now())\n            -&gt;update(&#91;'status' =&gt; 'Auto-Cancelled']);\n\n        \/\/ Auto-cancel Confirmed bookings not paid in time\n        Booking::where('status', 'Confirmed')\n            -&gt;where('auto_cancel_at', '&lt;=', now())\n            -&gt;update(&#91;'status' =&gt; 'Auto-Cancelled']);\n    }\n}\n<\/code><\/pre>\n\n\n\n<p><strong>Schedule Job<\/strong>: Add the job to <code>app\/Console\/Kernel.php<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>protected function schedule(Schedule $schedule)\n{\n    $schedule-&gt;job(new AutoCancelBookings)-&gt;everyMinute();\n}\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Step 2: Set Auto-Cancellation Deadline<\/strong><\/h4>\n\n\n\n<p>Set the <code>auto_cancel_at<\/code> timestamp when the booking enters <code>Pending<\/code> or <code>Confirmed<\/code> state.<\/p>\n\n\n\n<p><strong>Example<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$booking = Booking::create(&#91;\n    'status' =&gt; 'Pending',\n    'auto_cancel_at' =&gt; now()-&gt;addHour(),\n]);\n\n\/\/ If Partner confirms:\n$booking-&gt;update(&#91;\n    'status' =&gt; 'Confirmed',\n    'auto_cancel_at' =&gt; now()-&gt;addHour(),\n]);\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>5. Notifications<\/strong><\/h3>\n\n\n\n<p>Use Laravel Notifications for real-time updates to Renters and Partners.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Create Notifications<\/strong>: <code>php artisan make:notification BookingStatusChanged<\/code><\/li>\n\n\n\n<li><strong>Send Notifications<\/strong>: <\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>Notification::send($booking-&gt;renter, new BookingStatusChanged($booking));\nNotification::send($booking-&gt;partner, new BookingStatusChanged($booking));\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>6. Frontend Representation<\/strong><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Display the Current State:<\/h4>\n\n\n\n<p>Use badges or a progress bar to show the booking state:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;div&gt;\n    &lt;span class=\"badge bg-primary\"&gt;{{ $booking-&gt;status }}&lt;\/span&gt;\n&lt;\/div&gt;\n<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Show Countdown Timer:<\/h4>\n\n\n\n<p>For time-sensitive states like <code>Pending<\/code> or <code>Awaiting Payment<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;div&gt;\n    &lt;p&gt;Time remaining: &lt;span id=\"countdown\"&gt;&lt;\/span&gt;&lt;\/p&gt;\n&lt;\/div&gt;\n\n&lt;script&gt;\n    const deadline = new Date(\"{{ $booking-&gt;auto_cancel_at }}\").getTime();\n    const countdownElement = document.getElementById(\"countdown\");\n\n    setInterval(() =&gt; {\n        const now = new Date().getTime();\n        const distance = deadline - now;\n\n        if (distance &lt;= 0) {\n            countdownElement.innerText = \"Expired\";\n        } else {\n            const minutes = Math.floor((distance % (1000 * 60 * 60)) \/ (1000 * 60));\n            const seconds = Math.floor((distance % (1000 * 60)) \/ 1000);\n            countdownElement.innerText = `${minutes}m ${seconds}s`;\n        }\n    }, 1000);\n&lt;\/script&gt;\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>This approach provides a clean, extensible, and maintainable way to manage workflows in Laravel, ensuring automatic cancellations and real-time updates for MotoShare.in. Let me know if you&#8217;d like further elaboration or assistance!<\/p>\n\n\n\n<p>Here\u2019s a professional concept you can use to create the <strong>Booking Workflow Diagram<\/strong> in a tool like Lucidchart, Draw.io, or PowerPoint:<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Steps to Create the Diagram<\/strong><\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Diagram Tool<\/strong>: Open a diagramming tool such as <strong>Lucidchart<\/strong>, <strong>Draw.io<\/strong>, or <strong>Microsoft PowerPoint<\/strong>.<\/li>\n\n\n\n<li><strong>Nodes (States)<\/strong>: Add rounded rectangles for each state. Use the colors listed earlier for distinction.<\/li>\n\n\n\n<li><strong>Transitions<\/strong>: Draw directional arrows between the states with labels explaining the trigger.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Text Representation to Guide Your Diagram<\/strong><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>State Layout<\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Top Layer<\/strong>:\n<ul class=\"wp-block-list\">\n<li><code>Pending<\/code> \u2192 (to the right) <code>Confirmed<\/code><\/li>\n\n\n\n<li><code>Pending<\/code> \u2192 (down) <code>Auto-Cancelled<\/code><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Middle Layer<\/strong>:\n<ul class=\"wp-block-list\">\n<li><code>Confirmed<\/code> \u2192 (to the right) <code>Paid<\/code><\/li>\n\n\n\n<li><code>Confirmed<\/code> \u2192 (down) <code>Auto-Cancelled<\/code><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Lower Layers<\/strong>:\n<ul class=\"wp-block-list\">\n<li><code>Paid<\/code> \u2192 <code>Vehicle Ready<\/code> \u2192 <code>In Progress<\/code> \u2192 <code>Completed<\/code><\/li>\n\n\n\n<li><code>In Progress<\/code> \u2192 (down) <code>Issue Reported<\/code><\/li>\n\n\n\n<li><code>Issue Reported<\/code> \u2192 (back up) <code>Completed<\/code><\/li>\n\n\n\n<li>Any State \u2192 <code>Cancelled<\/code> \u2192 <code>Refunded<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Workflow States (Diagram Elements)<\/strong><\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th><strong>State Name<\/strong><\/th><th><strong>Color<\/strong><\/th><th><strong>Position<\/strong><\/th><th><strong>Connected To<\/strong><\/th><\/tr><\/thead><tbody><tr><td><strong>Pending<\/strong><\/td><td>Grey<\/td><td>Top center<\/td><td><code>Confirmed<\/code>, <code>Auto-Cancelled<\/code><\/td><\/tr><tr><td><strong>Auto-Cancelled<\/strong><\/td><td>Yellow<\/td><td>Below Pending<\/td><td>Trigger: No confirmation within 1 hour<\/td><\/tr><tr><td><strong>Confirmed<\/strong><\/td><td>Blue<\/td><td>Right of Pending<\/td><td><code>Paid<\/code>, <code>Auto-Cancelled<\/code><\/td><\/tr><tr><td><strong>Awaiting Payment<\/strong><\/td><td>Orange<\/td><td>Below Confirmed<\/td><td>Trigger: Awaiting payment (optional; before <code>Paid<\/code>)<\/td><\/tr><tr><td><strong>Paid<\/strong><\/td><td>Green<\/td><td>Right of Confirmed<\/td><td><code>Vehicle Ready<\/code><\/td><\/tr><tr><td><strong>Vehicle Ready<\/strong><\/td><td>Purple<\/td><td>Right of Paid<\/td><td><code>In Progress<\/code><\/td><\/tr><tr><td><strong>In Progress<\/strong><\/td><td>Cyan<\/td><td>Right of Vehicle Ready<\/td><td><code>Completed<\/code>, <code>Issue Reported<\/code><\/td><\/tr><tr><td><strong>Completed<\/strong><\/td><td>Dark Green<\/td><td>Right of In Progress<\/td><td>Final State<\/td><\/tr><tr><td><strong>Cancelled<\/strong><\/td><td>Red<\/td><td>Bottom center<\/td><td>Trigger: Manual cancellation<\/td><\/tr><tr><td><strong>Refunded<\/strong><\/td><td>Light Blue<\/td><td>Below Cancelled<\/td><td>Trigger: Refund after cancellation<\/td><\/tr><tr><td><strong>Issue Reported<\/strong><\/td><td>Orange-Red<\/td><td>Below In Progress<\/td><td>Trigger: Any issues (damage, delay)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Example Triggers for Arrows<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Pending \u2192 Confirmed<\/strong>: &#8220;Partner Confirms Booking.&#8221;<\/li>\n\n\n\n<li><strong>Pending \u2192 Auto-Cancelled<\/strong>: &#8220;No confirmation within 1 hour.&#8221;<\/li>\n\n\n\n<li><strong>Confirmed \u2192 Paid<\/strong>: &#8220;Payment Completed.&#8221;<\/li>\n\n\n\n<li><strong>Confirmed \u2192 Auto-Cancelled<\/strong>: &#8220;No payment within 1 hour.&#8221;<\/li>\n\n\n\n<li><strong>In Progress \u2192 Issue Reported<\/strong>: &#8220;Issue Raised by Renter\/Partner.&#8221;<\/li>\n\n\n\n<li><strong>Issue Reported \u2192 Completed<\/strong>: &#8220;Issue Resolved.&#8221;<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Final Touches<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Include a <strong>Legend<\/strong> for color-coding (e.g., Completed = Green, Auto-Cancelled = Yellow).<\/li>\n\n\n\n<li>Add a <strong>Title<\/strong>: &#8220;Booking Workflow for MotoShare.in.&#8221;<\/li>\n\n\n\n<li>Annotate arrows for clarity.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>Let me know if you need more assistance or adjustments!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Certainly! Adding an automatic cancellation mechanism for scenarios where the Partner doesn\u2019t confirm a booking within a set time or<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1441","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.cmsgalaxy.com\/blog\/wp-json\/wp\/v2\/posts\/1441","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.cmsgalaxy.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.cmsgalaxy.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.cmsgalaxy.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cmsgalaxy.com\/blog\/wp-json\/wp\/v2\/comments?post=1441"}],"version-history":[{"count":8,"href":"https:\/\/www.cmsgalaxy.com\/blog\/wp-json\/wp\/v2\/posts\/1441\/revisions"}],"predecessor-version":[{"id":1453,"href":"https:\/\/www.cmsgalaxy.com\/blog\/wp-json\/wp\/v2\/posts\/1441\/revisions\/1453"}],"wp:attachment":[{"href":"https:\/\/www.cmsgalaxy.com\/blog\/wp-json\/wp\/v2\/media?parent=1441"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cmsgalaxy.com\/blog\/wp-json\/wp\/v2\/categories?post=1441"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cmsgalaxy.com\/blog\/wp-json\/wp\/v2\/tags?post=1441"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}