feat(admin): improve payments and server settings

This commit is contained in:
baodev0
2026-10-19 07:59:23 +07:00
parent 9ed77a85fd
commit ea9a53f742
32 changed files with 680 additions and 78 deletions
+18 -38
View File
@@ -2,19 +2,18 @@
namespace App\Services\Api\Order;
use App\Enums\Invoice\InvoiceStatus;
use App\Enums\Order\OrderStatus;
use App\Helpers\OrderHelper;
use App\Jobs\Mail\Admin\AdminOrderNotificationJob;
use App\Models\Order;
use App\Models\Product;
use App\Repositories\Api\Invoice\InvoiceRepositoryInterface;
use App\Repositories\Api\Order\OrderRepositoryInterface;
use App\Repositories\Api\Service\ServiceRepository;
use App\Services\InvoicePaymentService;
use App\Services\AdminPaymentNotifier;
use App\Support\AddonQuantityValidator;
use Exception;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class OrderService
{
@@ -23,6 +22,7 @@ class OrderService
protected ServiceRepository $productRepo,
protected InvoiceRepositoryInterface $invoiceRepo,
protected InvoicePaymentService $invoicePaymentService,
protected AdminPaymentNotifier $adminPaymentNotifier,
) {}
// =========================================================================
@@ -110,7 +110,7 @@ class OrderService
throw new \InvalidArgumentException('Đơn hàng đã được thanh toán hoặc đang xử lý.');
}
return DB::transaction(function () use ($order, $method) {
$processedOrder = DB::transaction(function () use ($order, $method) {
$customer = $order->customer;
if ($customer->total < $order->total) {
@@ -121,22 +121,28 @@ class OrderService
));
}
// Allow re-paying a cancelled order
$invoice = $order->invoice;
if (! $invoice) {
throw new \InvalidArgumentException('Không tìm thấy hóa đơn của đơn hàng.');
}
if ((int) $invoice->status === InvoiceStatus::PAID->value) {
throw new \InvalidArgumentException('Đơn hàng đã được thanh toán hoặc đang xử lý.');
}
if ($order->status === OrderStatus::CANCELLED->value) {
$order->update(['status' => OrderStatus::PENDING->value]);
}
if (! $order->invoice) {
throw new \InvalidArgumentException('Không tìm thấy hóa đơn của đơn hàng.');
}
$this->invoicePaymentService->payWithBalance($order->invoice, $customer, $method);
$paidInvoice = $this->invoicePaymentService->payWithBalance($invoice, $customer, $method);
$processedOrder = $order->fresh(['orderItems', 'invoice', 'customer']);
$this->dispatchAdminNotification($processedOrder, $customer);
return $processedOrder;
});
$this->adminPaymentNotifier->notify($processedOrder->invoice, (int) $processedOrder->total, 'order');
return $processedOrder;
}
@@ -145,32 +151,6 @@ class OrderService
// =========================================================================
private function dispatchAdminNotification(Order $order, $customer): void
{
try {
$item = $order->orderItems->first();
$product = $item?->product;
$productType = $product?->category?->name ?? $product?->type ?? 'N/A';
AdminOrderNotificationJob::dispatch([
'order_num' => $order->order_num,
'customer_name' => (string) $customer->fullname,
'customer_email' => $customer->email,
'client_ip' => $order->client_ip ?? request()?->ip(),
'product_name' => $product?->name ?? 'N/A',
'product_type' => $productType,
'billing_cycle' => $item?->billing_cycle ?? 'N/A',
'total' => $order->total,
'created_at' => now()->format('d/m/Y H:i:s'),
]);
} catch (Exception $e) {
Log::error('OrderService: failed to dispatch admin notification', [
'order_id' => $order->id,
'error' => $e->getMessage(),
]);
}
}
/**
* Enrich raw addon entries with resolved price & subtotal.
*