96 lines
3.7 KiB
PHP
96 lines
3.7 KiB
PHP
<?php
|
|
|
|
namespace App\Repositories\Api\Invoice;
|
|
|
|
use App\Enums\Invoice\InvoiceStatus;
|
|
use App\Helpers\OrderHelper;
|
|
use App\Models\Invoice;
|
|
use App\Models\InvoiceItem;
|
|
use App\Models\Order;
|
|
use App\Repositories\Api\BaseApiRepository;
|
|
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
|
|
|
class InvoiceRepository extends BaseApiRepository implements InvoiceRepositoryInterface
|
|
{
|
|
public function getModel(): string
|
|
{
|
|
return Invoice::class;
|
|
}
|
|
|
|
// -------------------------------------------------------------------------
|
|
// getInvoice
|
|
// -------------------------------------------------------------------------
|
|
|
|
public function getInvoice(int $limit = 10, int $customerId = 0): LengthAwarePaginator
|
|
{
|
|
return $this->model
|
|
->where('customer_id', $customerId)
|
|
->orderByDesc('created_at')
|
|
->paginate($limit);
|
|
}
|
|
|
|
// -------------------------------------------------------------------------
|
|
// createFromOrder
|
|
// -------------------------------------------------------------------------
|
|
|
|
public function createFromOrder(Order $order): Invoice
|
|
{
|
|
$maxMonths = $order->orderItems->max(fn($item) => OrderHelper::cycleToMonths($item->billing_cycle)) ?? 1;
|
|
|
|
$invoice = $this->model->create([
|
|
'invoice_number' => OrderHelper::generateOrderNumber('INV'),
|
|
'customer_id' => $order->customer_id,
|
|
'order_id' => $order->id,
|
|
'invoice_type' => 1, // new service
|
|
'sub_total' => $order->total,
|
|
'discount_amount' => $order->discount_amount ?? 0,
|
|
'tax' => 0,
|
|
'total' => $order->total,
|
|
'status' => InvoiceStatus::UNPAID->value,
|
|
'due_date' => now()->addMonths($maxMonths)->toDateString(),
|
|
]);
|
|
|
|
// Create one invoice_item per order_item line + addon sub-lines
|
|
foreach ($order->orderItems as $item) {
|
|
InvoiceItem::create([
|
|
'invoice_id' => $invoice->id,
|
|
'product_id' => $item->product_id,
|
|
'type' => 'service',
|
|
'description' => $item->product?->name ?? 'Dịch vụ',
|
|
'months' => OrderHelper::cycleToMonths($item->billing_cycle),
|
|
'quantity' => $item->quantity ?? 1,
|
|
'unit_price' => $item->price,
|
|
'total_price' => $item->price * ($item->quantity ?? 1),
|
|
]);
|
|
|
|
$addonsMeta = is_array($item->addons_meta) ? $item->addons_meta : [];
|
|
foreach ($addonsMeta as $meta) {
|
|
$qty = (int) ($meta['qty'] ?? 1);
|
|
$price = (int) ($meta['price'] ?? 0);
|
|
$subtotal = (int) ($meta['subtotal'] ?? $price * $qty);
|
|
$name = $meta['name'] ?? ('Addon #' . ($meta['addon_id'] ?? '?'));
|
|
$code = strtoupper($meta['code'] ?? '');
|
|
$label = $code ? "[{$code}] {$name}" : $name;
|
|
|
|
InvoiceItem::create([
|
|
'invoice_id' => $invoice->id,
|
|
'product_id' => $item->product_id,
|
|
'type' => 'addon',
|
|
'description' => $label,
|
|
'months' => OrderHelper::cycleToMonths($item->billing_cycle),
|
|
'quantity' => $qty,
|
|
'unit_price' => $price,
|
|
'total_price' => $subtotal,
|
|
]);
|
|
}
|
|
}
|
|
|
|
return $invoice;
|
|
}
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Helpers
|
|
// -------------------------------------------------------------------------
|
|
|
|
}
|