• File: CreditSolicitationController-bkp-26112025.php
  • Full Path: /var/www/imaliapi/app/Http/Controllers/CreditSolicitationController-bkp-26112025.php
  • Date Modified: 11/26/2025 7:07 PM
  • File size: 52.64 KB
  • MIME-type: text/x-php
  • Charset: utf-8
<?php

namespace App\Http\Controllers;

use App\AgregadoFamiliar;
use App\BeginSolicitation;
use App\BemGarantia;
use App\BusinessCreditRequest;
use App\BusinessCreditRequestNew25;
use App\BusinessRequestWarrentyFile;
use App\Classes\ImageUploader;
use App\Classes\SendResponse;
use App\Classes\TransactionGeneration;
use App\DadosNegocio;
use App\DadosSolicitante;
use App\DespesaMensal;
use App\Exports\CreditSolicitation;
use App\Imali\BusinessAccount;
use App\MaritalStatus;
use App\User;
// use Barryvdh\DomPDF\PDF;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Http\Request;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\ValidationException;

class CreditSolicitationController extends Controller
{
    // Create Marital Status
    public function maritalStatus(Request $request)
    {

        $this->validate(
            $request,
            [
                'name' => 'required'
            ],
            [
                'name.required' => 'Campo name é obrigatório'
            ]
        );

        $marital_status = MaritalStatus::create([
            'name' => $request->name
        ]);

        if ($marital_status) return response()->json(['message' => 'Estado Civil salvo com Sucesso']);

        return response()->json(['message' => 'Houve uma falha no registo do Estado Civil', 500]);
    }

    // Create Bem Garantia
    public function bemGarantia(Request $request)
    {

        $this->validate(
            $request,
            [
                'name' => 'required'
            ],
            [
                'name.required' => 'Campo name é obrigatório'
            ]
        );

        $bem_garantia = BemGarantia::create([
            'name' => $request->name
        ]);

        if ($bem_garantia) return response()->json(['message' => 'Bem de Garantia salvo com Sucesso']);

        return response()->json(['message' => 'Houve uma falha no registo do Bem de Garantia', 500]);
    }

    // Create Agregado Familiar
    public function agregadoFamiliar(Request $request)
    {

        $this->validate(
            $request,
            [
                'household' => 'required',
                'family_dependents' => 'required|numeric'
            ],
            [
                'household.required' => 'Campo household é obrigatório',
                'family_dependents.required' => 'Campo family_dependents é obrigatório',
                'family_dependents.numeric' => 'Campo family_dependents é númerico',
            ]
        );

        $bem_garantia = AgregadoFamiliar::create([
            'household' => $request->household,
            'family_dependents' => $request->family_dependents,
            'own_house' => $request->own_house,
            'rented_house' => $request->rented_house
        ]);

        if ($bem_garantia) return response()->json(['message' => 'Dados do agregado Familiar salvos com Sucesso']);

        return response()->json(['message' => 'Houve uma falha no registo dos dados', 500]);
    }

    // Create Despesa Mensal
    public function despesaMensal(Request $request)
    {

        $this->validate(
            $request,
            [
                'food' => 'required|numeric',
                'salary' => 'required|numeric',
                'expenses' => 'required|numeric',
                'employee' => 'required|numeric',
                'transport' => 'required|numeric',
                'education' => 'required|numeric',
                'clothes' => 'required|numeric',
                'health' => 'required|numeric',
                'leisure' => 'required|numeric',

            ],
            [
                'food.required' => 'Campo food é obrigatório',
                'salary.required' => 'Campo salary é obrigatório',
                'expenses.required' => 'Campo expenses é obrigatório',
                'employee.required' => 'Campo employee é obrigatório',
                'transport.required' => 'Campo transport é obrigatório',
                'education.required' => 'Campo education é obrigatório',
                'clothes.required' => 'Campo clothes é obrigatório',
                'health.required' => 'Campo health é obrigatório',
                'leisure.required' => 'Campo leisure é obrigatório',

                'food.numeric' => 'Campo food é númerico',
                'salary.numeric' => 'Campo salary é númerico',
                'expenses.numeric' => 'Campo expenses é númerico',
                'employee.numeric' => 'Campo employee é númerico',
                'transport.numeric' => 'Campo transport é númerico',
                'education.numeric' => 'Campo education é númerico',
                'clothes.numeric' => 'Campo clothes é númerico',
                'health.numeric' => 'Campo health é númerico',
                'leisure.numeric' => 'Campo leisure é númerico',
            ]
        );

        $despesa = DespesaMensal::create([
            'food' => $request->food,
            'salary' => $request->salary,
            'expenses' => $request->expenses,
            'employee' => $request->employee,
            'transport' => $request->transport,
            'education' => $request->education,
            'clothes' => $request->clothes,
            'health' => $request->health,
            'leisure' => $request->leisure,
            'other' => $request->other,
            'other_description' => $request->other_description,
            'total' => $request->total
        ]);

        if ($despesa) return response()->json(['message' => 'Dados de Despesa Mensal salvos com Sucesso']);

        return response()->json(['message' => 'Houve uma falha no registo dos dados', 500]);
    }

    // Create beginSolicitation
    public function beginSolicitation(Request $request)
    {

        $this->validate(
            $request,
            [
                'credit_amount' => 'required|numeric|min:1',
                'duration' => 'required|numeric|min:1',
            ],
            [
                'credit_amount.required' => 'Campo credit_amount é obrigatório',
                'credit_amount.numeric' => 'Campo credit_amount deve ser um número',
                'credit_amount.min' => 'Campo credit_amount deve ser maior que 1',
                'duration.required' => 'Campo duration é obrigatório',
                'duration.numeric' => 'Campo duration deve ser um número',
                'duration.min' => 'Campo duration deve ser maior que 0',
            ]
        );

        $begin_solicitation = BeginSolicitation::create([
            'credit_amount' => $request->credit_amount,
            'duration' => $request->duration,
            'business_account_id'  => $request->business_account_id,
            'preparation_fee'  => $request->preparation_fee,
            'comission'  => $request->comission,
            'fee'  => $request->fee,
            'total_cost_credit'  => $request->total_cost_credit,
            'total_consumer_value'  => $request->total_consumer_value
        ]);

        if ($begin_solicitation) return response()->json(['message' => 'Dados de BeginSolicitation salvos com Sucesso']);

        return response()->json(['message' => 'Houve uma falha no registo dos dados', 500]);
    }

