feat: create PostCategoryFactory for generating post category data feat: create PostFactory for generating post data feat: add retry_requested_at column to services table feat: add vcenter provisioning fields to products table feat: add module_host_id to os table feat: create email_notification_templates table for email templates feat: add scenario and format fields to template table feat: add admin fields to transactions table fix: update ticket table columns and types feat: add uuid to ticket table and backfill existing records fix: make ticket_reply user_id nullable feat: create notifications table for user notifications fix: make ticket uuid nullable feat: create post_categories table for blog categories feat: create posts table for blog posts feat: add invoice email template for PDF generation
128 lines
5.6 KiB
PHP
128 lines
5.6 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api\Admin;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\EmailNotificationTemplate;
|
|
use App\Services\EmailNotificationTemplateRenderer;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
|
|
class EmailNotificationTemplateController extends Controller
|
|
{
|
|
public function __construct(
|
|
private readonly EmailNotificationTemplateRenderer $renderer,
|
|
) {}
|
|
|
|
public function index(): JsonResponse
|
|
{
|
|
$templates = EmailNotificationTemplate::orderByDesc('is_active')
|
|
->orderBy('name')
|
|
->get();
|
|
|
|
return response()->json(['error' => false, 'data' => $templates]);
|
|
}
|
|
|
|
public function show(int $id): JsonResponse
|
|
{
|
|
$tpl = EmailNotificationTemplate::findOrFail($id);
|
|
$tpl['block_field_definitions'] = EmailNotificationTemplate::blockFieldDefinitions();
|
|
return response()->json(['error' => false, 'data' => $tpl]);
|
|
}
|
|
|
|
public function store(Request $request): JsonResponse
|
|
{
|
|
$validated = $request->validate([
|
|
'name' => 'required|string|max:255',
|
|
'type' => 'required|string|in:invoice_notification,vm_credentials',
|
|
'subject' => 'required|string|max:500',
|
|
'header_color' => 'nullable|string|max:20',
|
|
'header_title' => 'nullable|string|max:255',
|
|
'blocks' => 'nullable|array',
|
|
'is_active' => 'boolean',
|
|
]);
|
|
|
|
// Use default blocks if none provided
|
|
if (empty($validated['blocks'])) {
|
|
$validated['blocks'] = EmailNotificationTemplate::defaultBlocks($validated['type']);
|
|
}
|
|
|
|
// If activating this template, deactivate others of the same type
|
|
if ($validated['is_active'] ?? true) {
|
|
EmailNotificationTemplate::where('type', $validated['type'])->update(['is_active' => false]);
|
|
}
|
|
|
|
$tpl = EmailNotificationTemplate::create($validated);
|
|
|
|
return response()->json(['error' => false, 'data' => $tpl], 201);
|
|
}
|
|
|
|
public function update(Request $request, int $id): JsonResponse
|
|
{
|
|
$tpl = EmailNotificationTemplate::findOrFail($id);
|
|
|
|
$validated = $request->validate([
|
|
'name' => 'sometimes|string|max:255',
|
|
'subject' => 'sometimes|string|max:500',
|
|
'header_color' => 'nullable|string|max:20',
|
|
'header_title' => 'nullable|string|max:255',
|
|
'blocks' => 'nullable|array',
|
|
'is_active' => 'boolean',
|
|
]);
|
|
|
|
// If activating this template, deactivate others of the same type
|
|
if (!empty($validated['is_active'])) {
|
|
EmailNotificationTemplate::where('type', $tpl->type)
|
|
->where('id', '!=', $id)
|
|
->update(['is_active' => false]);
|
|
}
|
|
|
|
$tpl->update($validated);
|
|
|
|
return response()->json(['error' => false, 'data' => $tpl->fresh()]);
|
|
}
|
|
|
|
public function destroy(int $id): JsonResponse
|
|
{
|
|
EmailNotificationTemplate::findOrFail($id)->delete();
|
|
return response()->json(['error' => false, 'message' => 'Đã xoá template.']);
|
|
}
|
|
|
|
public function preview(int $id): JsonResponse
|
|
{
|
|
$tpl = EmailNotificationTemplate::findOrFail($id);
|
|
$html = $this->renderer->renderPreview($tpl);
|
|
return response()->json(['error' => false, 'html' => $html]);
|
|
}
|
|
|
|
public function fieldDefinitions(): JsonResponse
|
|
{
|
|
return response()->json([
|
|
'error' => false,
|
|
'data' => [
|
|
'block_types' => $this->blockTypeDefinitions(),
|
|
'block_field_definitions' => EmailNotificationTemplate::blockFieldDefinitions(),
|
|
'default_blocks' => EmailNotificationTemplate::defaultBlocks(),
|
|
],
|
|
]);
|
|
}
|
|
|
|
private function blockTypeDefinitions(): array
|
|
{
|
|
return [
|
|
// Dùng cho cả 2 loại
|
|
['type' => 'greeting', 'label' => 'Lời chào', 'description' => 'Chào hỏi khách hàng theo tên', 'for' => ['invoice_notification', 'vm_credentials']],
|
|
['type' => 'custom_text', 'label' => 'Văn bản tùy chỉnh', 'description' => 'Nội dung HTML hoặc text tự do', 'for' => ['invoice_notification', 'vm_credentials']],
|
|
['type' => 'footer', 'label' => 'Chữ ký kết thúc', 'description' => 'Trân trọng + tên công ty', 'for' => ['invoice_notification', 'vm_credentials']],
|
|
// invoice_notification
|
|
['type' => 'invoice_info', 'label' => 'Thông tin hóa đơn', 'description' => 'Số HĐ, ngày tạo, tổng tiền, trạng thái...', 'for' => ['invoice_notification']],
|
|
['type' => 'customer_info', 'label' => 'Thông tin khách hàng', 'description' => 'Tên, email, địa chỉ khách hàng', 'for' => ['invoice_notification']],
|
|
['type' => 'order_items', 'label' => 'Chi tiết sản phẩm', 'description' => 'Bảng sản phẩm từ đơn hàng', 'for' => ['invoice_notification']],
|
|
['type' => 'attachments', 'label' => 'File đính kèm', 'description' => 'Danh sách file đính kèm hóa đơn', 'for' => ['invoice_notification']],
|
|
// vm_credentials
|
|
['type' => 'vm_credentials', 'label' => 'Thông tin truy cập VPS', 'description' => 'IP, username, port, password, OS', 'for' => ['vm_credentials']],
|
|
['type' => 'product_info', 'label' => 'Thông tin dịch vụ', 'description' => 'Tên sản phẩm, chu kỳ, giá, hạn dùng', 'for' => ['vm_credentials']],
|
|
];
|
|
}
|
|
}
|