HEX
Server: LiteSpeed
System: Linux s3.sitechai.com 4.18.0-553.51.1.lve.1.el8.x86_64 #1 SMP Wed May 14 14:34:57 UTC 2025 x86_64
User: workzeni (2217)
PHP: 8.1.32
Disabled: mail, show_source, system, shell_exec, passthru, exec, eval, shell
Upload Files
File: /home/workzeni/agency-erp-05.workzenix.com/app/Http/Controllers/FundTransferController.php
<?php

namespace App\Http\Controllers;

use App\Models\CompanyInfo;
use App\Models\FundTreansfer;
use App\Models\TransactionHistory;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

class FundTransferController extends Controller
{
    public function fundTransferList()
    {
        $agencies = CompanyInfo::latest()->get();

        $fundTransfers = FundTreansfer::orderBy('status', 'asc')
            ->orderBy('created_at', 'desc')
            ->get();

        return view('admin.fund_transfer.list', compact('fundTransfers', 'agencies'));
    }

    public function fundTransferStore(Request $request)
    {
        $validated = $request->validate([
            'agency_id' => 'required|exists:company_infos,id',
            'bdt_amount' => 'required|numeric|min:0',
            'currency_rate' => 'required|numeric|min:0',
            'sar_amount' => 'required|numeric|min:0',
            'transaction_id' => 'required|string|max:255',
            'transferred_date' => 'required|date',
            'proof' => 'required|file|mimes:jpg,jpeg,png,pdf',
            'additional' => 'nullable|string|max:1000',
            'status' => 'required|in:0,1,2',
        ]);

        // Handle proof file upload with unique name
        $proofFile = $request->file('proof');
        $proofPath = $proofFile->storeAs(
            'fund_transfer',
            Str::uuid().'.'.$proofFile->getClientOriginalExtension(),
            'public'
        );

        if (! $proofPath) {
            $errorMessage = 'Failed to upload proof file.';

            return $request->ajax()
                ? response()->json(['success' => false, 'message' => $errorMessage], 500)
                : redirect()->back()->with('error', $errorMessage);
        }

        DB::beginTransaction();

        $agency = CompanyInfo::findOrFail($validated['agency_id']);

        // Check BDT balance if status is approved
        if ((int) $validated['status'] === FundTreansfer::STATUS_APPROVED && $validated['bdt_amount'] > $agency->bdt_acct) {
            throw new \Exception('Insufficient BDT balance for this transfer.');
        }

        $approvedBy = null;
        if ((int) $validated['status'] === FundTreansfer::STATUS_APPROVED && in_array(auth()->user()->role, [1, 2, 3])) {
            $approvedBy = auth()->id();
        }

        // Create fund transfer record
        $fund = FundTreansfer::create([
            'agency_id' => $validated['agency_id'],
            'user_id' => auth()->id(),
            'bdt_amount' => $validated['bdt_amount'],
            'currency_rate' => $validated['currency_rate'],
            'sar_amount' => $validated['sar_amount'],
            'transaction_id' => $validated['transaction_id'],
            'transferred_date' => $validated['transferred_date'],
            'proof' => $proofPath,
            'additional' => $validated['additional'],
            'status' => $validated['status'],
            'approved_by' => $approvedBy,
        ]);

        // If approved and user has permission
        $checkTransfer = TransactionHistory::where('source_table', 'fund_transfers')
            ->where('source_id', $fund->id)
            ->exists();
        if ((int) $validated['status'] === FundTreansfer::STATUS_APPROVED && in_array(auth()->user()->role, [1, 2, 3]) && $checkTransfer === false) {
            $oldBdtBalance = $agency->bdt_acct;
            $oldSarBalance = $agency->sar_acct;
            $newBdtBalance = $oldBdtBalance - $validated['bdt_amount'];
            $newSarBalance = $oldSarBalance + $validated['sar_amount'];

            // Transaction: Deduct BDT
            TransactionHistory::create([
                'agency_id' => $agency->id,
                'source_table' => 'fund_transfers',
                'source_id' => $fund->id,
                'tnx_type' => 'Transfer Out',
                'currency' => 'BDT',
                'amount' => $validated['bdt_amount'],
                'old_balance' => $oldBdtBalance,
                'new_balance' => $newBdtBalance,
                'note' => 'Fund Transfer Approved: Deducted '.$validated['bdt_amount'].' BDT for transfer to SAR. Approved by '.auth()->user()->name,
                'created_at' => $validated['transferred_date'] ?? now(),
            ]);

             // Transaction: Add SAR
            TransactionHistory::create([
                'agency_id' => $agency->id,
                'source_table' => 'fund_transfers',
                'source_id' => $fund->id,
                'tnx_type' => 'Transfer In',
                'currency' => 'SAR',
                'amount' => $validated['sar_amount'],
                'old_balance' => $oldSarBalance,
                'new_balance' => $newSarBalance,
                'note' => 'Fund Transfer Approved: Converted '.$validated['bdt_amount'].' BDT to '.$validated['sar_amount'].' SAR. Approved by '.auth()->user()->name,
                'created_at' => $validated['transferred_date'] ?? now(),
            ]);

            // Update balances
            $agency->bdt_acct = $newBdtBalance;
            $agency->sar_acct = $newSarBalance;
            $agency->save();

            // Update approver
            $fund->approved_by = auth()->id();
            $fund->save();
        }

        DB::commit();

        $fund->load('agency');

        return $request->ajax()
            ? response()->json([
                'success' => true,
                'message' => 'Fund Transfer added successfully.',
                'fundTransfer' => $fund,
            ])
            : redirect()->back()->with('success', 'Fund Transfer added successfully.');
    }

