Files
baodev0andClaude Sonnet 5.5 b44a88bb52 feat(service): huỷ dịch vụ, SSL, đổi mật khẩu hosting, lịch sử thanh toán theo hình thức
- 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>
2026-10-28 16:40:24 +07:00

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'),
};
}
}