feat: standardize invoice number field, refine invoice creation logic, and update module foreign key constraints

This commit is contained in:
pbao9
2026-03-12 10:10:20 +07:00
parent 1e09ccf17b
commit 1934be9a19
10 changed files with 24 additions and 30 deletions
+1 -1
View File
@@ -23,7 +23,7 @@ class OrderHelper
$number = $prefix . '-' . strtoupper(Str::random(8));
$exists = match ($prefix) {
'INV' => Invoice::where('invoice_num', $number)->exists(),
'INV' => Invoice::where('invoice_number', $number)->exists(),
default => Order::where('order_num', $number)->exists(),
};
} while ($exists);
@@ -58,14 +58,14 @@ class InvoiceController extends Controller
);
return DataTables::eloquent($query)
->addColumn('invoice_num', fn($d) => $d->invoice_num)
->addColumn('invoice_number', fn($d) => $d->invoice_number)
->addColumn('date', fn($d) => $d->date)
->addColumn('customer', fn($d) => $d->customer?->fullname)
->addColumn('payment', fn($d) => $d->payment?->name)
->addColumn('total', fn($d) => $d->total)
->addColumn('status', fn($d) => $d->status)
->addColumn('action', fn($d) => $d->id)
->rawColumns(['invoice_num', 'date', 'customer', 'payment', 'total', 'status', 'action'])
->rawColumns(['invoice_number', 'date', 'customer', 'payment', 'total', 'status', 'action'])
->make(true);
}
@@ -466,7 +466,7 @@ class OrderController extends Controller
return [
'id' => $invoice->id,
'invoice_number' => $invoice->invoice_number,
'invoice_number' => $invoice->invoice_number,
'invoice_type' => $invoice->invoice_type,
'status' => $invoice->status,
'status_text' => InvoiceStatus::tryFrom((int) $invoice->status)?->label() ?? '-',
@@ -151,8 +151,8 @@ class InvoiceController extends Controller
);
return DataTables::eloquent($query)
->addColumn('invoice_num', function ($d) {
return view('administrator.pages.invoice.datatable.invoice_num', ['row' => $d])->render();
->addColumn('invoice_number', function ($d) {
return view('administrator.pages.invoice.datatable.invoice_number', ['row' => $d])->render();
})
->addColumn('date', function ($d) {
return view('administrator.pages.invoice.datatable.date', ['row' => $d])->render();
@@ -172,7 +172,7 @@ class InvoiceController extends Controller
->addColumn('action', function ($d) {
return view('administrator.pages.invoice.datatable.action', ['row' => $d])->render();
})
->rawColumns(['invoice_num', 'date', 'customer', 'payment', 'total', 'status', 'action'])
->rawColumns(['invoice_number', 'date', 'customer', 'payment', 'total', 'status', 'action'])
->make(true);
}
}
-11
View File
@@ -29,17 +29,6 @@ class Os extends Model
default => '<span class="badge bg-danger">De-Active</span>'
};
}
/**
* Many-to-many relationship với VPS products.
*/
public function vpsProducts()
{
return $this->belongsToMany(\App\Models\VPS::class, 'product_os', 'os_id', 'product_id')
->withTimestamps()
->withPivot('product_type');
}
/**
* Many-to-many relationship với Products (new table: os_product)
*/
+1 -1
View File
@@ -80,7 +80,7 @@ class Product extends Model
*/
public function operatingSystems()
{
return $this->belongsToMany(Os::class, 'product_os', 'product_id', 'os_id')
return $this->belongsToMany(Os::class, 'os_product', 'product_id', 'os_id')
->withTimestamps();
}
@@ -36,7 +36,7 @@ class InvoiceRepository extends BaseApiRepository implements InvoiceRepositoryIn
public function createFromOrder(Order $order): Invoice
{
$invoice = $this->model->create([
'invoice_number' => OrderHelper::generateOrderNumber('INV'),
'invoice_number' => OrderHelper::generateOrderNumber('INV'),
'customer_id' => $order->customer_id,
'order_id' => $order->id,
'invoice_type' => 1, // new service
+12 -7
View File
@@ -42,14 +42,14 @@ class OrderService
[$productItems, $relIdData, $total] = $this->buildProductItems($data);
$invoiceData = [
'date' => Carbon::today()->toDateString(),
'invoice_number' => Helper::generateUniqueCode(),
'due_date' => Carbon::today()->toDateString(),
'date_paid' => (int) $data['status'] === 1 ? Carbon::today()->toDateString() : null,
'paid_at' => (int) $data['status'] === 1 ? Carbon::today()->toDateString() : null,
'sub_total' => $total,
'tax' => $total * (10 / 100),
'total' => $total + ($total * (10 / 100)),
'payment_method' => $paymentRecord?->id,
'customer_id' => ($data['create_invoice'] ?? false) ? $data['customer_id'] : 0,
'customer_id' => $data['customer_id'],
'status' => $data['status'],
];
@@ -84,10 +84,15 @@ class OrderService
$this->createModules($relIdData);
$invoiceItemData = array_map(
fn ($item) => \Illuminate\Support\Arr::except($item, ['billing_cycle', 'code']),
$productItems
);
$invoiceItemData = array_map(fn ($item) => [
'invoice_id' => $item['invoice_id'],
'product_id' => $item['product_id'],
'type' => 'service',
'months' => $item['months'],
'quantity' => $item['quantity'],
'unit_price' => $item['price'],
'total_price' => $item['price'] * $item['quantity'],
], $productItems);
$this->invoiceItemRepository->insert($invoiceItemData);
$now = now();
@@ -18,10 +18,10 @@ return new class extends Migration
$table->string('name')->nullable();
$table->foreignId('module_ip_address')
->constrained('module_ip_address');
->constrained('module_ip_address')->nullable();
$table->foreignId('vcenter_id')
->constrained('module_vcenter');
->constrained('module_vcenter')->nullable();
$table->integer('port')->nullable();
$table->integer('order_id')->nullable();
+1 -1
View File
@@ -23,6 +23,6 @@ class DatabaseSeeder extends Seeder
$this->call(TemplateSeeder::class);
$this->call(Setting::class);
$this->call(ControlPanelSeeder::class);
$this->call(VPSProductSeeder::class);
// $this->call(VPSProductSeeder::class);
}
}