    // Create Dados do Negocio
    public function dadosNegocio(Request $request)
    {

        $this->validate(
            $request,
            [
                'business_address' => 'required',
                'business_accounts_id' => 'required|numeric',
                'activity_type' => 'required|numeric',
                'antiquity' => 'required',
                'current_location_antiquity' => 'required',
                'monthly_income' => 'required'
            ],
            [
                'business_address.required' => 'Campo business_address é obrigatório',
                'business_accounts_id.required' => 'Campo business_accounts_id é obrigatório',
                'business_accounts_id.numeric' => 'Campo business_accounts_id é numeric',
                'activity_type.required' => 'Campo activity_type é obrigatório',
                'activity_type.numeric' => 'Campo activity_type é numeric',
                'antiquity.required' => 'Campo antiquity é obrigatório',
                'current_location_antiquity.required' => 'Campo current_location_antiquity é obrigatório',
                'monthly_income.required' => 'Campo monthly_income é obrigatório',
            ]
        );

        $dados_negocio = DadosNegocio::create([
            'business_address' => $request->business_address,
            'business_accounts_id' => $request->business_accounts_id,
            'activity_type' => $request->activity_type,
            'antiquity' => $request->antiquity,
            'current_location_antiquity' => $request->current_location_antiquity,
            'other_activities' => $request->other_activities,
            'monthly_income' => $request->monthly_income
        ]);

        if ($dados_negocio) return response()->json(['message' => 'Dados do Negocio salvos com Sucesso']);

        return response()->json(['message' => 'Houve uma falha no registo dos dados', 500]);
    }

    // Create Dados do Solicitante
    public function dadosSolicitante(Request $request)
    {
        $error = $this->solicitante_params($request);

        if ($error && $error->getStatusCode() != 200) return $error;

        $dados_negocio = DadosSolicitante::create([
            'name' => $request->name,
            'business_accounts_id' => $request->business_accounts_id,
            'father_name' => $request->father_name,
            'mother_name' => $request->mother_name,
            'marital_status' => $request->marital_status,
            'marital_name' => $request->marital_name,
            'phone' => $request->phone,
            'alternative_phone' => $request->alternative_phone,
            'nuit' => $request->nuit,
            'identity_number' => $request->identity_number,
            'province_id' => $request->province_id,
            'quarter' => $request->quarter,
            'address' => $request->address,
            'agregado_familiars_id' => $request->agregado_familiars_id,
            'despesa_mensals_id' => $request->despesa_mensals_id
        ]);

        if ($dados_negocio) {
            try {
                //code...
                $dados_negocio->bensGarantia()->syncWithPivotValues(
                    $request->bem_garantias_id,
                    ['dados_solicitantes_id' => $dados_negocio->id]
                );
                $dados_negocio->save();

                return response()->json(['message' => 'Dados de Solicitação de Crédito criados com Sucesso'], 200);
            } catch (\Throwable $th) {
                //throw $th;
                return response()->json(['message' => 'Houve uma falha no registo dos dados', 'exception' => $th], 500);
            }
        }
    }

    private function solicitante_params($request)
    {
        try {
            $this->validate(
                $request,
                [
                    'name' => 'required',
                    'business_accounts_id' => 'required',
                    'father_name' => 'required',
                    'mother_name' => 'required',
                    'marital_status' => 'required',
                    'marital_name' => 'required',
                    'phone' => 'required|numeric',
                    'nuit' => 'required|min:9|max:9',
                    'identity_number' => 'required',
                    'province_id' => 'required',
                    // 'quarter' => 'required',
                    'address' => 'required',
                    'agregado_familiars_id' => 'required',
                    'despesa_mensals_id' => 'required',
                    // 'bem_garantias_id' => 'required',

                ],
                [
                    'name.required' => 'Campo name é obrigatório',
                    'business_accounts_id.required' => 'Campo business_accounts_id é obrigatório',
                    'father_name.required' => 'Campo father_name é obrigatório',
                    'mother_name.required' => 'Campo mother_name é obrigatório',
                    'marital_status.required' => 'Campo marital_status é obrigatório',
                    'marital_name.required' => 'Campo marital_name é obrigatório',
                    'phone.required' => 'Campo phone é obrigatório',
                    'phone.numeric' => 'Campo phone é numérico',
                    'nuit.required' => 'Campo nuit é obrigatório',
                    'nuit.min' => 'Campo nuit deve ter 9 carateres',
                    'nuit.max' => 'Campo nuit deve ter 9 carateres',
                    'identity_number.required' => 'Campo identity_number é obrigatório',
                    'province_id.required' => 'Campo province_id é obrigatório',
                    // 'quarter.required' => 'Campo quarter é obrigatório',
                    'address.required' => 'Campo address é obrigatório',
                    'agregado_familiars_id.required' => 'Campo agregado_familiars_id é obrigatório',
                    'despesa_mensals_id.required' => 'Campo despesa_mensals_id é obrigatório',
                    // 'bem_garantias_id.required' => 'Selecione um ou varios bens de garantia',

                ]
            );
        } catch (ValidationException $e) {
            return response()->json([
                'message' => $e->validator->errors()
            ], 422);
        }
    }


