354 lines
14 KiB
PHP
354 lines
14 KiB
PHP
<?php
|
|
|
|
namespace Modules\Business\App\Http\Controllers;
|
|
|
|
use App\Models\DueCollect;
|
|
use App\Models\Income;
|
|
use App\Models\Party;
|
|
use App\Models\PaymentType;
|
|
use App\Models\Sale;
|
|
use App\Models\Transaction;
|
|
use App\Http\Controllers\Controller;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class AcnooChequeController extends Controller
|
|
{
|
|
public function index(Request $request)
|
|
{
|
|
$business_id = auth()->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);
|
|
}
|
|
}
|
|
}
|