Repo rebuild

This commit is contained in:
Mark Gregory
2026-09-15 12:33:28 +01:00
commit be28c4feec
5629 changed files with 317074 additions and 0 deletions
@@ -0,0 +1,48 @@
<?php
namespace Modules\Platform\app\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Str;
use Modules\Company\Models\Company;
class LicenseKey extends Model
{
protected $fillable = [
'company_id', 'key_hash', 'key_prefix', 'label', 'plan', 'max_users',
'is_active', 'starts_at', 'expires_at', 'last_used_at', 'revoked_at',
];
protected $casts = [
'is_active' => 'boolean',
'starts_at' => 'datetime',
'expires_at' => 'datetime',
'last_used_at' => 'datetime',
'revoked_at' => 'datetime',
];
public function company(): BelongsTo
{
return $this->belongsTo(Company::class);
}
public static function issueFor(Company $company, string $label, string $plan = 'standard', int $maxUsers = 10): string
{
$plainKey = 'WMS-' . Str::upper(Str::random(32));
self::create([
'company_id' => $company->id,
'key_hash' => hash('sha256', $plainKey),
'key_prefix' => Str::substr($plainKey, 0, 12),
'label' => $label,
'plan' => $plan,
'max_users' => $maxUsers,
'is_active' => true,
'starts_at' => now(),
'expires_at' => now()->addYear(),
]);
return $plainKey;
}
}
+26
View File
@@ -0,0 +1,26 @@
<?php
namespace Modules\Platform\app\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Modules\Company\Models\Company;
class Payment extends Model
{
protected $fillable = [
'company_id', 'stripe_payment_intent_id', 'stripe_invoice_id', 'amount',
'currency', 'status', 'description', 'paid_at', 'metadata',
];
protected $casts = [
'amount' => 'integer',
'paid_at' => 'datetime',
'metadata' => 'array',
];
public function company(): BelongsTo
{
return $this->belongsTo(Company::class);
}
}
@@ -0,0 +1,80 @@
<?php
namespace Modules\Platform\app\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
class PlatformPrice extends Model
{
protected $fillable = [
'code',
'name',
'strapline',
'description',
'monthly_amount',
'annual_amount',
'currency',
'badge_label',
'features',
'sort_order',
'is_featured',
'is_active',
];
protected $casts = [
'features' => 'array',
'monthly_amount' => 'integer',
'annual_amount' => 'integer',
'sort_order' => 'integer',
'is_featured' => 'boolean',
'is_active' => 'boolean',
];
/**
* Scope prices into display order.
*/
public function scopeOrdered(Builder $query): Builder
{
return $query->orderBy('sort_order')->orderBy('name');
}
/**
* Return the display currency symbol.
*/
public function currencySymbol(): string
{
return match (strtolower($this->currency)) {
'gbp' => '£',
'eur' => '€',
'usd' => '$',
default => strtoupper($this->currency) . ' ',
};
}
/**
* Format a stored minor-unit amount for display.
*/
public function formatAmount(?int $amount): string
{
if ($amount === null) {
return '—';
}
return $this->currencySymbol() . number_format($amount / 100, 2);
}
/**
* Return normalised feature rows.
*
* @return array<int, string>
*/
public function featureRows(): array
{
return collect($this->features ?? [])
->filter(fn ($feature): bool => is_string($feature) && trim($feature) !== '')
->map(fn (string $feature): string => trim($feature))
->values()
->all();
}
}