    private function dados_negocio_validator($request)
    {
        try {
            $this->validate(
                $request,
                [
                    'antiquity' => 'required',
                    'current_location_antiquity' => 'required',
                    'monthly_income' => 'required'
                ],
                [
                    'antiquity.required' => 'Campo antiquity é obrigatório',
                    'current_location_antiquity.required' => 'Campo current_location_antiquity é obrigatório',
                    'monthly_income.required' => 'Campo monthly_income é obrigatório',
                ]
            );
        } catch (ValidationException $e) {
            return response()->json([
                'message' => $e->validator->errors()
            ], 422);
        }
    }

    private function begin_solicitation_params($request)
    {
        try {
            $this->validate(
                $request,
                [
                    'credit_amount' => 'required|numeric|min:1',
                    'duration' => 'required|numeric|min:1',
                    'preparation_fee' => 'required',
                ],
                [
                    'credit_amount.required' => 'Campo credit_amount é obrigatório',
                    'credit_amount.numeric' => 'Campo credit_amount deve ser um número',
                    'credit_amount.min' => 'Campo credit_amount deve ser maior que 0',
                    'duration.required' => 'Campo duration é obrigatório',
                    'duration.numeric' => 'Campo duration deve ser um número',
                    'duration.min' => 'Campo duration deve ser maior que 0',
                    'preparation_fee.required' => 'Campo preparation_fee é obrigatório',
                ]
            );
        } catch (ValidationException $e) {
            return response()->json([
                'message' => $e->validator->errors()
            ], 422);
        }
    }

    private function business_credit_request_solicitation_params($request)
    {
        try {
            $this->validate(
                $request,
                [
                    'document_type' => 'required|in:MPESA,EMOLA,BANK,DECLARATION,WATER,LIGHT',
                    'document_file' => 'required|file|mimes:jpeg,jpg,png|max:4096',
                    'declaration_market' => 'required|file|mimes:jpeg,jpg,png|max:4096',
                    'photo_market' => 'required|file|mimes:jpeg,jpg,png|max:4096',
                ],
                [
                    'document_type.required' => 'Campo document_type é obrigatório',
                    'document_type.in' => 'document_type só permite os seguintes tipos:MPESA,EMOLA,BANK,DECLARATION,WATER,LIGHT',

                    'document_file.required' => 'Campo document_file é obrigatório',
                    'document_file.file' => 'O campo document_file é um ficheiro',
                    'document_file.mimes' => 'Formato de imagem invalido, formatos permitidos jpeg,jpg,png',
                    'document_file.max' => 'Tamanho máximo permitido para document_file é 4MB',

                    'declaration_market.required' => 'Campo declaration_market é obrigatório',
                    'declaration_market.file' => 'O campo declaration_market é um ficheiro',
                    'declaration_market.mimes' => 'Formato de imagem invalido, formatos permitidos jpeg,jpg,png',
                    'declaration_market.max' => 'Tamanho máximo permitido para declaration_market é 4MB',

                    'photo_market.required' => 'Campo photo_market é obrigatório',
                    'photo_market.file' => 'O campo photo_market é um ficheiro',
                    'photo_market.mimes' => 'Formato de imagem invalido, formatos permitidos jpeg,jpg,png',
                    'photo_market.max' => 'Tamanho máximo permitido para photo_market é 4MB',
                ]
            );
        } catch (ValidationException $e) {
            return response()->json([
                'message' => $e->validator->errors()
            ], 422);
        }
    }


    // METODO FINAL ::.

    // Create AgregadoFamiliar
    private function agregado_familiar($request, $userPayer)
    {
        return AgregadoFamiliar::create([
            'household' => $request->household,
            'family_dependents' => $request->family_dependents,
            // 'own_house' => $request->own_house,
            'residency_type' => $request->residency_type,
            'business_accounts_id' => $userPayer->account_id
        ]);
    }

    // Create Despesa Mensal
    private function despesa_mensal($request, $userPayer)
    {
        $total = collect([
            $request->food,
            $request->rent,
            $request->expenses,
            $request->employee,
            $request->transport,
            $request->education,
            $request->clothes,
            $request->health,
            $request->leisure,
            // $request->other
        ])->filter()->sum();

        return DespesaMensal::create([
            'food' => $request->food,
            'rent' => $request->rent,
            'expenses' => $request->expenses,
            'employee' => $request->employee,
            'transport' => $request->transport,
            'education' => $request->education,
            'clothes' => $request->clothes,
            'health' => $request->health,
            'leisure' => $request->leisure,
            'other' => $request->other,
            'other_description' => $request->other_description,
            'total' => $total, // Soma automática
            'business_accounts_id' => $userPayer->account_id
        ]);
    }

    // Create Dados do Negocio
    private function dados_negocio($request, $userPayer)
    {


        return DadosNegocio::create([
            // 'business_address' => $request->business_address,
            'business_address' => $userPayer->company_address,
            'business_accounts_id' => $userPayer->account_id,
            // 'activity_type' => $request->activity_type,
            'activity_type' => $userPayer->activity_branch,
            'antiquity' => $request->antiquity,
            'current_location_antiquity' => $request->current_location_antiquity,
            'other_activities' => $request->other_activities,
            'monthly_income' => $request->monthly_income
        ]);
    }

    // Create beginSolicitation
    private function dados_begin_solicitation($request, $userPayer)
    {



        return BeginSolicitation::create([
            'credit_amount' => $request->credit_amount,
            'duration' => $request->duration,
            'business_account_id'  => $userPayer->account_id,
            'preparation_fee'  => $request->preparation_fee,
            'comission'  => $request->comission,
            'fee'  => $request->fee,
            'total_cost_credit'  => $request->total_cost_credit,
            'total_consumer_value'  => $request->total_consumer_value
        ]);
    }

