- Lịch sử thanh toán hoá đơn trả thêm `method` (tự động gia hạn / số dư / admin / chuyển khoản / hoàn tiền), bỏ đuôi `(method)` khỏi ghi chú - `DnsServer::panelUrl()` = https://<domain>/ dùng cho email cấp hosting và nút Plesk của khách - Order item trả thêm `uuid`/`type` của dịch vụ để FE dẫn tới trang quản lý - Yêu cầu huỷ dịch vụ, chứng chỉ SSL, lịch sử gia hạn, đổi mật khẩu hosting cho khách Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
59 lines
2.3 KiB
PHP
59 lines
2.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Support;
|
|
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
|
|
class ServiceGroup
|
|
{
|
|
public const SSL = 'ssl';
|
|
|
|
public const COLO = 'colo';
|
|
|
|
public const DEDICATED = 'dedicated';
|
|
|
|
public const EMAIL = 'email';
|
|
|
|
public const ALL = [self::SSL, self::COLO, self::DEDICATED, self::EMAIL];
|
|
|
|
private const UNTYPED_PRODUCT_TYPES = ['other', 'server_rental'];
|
|
|
|
public static function of(?string $productType, ?string $productName): ?string
|
|
{
|
|
$name = mb_strtolower(trim((string) $productName));
|
|
|
|
return match (true) {
|
|
$productType === 'email' => self::EMAIL,
|
|
$productType === 'ssl' => self::SSL,
|
|
! in_array($productType, self::UNTYPED_PRODUCT_TYPES, true) => null,
|
|
str_starts_with($name, 'ssl') => self::SSL,
|
|
str_contains($name, 'colo') || str_contains($name, 'chỗ đặt') => self::COLO,
|
|
$productType === 'server_rental' || str_contains($name, 'dedicated') => self::DEDICATED,
|
|
default => null,
|
|
};
|
|
}
|
|
|
|
public static function constrain(Builder $products, string $group): Builder
|
|
{
|
|
$untyped = fn (Builder $query) => $query->whereIn('product_type', self::UNTYPED_PRODUCT_TYPES);
|
|
$notSsl = fn (Builder $query) => $query->whereRaw("TRIM(name) NOT LIKE 'ssl%'");
|
|
$notColo = fn (Builder $query) => $query->where('name', 'not like', '%colo%')->where('name', 'not like', '%chỗ đặt%');
|
|
|
|
return match ($group) {
|
|
self::EMAIL => $products->where('product_type', 'email'),
|
|
self::SSL => $products->where(fn (Builder $query) => $query
|
|
->where('product_type', 'ssl')
|
|
->orWhere(fn (Builder $other) => $untyped($other)->whereRaw("TRIM(name) LIKE 'ssl%'"))),
|
|
self::COLO => $untyped($products)->tap($notSsl)->where(fn (Builder $query) => $query
|
|
->where('name', 'like', '%colo%')
|
|
->orWhere('name', 'like', '%chỗ đặt%')),
|
|
self::DEDICATED => $untyped($products)->tap($notSsl)->tap($notColo)->where(fn (Builder $query) => $query
|
|
->where('product_type', 'server_rental')
|
|
->orWhere('name', 'like', '%dedicated%')),
|
|
default => $products->whereRaw('1 = 0'),
|
|
};
|
|
}
|
|
}
|