user()->business_id; $banks = PaymentType::where('business_id', $business_id)->latest()->get(); $cheque = Transaction::with('user:id,name') ->where('business_id', auth()->user()->business_id) ->whereIn('transaction_type', ['cheque_payment', 'cheque_reopen']); // Default to today $startDate = Carbon::today()->format('Y-m-d'); $endDate = Carbon::today()->format('Y-m-d'); if ($request->custom_days === 'yesterday') { $startDate = Carbon::yesterday()->format('Y-m-d'); $endDate = Carbon::yesterday()->format('Y-m-d'); } elseif ($request->custom_days === 'last_seven_days') { $startDate = Carbon::today()->subDays(6)->format('Y-m-d'); } elseif ($request->custom_days === 'last_thirty_days') { $startDate = Carbon::today()->subDays(29)->format('Y-m-d'); } elseif ($request->custom_days === 'current_month') { $startDate = Carbon::now()->startOfMonth()->format('Y-m-d'); $endDate = Carbon::now()->endOfMonth()->format('Y-m-d'); } elseif ($request->custom_days === 'last_month') { $startDate = Carbon::now()->subMonth()->startOfMonth()->format('Y-m-d'); $endDate = Carbon::now()->subMonth()->endOfMonth()->format('Y-m-d'); } elseif ($request->custom_days === 'current_year') { $startDate = Carbon::now()->startOfYear()->format('Y-m-d'); $endDate = Carbon::now()->endOfYear()->format('Y-m-d'); } elseif ($request->custom_days === 'custom_date' && $request->from_date && $request->to_date) { $startDate = Carbon::parse($request->from_date)->format('Y-m-d'); $endDate = Carbon::parse($request->to_date)->format('Y-m-d'); } $cheque->whereDate('date', '>=', $startDate) ->whereDate('date', '<=', $endDate); $cheques = $cheque->when(request('search'), function ($q) use ($request) { $q->where(function ($q) use ($request) { $q->where('date', 'like', '%' . $request->search . '%') ->orWhere('transaction_type', 'like', '%' . $request->search . '%') ->orWhere('amount', 'like', '%' . $request->search . '%') ->orWhere('meta->cheque_number', 'like', '%' . $request->search . '%') ->orWhereHas('user', function ($q) use ($request) { $q->where('name', 'like', '%' . $request->search . '%'); }); }); }) ->latest() ->paginate($request->per_page ?? 20)->appends($request->query()); if ($request->ajax()) { return response()->json([ 'data' => view('business::cheques.datas', compact('cheques'))->render() ]); } return view('business::cheques.index', compact('cheques', 'banks')); } // Deposit cheque public function store(Request $request) { $request->validate([ 'transaction_id' => 'required|exists:transactions,id', 'date' => 'nullable|date', 'note' => 'nullable|string', 'payment_type' => [ 'required', function ($attribute, $value, $fail) { if ($value !== 'cash' && !PaymentType::where('id', $value)->exists()) { $fail(__('The selected payment type is invalid.')); } }, ], ]); $business_id = auth()->user()->business_id; DB::beginTransaction(); try { $transaction = Transaction::findOrFail($request->transaction_id); $amount = $transaction->amount; $platform = strtolower($transaction->platform); $transaction->update([ 'type' => 'deposit', ]); $newTransactionData = [ 'business_id' => $business_id, 'user_id' => auth()->id(), 'type' => 'credit', 'platform' => 'cheque', 'amount' => $amount, 'date' => $request->date ?? now(), 'note' => $request->note, 'meta' => [ 'source_transaction_id' => $request->transaction_id ?? null, ], ]; // Cheque deposited into Cash if ($request->payment_type === 'cash') { $newTransactionData['transaction_type'] = 'cheque_to_cash'; $newTransactionData['payment_type_id'] = null; } else { // Cheque deposited into Bank $toBank = PaymentType::findOrFail($request->payment_type); $toBank->increment('balance', $amount); $newTransactionData['transaction_type'] = 'cheque_to_bank'; $newTransactionData['payment_type_id'] = $toBank->id; } Transaction::create($newTransactionData); // update related platform if ($platform == 'sale') { $sale = Sale::find($transaction->reference_id); updateBalance($amount, 'increment'); $newPaid = $sale->paidAmount + $amount; $expectedTotal = $sale->paidAmount + $sale->dueAmount; $newChange = max($newPaid - $expectedTotal, 0); $newDue = max($sale->dueAmount - $amount, 0); $sale->update([ 'paidAmount' => $newPaid, 'change_amount' => $sale->change_amount + $newChange, 'dueAmount' => $newDue, 'isPaid' => $newDue > 0 ? 0 : 1, ]); // update party due if ($sale->party_id) { $party = Party::find($sale->party_id); if ($party) { $party->decrement('due', min($amount, $party->due)); } } } elseif ($transaction->platform == 'income') { $income = Income::find($transaction->reference_id); $income->increment('amount', $transaction->amount); } elseif ($transaction->platform == 'due_collect'){ $due = DueCollect::find($transaction->reference_id); if ($due) { if ($due->sale_id) { $invoice = Sale::find($due->sale_id); if ($invoice) { $invoice->update([ 'dueAmount' => max($invoice->dueAmount - $amount, 0), ]); } } // Update DueCollect $due->update([ 'dueAmountAfterPay' => max($due->dueAmountAfterPay - $amount, 0), ]); if ($due->party_id) { $party = Party::find($due->party_id); if ($party) { // Reduce customer's due $party->decrement('due', min($amount, $party->due)); // Opening balance reduce (if due type) if ($party->opening_balance_type == 'due') { $party->update([ 'opening_balance' => max(0, $party->opening_balance - $amount), ]); } } } updateBalance($amount, 'increment'); } } DB::commit(); return response()->json([ 'message' => __('Cheque data saved successfully'), 'redirect' => route('business.cheques.index'), ]); } catch (\Exception $e) { DB::rollback(); return response()->json([ 'message' => $e->getMessage() ], 406); } } // Reopen cheque public function reopen(Request $request) { $request->validate([ 'transaction_id' => 'required|exists:transactions,id', ]); DB::beginTransaction(); try { // original cheque payment $originalTxn = Transaction::findOrFail($request->transaction_id); // Must be cheque_payment if ($originalTxn->transaction_type !== 'cheque_payment') { return response()->json(['message' => __('This transaction cannot be reopened.')], 400); } $amount = $originalTxn->amount; $business_id = auth()->user()->business_id; $depositTxn = Transaction::where('platform', 'cheque') ->where('meta->source_transaction_id', $originalTxn->id) ->first(); if (!$depositTxn) { return response()->json(['message' => __('Deposited cheque record not found.')], 400); } // Reverse bank balance only if cheque_to_bank if ($depositTxn->transaction_type === 'cheque_to_bank' && $depositTxn->payment_type_id) { $bank = PaymentType::find($depositTxn->payment_type_id); if ($bank) { $bank->decrement('balance', $amount); } } $platform = strtolower($originalTxn->platform); // Reverse Sale or Income if ($platform == 'sale') { $sale = Sale::find($originalTxn->reference_id); if ($sale) { // Reverse paid, change, and due amounts $newPaid = $sale->paidAmount - $amount; $newDue = $sale->dueAmount + $amount; $newChange = max($sale->change_amount - max($sale->paidAmount - ($sale->paidAmount + $sale->dueAmount - $amount), 0), 0); $sale->update([ 'paidAmount' => max($newPaid, 0), 'change_amount' => max($newChange, 0), 'dueAmount' => $newDue, 'isPaid' => $newDue > 0 ? 0 : 1, ]); // Reverse party due if exists if ($sale->party_id) { $party = Party::find($sale->party_id); if ($party) { $party->increment('due', $amount); } } } } elseif ($platform == 'income') { $income = Income::find($originalTxn->reference_id); if ($income) { $income->decrement('amount', $amount); } } elseif ($platform == 'due_collect') { $due = DueCollect::find($originalTxn->reference_id); if ($due) { if ($due->sale_id) { $invoice = Sale::find($due->sale_id); if ($invoice) { $invoice->update([ 'dueAmount' => $invoice->dueAmount + $amount, ]); } } $due->update([ 'dueAmountAfterPay' => $due->dueAmountAfterPay + $amount, ]); if ($due->party_id) { $party = Party::find($due->party_id); if ($party) { $party->increment('due', $amount); if ($party->opening_balance_type == 'due') { $party->update([ 'opening_balance' => $party->opening_balance + $amount, ]); } } } updateBalance($amount, 'decrement'); } } $reverseType = $depositTxn->transaction_type === 'cheque_to_cash' ? 'cash_to_cheque' : 'bank_to_cheque'; // Create reverse debit transaction Transaction::create([ 'business_id' => $business_id, 'user_id' => auth()->id(), 'type' => 'debit', 'platform' => 'cheque', 'amount' => $amount, 'date' => now(), 'note' => 'Cheque reopened', 'transaction_type' => $reverseType, 'payment_type_id' => $depositTxn->payment_type_id, 'meta' => [ 'reverted_transaction_id' => $depositTxn->id ] ]); $originalTxn->update([ 'type' => 'pending', ]); DB::commit(); return response()->json([ 'message' => __('Cheque reopened successfully'), 'redirect' => route('business.cheques.index'), ]); } catch (\Exception $e) { DB::rollBack(); return response()->json([ 'message' => $e->getMessage() ], 406); } } }