    // Create Dados do solicitante
    private function dados_solicitanteOLD($request, $userPayer, $agregado_familiar, $despesa)
    {
        return DadosSolicitante::create([
            // 'name' => $request->name,
            'name' => $userPayer->name . ' ' . $userPayer->last_name,
            'business_accounts_id' => $userPayer->account_id,
            // 'father_name' => $request->father_name,
            'father_name' => $request->father_name,
            'mother_name' => $request->mother_name,
            'marital_status' => $request->marital_status,
            'marital_name' => $request->marital_name,
            // 'phone' => $request->phone,
            'phone' => $userPayer->owner_phone,
            'alternative_phone' => $request->alternative_phone,
            // 'nuit' => $request->nuit,
            'nuit' => $userPayer->company_nuit,
            'identity_number' => $request->identity_number,
            // 'province_id' => $request->province_id,
            'province_id' => $userPayer->country_id,
            'quarter' => $request->quarter,
            'address' => $request->address,
            'agregado_familiars_id' => $agregado_familiar->id, //! REMOVER
            'despesa_mensals_id' => $despesa->id
        ]);

        // $business_credit_request = BusinessCreditRequest::update([
        //     'step' => 2,
        //     'dados_solicitantes_id' => $dados_solicitante->id
        // ]);
    }

    private function dados_solicitante($request, $userPayer, $agregado_familiar, $despesa)
    {
        $dados_solicitante = DadosSolicitante::create([
            // 'name' => $request->name,
            'name' => $userPayer->name . ' ' . $userPayer->last_name,
            'business_accounts_id' => $userPayer->account_id,
            // 'father_name' => $request->father_name,
            'father_name' => $request->father_name,
            'mother_name' => $request->mother_name,
            'marital_status' => $request->marital_status,
            'marital_name' => $request->marital_name,
            // 'phone' => $request->phone,
            'phone' => $userPayer->owner_phone,
            'alternative_phone' => $request->alternative_phone,
            // 'nuit' => $request->nuit,
            // 'nuit' => $userPayer->company_nuit,
            // 'nuit' => $userPayer->business_type === 'INFORMAL' ? $request->nuit : $userPayer->company_nuit, // todo NEW 14.10.2025
            'nuit' => !empty($userPayer->company_nuit) ? $userPayer->company_nuit : $request->nuit,
            'identity_number' => $request->identity_number,
            // 'province_id' => $request->province_id,
            'province_id' => $userPayer->country_id,
            'quarter' => $request->quarter,
            'address' => $request->address,
            'agregado_familiars_id' => $agregado_familiar->id, //! REMOVER
            'despesa_mensals_id' => $despesa->id
        ]);

        // 🔄 Actualizar company_nuit na tabela business_accounts (se estiver vazio)
        if (empty($userPayer->company_nuit) && !empty($dados_solicitante->nuit)) {
            // Garante que estás a atualizar a tabela correta
            $businessAccount = BusinessAccount::find($userPayer->account_id);

            if ($businessAccount) {
                $businessAccount->update([
                    'company_nuit' => $dados_solicitante->nuit,
                ]);
            }
        }

        return $dados_solicitante;
    }

    // Business Credit Solicitation
    private function business_credit_request($request, $userPayer, $dados_negocio, $dados_begin_solicitation)
    {
        // Registar a transacao de transferencia | Envio de Dinheiro
        $random = new TransactionGeneration();
        $transactionReference = $random->generateTransaction();

        $credit_request = BusinessCreditRequest::create([
            'transaction_id' => $transactionReference,
            'credit_reference' => $request->credit_reference,

            'business_accounts_id' => $userPayer->account_id,

            'document_type' => $request->document_type,
            'document_file' => $request->document_file,

            'declaration_market' => $request->declaration_market,
            'photo_market' => $request->photo_market,

            'dados_negocios_id' => $dados_negocio->id,
            'dados_begin_solicitation' => $dados_begin_solicitation->id,
            'step' => 1,
        ]);

        return $credit_request->fresh();
    }

    // Images::.
    private function businessRequestWarrenty($request, $userPayer, $credit_request)
    {
        $new_items = [];
        $img_uploader = new ImageUploader();

        foreach ($request->itens as $index => $item) {

            if (!$request->hasFile('itens.' . $index . '.img')) {

                $item['img'] = $img_uploader->generateImageUrlName25(new Request(['img' => $item['img']]), 'img', 'documentos/', 11);
                // $item['img'] = $img_uploader->generateImageUrlName(new Request(['img' => $item['img']]), 'img');
            } else {
                $item['img'] = $img_uploader->generateImageUrlName25($request, 'itens.' . $index . '.img', 'documentos/', 11);
                // $item['img'] = $img_uploader->generateImageUrlName($request, 'itens.' . $index . '.img');
            }

            $item['business_accounts_id'] = $userPayer->account_id;
            $item['created_at'] = $credit_request->created_at;
            $item['updated_at'] = $credit_request->updated_at;
            unset($item['img_type']);

            array_push($new_items, $item);
        }

        if ($credit_request) {
            try {
                //code...
                $credit_request->items()->sync($new_items);

                return response()->json(['message' => 'Dados registados com sucesso!'], 200);
            } catch (\Throwable $th) {
                //throw $th;
                return response()->json(['message' => 'Erro ao salvar', 'exception' => $th], 500);
            }
        } else {
            return response()->json(['message' => 'Nao pode registar os dados informados ja estao em uso'], 400);
        }
    }