    public function fundTransferShow($id)
    {
        $fundTransfer = FundTreansfer::findOrFail($id);

        return view('admin.fund_transfer.show', compact('fundTransfer'));
    }

    public function fundTransferEdit($id)
    {
        $agencies = CompanyInfo::latest()->get();
        $fundTransfer = FundTreansfer::findOrFail($id);

        return view('admin.fund_transfer.edit', compact('fundTransfer', 'agencies'));
    }

    public function fundTransferUpdate(Request $request, $id)
    {
        $fundTransfer = FundTreansfer::findOrFail($id);

        // ✅ Step 1: Validate the request
        $validated = $request->validate([
            'agency_id' => 'required|exists:company_infos,id',
            'bdt_amount' => 'required|numeric|min:0',
            'currency_rate' => 'required|numeric|min:0',
            'sar_amount' => 'required|numeric|min:0',
            'transaction_id' => 'required|string|max:255',
            'transferred_date' => 'required|date',
            'additional' => 'nullable|string',
            'status' => 'required|in:0,1,2',
            'proof' => 'nullable|file|mimes:jpg,jpeg,png,pdf|max:2048',
        ]);

        $checkTransfer = TransactionHistory::where('source_table', 'fund_transfers')
            ->where('source_id', $fundTransfer->id)
            ->exists();

        // ✅ Step 2: Handle proof file upload
        if ($request->hasFile('proof')) {
            if ($fundTransfer->proof && Storage::disk('public')->exists($fundTransfer->proof)) {
                Storage::disk('public')->delete($fundTransfer->proof);
            }
            $proofPath = $request->file('proof')->store('fund_transfer', 'public');
            if (! $proofPath) {
                $errorMessage = 'Failed to upload proof file.';

                return $request->ajax()
                    ? response()->json(['success' => false, 'message' => $errorMessage], 500)
                    : redirect()->back()->with('error', $errorMessage);
            }
            $fundTransfer->proof = $proofPath;
        }

        // ✅ Step 3: Handle approval status & balance adjustment
        $oldStatus = (int) $fundTransfer->status;
        $newStatus = (int) $validated['status'];

        if (in_array(auth()->user()->role, [1, 2, 3])) {
            if ($newStatus === 1 && $oldStatus !== 1) {
                // balance check
                $agency = CompanyInfo::find($validated['agency_id']);

                // check balance
                if ($validated['bdt_amount'] > $agency->bdt_acct) {
                    return $request->ajax()
                        ? response()->json(['success' => false, 'message' => 'Insufficient BDT balance for this transfer.'], 400)
                        : redirect()->back()->with('error', 'Insufficient BDT balance for this transfer.');
                }

                $oldBDTBalance = $agency->bdt_acct;
                $newBdtBalance = $oldBDTBalance - $validated['bdt_amount'];
                $oldSARBalance = $agency->sar_acct;
                $newSarBalance = $oldSARBalance + $validated['sar_amount'];
                // Create transaction history
                if ($checkTransfer) {
                    return $request->ajax()
                        ? response()->json(['success' => false, 'message' => 'This fund transfer has already been approved and recorded in transaction history.'], 400)
                        : redirect()->back()->with('error', 'This fund transfer has already been approved and recorded in transaction history.');
                }

                // Transaction: Deduct BDT
                TransactionHistory::create([
                    'agency_id' => $agency->id,
                    'source_table' => 'fund_transfers',
                    'source_id' => $fundTransfer->id,
                    'tnx_type' => 'Transfer Out',
                    'currency' => 'BDT',
                    'amount' => $validated['bdt_amount'],
                    'old_balance' => $oldBDTBalance,
                    'new_balance' => $newBdtBalance,
                    'note' => 'Fund Transfer Approved: Deducted '.$validated['bdt_amount'].' BDT for transfer to SAR. Approved by '.auth()->user()->name,
                    'created_at' => $validated['transferred_date'] ?? now(),
                ]);

                // Transaction: Add SAR
                TransactionHistory::create([
                    'agency_id' => $agency->id,
                    'source_table' => 'fund_transfers',
                    'source_id' => $fundTransfer->id,
                    'tnx_type' => 'Transfer In',
                    'currency' => 'SAR',
                    'amount' => $validated['sar_amount'],
                    'old_balance' => $oldSARBalance,
                    'new_balance' => $newSarBalance,
                    'note' => 'Fund Transfer Approved: Converted '.$validated['bdt_amount'].' BDT to '.$validated['sar_amount'].' SAR. Approved by '.auth()->user()->name,
                    'created_at' => $validated['transferred_date'] ?? now(),
                ]);

                

                // Approved -> Deduct BDT, Add SAR
                if ($agency) {
                    $agency->bdt_acct = $newBdtBalance;
                    $agency->sar_acct = $newSarBalance;
                    $agency->save();
                }
                $fundTransfer->approved_by = auth()->id();
            } elseif (in_array($newStatus, [0, 2]) && $oldStatus === 1) {
                // Revert approved balances
                $agency = CompanyInfo::find($fundTransfer->agency_id);
                // Revert balances
                $oldBdtBalance = $agency->bdt_acct;
                $newBdtBalance = $oldBdtBalance + $fundTransfer->bdt_amount;
                $oldSarBalance = $agency->sar_acct;
                $newSarBalance = $oldSarBalance - $fundTransfer->sar_amount;

                // delete transaction histories related to this fund transfer
                TransactionHistory::where('source_table', 'fund_transfers')
                    ->where('source_id', $fundTransfer->id)
                    ->delete();

                if ($agency) {
                    $agency->bdt_acct = $newBdtBalance;
                    $agency->sar_acct = $newSarBalance;
                    $agency->save();
                }
                $fundTransfer->approved_by = null;
            }
        } elseif ($newStatus !== $oldStatus) {
            return $request->ajax()
                ? response()->json(['success' => false, 'message' => 'You are not authorized to change the status.'], 403)
                : redirect()->back()->with('error', 'You are not authorized to change the status.');
        }

        // ✅ Step 4: Update fund transfer record
        $fundTransfer->agency_id = $validated['agency_id'];
        $fundTransfer->bdt_amount = $validated['bdt_amount'];
        $fundTransfer->currency_rate = $validated['currency_rate'];
        $fundTransfer->sar_amount = $validated['sar_amount'];
        $fundTransfer->transaction_id = $validated['transaction_id'];
        $fundTransfer->transferred_date = $validated['transferred_date'];
        $fundTransfer->additional = $validated['additional'];
        $fundTransfer->status = $validated['status'];

        $fundTransfer->save();
        $fundTransfer->load('agency');

        // ✅ Step 5: Return response
        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'message' => 'Fund Transfer updated successfully.',
                'fundTransfer' => $fundTransfer,
            ]);
        }

        return redirect()->back()->with('success', 'Fund Transfer updated successfully.');
    }
}