diff --git a/app/Console/Commands/GeneratePayrollCommand.php b/app/Console/Commands/GeneratePayrollCommand.php index 11a1477..d44da53 100644 --- a/app/Console/Commands/GeneratePayrollCommand.php +++ b/app/Console/Commands/GeneratePayrollCommand.php @@ -4,10 +4,10 @@ use App\Models\Payroll; use App\Models\User; +use App\Support\LogHelper; use Carbon\Carbon; use Illuminate\Console\Command; use Illuminate\Support\Facades\DB; -use Illuminate\Support\Facades\Log; use Throwable; class GeneratePayrollCommand extends Command @@ -60,8 +60,8 @@ public function handle() } }); } catch (Throwable $e) { - Log::error('Payroll generate failed', [ - 'error' => $e->getMessage(), + LogHelper::logException($e, 'Payroll generate failed', [ + 'period' => $periodMonth, ]); $this->info('Gagal generate data penggajian, silakan hubungi pengembang.'); diff --git a/app/Http/Controllers/Admin/Finance/PayrollController.php b/app/Http/Controllers/Admin/Finance/PayrollController.php index 829ac96..5149c21 100644 --- a/app/Http/Controllers/Admin/Finance/PayrollController.php +++ b/app/Http/Controllers/Admin/Finance/PayrollController.php @@ -5,12 +5,12 @@ use App\Http\Controllers\Controller; use App\Http\Requests\Admin\Finance\SalaryAdjustmentRequest; use App\Models\Payroll; +use App\Support\LogHelper; use Carbon\Carbon; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\DB; -use Illuminate\Support\Facades\Log; use Inertia\Inertia; use Inertia\Response; use Throwable; @@ -75,9 +75,8 @@ public function update(SalaryAdjustmentRequest $request, Payroll $payroll): Redi ]); }); } catch (Throwable $e) { - Log::error('Payroll update failed', [ + LogHelper::logException($e, 'Payroll update failed', [ 'payroll_id' => $payroll->id, - 'error' => $e->getMessage(), ]); return back()->withInput()->with('error', 'Gagal memperbarui data. Silakan coba lagi.'); diff --git a/app/Http/Controllers/Admin/Manage/OrderController.php b/app/Http/Controllers/Admin/Manage/OrderController.php index d21fe72..9f48f2a 100644 --- a/app/Http/Controllers/Admin/Manage/OrderController.php +++ b/app/Http/Controllers/Admin/Manage/OrderController.php @@ -11,6 +11,7 @@ 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; @@ -46,48 +47,60 @@ public function store(OrderRequest $request): RedirectResponse { $validated = $request->validated(); - DB::transaction(function () use ($validated) { - $totalItemsPrice = collect($validated['items'])->sum('total'); - $hpp = collect($validated['items'])->sum(function ($item) { - $product = Product::find($item['product_id']); - $purchasePrice = $product->prices()->where('price_type', PriceType::PURCHASE)->first()?->price ?? 0; + try { + DB::transaction(function () use ($validated) { + $totalItemsPrice = collect($validated['items'])->sum('total'); + $hpp = 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']; - }); + return $purchasePrice * $item['qty']; + }); - $order = Order::create([ - 'user_id' => auth()->id(), - 'invoice_number' => $validated['invoice_number'] ?? 'INV-'.now()->format('YmdHis').'-'.strtoupper(fake()->bothify('??##')), - 'customer_name' => $validated['customer_name'], - 'hpp' => $hpp, - 'discount' => $validated['discount'], - 'payment' => $validated['payment'], - 'total' => $totalItemsPrice - $validated['discount'], - 'payment_method' => $validated['payment_method'], - 'order_status' => $validated['order_status'], - 'order_channel' => $validated['order_channel'], - ]); - - foreach ($validated['items'] as $item) { - OrderItem::create([ + $order = Order::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'], + 'invoice_number' => $validated['invoice_number'] ?? 'INV-'.now()->format('YmdHis').'-'.strtoupper(fake()->bothify('??##')), + 'customer_name' => $validated['customer_name'], + 'hpp' => $hpp, + 'discount' => $validated['discount'], + 'payment' => $validated['payment'], + 'total' => $totalItemsPrice - $validated['discount'], + 'payment_method' => $validated['payment_method'], + 'order_status' => $validated['order_status'], + 'order_channel' => $validated['order_channel'], ]); - Product::find($item['product_id'])->decrement('stock', $item['qty']); - } + 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'], + ]); - OrderItem::where('user_id', auth()->id()) - ->whereNull('order_id') - ->delete(); - }); + Product::find($item['product_id'])->decrement('stock', $item['qty']); + } - return redirect()->route('order.index')->with('success', 'Pesanan berhasil disimpan'); + 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 saat menyimpan pesanan'); + } } public function edit(Order $order): Response @@ -108,76 +121,104 @@ public function update(OrderRequest $request, Order $order): RedirectResponse { $validated = $request->validated(); - DB::transaction(function () use ($validated, $order) { - $totalItemsPrice = collect($validated['items'])->sum(fn ($item) => $item['qty'] * $item['price']); - $hpp = collect($validated['items'])->sum(function ($item) { - $product = Product::find($item['product_id']); - $purchasePrice = $product->prices()->where('price_type', PriceType::PURCHASE)->first()?->price ?? 0; + try { + DB::transaction(function () use ($validated, $order) { + $totalItemsPrice = collect($validated['items'])->sum(fn ($item) => $item['qty'] * $item['price']); + $hpp = 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']; - }); + return $purchasePrice * $item['qty']; + }); - // Restore stock for old items - foreach ($order->items as $item) { - $item->product->increment('stock', $item->qty); - } + // Restore stock for old items + foreach ($order->items as $item) { + $item->product->increment('stock', $item->qty); + } - $order->items()->delete(); + $order->items()->delete(); - $order->update([ - 'customer_name' => $validated['customer_name'], - 'hpp' => $hpp, - 'discount' => $validated['discount'], - 'payment' => $validated['payment'], - 'total' => $totalItemsPrice - $validated['discount'], - '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'], + $order->update([ + 'customer_name' => $validated['customer_name'], + 'hpp' => $hpp, + 'discount' => $validated['discount'], + 'payment' => $validated['payment'], + 'total' => $totalItemsPrice - $validated['discount'], + 'payment_method' => $validated['payment_method'], + 'order_status' => $validated['order_status'], + 'order_channel' => $validated['order_channel'], ]); - Product::find($item['product_id'])->decrement('stock', $item['qty']); - } - }); + 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'], + ]); - return redirect()->route('order.index')->with('success', 'Pesanan berhasil diperbarui'); + 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 saat memperbarui pesanan'); + } } public function destroy(Order $order): RedirectResponse { - DB::transaction(function () use ($order) { - foreach ($order->items as $item) { - $item->product->increment('stock', $item->qty); - } - $order->delete(); - }); + try { + DB::transaction(function () use ($order) { + foreach ($order->items as $item) { + $item->product->increment('stock', $item->qty); + } + $order->delete(); + }); - return redirect()->back()->with('success', 'Pesanan berhasil dihapus'); + return redirect()->back()->with('success', 'Pesanan berhasil dihapus'); + } catch (\Throwable $e) { + LogHelper::logException($e, 'Failed to delete order', [ + 'order_id' => $order->id, + ]); + + return redirect()->back()->with('error', 'Terjadi kesalahan saat menghapus pesanan'); + } } public function bulkDestroy(Request $request): RedirectResponse { $ids = $request->input('ids'); - DB::transaction(function () use ($ids) { - $orders = Order::with('items')->whereIn('id', $ids)->get(); - foreach ($orders as $order) { - foreach ($order->items as $item) { - $item->product->increment('stock', $item->qty); + try { + DB::transaction(function () use ($ids) { + $orders = Order::with('items')->whereIn('id', $ids)->get(); + foreach ($orders as $order) { + foreach ($order->items as $item) { + $item->product->increment('stock', $item->qty); + } + $order->delete(); } - $order->delete(); - } - }); + }); - return redirect()->back()->with('success', 'Pesanan terpilih berhasil dihapus'); + 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 saat menghapus beberapa pesanan'); + } } } diff --git a/app/Http/Controllers/Admin/Manage/PurchaseController.php b/app/Http/Controllers/Admin/Manage/PurchaseController.php index 1072d29..7de0ad5 100644 --- a/app/Http/Controllers/Admin/Manage/PurchaseController.php +++ b/app/Http/Controllers/Admin/Manage/PurchaseController.php @@ -7,6 +7,7 @@ use App\Models\Product; use App\Models\Purchase; use App\Models\PurchaseItem; +use App\Support\LogHelper; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; @@ -38,34 +39,46 @@ public function store(PurchaseRequest $request): RedirectResponse { $validated = $request->validated(); - DB::transaction(function () use ($validated) { - $total = collect($validated['items'])->sum(fn ($item) => $item['quantity'] * $item['unit_price']); + try { + DB::transaction(function () use ($validated) { + $total = collect($validated['items'])->sum(fn ($item) => $item['quantity'] * $item['unit_price']); - $purchase = Purchase::create([ - 'purchase_date' => $validated['purchase_date'], - 'note' => $validated['note'], - 'total' => $total, - ]); - - foreach ($validated['items'] as $item) { - PurchaseItem::create([ - 'user_id' => auth()->id(), - 'purchase_id' => $purchase->id, - 'product_id' => $item['product_id'], - 'quantity' => $item['quantity'], - 'unit_price' => $item['unit_price'], - 'total_price' => $item['quantity'] * $item['unit_price'], + $purchase = Purchase::create([ + 'purchase_date' => $validated['purchase_date'], + 'note' => $validated['note'], + 'total' => $total, ]); - Product::find($item['product_id'])->increment('stock', $item['quantity']); - } + foreach ($validated['items'] as $item) { + PurchaseItem::create([ + 'user_id' => auth()->id(), + 'purchase_id' => $purchase->id, + 'product_id' => $item['product_id'], + 'quantity' => $item['quantity'], + 'unit_price' => $item['unit_price'], + 'total_price' => $item['quantity'] * $item['unit_price'], + ]); - PurchaseItem::where('user_id', auth()->id()) - ->whereNull('purchase_id') - ->delete(); - }); + Product::find($item['product_id'])->increment('stock', $item['quantity']); + } - return redirect()->route('purchase.index')->with('success', 'Data berhasil disimpan'); + PurchaseItem::where('user_id', auth()->id()) + ->whereNull('purchase_id') + ->delete(); + }); + + return redirect()->route('purchase.index')->with('success', 'Data berhasil disimpan'); + } catch (\Throwable $e) { + LogHelper::logException($e, 'Failed to store purchase', [ + 'purchase_date' => $validated['purchase_date'] ?? null, + 'items_count' => count($validated['items'] ?? []), + ]); + + return redirect() + ->back() + ->withInput() + ->with('error', 'Terjadi kesalahan saat menyimpan pembelian'); + } } public function edit(Purchase $purchase): Response @@ -82,63 +95,91 @@ public function update(PurchaseRequest $request, Purchase $purchase): RedirectRe { $validated = $request->validated(); - DB::transaction(function () use ($validated, $purchase) { - $total = collect($validated['items'])->sum(fn ($item) => $item['quantity'] * $item['unit_price']); + try { + DB::transaction(function () use ($validated, $purchase) { + $total = collect($validated['items'])->sum(fn ($item) => $item['quantity'] * $item['unit_price']); - $purchase->update([ - 'purchase_date' => $validated['purchase_date'], - 'note' => $validated['note'], - 'total' => $total, - ]); - - foreach ($purchase->items as $item) { - $item->product->decrement('stock', $item->quantity); - } - - $purchase->items()->delete(); - - foreach ($validated['items'] as $item) { - $purchase->items()->create([ - 'user_id' => auth()->id(), - 'product_id' => $item['product_id'], - 'quantity' => $item['quantity'], - 'unit_price' => $item['unit_price'], - 'total_price' => $item['quantity'] * $item['unit_price'], + $purchase->update([ + 'purchase_date' => $validated['purchase_date'], + 'note' => $validated['note'], + 'total' => $total, ]); - Product::find($item['product_id'])->increment('stock', $item['quantity']); - } - }); + foreach ($purchase->items as $item) { + $item->product->decrement('stock', $item->quantity); + } - return redirect()->route('purchase.index')->with('success', 'Data berhasil diperbarui'); + $purchase->items()->delete(); + + foreach ($validated['items'] as $item) { + $purchase->items()->create([ + 'user_id' => auth()->id(), + 'product_id' => $item['product_id'], + 'quantity' => $item['quantity'], + 'unit_price' => $item['unit_price'], + 'total_price' => $item['quantity'] * $item['unit_price'], + ]); + + Product::find($item['product_id'])->increment('stock', $item['quantity']); + } + }); + + return redirect()->route('purchase.index')->with('success', 'Data berhasil diperbarui'); + } catch (\Throwable $e) { + LogHelper::logException($e, 'Failed to update purchase', [ + 'purchase_id' => $purchase->id, + 'items_count' => count($validated['items'] ?? []), + ]); + + return redirect() + ->back() + ->withInput() + ->with('error', 'Terjadi kesalahan saat memperbarui pembelian'); + } } public function destroy(Purchase $purchase): RedirectResponse { - DB::transaction(function () use ($purchase) { - foreach ($purchase->items as $item) { - $item->product->decrement('stock', $item->quantity); - } - $purchase->delete(); - }); + try { + DB::transaction(function () use ($purchase) { + foreach ($purchase->items as $item) { + $item->product->decrement('stock', $item->quantity); + } + $purchase->delete(); + }); - return redirect()->back()->with('success', 'Data berhasil dihapus'); + return redirect()->back()->with('success', 'Data berhasil dihapus'); + } catch (\Throwable $e) { + LogHelper::logException($e, 'Failed to delete purchase', [ + 'purchase_id' => $purchase->id, + ]); + + return redirect()->back()->with('error', 'Terjadi kesalahan saat menghapus pembelian'); + } } public function bulkDestroy(Request $request): RedirectResponse { $ids = $request->input('ids'); - DB::transaction(function () use ($ids) { - $purchases = Purchase::with('items')->whereIn('id', $ids)->get(); - foreach ($purchases as $purchase) { - foreach ($purchase->items as $item) { - $item->product->decrement('stock', $item->quantity); + try { + DB::transaction(function () use ($ids) { + $purchases = Purchase::with('items')->whereIn('id', $ids)->get(); + foreach ($purchases as $purchase) { + foreach ($purchase->items as $item) { + $item->product->decrement('stock', $item->quantity); + } + $purchase->delete(); } - $purchase->delete(); - } - }); + }); - return redirect()->back()->with('success', 'Data terpilih berhasil dihapus'); + return redirect()->back()->with('success', 'Data terpilih berhasil dihapus'); + } catch (\Throwable $e) { + LogHelper::logException($e, 'Failed to bulk delete purchases', [ + 'ids' => $ids, + ]); + + return redirect()->back()->with('error', 'Terjadi kesalahan saat menghapus beberapa pembelian'); + } } } diff --git a/app/Http/Controllers/Admin/Master/ProductController.php b/app/Http/Controllers/Admin/Master/ProductController.php index 317b0f5..9d8d3ea 100644 --- a/app/Http/Controllers/Admin/Master/ProductController.php +++ b/app/Http/Controllers/Admin/Master/ProductController.php @@ -7,6 +7,7 @@ use App\Http\Requests\Admin\Master\ProductRequest; use App\Models\Category; use App\Models\Product; +use App\Support\LogHelper; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; @@ -35,38 +36,57 @@ public function store(ProductRequest $request): RedirectResponse { $validated = $request->validated(); - DB::transaction(function () use ($request, $validated) { - $product = Product::create([ - 'name' => $validated['name'], - 'description' => $validated['description'], + try { + DB::transaction(function () use ($request, $validated) { + $product = Product::create([ + 'name' => $validated['name'], + 'description' => $validated['description'], + ]); + + $product->categories()->sync($validated['category_ids'] ?? []); + + foreach ($validated['prices'] as $type => $price) { + $enumType = PriceType::tryFrom($type); + if ($enumType) { + $product->prices()->create([ + 'price_type' => $enumType, + 'price' => $price, + ]); + } + } + + if ($request->hasFile('thumbnail')) { + $product->addMediaFromRequest('thumbnail') + ->toMediaCollection('thumbnail'); + } + + if ($request->hasFile('images')) { + foreach ($request->file('images') as $image) { + $product->addMedia($image) + ->toMediaCollection('images'); + } + } + }); + + return redirect()->route('product.index')->with('success', 'Data berhasil disimpan'); + } catch (\Throwable $e) { + LogHelper::logException($e, 'Failed to store product', [ + 'input_summary' => [ + 'name' => $request->input('name'), + 'categories_count' => count($request->input('category_ids', [])), + 'prices_keys' => array_keys($request->input('prices', [])), + 'has_thumbnail' => $request->hasFile('thumbnail'), + 'images_count' => $request->hasFile('images') + ? count($request->file('images')) + : 0, + ], ]); - $product->categories()->sync($validated['category_ids'] ?? []); - - foreach ($validated['prices'] as $type => $price) { - $enumType = PriceType::tryFrom($type); - if ($enumType) { - $product->prices()->create([ - 'price_type' => $enumType, - 'price' => $price, - ]); - } - } - - if ($request->hasFile('thumbnail')) { - $product->addMediaFromRequest('thumbnail') - ->toMediaCollection('thumbnail'); - } - - if ($request->hasFile('images')) { - foreach ($request->file('images') as $image) { - $product->addMedia($image) - ->toMediaCollection('images'); - } - } - }); - - return redirect()->route('product.index')->with('success', 'Data berhasil disimpan'); + return redirect() + ->back() + ->withInput() + ->with('error', 'Terjadi kesalahan saat menyimpan data'); + } } public function edit(Product $product): Response @@ -83,46 +103,63 @@ public function update(ProductRequest $request, Product $product): RedirectRespo { $validated = $request->validated(); - DB::transaction(function () use ($request, $product, $validated) { - $product->update([ - 'name' => $validated['name'], - 'description' => $validated['description'], - 'stock' => $validated['stock'] ?? 0, + try { + DB::transaction(function () use ($request, $product, $validated) { + $product->update([ + 'name' => $validated['name'], + 'description' => $validated['description'], + 'stock' => $validated['stock'] ?? 0, + ]); + + $product->categories()->sync($validated['category_ids'] ?? []); + + foreach ($validated['prices'] as $type => $price) { + $enumType = PriceType::tryFrom($type); + if ($enumType) { + $product->prices()->updateOrCreate( + ['price_type' => $enumType], + ['price' => $price] + ); + } + } + + if (! empty($validated['delete_image_ids'])) { + Media::whereIn('id', $validated['delete_image_ids']) + ->where('model_type', Product::class) + ->where('model_id', $product->id) + ->each(fn ($media) => $media->delete()); + } + + if ($request->hasFile('thumbnail')) { + $product->addMediaFromRequest('thumbnail') + ->toMediaCollection('thumbnail'); + } + + if ($request->hasFile('images')) { + foreach ($request->file('images') as $image) { + $product->addMedia($image) + ->toMediaCollection('images'); + } + } + }); + + return redirect()->route('product.index')->with('success', 'Data berhasil diperbarui'); + } catch (\Throwable $e) { + LogHelper::logException($e, 'Failed to update product', [ + 'product_id' => $product->id, + 'input_summary' => [ + 'name' => $request->input('name'), + 'categories_count' => count($request->input('category_ids', [])), + 'prices_keys' => array_keys($request->input('prices', [])), + 'has_thumbnail' => $request->hasFile('thumbnail'), + ], ]); - $product->categories()->sync($validated['category_ids'] ?? []); - - foreach ($validated['prices'] as $type => $price) { - $enumType = PriceType::tryFrom($type); - if ($enumType) { - $product->prices()->updateOrCreate( - ['price_type' => $enumType], - ['price' => $price] - ); - } - } - - if (! empty($validated['delete_image_ids'])) { - Media::whereIn('id', $validated['delete_image_ids']) - ->where('model_type', Product::class) - ->where('model_id', $product->id) - ->each(fn ($media) => $media->delete()); - } - - if ($request->hasFile('thumbnail')) { - $product->addMediaFromRequest('thumbnail') - ->toMediaCollection('thumbnail'); - } - - if ($request->hasFile('images')) { - foreach ($request->file('images') as $image) { - $product->addMedia($image) - ->toMediaCollection('images'); - } - } - }); - - return redirect()->route('product.index')->with('success', 'Data berhasil diperbarui'); + return redirect() + ->back() + ->withInput() + ->with('error', 'Terjadi kesalahan saat memperbarui data'); + } } public function destroy(Product $product): RedirectResponse diff --git a/app/Http/Controllers/Admin/Master/UserController.php b/app/Http/Controllers/Admin/Master/UserController.php index 68d3657..89734b7 100644 --- a/app/Http/Controllers/Admin/Master/UserController.php +++ b/app/Http/Controllers/Admin/Master/UserController.php @@ -5,6 +5,7 @@ use App\Http\Controllers\Controller; use App\Http\Requests\Admin\Master\UserRequest; use App\Models\User; +use App\Support\LogHelper; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; @@ -31,25 +32,37 @@ public function store(UserRequest $request): RedirectResponse { $validated = $request->validated(); - DB::transaction(function () use ($validated) { - $user = User::create([ + try { + DB::transaction(function () use ($validated) { + $user = User::create([ + 'username' => $validated['username'], + 'email' => $validated['email'], + 'password' => Hash::make(config('auth.password_default')), + ]); + + $user->profile()->create([ + 'nik' => $validated['nik'], + 'full_name' => $validated['full_name'], + 'phone_number' => $validated['phone_number'], + 'address' => $validated['address'], + 'birth_place' => $validated['birth_place'], + 'birth_date' => $validated['birth_date'], + 'base_salary' => $validated['base_salary'], + ]); + }); + + return redirect()->route('user.index')->with('success', 'Data berhasil disimpan'); + } catch (\Throwable $e) { + LogHelper::logException($e, 'Failed to store user', [ 'username' => $validated['username'], 'email' => $validated['email'], - 'password' => Hash::make(config('auth.password_default')), ]); - $user->profile()->create([ - 'nik' => $validated['nik'], - 'full_name' => $validated['full_name'], - 'phone_number' => $validated['phone_number'], - 'address' => $validated['address'], - 'birth_place' => $validated['birth_place'], - 'birth_date' => $validated['birth_date'], - 'base_salary' => $validated['base_salary'], - ]); - }); - - return redirect()->route('user.index')->with('success', 'Data berhasil disimpan'); + return redirect() + ->back() + ->withInput() + ->with('error', 'Terjadi kesalahan saat menyimpan data'); + } } public function edit(User $user): Response @@ -65,24 +78,36 @@ public function update(UserRequest $request, User $user): RedirectResponse { $validated = $request->validated(); - DB::transaction(function () use ($user, $validated) { - $user->update([ + try { + DB::transaction(function () use ($user, $validated) { + $user->update([ + 'username' => $validated['username'], + 'email' => $validated['email'], + ]); + + $user->profile()->update([ + 'nik' => $validated['nik'], + 'full_name' => $validated['full_name'], + 'phone_number' => $validated['phone_number'], + 'address' => $validated['address'], + 'birth_place' => $validated['birth_place'], + 'birth_date' => $validated['birth_date'], + 'base_salary' => $validated['base_salary'], + ]); + }); + + return redirect()->route('user.index')->with('success', 'Data berhasil diperbarui'); + } catch (\Throwable $e) { + LogHelper::logException($e, 'Failed to update user', [ + 'user_id' => $user->id, 'username' => $validated['username'], - 'email' => $validated['email'], ]); - $user->profile()->update([ - 'nik' => $validated['nik'], - 'full_name' => $validated['full_name'], - 'phone_number' => $validated['phone_number'], - 'address' => $validated['address'], - 'birth_place' => $validated['birth_place'], - 'birth_date' => $validated['birth_date'], - 'base_salary' => $validated['base_salary'], - ]); - }); - - return redirect()->route('user.index')->with('success', 'Data berhasil diperbarui'); + return redirect() + ->back() + ->withInput() + ->with('error', 'Terjadi kesalahan saat memperbarui data'); + } } public function resetPassword(User $user): RedirectResponse diff --git a/app/Http/Controllers/Admin/System/LogController.php b/app/Http/Controllers/Admin/System/LogController.php index 116cdf4..3637928 100644 --- a/app/Http/Controllers/Admin/System/LogController.php +++ b/app/Http/Controllers/Admin/System/LogController.php @@ -39,8 +39,8 @@ private function getLogFiles(): array $files = File::files($path); return collect($files) - ->map(fn($file) => $file->getFilename()) - ->filter(fn($filename) => str_ends_with($filename, '.log')) + ->map(fn ($file) => $file->getFilename()) + ->filter(fn ($filename) => str_ends_with($filename, '.log')) ->sortDesc() ->take(10) ->values() diff --git a/app/Support/LogHelper.php b/app/Support/LogHelper.php new file mode 100644 index 0000000..bdc4a89 --- /dev/null +++ b/app/Support/LogHelper.php @@ -0,0 +1,47 @@ + $e->getMessage(), + 'exception' => get_class($e), + 'file' => $e->getFile(), + 'line' => $e->getLine(), + + // stack trace (take top 10) + 'trace' => collect($e->getTrace())->take(10)->toArray(), + + // request context + 'request' => [ + 'url' => $request->fullUrl(), + 'method' => $request->method(), + 'ip' => $request->ip(), + 'user_agent' => $request->userAgent(), + 'payload' => Arr::except($request->all(), ['password', 'token', 'password_confirmation']), + ], + + // auth context + 'user' => optional(auth()->user())->only(['id', 'email']), + + // custom context + 'extra' => $extraContext, + ]); + } +}