    // METODO DA VERDADE..
    public function business_credit_request_method(Request $request)
    {
        $userPayer = User::getUserAccount();
        if (!$userPayer) return SendResponse::errorResp404notfound('Conta não encontrada', 'Account Not Found');

        $business_request = BusinessCreditRequest::query()
            ->where('business_accounts_id', $userPayer->account_id)
            ->whereNotNull('transaction_id')
            ->where('transaction_id', '!=', '')
            ->whereNotIn('status', ['PENDING', 'UNDER_EVALUATION', 'APPROVED', 'REJECTED'])
            ->first();

        if (!$business_request || !in_array($business_request->step, [1, 2, 3])) {
            // Criar Solicitação
            return $this->businessCreditRequest($request, $userPayer);
        }

        switch ($business_request->step) {
            case 1:
                // Chamar método de step 2;
                return $this->businessCreditRequest2($request, $userPayer);
                break;
            case 2:
                // Chamar método de step 3";
                return $this->businessCreditRequest3($request, $userPayer);
                break;
            case 3:
                // Dados de Registo Finalizados...";
                return $this->businessCreditRequest($request, $userPayer);
            default:
                // Criar novamente
                return $this->businessCreditRequest($request, $userPayer);
                break;
        }
    }
    // METODO DA VERDADE..

    // todo --- STEP 1
    // Create Dados do Solicitante 
    public function businessCreditRequest(Request $request, $userPayer)
    {
        try {
            DB::beginTransaction();

            $error = $this->dados_negocio_validator($request);

            if ($error && $error->getStatusCode() != 200) return $error;

            $dados_negocio = $this->dados_negocio($request, $userPayer); // STEP 1

            $error = $this->begin_solicitation_params($request);

            if ($error && $error->getStatusCode() != 200) return $error;

            $dados_begin_solicitation = $this->dados_begin_solicitation($request, $userPayer); // STEP 1

            $error = $this->business_credit_request_solicitation_params($request);

            if ($error && $error->getStatusCode() != 200) return $error;

            $credit_request = $this->business_credit_request($request, $userPayer, $dados_negocio, $dados_begin_solicitation); // STEP 1

            $this->uploadImages($request, $credit_request);

            DB::commit();

            if ($credit_request) return response()->json(['message' => 'Dados de Solicitação de Crédito criados com Sucesso', 'data' => $credit_request]);
        } catch (\Throwable $th) {
            //throw $th;
            return response()->json(['message' => 'Houve uma falha no registo dos dados' . $th, 500]);
        }
    }


    private function validate_transaction_id($request)
    {
        return $this->validate(
            $request,
            [
                'transaction_id' => 'required'
            ],
            [
                'transaction_id.required' => 'Campo transaction_id é obrigatório. Informe o valor do parametro transaction_id'
            ]
        );
    }

    // todo --- STEP 2
    public function businessCreditRequest2(Request $request, $userPayer)
    {
        $this->validate_transaction_id($request);

        // 👇🏽 Aqui entra a verificação do NUIT
        // if ($userPayer->business_type === 'INFORMAL' && empty($request->nuit)) {
        //     return response()->json([
        //         'info' => false,
        //         'message' => 'O campo NUIT é obrigatório para contas Business informais.'
        //     ], 422);
        // }

        if (!$userPayer->company_nuit && empty($request->nuit)) {
            return response()->json([
                'info' => false,
                'message' => 'O campo NUIT é obrigatório para contas Business informais.'
            ], 422);
        }

        $business_request = BusinessCreditRequest::query()
            ->where('business_accounts_id', $userPayer->account_id)
            ->where('transaction_id', $request->transaction_id)
            ->where('step', 1)
            ->where('status', 'IN_CREATION')
            ->first();

        if (!$business_request) return SendResponse::errorResp404notfound('Solicitação não encontrada', 'Solicitation Not Found');

        try {
            DB::beginTransaction();

            $despesa = $this->despesa_mensal($request, $userPayer); // STEP 2
            $agregado_familiar = $this->agregado_familiar($request, $userPayer); // STEP 2
            $dados_solicitante = $this->dados_solicitante($request, $userPayer, $agregado_familiar, $despesa); // STEP 2

            $business_request->update([
                'step' => 2,
                'dados_solicitantes_id' => $dados_solicitante->id
            ]);

            DB::commit();

            if ($dados_solicitante) return response()->json(['message' => 'Dados de Solicitação de Crédito criados com Sucesso']);
        } catch (\Throwable $th) {

            //throw $th;
            return response()->json(['message' => 'Houve uma falha no registo dos dados' . $th, 500]);
        }
    }

    // todo --- STEP 3
    public function businessCreditRequest3(Request $request, $userPayer)
    {
        $this->validate_transaction_id($request); // STEP 3

        $business_request = BusinessCreditRequest::query()
            ->where('business_accounts_id', $userPayer->account_id)
            ->where('transaction_id', $request->transaction_id)
            ->where('step', 2)
            ->where('status', 'IN_CREATION')
            ->first();

        if (!$business_request) return SendResponse::errorResp404notfound('Solicitação não encontrada', 'Solicitation Not Found');

        try {
            DB::beginTransaction();

            $this->business_credit_params($request);

            $business_warrenty_files = $this->businessRequestWarrenty($request, $userPayer, $business_request);

            $business_request->update([
                'step' => 3,
                'status' => 'PENDING'
            ]);

            DB::commit();

            (new CreditSolicitation($request->transaction_id))->exportPDF();

            if ($business_warrenty_files) return response()->json(['message' => 'Dados de Solicitação de Crédito criados com Sucesso']);
        } catch (\Throwable $th) {

            //throw $th;
            return response()->json(['message' => 'Houve uma falha no registo dos dados' . $th, 500]);
        }
    }

