input('search')) { $query->where(function ($q) use ($search) { $q->where('customer_name', 'like', "%{$search}%") ->orWhere('invoice_no', 'like', "%{$search}%"); }); } if ($status = $request->input('status')) { if ($status !== 'all') { $query->where('status', $status); } } if ($category = $request->input('category')) { if ($category !== 'all') { $query->where('category', $category); } } $receivables = $query->orderBy('created_at', 'desc') ->get() ->map(function ($item) { return [ 'id' => $item->id, 'customerName' => $item->customer_name, 'invoiceNo' => $item->invoice_no, 'issueDate' => $item->issue_date?->format('Y-m-d'), 'dueDate' => $item->due_date?->format('Y-m-d'), 'category' => $item->category, 'amount' => $item->amount, 'collectedAmount' => $item->collected_amount, 'status' => $item->status, 'description' => $item->description, 'memo' => $item->memo, ]; }); $allQuery = Receivable::forTenant($tenantId); $all = (clone $allQuery)->get(); $totalAmount = $all->sum('amount'); $totalCollected = $all->sum('collected_amount'); $overdueAmount = $all->where('status', 'overdue')->sum(function ($item) { return $item->amount - $item->collected_amount; }); $stats = [ 'totalAmount' => $totalAmount, 'totalCollected' => $totalCollected, 'totalOutstanding' => $totalAmount - $totalCollected, 'overdueAmount' => $overdueAmount, 'count' => $all->count(), ]; return response()->json([ 'success' => true, 'data' => $receivables, 'stats' => $stats, ]); } public function store(Request $request): JsonResponse { $request->validate([ 'customerName' => 'required|string|max:100', 'invoiceNo' => 'required|string|max:50', 'amount' => 'required|integer|min:0', ]); $tenantId = session('selected_tenant_id', 1); $receivable = Receivable::create([ 'tenant_id' => $tenantId, 'customer_name' => $request->input('customerName'), 'invoice_no' => $request->input('invoiceNo'), 'issue_date' => $request->input('issueDate'), 'due_date' => $request->input('dueDate'), 'category' => $request->input('category', '서비스'), 'amount' => $request->input('amount', 0), 'collected_amount' => 0, 'status' => 'outstanding', 'description' => $request->input('description'), 'memo' => $request->input('memo'), ]); return response()->json([ 'success' => true, 'message' => '미수금이 등록되었습니다.', ]); } public function update(Request $request, int $id): JsonResponse { $tenantId = session('selected_tenant_id', 1); $receivable = Receivable::forTenant($tenantId)->findOrFail($id); $request->validate([ 'customerName' => 'required|string|max:100', 'invoiceNo' => 'required|string|max:50', 'amount' => 'required|integer|min:0', ]); $receivable->update([ 'customer_name' => $request->input('customerName'), 'invoice_no' => $request->input('invoiceNo'), 'issue_date' => $request->input('issueDate'), 'due_date' => $request->input('dueDate'), 'category' => $request->input('category'), 'amount' => $request->input('amount'), 'status' => $request->input('status', $receivable->status), 'description' => $request->input('description'), 'memo' => $request->input('memo'), ]); return response()->json([ 'success' => true, 'message' => '미수금이 수정되었습니다.', ]); } public function collect(Request $request, int $id): JsonResponse { $tenantId = session('selected_tenant_id', 1); $receivable = Receivable::forTenant($tenantId)->findOrFail($id); $request->validate([ 'collectAmount' => 'required|integer|min:1', ]); $collectAmount = $request->input('collectAmount'); $remaining = $receivable->amount - $receivable->collected_amount; if ($collectAmount > $remaining) { return response()->json([ 'success' => false, 'message' => '수금액이 잔액을 초과합니다.', ], 422); } $newCollected = $receivable->collected_amount + $collectAmount; $newStatus = $newCollected >= $receivable->amount ? 'collected' : 'partial'; $receivable->update([ 'collected_amount' => $newCollected, 'status' => $newStatus, ]); return response()->json([ 'success' => true, 'message' => '수금 처리되었습니다.', ]); } public function destroy(int $id): JsonResponse { $tenantId = session('selected_tenant_id', 1); $receivable = Receivable::forTenant($tenantId)->findOrFail($id); $receivable->delete(); return response()->json([ 'success' => true, 'message' => '미수금이 삭제되었습니다.', ]); } }