SystemNotificationRollBackJob.php 2.22 KB
<?php

namespace App\Jobs;

use App\Enums\NotificationStatusEnum;
use App\Models\Notification;
use App\Models\NotificationUser;
use Bus;
use Illuminate\Bus\Batch;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\Middleware\WithoutOverlapping;
use Illuminate\Queue\SerializesModels;


class SystemNotificationRollBackJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * @var \App\Models\Notification
     */
    public Notification $notification;

    public function middleware(): array
    {
        return [new WithoutOverlapping($this->notification->getKey())];
    }

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(Notification $notification)
    {
        $this->queue        = 'im_rollback';
        $this->notification = $notification;
    }

    /**
     * Execute the job.
     *
     * @return void
     * @throws \Exception
     * @throws \Throwable
     */
    public function handle(): void
    {
        $this->notification->update(['status' => NotificationStatusEnum::PROCESSING]);

        $batch = Bus::batch([]);

        NotificationUser::query()->where('notification_id', $this->notification->getKey())
            ->where('status', NotificationStatusEnum::SUCCESS)
            ->eachById(fn(NotificationUser $notificationUser) => $batch->add(new  SystemNotificationRollBackItemJob($notificationUser)));

        $batch->name('SystemNotificationBack-' . $this->notification->getKey())
            ->withOption('notification_id', $this->notification->getKey())
            ->finally(function (Batch $batch) {
                Notification::query()->whereKey($batch->options['notification_id'])->update([
                    'status' => NotificationUser::query()
                        ->where('notification_id', $batch->options['notification_id'])
                        ->where('status', NotificationStatusEnum::ROLLBACK)
                        ->exists() ? NotificationStatusEnum::ROLLBACK : NotificationStatusEnum::SUCCESS
                ]);
            })->allowFailures()->dispatch();

    }
}