    private function uploadImages($request, $credit_request)
    {
        $img_uploader = new ImageUploader();
        $updateData = [];

        // Lista de campos a serem processados
        $fields = [
            'document_file',
            'declaration_market',
            'photo_market',
            // 'img',
        ];

        foreach ($fields as $field) {
            if ($request->hasFile($field) && !$this->isPdf($request->$field)) {
                $updateData[$field] = $img_uploader->generateImageUrlName25($request, $field, 'documentos/', 11);
                // $updateData[$field] = $img_uploader->generateImageUrlName($request, $field);
            }
        }

        // Apenas atualiza se houver novos dados
        if (!empty($updateData)) {
            $credit_request->update($updateData);
        }

        // 
        // if (!empty($updateData)) {
        //     $business_warrenty_files->update($updateData);
        // }
    }

    private function isPdf($file)
    {
        return strtolower($file->getClientOriginalExtension()) === 'pdf';
    }

    // Imagens
    private function business_credit_params($request)
    {
        $this->validate(
            $request,
            [
                // Os campos abaixo agora são opcionais e não obrigatórios
                'document_file' => 'nullable',
                'itens' => 'required|array',
                'itens.*.item' => 'required|string',
                'itens.*.img_type' => 'required|string|in:base64,file',
                'itens.*.img' => [
                    'required',
                    function ($attribute, $value, $fail) use ($request) {
                        // Extrai o índice do item
                        preg_match('/itens\.(\d+)\.img/', $attribute, $matches);
                        $index = $matches[1] ?? null;
                        $img_type = data_get($request, "itens.$index.img_type");

                        if ($img_type === 'file') {
                            if (!$value instanceof \Illuminate\Http\UploadedFile) {
                                $fail("O campo $attribute deve ser um arquivo.");
                                return;
                            }
                            $ext = strtolower($value->getClientOriginalExtension());
                            if (!in_array($ext, ['jpg', 'jpeg', 'png'])) {
                                $fail("O campo $attribute deve ser um arquivo do tipo: jpg, jpeg, png.");
                            }
                        } elseif ($img_type === 'base64') {
                            if (!is_string($value) || !preg_match('/^data:image\/(png|jpeg|jpg);base64,/', $value)) {
                                $fail("O campo $attribute deve ser uma imagem base64 válida.");
                            }
                        } else {
                            $fail("Tipo de imagem inválido para $attribute.");
                        }
                    },
                ],
            ],

            // 'itens.*.img_file' => 'required_if:itens.*.img_type,file|file|mimes:png,jpeg,jpg',
            // 'itens.*.img_base64' => 'required_if:itens.*.img_type,base64|string',


        );
    }

    public function getbusinessCreditRequest()
    {
        $userPayer = User::getUserAccount();
        if (!$userPayer) return SendResponse::errorResp404notfound('Conta não encontrada', 'Account Not Found');

        $business_request = BusinessCreditRequest::query()
            ->join('dados_negocios', 'dados_negocios.id', 'business_credit_requests.dados_negocios_id')
            ->join('dados_solicitantes', 'dados_solicitantes.id', 'business_credit_requests.dados_solicitantes_id')
            ->join('begin_solicitations', 'begin_solicitations.id', 'business_credit_requests.dados_begin_solicitation')
            ->join('ramo_activities', 'ramo_activities.id', 'dados_negocios.activity_type')
            ->where('business_credit_requests.business_accounts_id', $userPayer->account_id)
            ->select(
                'business_credit_requests.id',
                'business_credit_requests.transaction_id',
                'business_credit_requests.credit_reference',
                'business_credit_requests.status',
                'business_credit_requests.created_at',
                'business_credit_requests.updated_at',
                'dados_solicitantes.name',
                'dados_solicitantes.address',
                'begin_solicitations.fee',
                'begin_solicitations.credit_amount',
                'begin_solicitations.duration',
                'begin_solicitations.preparation_fee',
                'begin_solicitations.comission',
                'begin_solicitations.total_cost_credit',
                'begin_solicitations.total_consumer_value',
                'dados_negocios.business_address',
                'ramo_activities.nome as activity',
            )
            ->orderByDesc('business_credit_requests.created_at')
            ->get();

        if (!$business_request) return SendResponse::errorResp404notfound('Sem dados', 'No data Found');

        return response()->json(['data' => $business_request], 200);
    }

    // IN_CREATION business solicitation data
    public function getInCreationBusinessCreditRequest()
    {
        // return "IN_CREATION business solicitation";

        $userPayer = User::getUserAccount();
        if (!$userPayer) return SendResponse::errorResp404notfound('Conta não encontrada', 'Account Not Found');

        $business_request = BusinessCreditRequest::query()
            ->join('dados_negocios', 'dados_negocios.id', 'business_credit_requests.dados_negocios_id')
            // ->join('dados_solicitantes', 'dados_solicitantes.id', 'business_credit_requests.dados_solicitantes_id')
            ->leftJoin('dados_solicitantes', 'dados_solicitantes.id', 'business_credit_requests.dados_solicitantes_id')
            ->join('begin_solicitations', 'begin_solicitations.id', 'business_credit_requests.dados_begin_solicitation')
            ->join('ramo_activities', 'ramo_activities.id', 'dados_negocios.activity_type')
            ->where('business_credit_requests.business_accounts_id', $userPayer->account_id)
            ->where('business_credit_requests.status', 'IN_CREATION')
            ->select(
                'business_credit_requests.id',
                'business_credit_requests.transaction_id',
                'business_credit_requests.credit_reference',
                'business_credit_requests.status',
                'business_credit_requests.step',
                'dados_solicitantes.name',
                'dados_solicitantes.address',
                'begin_solicitations.fee',
                'begin_solicitations.credit_amount',
                'begin_solicitations.duration',
                'begin_solicitations.preparation_fee',
                'begin_solicitations.comission',
                'begin_solicitations.total_cost_credit',
                'begin_solicitations.total_consumer_value',
                'dados_negocios.business_address',
                'ramo_activities.nome as activity',
                'business_credit_requests.created_at',
                'business_credit_requests.updated_at',
            )
            ->orderByDesc('business_credit_requests.created_at')
            ->get();

        if (!$business_request) return SendResponse::errorResp404notfound('Sem dados', 'No data Found');

        Log::info('[getInCreationBusinessCreditRequest]', ['data' => $business_request]);

        return response()->json(['data' => $business_request], 200);
    }

