feat: add Weeztix OAuth, coupon codes, and Mailwizz mapping
Implement Weeztix integration per documentation: database config and subscriber coupon_code, OAuth redirect/callback, admin setup UI with company/coupon selection via AJAX, synchronous coupon creation on public subscribe with duplicate and rate-limit handling, Mailwizz field mapping for coupon codes, subscriber table and CSV export, and connection hint on the pages list. Made-with: Cursor
This commit is contained in:
@@ -21,6 +21,7 @@ class MailwizzConfig extends Model
|
||||
'field_first_name',
|
||||
'field_last_name',
|
||||
'field_phone',
|
||||
'field_coupon_code',
|
||||
'tag_field',
|
||||
'tag_value',
|
||||
];
|
||||
|
||||
@@ -162,6 +162,11 @@ class PreregistrationPage extends Model
|
||||
return $this->hasOne(MailwizzConfig::class);
|
||||
}
|
||||
|
||||
public function weeztixConfig(): HasOne
|
||||
{
|
||||
return $this->hasOne(WeeztixConfig::class);
|
||||
}
|
||||
|
||||
public function isBeforeStart(): bool
|
||||
{
|
||||
return Carbon::now()->lt($this->start_date);
|
||||
|
||||
@@ -22,6 +22,7 @@ class Subscriber extends Model
|
||||
'phone',
|
||||
'synced_to_mailwizz',
|
||||
'synced_at',
|
||||
'coupon_code',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
@@ -95,7 +96,8 @@ class Subscriber extends Model
|
||||
$q->where('first_name', 'like', $like)
|
||||
->orWhere('last_name', 'like', $like)
|
||||
->orWhere('email', 'like', $like)
|
||||
->orWhere('phone', 'like', $like);
|
||||
->orWhere('phone', 'like', $like)
|
||||
->orWhere('coupon_code', 'like', $like);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
64
app/Models/WeeztixConfig.php
Normal file
64
app/Models/WeeztixConfig.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class WeeztixConfig extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'preregistration_page_id',
|
||||
'client_id',
|
||||
'client_secret',
|
||||
'redirect_uri',
|
||||
'access_token',
|
||||
'refresh_token',
|
||||
'token_expires_at',
|
||||
'refresh_token_expires_at',
|
||||
'company_guid',
|
||||
'company_name',
|
||||
'coupon_guid',
|
||||
'coupon_name',
|
||||
'code_prefix',
|
||||
'usage_count',
|
||||
'is_connected',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'client_id' => 'encrypted',
|
||||
'client_secret' => 'encrypted',
|
||||
'access_token' => 'encrypted',
|
||||
'refresh_token' => 'encrypted',
|
||||
'token_expires_at' => 'datetime',
|
||||
'refresh_token_expires_at' => 'datetime',
|
||||
'is_connected' => 'boolean',
|
||||
];
|
||||
}
|
||||
|
||||
public function preregistrationPage(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(PreregistrationPage::class);
|
||||
}
|
||||
|
||||
public function isTokenExpired(): bool
|
||||
{
|
||||
return ! $this->token_expires_at || $this->token_expires_at->isPast();
|
||||
}
|
||||
|
||||
public function isRefreshTokenExpired(): bool
|
||||
{
|
||||
if ($this->refresh_token_expires_at === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->refresh_token_expires_at->isPast();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user