From c470240dc0b9342d5651f09759fe1ee013f21521 Mon Sep 17 00:00:00 2001 From: Daniel Stock Date: Thu, 5 Mar 2026 10:42:40 +0100 Subject: [PATCH] Fix: Job to check invoice due dates was never run Made it a command so it runs with the scheduler --- app/Console/Commands/CaldavSyncCommand.php | 7 +-- .../Commands/CheckInvoiceDueDatesCommand.php | 54 +++++++++++++++++++ app/Console/Kernel.php | 11 +++- app/Jobs/CheckInvoiceDueDatesJob.php | 41 -------------- app/Providers/EventServiceProvider.php | 11 ---- app/Services/CaldavService.php | 8 +-- bootstrap/app.php | 12 ++++- routes/api.php | 1 - 8 files changed, 82 insertions(+), 63 deletions(-) create mode 100644 app/Console/Commands/CheckInvoiceDueDatesCommand.php delete mode 100644 app/Jobs/CheckInvoiceDueDatesJob.php diff --git a/app/Console/Commands/CaldavSyncCommand.php b/app/Console/Commands/CaldavSyncCommand.php index 170938a..8a66849 100644 --- a/app/Console/Commands/CaldavSyncCommand.php +++ b/app/Console/Commands/CaldavSyncCommand.php @@ -14,7 +14,7 @@ class CaldavSyncCommand extends Command protected $signature = 'caldav:sync'; protected $description = 'Sync CalDAV VTODOs into local todos table'; - public function handle(CaldavService $service) + public function handle(CaldavService $service) { // only run every 5 minutes although the task is called every minute $cacheKey = 'caldav_sync_last_run'; @@ -24,8 +24,8 @@ public function handle(CaldavService $service) } Cache::put($cacheKey, true, 300); - Log::info('Running CalDAV sync'); - $this->info('Starting CalDAV sync'); + Log::info('Synchronizing Todo itmes with CalDAV server'); + $this->info('Synchronizing Todo itmes with CalDAV server'); $todos = $service->getTodos(); @@ -106,6 +106,7 @@ public function handle(CaldavService $service) Log::info("Synced " . count($todos) . " todos."); $this->info("Synced " . count($todos) . " todos."); + return 0; } } diff --git a/app/Console/Commands/CheckInvoiceDueDatesCommand.php b/app/Console/Commands/CheckInvoiceDueDatesCommand.php new file mode 100644 index 0000000..2ce0b5d --- /dev/null +++ b/app/Console/Commands/CheckInvoiceDueDatesCommand.php @@ -0,0 +1,54 @@ +info('Check invoice due dates'); + Log::info('Check invoice due dates'); + + try { + $today = Carbon::today(); + + // Find invoices with payment_status 'issued' and due_date <= today + $invoices = Invoice::where('payment_status', 'issued') + ->whereDate('due_date', '<=', $today) + ->get(); + + foreach ($invoices as $invoice) { + $invoice->update(['payment_status' => 'due']); + $this->info("Updated invoice {$invoice->nr} to 'due' status"); + } + + $this->info("Checked {$invoices->count()} invoices for due dates."); + } catch (\Exception $e) { + $this->error("Error in CheckInvoiceDueDatesJob: " . $e->getMessage()); + } + + return 0; + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 8b6c638..1c0a981 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -14,6 +14,7 @@ class Kernel extends ConsoleKernel */ protected $commands = [ \App\Console\Commands\CaldavSyncCommand::class, + \App\Console\Commands\CheckInvoiceDueDatesCommand::class, ]; /** @@ -21,6 +22,14 @@ class Kernel extends ConsoleKernel */ protected function schedule(Schedule $schedule): void { + $schedule->command('caldav:sync') + ->everyMinute() + ->withoutOverlapping(); + + // Run synchronously on schedule to support environments without queue workers + $schedule->command('invoices:check-due') + ->dailyAt('3:00') + ->withoutOverlapping(); } /** @@ -32,4 +41,4 @@ protected function commands(): void require base_path('routes/console.php'); } -} \ No newline at end of file +} diff --git a/app/Jobs/CheckInvoiceDueDatesJob.php b/app/Jobs/CheckInvoiceDueDatesJob.php deleted file mode 100644 index e21afa6..0000000 --- a/app/Jobs/CheckInvoiceDueDatesJob.php +++ /dev/null @@ -1,41 +0,0 @@ -whereDate('due_date', '<=', $today) - ->get(); - - foreach ($invoices as $invoice) { - $invoice->update(['payment_status' => 'due']); - Log::info("Updated invoice {$invoice->nr} to 'due' status"); - } - - Log::info("Checked {$invoices->count()} invoices for due dates."); - } catch (\Exception $e) { - Log::error("Error in CheckInvoiceDueDatesJob: " . $e->getMessage()); - } - } -} \ No newline at end of file diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 8246185..480e710 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -16,16 +16,5 @@ class EventServiceProvider extends ServiceProvider public function boot(): void { parent::boot(); - - // // TODO: read where to put these or ask in the forums - // // it seems to work here, but where is the apropriate place? - // // Kernel::schedule did not work - Schedule::command('caldav:sync') - ->everyMinute() - ->withoutOverlapping(); - - Schedule::job(new CheckInvoiceDueDatesJob()) - ->daily() - ->withoutOverlapping(); } } diff --git a/app/Services/CaldavService.php b/app/Services/CaldavService.php index 7d97784..ad72d2c 100644 --- a/app/Services/CaldavService.php +++ b/app/Services/CaldavService.php @@ -159,10 +159,10 @@ public function getTodos() $todo->type_id = 2; $todo->url = $href; if (isset($vcalendar->VTODO->DUE)) $todo->due_date = $vcalendar->VTODO->DUE->getDateTime(); - if(isset($vcalendar->VTODO->RRULE)) $todo->recurring = $vcalendar->VTODO->RRULE->getValue(); - if(isset($vcalendar->VTODO->PRIORITY)) $todo->priority = $vcalendar->VTODO->PRIORITY->getValue(); - if(isset($vcalendar->VTODO->STATUS)) $todo->status = $vcalendar->VTODO->STATUS->getValue(); - if(isset($vcalendar->VTODO->{'RELATED-TO'})) $todo->parent = $vcalendar->VTODO->{'RELATED-TO'}->getValue(); + if (isset($vcalendar->VTODO->RRULE)) $todo->recurring = $vcalendar->VTODO->RRULE->getValue(); + if (isset($vcalendar->VTODO->PRIORITY)) $todo->priority = $vcalendar->VTODO->PRIORITY->getValue(); + if (isset($vcalendar->VTODO->STATUS)) $todo->status = $vcalendar->VTODO->STATUS->getValue(); + if (isset($vcalendar->VTODO->{'RELATED-TO'})) $todo->parent = $vcalendar->VTODO->{'RELATED-TO'}->getValue(); $todo->created_at = $vcalendar->VTODO->CREATED->getDateTime(); $todo->last_modified = $vcalendar->VTODO->{'LAST-MODIFIED'}->getDateTime(); diff --git a/bootstrap/app.php b/bootstrap/app.php index 39e6533..de2accf 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -7,7 +7,7 @@ use Illuminate\Foundation\Configuration\Middleware; use Illuminate\Http\Middleware\AddLinkHeadersForPreloadedAssets; -return Application::configure(basePath: dirname(__DIR__)) +$app = Application::configure(basePath: dirname(__DIR__)) ->withRouting( web: __DIR__ . '/../routes/web.php', commands: __DIR__ . '/../routes/console.php', @@ -26,4 +26,12 @@ }) ->withExceptions(function (Exceptions $exceptions) { // - })->create(); + })->withKernels()->create(); + +$app->singleton( + \Illuminate\Contracts\Console\Kernel::class, + \App\Console\Kernel::class +); + +return $app; + diff --git a/routes/api.php b/routes/api.php index 0686815..1527cf8 100644 --- a/routes/api.php +++ b/routes/api.php @@ -11,7 +11,6 @@ use App\Http\Controllers\TodoController; use App\Http\Controllers\UnitController; use App\Mail\OrderConfirmation; -use App\Services\CaldavService; use App\Http\Controllers\TimesheetController; use App\Http\Controllers\TimesheetEntryController; use App\Http\Controllers\PipelineController;