86 lines
2.2 KiB
PHP
86 lines
2.2 KiB
PHP
<?php
|
|
|
|
namespace App\Enums;
|
|
|
|
/**
|
|
* The billable tiers advertised on the pricing page. Prices are the annual
|
|
* amount in cents (EUR); certificateLimit() is null for unlimited plans.
|
|
*/
|
|
enum SubscriptionPlan: string
|
|
{
|
|
case Free = 'free';
|
|
case Starter = 'starter';
|
|
case Unlimited = 'unlimited';
|
|
|
|
/**
|
|
* The VAT rate baked into the advertised (incl. VAT) prices below.
|
|
*/
|
|
private const VAT_RATE = 0.21;
|
|
|
|
public function label(): string
|
|
{
|
|
return match ($this) {
|
|
self::Free => __('Gratis'),
|
|
self::Starter => 'Certified Starter',
|
|
self::Unlimited => 'Certified Pro',
|
|
};
|
|
}
|
|
|
|
public function certificateLimit(): ?int
|
|
{
|
|
return match ($this) {
|
|
self::Free => 5,
|
|
self::Starter => 15,
|
|
self::Unlimited => null,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* The net (excl. VAT) annual price — the amount invoiced via
|
|
* Moneybird, which adds VAT on top via the configured tax rate.
|
|
* Derived from priceInclVatCents() so the two can never drift apart.
|
|
*/
|
|
public function priceInCents(): int
|
|
{
|
|
return (int) round($this->priceInclVatCents() / (1 + self::VAT_RATE));
|
|
}
|
|
|
|
/**
|
|
* The advertised annual price, incl. 21% VAT — the headline figure
|
|
* shown on the pricing and billing pages.
|
|
*/
|
|
public function priceInclVatCents(): int
|
|
{
|
|
return match ($this) {
|
|
self::Free => 0,
|
|
self::Starter => 1900,
|
|
self::Unlimited => 4900,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* The line-item description used on Moneybird invoices.
|
|
*/
|
|
public function moneybirdDescription(): string
|
|
{
|
|
return match ($this) {
|
|
self::Free => 'Certified — Gratis',
|
|
self::Starter => 'Certified Starter — jaarabonnement (1 jaar)',
|
|
self::Unlimited => 'Certified Pro — jaarabonnement (1 jaar)',
|
|
};
|
|
}
|
|
|
|
public function isPaid(): bool
|
|
{
|
|
return $this !== self::Free;
|
|
}
|
|
|
|
/**
|
|
* Whether this plan includes document scanning (OCR). Free accounts
|
|
* enter certificate details manually; OCR is a paid-plan perk.
|
|
*/
|
|
public function includesOcr(): bool
|
|
{
|
|
return $this !== self::Free;
|
|
}
|
|
}
|