    public function getbusinessCreditRequestPDF(Request $request)
    {
        // $business_request = BusinessCreditRequest::query()
        //     ->where('transaction_id', $request->transaction_id)
        //     ->orWhere('credit_reference', $request->transaction_id)
        //     ->first();

        // if (!$business_request) return SendResponse::errorResp404notfound('Dados não encontrados', 'Data Not Found');

        // return response()->json(['data' => $business_request], 200);

        // $userPayer = User::getUserAccount();
        // if (!$userPayer) return SendResponse::errorResp404notfound('Conta não encontrada', 'Account Not Found');

        $business_request = BusinessCreditRequest::query()
            ->with('images')
            ->join('dados_negocios', 'dados_negocios.id', 'business_credit_requests.dados_negocios_id')
            ->join('dados_solicitantes', 'dados_solicitantes.id', 'business_credit_requests.dados_solicitantes_id')
            ->join('begin_solicitations', 'begin_solicitations.id', 'business_credit_requests.dados_begin_solicitation')
            ->join('ramo_activities', 'ramo_activities.id', 'dados_negocios.activity_type')
            ->join('agregado_familiars', 'agregado_familiars.id', 'dados_solicitantes.agregado_familiars_id')
            ->join('despesa_mensals', 'despesa_mensals.id', 'dados_solicitantes.despesa_mensals_id')
            // ->where('business_credit_requests.business_accounts_id', $userPayer->account_id)
            ->where('business_credit_requests.transaction_id', $request->transaction_id)
            ->orWhere('business_credit_requests.credit_reference', $request->transaction_id)
            ->select(
                'business_credit_requests.*',
                'dados_solicitantes.name',
                'dados_solicitantes.father_name',
                'dados_solicitantes.mother_name',
                'dados_solicitantes.marital_name',
                'dados_solicitantes.phone',
                'dados_solicitantes.alternative_phone',
                'dados_solicitantes.nuit',
                'dados_solicitantes.identity_number',
                'dados_solicitantes.quarter',
                'dados_solicitantes.address',

                'begin_solicitations.fee',
                'begin_solicitations.credit_amount',
                'begin_solicitations.duration',
                'begin_solicitations.preparation_fee',
                'begin_solicitations.comission',
                'begin_solicitations.total_cost_credit',
                'begin_solicitations.total_consumer_value',

                'agregado_familiars.household',
                'agregado_familiars.family_dependents',
                'agregado_familiars.residency_type',
                'despesa_mensals.food',
                'despesa_mensals.rent',
                'despesa_mensals.expenses',
                'despesa_mensals.employee',
                'despesa_mensals.transport',
                'despesa_mensals.education',
                'despesa_mensals.clothes',
                'despesa_mensals.health',
                'despesa_mensals.leisure',
                'despesa_mensals.other',
                'despesa_mensals.other_description',
                'despesa_mensals.total',
                'dados_negocios.business_address',
                'dados_negocios.current_location_antiquity',
                'dados_negocios.antiquity',
                'dados_negocios.other_activities',
                'dados_negocios.monthly_income',
                'ramo_activities.nome as activity',
            )
            ->orderByDesc('business_credit_requests.created_at');
        // ->get();

        if (!$business_request) return SendResponse::errorResp404notfound('Sem dados', 'No data Found');

        $pdf = Pdf::loadView('pdf.exemplo', ['dados' => $business_request]);

        return $pdf->download('documento.pdf');

        // return response()->json(['data' => $business_request], 200);

    }

