110 lines
4.2 KiB
PHP
110 lines
4.2 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Resources\Api\Service;
|
|
|
|
use App\Support\BillingCycleCatalog;
|
|
use App\Support\ProductBillingCycles;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Http\Resources\Json\JsonResource;
|
|
|
|
class ServiceResource extends JsonResource
|
|
{
|
|
/**
|
|
* Transform the resource into an array.
|
|
*
|
|
* @return array<string, mixed>
|
|
*/
|
|
public function toArray(Request $request): array
|
|
{
|
|
$billingCycleLabels = [
|
|
'monthly' => 'Hàng tháng',
|
|
'quarterly' => 'Hàng quý',
|
|
'semi_annually' => 'Nửa năm',
|
|
'annually' => 'Hàng năm',
|
|
'biennially' => '2 năm',
|
|
'triennially' => '3 năm',
|
|
'onetime' => 'Một lần',
|
|
];
|
|
|
|
$periodUnits = [
|
|
'monthly' => 'month',
|
|
'quarterly' => 'quarter',
|
|
'semi_annually' => 'semi_year',
|
|
'annually' => 'year',
|
|
'biennially' => 'biennially',
|
|
'triennially' => 'triennially',
|
|
'onetime' => 'none',
|
|
];
|
|
|
|
$periodMonths = [
|
|
'monthly' => 1,
|
|
'quarterly' => 3,
|
|
'semi_annually' => 6,
|
|
'annually' => 12,
|
|
'biennially' => 24,
|
|
'triennially' => 36,
|
|
'onetime' => 0,
|
|
];
|
|
|
|
return [
|
|
'uuid' => $this->uuid,
|
|
'name' => $this->name,
|
|
'slug' => $this->slug,
|
|
'short_description' => $this->short_description,
|
|
'description' => $this->description,
|
|
'thumbnail' => $this->thumbnail ? asset($this->thumbnail) : null,
|
|
'product_type' => $this->product_type,
|
|
'page_type' => $this->resolvePageType($this->product_type),
|
|
'specs' => [
|
|
'cpu' => (int) $this->cpu,
|
|
'ram' => (int) $this->ram,
|
|
'disk' => (int) $this->disk,
|
|
'bandwidth' => (int) $this->bandwidth,
|
|
'gpu' => $this->gpu
|
|
],
|
|
'stock' => $this->stock,
|
|
'price' => (int) $this->price,
|
|
'price_sale' => $this->price_sale ? (int) $this->price_sale : null,
|
|
'group' => $this->category->name ?? null,
|
|
'os' => $this->osVersions->groupBy('os_group_id')->map(function ($versions) {
|
|
$group = $versions->first()->osGroup;
|
|
return [
|
|
'name' => $group?->name,
|
|
'thumbnail' => $group?->thumbnail,
|
|
'versions' => $versions->map(fn($os) => [
|
|
'id' => $os->id,
|
|
'version' => $os->version,
|
|
'name' => $os->name,
|
|
])->values(),
|
|
];
|
|
})->values(),
|
|
'pricing' => $this->pricings
|
|
->filter(fn($p) => ProductBillingCycles::allows($this->product_type, $p->billing_cycle))
|
|
->sortBy(fn($p) => $periodMonths[$p->billing_cycle] ?? BillingCycleCatalog::monthsFor($p->billing_cycle) ?? 999)
|
|
->values()
|
|
->map(fn($p) => [
|
|
'id' => $p->id,
|
|
'name' => $billingCycleLabels[$p->billing_cycle] ?? BillingCycleCatalog::labelForCode($p->billing_cycle) ?? $p->billing_cycle,
|
|
'price' => (int) $p->price,
|
|
'price_sale' => $p->price_sale ? (int) $p->price_sale : null,
|
|
'period' => $periodMonths[$p->billing_cycle] ?? BillingCycleCatalog::monthsFor($p->billing_cycle) ?? 1,
|
|
'period_unit' => $periodUnits[$p->billing_cycle] ?? (BillingCycleCatalog::monthsFor($p->billing_cycle) ? $p->billing_cycle : 'month'),
|
|
]),
|
|
$this->mergeWhen($this->product_type === 'hosting', fn () => [
|
|
'service_plan' => $this->servicePlan?->summary(),
|
|
]),
|
|
];
|
|
}
|
|
|
|
private function resolvePageType(?string $productType): string
|
|
{
|
|
return match ($productType) {
|
|
'vps', 'cloud' => 'service_vps',
|
|
'hosting', 'email', 'ssl' => 'service_hosting',
|
|
'domain' => 'service_domain',
|
|
'blog' => 'blog',
|
|
default => 'service_vps',
|
|
};
|
|
}
|
|
}
|