*/ public array $backoff = [5, 15, 45]; /** * Seconds before the unique lock expires if the worker dies before releasing it. */ public int $uniqueFor = 300; public function __construct(public Subscriber $subscriber) { $this->onQueue('weeztix'); } public function uniqueId(): string { return 'weeztix-coupon-subscriber-'.$this->subscriber->getKey(); } public function handle(): void { try { $subscriber = Subscriber::query() ->with(['preregistrationPage.weeztixConfig', 'preregistrationPage.mailwizzConfig']) ->find($this->subscriber->id); if ($subscriber === null) { return; } $page = $subscriber->preregistrationPage; if ($page === null) { return; } $config = $page->weeztixConfig; $couponMissing = ! is_string($subscriber->coupon_code) || $subscriber->coupon_code === ''; if ($couponMissing && $this->weeztixCanIssueCodes($config)) { $this->tryAttachWeeztixCouponCode($subscriber, $config); } $this->dispatchMailwizzIfNeeded($subscriber); } catch (Throwable $e) { Log::error('IssueWeeztixCouponForSubscriber: handle failed', [ 'subscriber_id' => $this->subscriber->id, 'message' => $e->getMessage(), ]); $subscriber = Subscriber::query() ->with(['preregistrationPage.mailwizzConfig']) ->find($this->subscriber->id); if ($subscriber !== null) { $this->dispatchMailwizzIfNeeded($subscriber); } } } public function failed(?Throwable $exception): void { Log::error('IssueWeeztixCouponForSubscriber failed', [ 'subscriber_id' => $this->subscriber->id, 'message' => $exception?->getMessage(), ]); $subscriber = Subscriber::query() ->with('preregistrationPage.mailwizzConfig') ->find($this->subscriber->id); if ($subscriber !== null) { $this->dispatchMailwizzIfNeeded($subscriber); } } private function dispatchMailwizzIfNeeded(Subscriber $subscriber): void { $page = $subscriber->preregistrationPage; $page?->loadMissing('mailwizzConfig'); if ($page?->mailwizzConfig !== null) { try { SyncSubscriberToMailwizz::dispatch($subscriber->fresh()); } catch (Throwable $e) { Log::error('IssueWeeztixCouponForSubscriber: could not queue Mailwizz sync', [ 'subscriber_id' => $subscriber->id, 'message' => $e->getMessage(), ]); } } } private function weeztixCanIssueCodes(?WeeztixConfig $config): bool { if ($config === null || ! $config->is_connected) { return false; } $company = $config->company_guid; $coupon = $config->coupon_guid; return is_string($company) && $company !== '' && is_string($coupon) && $coupon !== ''; } private function tryAttachWeeztixCouponCode(Subscriber $subscriber, WeeztixConfig $config): void { $freshConfig = $config->fresh(); if ($freshConfig === null) { return; } $service = new WeeztixService($freshConfig); $maxAttempts = 5; for ($attempt = 0; $attempt < $maxAttempts; $attempt++) { try { $code = WeeztixService::generateUniqueCode( is_string($freshConfig->code_prefix) && $freshConfig->code_prefix !== '' ? $freshConfig->code_prefix : 'PREREG' ); $service->createCouponCode($code); $subscriber->update(['coupon_code' => $code]); return; } catch (WeeztixCouponCodeConflictException) { continue; } catch (Throwable $e) { Log::error('Weeztix coupon creation failed', [ 'subscriber_id' => $subscriber->id, 'message' => $e->getMessage(), ]); return; } } Log::warning('Weeztix coupon: exhausted duplicate retries', [ 'subscriber_id' => $subscriber->id, ]); } }