    public function getbusinessCreditRequestPDFBKP(Request $request)
    {
        $userPayer = User::getUserAccount();
        if (!$userPayer) return SendResponse::errorResp404notfound('Conta não encontrada', 'Account Not Found');

        $business_request = BusinessCreditRequest::query()
            ->with('images')
            ->join('dados_negocios', 'dados_negocios.id', 'business_credit_requests.dados_negocios_id')
            ->join('dados_solicitantes', 'dados_solicitantes.id', 'business_credit_requests.dados_solicitantes_id')
            ->join('begin_solicitations', 'begin_solicitations.id', 'business_credit_requests.dados_begin_solicitation')
            ->join('ramo_activities', 'ramo_activities.id', 'dados_negocios.activity_type')
            ->join('agregado_familiars', 'agregado_familiars.id', 'dados_solicitantes.agregado_familiars_id')
            ->join('despesa_mensals', 'despesa_mensals.id', 'dados_solicitantes.despesa_mensals_id')
            // ->where('business_accounts_id', $userPayer->id)
            ->where('business_credit_requests.business_accounts_id', $userPayer->account_id)
            ->select(
                'business_credit_requests.*',
                'dados_solicitantes.name',
                'dados_solicitantes.father_name',
                'dados_solicitantes.mother_name',
                'dados_solicitantes.marital_name',
                'dados_solicitantes.phone',
                'dados_solicitantes.alternative_phone',
                'dados_solicitantes.nuit',
                'dados_solicitantes.identity_number',
                'dados_solicitantes.quarter',
                'dados_solicitantes.address',

                'begin_solicitations.fee',
                'begin_solicitations.credit_amount',
                'begin_solicitations.duration',
                'begin_solicitations.preparation_fee',
                'begin_solicitations.comission',
                'begin_solicitations.total_cost_credit',
                'begin_solicitations.total_consumer_value',

                'agregado_familiars.household',
                'agregado_familiars.family_dependents',
                'agregado_familiars.residency_type',
                'despesa_mensals.food',
                'despesa_mensals.rent',
                'despesa_mensals.expenses',
                'despesa_mensals.employee',
                'despesa_mensals.transport',
                'despesa_mensals.education',
                'despesa_mensals.clothes',
                'despesa_mensals.health',
                'despesa_mensals.leisure',
                'despesa_mensals.other',
                'despesa_mensals.other_description',
                'despesa_mensals.total',
                'dados_negocios.business_address',
                'dados_negocios.current_location_antiquity',
                'dados_negocios.antiquity',
                'dados_negocios.other_activities',
                'dados_negocios.monthly_income',
                'ramo_activities.nome as activity',
            )
            ->orderByDesc('business_credit_requests.created_at')
            ->get();

        if (!$business_request) return SendResponse::errorResp404notfound('Sem dados', 'No data Found');

        return response()->json(['data' => $business_request], 200);
    }


public function get_credit_solicitation(Request $request)
{
    $size = $request->per_page ?? 4;

    // Buscar conta da empresa do usuário autenticado
    $business = User::getUserDetails(auth()->user()->user_id);

    if (!$business) {
        return response()->json([
            'status' => false,
            'message' => 'CONTA EMPRESA NÃO ENCONTRADA.'
        ], 404);
    }

    // Verificar se a conta aceita crédito
    if ($business->accept_loans != 1) {
        return response()->json([
            'status' => false,
            'message' => 'A CONTA NÃO ACEITA SOLICITAÇÃO DE CRÉDITO.'
        ], 403);
    }

    // Obter status (padrão: PENDING)
    $status = strtoupper($request->status ?? 'PENDING');

    // Montar query base
    $query = BusinessCreditRequest::query()
        ->join('begin_solicitations', 'begin_solicitations.id', '=', 'business_credit_requests.dados_begin_solicitation')
        ->join('business_accounts', 'business_accounts.id', '=', 'business_credit_requests.business_accounts_id')
        ->join('users', 'users.id', '=', 'business_accounts.user_id')
        ->select([
            'business_credit_requests.id',
            'business_credit_requests.transaction_id',
            'business_credit_requests.credit_reference',
            'business_credit_requests.business_accounts_id',
            'business_credit_requests.document_type',
            'business_credit_requests.document_file',
            'business_credit_requests.declaration_market',
            'business_credit_requests.photo_market',
            'business_credit_requests.dados_begin_solicitation',
            'business_credit_requests.dados_negocios_id',
            'business_credit_requests.dados_solicitantes_id',
            'business_credit_requests.status',
            'business_credit_requests.step',
            'business_credit_requests.rejected_reason',
            'business_credit_requests.created_at',
            'business_credit_requests.updated_at',
            'begin_solicitations.credit_amount as amount',
            'business_accounts.account_number',
            'users.name',
            'users.phone',
            'users.email',
        ])
        ->orderByDesc('business_credit_requests.created_at');

    // Aplicar filtros de status
    if ($status === 'ALL') {
        $query->where('business_credit_requests.status', '!=', 'IN_CREATION');
    } else {
        $query->where('business_credit_requests.status', $status);
    }

    // Filtrar por transaction_id, se fornecido
    if ($request->filled('transaction_id')) {
        $query->where('transaction_id', $request->transaction_id);
    }

    // Paginar resultados
    $solicitations = $query->paginate($size);

    // Retornar resposta formatada
    return response()->json([
        'status' => true,
        'message' => $status === 'ALL'
            ? 'TODAS AS SOLICITAÇÕES DE CRÉDITO.'
            : "SOLICITAÇÕES DE CRÉDITO COM STATUS {$status}.",
        'data' => $solicitations
    ]);
}


    public function get_credit_solicitation03(Request $request)
    {
        $size = $request->per_page ?? 4;

        // Buscar conta da empresa do usuário autenticado
        $business = User::getUserDetails(auth()->user()->user_id);

        if (!$business) {
            return response()->json([
                'status' => false,
                'message' => 'CONTA EMPRESA NÃO ENCONTRADA.'
            ], 404);
        }

        // Verificar se a conta aceita crédito
        if ($business->accept_loans != 1) {
            return response()->json([
                'status' => false,
                'message' => 'A CONTA NÃO ACEITA SOLICITAÇÃO DE CRÉDITO.'
            ], 403);
        }

        // Obter status (padrão: PENDING)
        $status = strtoupper($request->status ?? 'PENDING');

        // Montar query base
        // $query = BusinessCreditRequest::query()
        //     ->select('business_credit_requests.*', 'begin_solicitations.credit_amount')
        //     ->orderByDesc('created_at');

        $query = BusinessCreditRequest::query()
            ->join('begin_solicitations', 'begin_solicitations.id', '=', 'business_credit_requests.dados_begin_solicitation')
            ->select('business_credit_requests.*', 'begin_solicitations.credit_amount as amount')
            ->orderByDesc('business_credit_requests.created_at');

        // Se o status não for "ALL", aplicar filtro de status
        // if ($status !== 'ALL') {
        //     $query->where('status', $status);
        // }

        // Aplicar filtros de status
        if ($status === 'ALL') {
            // Excluir apenas as solicitações com status IN_CREATION
            $query->where('status', '!=', 'IN_CREATION');
        } else {
            // Mostrar apenas as solicitações com o status informado
            $query->where('status', $status);
        }

        // Filtrar opcionalmente por transaction_id
        if ($request->filled('transaction_id')) {
            $query->where('transaction_id', $request->transaction_id);
        }

        // Paginar resultados
        $solicitations = $query->paginate($size);

        // Retornar resposta
        return response()->json([
            'status' => true,
            'message' => $status === 'ALL'
                ? 'TODAS AS SOLICITAÇÕES DE CRÉDITO.'
                : "SOLICITAÇÕES DE CRÉDITO COM STATUS {$status}.",
            'data' => $solicitations
        ]);
    }
}