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>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
a6b641015e
commit
b44a88bb52
@@ -7,6 +7,7 @@ use App\Enums\Order\OrderStatus;
|
||||
use App\Models\InvoiceAttachment;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class InvoiceDetailResource extends JsonResource
|
||||
{
|
||||
@@ -33,6 +34,9 @@ class InvoiceDetailResource extends JsonResource
|
||||
'auto_renew' => (bool) $this->auto_renew,
|
||||
'created_at' => $this->created_at?->toISOString(),
|
||||
'due_date' => $this->due_date?->toISOString(),
|
||||
'billing_period_start' => $this->billing_period_start ? Carbon::parse($this->billing_period_start)->toDateString() : null,
|
||||
'billing_period_end' => $this->billing_period_end ? Carbon::parse($this->billing_period_end)->toDateString() : null,
|
||||
'next_renewal_date' => $this->whenLoaded('order', fn () => $this->nextRenewalDate()),
|
||||
'paid_at' => $this->paid_at?->toISOString(),
|
||||
'customer' => $this->whenLoaded('customer', fn () => [
|
||||
'name' => $this->customer->fullname,
|
||||
@@ -46,7 +50,7 @@ class InvoiceDetailResource extends JsonResource
|
||||
'total' => (float) $this->order->total,
|
||||
'created_at' => $this->order->created_at?->toISOString(),
|
||||
]),
|
||||
'items' => $this->whenLoaded('order', fn () => $this->order->orderItems->map(fn ($item) => [
|
||||
'items' => $this->whenLoaded('order', fn () => $this->isRenewal() ? $this->renewalItems() : $this->order->orderItems->map(fn ($item) => [
|
||||
'product_name' => $item->product?->name,
|
||||
'server_name' => $item->server_name,
|
||||
'billing_cycle' => $item->billing_cycle,
|
||||
@@ -70,19 +74,59 @@ class InvoiceDetailResource extends JsonResource
|
||||
];
|
||||
}
|
||||
|
||||
private function resolveService(): ?array
|
||||
private function isRenewal(): bool
|
||||
{
|
||||
return (int) $this->invoice_type === 2;
|
||||
}
|
||||
|
||||
private function resolveOrderItem(): mixed
|
||||
{
|
||||
$items = $this->order->orderItems;
|
||||
$item = $this->service_id
|
||||
? $items->first(fn ($i) => (int) $i->service?->id === (int) $this->service_id)
|
||||
: null;
|
||||
$item ??= $items->first();
|
||||
|
||||
return $item ?? $items->first();
|
||||
}
|
||||
|
||||
private function renewalMonths(): ?int
|
||||
{
|
||||
return $this->invoiceItems->firstWhere('type', 'renewal')?->months;
|
||||
}
|
||||
|
||||
private function renewalItems(): array
|
||||
{
|
||||
$serverName = $this->resolveOrderItem()?->server_name;
|
||||
|
||||
return $this->invoiceItems->map(fn ($item) => [
|
||||
'product_name' => $item->description,
|
||||
'server_name' => $serverName,
|
||||
'billing_cycle' => $item->months ? 'monthly' : null,
|
||||
'price' => (float) $item->total_price,
|
||||
'months' => $item->months,
|
||||
'os_id' => null,
|
||||
])->values()->all();
|
||||
}
|
||||
|
||||
private function nextRenewalDate(): ?string
|
||||
{
|
||||
if ($this->isRenewal() && $this->billing_period_end) {
|
||||
return Carbon::parse($this->billing_period_end)->toDateString();
|
||||
}
|
||||
|
||||
return $this->resolveOrderItem()?->service?->expires_at?->toDateString();
|
||||
}
|
||||
|
||||
private function resolveService(): ?array
|
||||
{
|
||||
$item = $this->resolveOrderItem();
|
||||
$renewalMonths = $this->isRenewal() ? $this->renewalMonths() : null;
|
||||
|
||||
return $item ? [
|
||||
'product_id' => $item->product_id,
|
||||
'name' => $item->product?->name,
|
||||
'billing_cycle' => $item->billing_cycle,
|
||||
'months' => $item->months,
|
||||
'billing_cycle' => $renewalMonths ? 'monthly' : $item->billing_cycle,
|
||||
'months' => $renewalMonths ?: $item->months,
|
||||
'server_name' => $item->server_name,
|
||||
'product_type' => $item->product?->product_type,
|
||||
] : null;
|
||||
|
||||
Reference in New Issue
Block a user