dress/app/Http/Controllers/Admin/Manage/OrderController.php

207 lines
8.2 KiB
PHP

<?php
namespace App\Http\Controllers\Admin\Manage;
use App\Enums\OrderChannel;
use App\Enums\OrderStatus;
use App\Enums\PaymentMethod;
use App\Enums\PriceType;
use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\Manage\Order\OrderRequest;
use App\Models\Order;
use App\Models\OrderItem;
use App\Models\Product;
use App\Support\LogHelper;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Inertia\Inertia;
use Inertia\Response;
class OrderController extends Controller
{
public function index(): Response
{
return Inertia::render('admin/manage/order/index', [
'orders' => Order::with(['items.product'])->latest()->get(),
]);
}
public function create(): Response
{
return Inertia::render('admin/manage/order/create', [
'products' => Product::with(['prices', 'categories'])->active()->get(),
'cartItems' => OrderItem::with(['product.prices', 'product.categories'])
->where('user_id', auth()->id())
->whereNull('order_id')
->latest()
->get(),
'orderStatus' => collect(OrderStatus::cases())->map(fn ($case) => ['value' => $case->value, 'label' => $case->label()]),
'orderChannels' => collect(OrderChannel::cases())->map(fn ($case) => ['value' => $case->value, 'label' => $case->label()]),
'paymentMethods' => collect(PaymentMethod::cases())->map(fn ($case) => ['value' => $case->value, 'label' => $case->label()]),
'priceTypes' => collect(PriceType::cases())->map(fn ($case) => ['value' => $case->value, 'label' => $case->label()]),
]);
}
public function store(OrderRequest $request): RedirectResponse
{
$validated = $request->validated();
try {
DB::transaction(function () use ($validated) {
$totalItemsPrice = collect($validated['items'])->sum('total');
$cogs = collect($validated['items'])->sum(function ($item) {
$product = Product::find($item['product_id']);
$purchasePrice = $product->prices()->where('price_type', PriceType::PURCHASE)->first()?->price ?? 0;
return $purchasePrice * $item['qty'];
});
$order = Order::create([
'customer_name' => $validated['customer_name'],
'cogs' => $cogs,
'subtotal' => $totalItemsPrice,
'discount' => $validated['discount'],
'payment' => $validated['payment'],
'payment_method' => $validated['payment_method'],
'order_status' => $validated['order_status'],
'order_channel' => $validated['order_channel'],
]);
foreach ($validated['items'] as $item) {
OrderItem::create([
'user_id' => auth()->id(),
'order_id' => $order->id,
'product_id' => $item['product_id'],
'price' => $item['price'],
'qty' => $item['qty'],
'total' => $item['total'],
'price_type' => $item['price_type'],
]);
Product::find($item['product_id'])->decrement('stock', $item['qty']);
}
OrderItem::where('user_id', auth()->id())
->whereNull('order_id')
->delete();
});
return redirect()->route('order.index')->with('success', 'Pesanan berhasil disimpan');
} catch (\Throwable $e) {
LogHelper::logException($e, 'Failed to store order', [
'customer_name' => $validated['customer_name'],
'items_count' => count($validated['items'] ?? []),
]);
return redirect()
->back()
->withInput()
->with('error', 'Terjadi kesalahan, silakan hubungi pengembang');
}
}
public function edit(Order $order): Response
{
$order->load(['items.product']);
return Inertia::render('admin/manage/order/edit', [
'order' => $order,
'products' => Product::with(['prices', 'categories'])->active()->get(),
'orderStatus' => collect(OrderStatus::cases())->map(fn ($case) => ['value' => $case->value, 'label' => $case->label()]),
'orderChannels' => collect(OrderChannel::cases())->map(fn ($case) => ['value' => $case->value, 'label' => $case->label()]),
'paymentMethods' => collect(PaymentMethod::cases())->map(fn ($case) => ['value' => $case->value, 'label' => $case->label()]),
'priceTypes' => collect(PriceType::cases())->map(fn ($case) => ['value' => $case->value, 'label' => $case->label()]),
]);
}
public function update(OrderRequest $request, Order $order): RedirectResponse
{
$validated = $request->validated();
try {
DB::transaction(function () use ($validated, $order) {
$totalItemsPrice = collect($validated['items'])->sum(fn ($item) => $item['qty'] * $item['price']);
$cogs = collect($validated['items'])->sum(function ($item) {
$product = Product::find($item['product_id']);
$purchasePrice = $product->prices()->where('price_type', PriceType::PURCHASE)->first()?->price ?? 0;
return $purchasePrice * $item['qty'];
});
// Restore stock for old items
foreach ($order->items as $item) {
$item->product->increment('stock', $item->qty);
}
$order->items()->delete();
$order->update([
'customer_name' => $validated['customer_name'],
'cogs' => $cogs,
'subtotal' => $totalItemsPrice,
'discount' => $validated['discount'],
'payment' => $validated['payment'],
'payment_method' => $validated['payment_method'],
'order_status' => $validated['order_status'],
'order_channel' => $validated['order_channel'],
]);
foreach ($validated['items'] as $item) {
$order->items()->create([
'user_id' => auth()->id(),
'product_id' => $item['product_id'],
'price' => $item['price'],
'qty' => $item['qty'],
'total' => $item['total'],
'price_type' => $item['price_type'],
]);
Product::find($item['product_id'])->decrement('stock', $item['qty']);
}
});
return redirect()->route('order.index')->with('success', 'Pesanan berhasil diperbarui');
} catch (\Throwable $e) {
LogHelper::logException($e, 'Failed to update order', [
'order_id' => $order->id,
'customer_name' => $validated['customer_name'],
]);
return redirect()
->back()
->withInput()
->with('error', 'Terjadi kesalahan, silakan hubungi pengembang');
}
}
public function destroy(Order $order): RedirectResponse
{
$order->delete();
return redirect()->back()->with('success', 'Pesanan berhasil dihapus');
}
public function bulkDestroy(Request $request): RedirectResponse
{
$ids = $request->input('ids');
try {
DB::transaction(function () use ($ids) {
$orders = Order::whereIn('id', $ids)->get();
foreach ($orders as $order) {
$order->delete();
}
});
return redirect()->back()->with('success', 'Pesanan terpilih berhasil dihapus');
} catch (\Throwable $e) {
LogHelper::logException($e, 'Failed to bulk delete orders', [
'ids' => $ids,
]);
return redirect()->back()->with('error', 'Terjadi kesalahan, silakan hubungi pengembang');
}
}
}