• File: MerchantController.php
  • Full Path: /var/www/imaliapi/app/Http/Controllers/MerchantController.php
  • Date Modified: 01/20/2025 7:03 PM
  • File size: 23.72 KB
  • MIME-type: text/x-php
  • Charset: utf-8
<?php

namespace App\Http\Controllers;

use App\Bank\Payment;
use App\Classes\CurrentPassword;
use App\Classes\TransactionGeneration;
use App\DayCloseStore;
use App\Imali\ImaliAccount;
use App\Imali\MerchantAccount;
use App\PartnerService;
use App\PeriodCloseStore;
use App\Store;
use App\StoreConfig;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;

class MerchantController extends Controller
{
    public function changePassword(Request $request)
    {

        $this->validate(
            $request,
            [
                'current_password' => ['required', new CurrentPassword()],
                'new_password' => ['required', 'min:8', 'confirmed'],
                'new_password_confirmation' => 'required|min:8',
            ],
            [
                'current_password.required' => 'O Campo Senha Actual é Obrigatório',
                'new_password.required' => 'O Campo Nova Senha é Obrigatório',
                'new_password_confirmation.required' => 'O Campo Confirmar Senha é Obrigatório',
                'new_password.confirmed' => 'Senhas incompatíveis',
                'current_password.min' => 'A senha deve ter 8 digitos no mínimo',
                'new_password.min' => 'A senha deve ter 8 digitos no mínimo',
                'new_password_confirmation.min' => 'A senha deve ter 8 digitos no mínimo'
            ]
        );


        if (Hash::check($request->current_password, $request->user()->password)) {

            $request->user()->update([
                'password' => bcrypt($request->new_password),
                'session_status' => 1
            ]);

            return response()->json(['message' => trans('updated_successfully')]);
        } else {
            return response()->json(['message' => trans('invalid_old_password')], 400);
        }
    }


    public function getAccountNumber_OLD(Request $request)
    {

        $query = $request->route('query');
        $perPage = !!$request->input('per_page') ? $request->input('per_page') : 10;
        $orderType = $request->input('order_type') === 'ASC' ? 'ASC' : 'DESC';
        $orderBy = !!$request->input('order_by') && $request->input('order_by') !== 'null' ? $request->input('order_by') : 'imali_accounts.id';

        $users = User::query()
            ->join('imali_accounts', 'users.id', '=', 'imali_accounts.user_id')
            ->join('imali_account_configs', 'imali_account_configs.id', '=', 'imali_accounts.imali_account_config')
            ->where('imali_accounts.account_number', 'like', '%' . $query . '%')
            ->orWhere('users.name', 'like', '%' . $query . '%')
            ->orWhere('users.last_name', 'like', '%' . $query . '%')
            ->orWhere('imali_accounts.reference', 'like', '%' . $query . '%')
            ->orderBy($orderBy, $orderType)
            ->select('imali_accounts.*', 'imali_account_configs.level', 'users.*')
            ->paginate($perPage);

        $imali = $users->setCollection($users->getCollection()
            ->transform(function ($item) {
                $item['last_recharge'] = $item->imaliAccount->recharges()->orderBy('id', 'desc')->first();
                $item['document'] = $item->documents()->where('status', '=', 'actualizado')->orderBy('id', 'desc')->first();
                return $item;
            }));

        $imali->makeHidden([
            'password',
            'pin',
            'imali_account_config',
            'document_id',
            'profile',
            'remember_token',
            'firebase_token'
        ]);

        return response()->json($imali);
    }


    // todo ---- 20 - 01 - 2025
    public function getAccountNumber(Request $request)
    {
        $query = $request->route('query');
        $perPage = !!$request->input('per_page') ? $request->input('per_page') : 10;
        $orderType = $request->input('order_type') === 'ASC' ? 'ASC' : 'DESC';
        $orderBy = !!$request->input('order_by') && $request->input('order_by') !== 'null' ? $request->input('order_by') : 'users.id';


         $users = User::query()
            ->with([
                'imaliAccount' => function ($imali) use ($query) {
                    return $imali->join('imali_account_configs', 'imali_account_configs.id', '=', 'imali_accounts.imali_account_config')
                        ->select(
                            'imali_accounts.*',
                            'imali_account_configs.level'
                        )->get();
                },
                'imaliBusinessAccount' => function ($business) use ($query) {
                    return $business->join('imali_account_configs', 'imali_account_configs.id', '=', 'business_accounts.imali_account_config')
                        ->select(
                            'business_accounts.*',
                            'imali_account_configs.level'
                        )->get();
                },
                'document' => function ($document) {
                    return $document->orderBy('id', 'desc')->get();
                }
            ])
            ->leftJoin('imali_accounts', 'users.id', '=', 'imali_accounts.user_id')
            ->leftJoin('business_accounts', 'users.id', '=', 'business_accounts.user_id')
            ->where('users.name', 'like', '%' . $query . '%')
            ->orWhere('users.last_name', 'like', '%' . $query . '%')
            ->orWhere('imali_accounts.account_number', 'like', '%' . $query . '%')
            ->orWhere('imali_accounts.reference', 'like', '%' . $query . '%')
            ->orWhere('business_accounts.account_number', 'like', '%' . $query . '%')
            ->orWhere('business_accounts.reference', 'like', '%' . $query . '%')
            ->select('users.*')
            ->orderBy($orderBy, $orderType)
            ->paginate($perPage);

        $imali = $users->setCollection($users->getCollection()
            ->transform(function ($user) {
                $combined_accounts = array_merge(
                    $user->imaliAccount ? $user->imaliAccount->toArray() : [],
                    $user->imaliBusinessAccount ? $user->imaliBusinessAccount->toArray() : []
                );

                if ($user->profile === 'client')
                    $user->last_recharge = $user->imaliAccount->recharges()->orderBy('id', 'desc')->first();
                else
                    $user->last_recharge = $user->imaliBusinessAccount->recharges()->orderBy('id', 'desc')->first();
                unset(
                    $user->imaliAccount,
                    $user->imaliBusinessAccount
                );
                $user->imaliAccount = $combined_accounts;
                return $user;
            }));

        $imali->makeHidden([
            'password',
            'pin',
            'imali_account_config',
            'document_id',
            'remember_token',
            'firebase_token'
        ]);

        return response()->json($imali);
    }
    // todo ---- 20 - 01 - 2025


    public function getStoreAccount(Request $request)
    {
        $query = $request->route('query');
        $perPage = !!$request->input('per_page') ? $request->input('per_page') : 10;
        $orderType = $request->input('order_type') === 'ASC' ? 'ASC' : 'DESC';
        $orderBy = !!$request->input('order_by') && $request->input('order_by') !== 'null' ? $request->input('order_by') : 'stores.id';

        $stores = Store::query()
            ->leftJoin('admins', 'admins.id', '=', 'stores.user_id')
            ->leftJoin('ramo_activities', 'ramo_activities.id', '=', 'stores.industry_activity')
            ->leftJoin('merchant_contracts', 'stores.merchant_contract_id', '=', 'merchant_contracts.id')
            ->leftJoin('merchant_accounts', 'stores.merchant_account_id', '=', 'merchant_accounts.id')
            ->where('stores.account_number', 'like', '%' . $query . '%')
            ->orWhere('stores.name', 'like', '%' . $query . '%')
            ->orderBy($orderBy, $orderType)
            ->select(
                'stores.*',
                'ramo_activities.nome as industry',
                'merchant_contracts.taxa',
                'merchant_contracts.max_balance',
                'merchant_contracts.nr_transaction',
                'merchant_contracts.min_amount',
                'merchant_contracts.max_amount',
                'merchant_contracts.use_point_limit',
                'merchant_accounts.name as merchant_name',
                'stores.name as store_name',
                'stores.id as id_store'
            )
            ->paginate($perPage);

        return response()->json($stores);
    }

    public function getMerchantAccount(Request $request)
    {
        $query = $request->route('query');
        $perPage = !!$request->input('per_page') ? $request->input('per_page') : 10;
        $orderType = $request->input('order_type') === 'ASC' ? 'ASC' : 'DESC';
        $orderBy = !!$request->input('order_by') && $request->input('order_by') !== 'null' ? $request->input('order_by') : 'merchant_accounts.id';

        $merchants = MerchantAccount::query()
            ->where('account_number', 'like', '%' . $query . '%')
            ->orWhere('name', 'like', '%' . $query . '%')
            ->orderBy($orderBy, $orderType)
            ->paginate($perPage);

        return response()->json($merchants);
    }

    public function loggedUser(Request $request)
    {
        return response()->json($request->user());
    }

    public function getMerchantDashboard(Request $request)
    {
        //        $dashboard = Payment::query()
        //            ->whereDate('created_at', date('Y-m-d'))
        //            ->sum('amount_credited');

        $amount = Store::query()
            ->join('payments', 'payments.store_id', '=', 'stores.id')
            ->whereDate('payments.created_at', date('Y-m-d'))
            ->where('stores.merchant_account_id', $request->user()->id)
            ->sum('payments.amount');

        //        $amount = Store::query()
        //            ->join('payments', 'payments.store_id', '=', 'stores.id')
        //            ->whereDate('payments.created_at', date('Y-m-d'))
        //            ->where('stores.merchant_account_id', $request->user()->id)
        //            ->count('payments.amount');
        $payments = Payment::query()
            ->join('stores', 'stores.id', '=', 'payments.store_id')
            ->where('stores.merchant_account_id', $request->user()->id)
            ->distinct()
            ->count();

        $amountCredited = Store::query()
            ->join('payments', 'payments.store_id', '=', 'stores.id')
            ->whereDate('payments.created_at', date('Y-m-d'))
            ->where('stores.merchant_account_id', $request->user()->id)
            ->sum('payments.amount_credited');

        $lojas = Store::query()
            ->where('stores.merchant_account_id', $request->user()->id)
            ->count();

        return response()->json([
            'amount' => $amount,
            'amountCredited' => $amountCredited,
            'payments' => $payments,
            'stores' => $lojas
        ]);
    }

    public function getStoreDashboard($storeId)
    {

        $payments = Payment::query()
            ->where('store_id', $storeId)
            ->whereDate('payments.created_at', date('Y-m-d'))
            ->count();


        $amount = Payment::query()
            ->where('store_id', $storeId)
            ->whereDate('payments.created_at', date('Y-m-d'))
            ->sum('amount');

        $amountCredited = Payment::query()
            ->where('store_id', $storeId)
            ->whereDate('payments.created_at', date('Y-m-d'))
            ->sum('amount_credited');


        $comissao = Payment::query()
            ->where('store_id', $storeId)
            ->whereDate('payments.created_at', date('Y-m-d'))
            ->sum('comissao');


        return response()->json([
            'amount' => $amount,
            'amountCredited' => $amountCredited,
            'payments' => $payments,
            'comissao' => $comissao
        ]);
    }

    public function getImaliAccount($accountNumber)
    {
        $account = ImaliAccount::query()
            ->join('users', 'users.id', '=', 'imali_accounts.user_id')
            ->where('imali_accounts.account_number', $accountNumber)
            ->select('users.name', 'imali_accounts.account_number', 'imali_accounts.reference')
            ->first();


        if ($account) {
            return response()->json($account);
        } else {
            return response()->json(['message' => trans('invalid_imali_account')], 400);
        }
    }

    public function getPeridos(Request $request)
    {
        //        $closes = DayCloseStore::query()

        $closes = Store::query()
            ->join('day_close_stores', 'day_close_stores.store_id', '=', 'stores.id')
            ->where('stores.merchant_account_id', $request->user()->id)
            ->select('day_close_stores.*', 'stores.name as store_name', 'stores.account_number')
            ->get();

        return response()->json(['data' => $closes]);
    }

    public function getPeridosLoja(Request $request, $storeId)
    {

        $closes = Store::query()
            ->join('day_close_stores', 'day_close_stores.store_id', '=', 'stores.id')
            ->where('stores.merchant_account_id', $request->user()->id)
            ->where('stores.id', $storeId)
            ->select('day_close_stores.*', 'stores.name as store_name', 'stores.account_number')
            ->get();

        return response()->json(['data' => $closes]);
    }

    public function getPagamentosPeriodoLoja(Request $request, $storeId, $dateReference)
    {
        $payment = Payment::query()
            ->join('stores', 'stores.id', '=', 'payments.store_id')
            ->join('users', 'users.id', '=', 'payments.sender_id')
            ->join('imali_accounts', 'imali_accounts.user_id', '=', 'payments.sender_id')
            ->where('stores.id', $storeId)
            ->whereDate('payments.created_at', $dateReference)
            ->orderByDesc('payments.created_at')
            ->select('payments.*', 'imali_accounts.account_number as imali_account', 'users.name as username')
            ->get();

        return response()->json(['data' => $payment]);
    }

    public function refundCustomer(Request $request)
    {
        $this->validate($request, [
            'transaction' => 'required',
            'amount' => 'required',
            'description' => 'required',
            'account_number' => 'required',
            'merchant_id' => 'required',
            'imali_user_id' => 'required',
            'store_id' => 'required',
            'user_client_id' => 'required',
            'password' => 'required'
        ], [
            'transaction.required' => 'O Campo transaction é de carácter Obrigatório',
            'amount.required' => 'O Campo transaction é de carácter Obrigatório',
            'description.required' => 'O campo description é obrigatório',
            'account_number.required' => 'O campo account_number é obrigatório',
            'merchant_id.required' => 'O campo merchant_id é obrigatório',
            'imali_user_id.required' => 'O campo imali_user_id é obrigatório',
            'store_id.required' => 'O campo imali_user_id é obrigatório',
            'user_client_id.required' => 'O campo imali_user_id é obrigatório',
        ]);
    }

    public function getMerchantStores(Request $request)
    {
        $store = Store::query()
            ->where('stores.merchant_account_id', $request->user()->id)
            ->leftJoin('admins', 'admins.id', '=', 'stores.user_id')
            ->leftJoin('ramo_activities', 'ramo_activities.id', '=', 'stores.industry_activity')
            ->leftJoin('merchant_contracts', 'stores.merchant_contract_id', '=', 'merchant_contracts.id')
            ->join('merchant_accounts', 'stores.merchant_account_id', '=', 'merchant_accounts.id')
            ->select('stores.*', 'admins.name as username', 'ramo_activities.nome as industry', 'merchant_contracts.*', 'merchant_accounts.name as merchant_name', 'stores.name as store_name')
            ->get();

        return response()->json(['data' => $store]);
    }

    public function getAllStores(Request $request)
    {
        $store = Store::query()
            //            ->where('stores.merchant_account_id', $request->user()->id)
            ->leftJoin('admins', 'admins.id', '=', 'stores.user_id')
            ->leftJoin('ramo_activities', 'ramo_activities.id', '=', 'stores.industry_activity')
            ->leftJoin('merchant_contracts', 'stores.merchant_contract_id', '=', 'merchant_contracts.id')
            ->join('merchant_accounts', 'stores.merchant_account_id', '=', 'merchant_accounts.id')
            ->select('stores.name', 'stores.address', 'stores.longitude', 'stores.latitude', 'stores.mobile_phone')
            ->get();

        return response()->json(['data' => $store]);
    }

    public function getPayments(Request $request)
    {
        $payments = Payment::query()->join('users', 'users.id', '=', 'payments.sender_id')
            ->join('stores', 'stores.id', 'payments.store_id')
            ->join('imali_accounts', 'imali_accounts.user_id', 'payments.sender_id')
            ->where('stores.merchant_account_id', $request->user()->id)
            ->orderBy('payments.created_at', 'desc')
            ->select('payments.*', 'users.name as client_name', 'stores.name as merchant_name', 'stores.account_number as merchant_account', 'imali_accounts.account_number as client_account')
            ->get();

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

    public function getPaymentsWithDate(Request $request, $date1, $date2)
    {
        if ($date1 === $date2) {

            $payments = Payment::query()->join('users', 'users.id', '=', 'payments.sender_id')
                ->join('stores', 'stores.id', 'payments.store_id')
                ->join('imali_accounts', 'imali_accounts.user_id', 'payments.sender_id')
                ->where('stores.merchant_account_id', $request->user()->id)
                ->whereDate('payments.created_at', '=', date('y-m-d'))
                ->orderBy('payments.created_at', 'desc')
                ->select('payments.*', 'users.name as client_name', 'stores.name as merchant_name', 'stores.account_number as merchant_account', 'imali_accounts.account_number as client_account')
                ->get();

            return response()->json(['data' => $payments], 200);
        } else {
            $payments = Payment::query()->join('users', 'users.id', '=', 'payments.sender_id')
                ->join('stores', 'stores.id', 'payments.store_id')
                ->join('imali_accounts', 'imali_accounts.user_id', 'payments.sender_id')
                ->where('stores.merchant_account_id', $request->user()->id)
                ->where('payments.created_at', '>=', $date1)
                ->where('payments.created_at', '<=', $date2)
                ->orderBy('payments.created_at', 'desc')
                ->select('payments.*', 'users.name as client_name', 'stores.name as merchant_name', 'stores.account_number as merchant_account', 'imali_accounts.account_number as client_account')
                ->get();

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

    public function getStorePeriods(Request $request, $storeId, $page)
    {
        //        if ($page <= 0)
        //            $page = 10;
        //        elseif ($page == null || $page == "") {
        //            $page = 10;
        //        }
        $transactions = PeriodCloseStore::query()
            ->join('stores', 'stores.id', '=', 'period_close_stores.store_id')
            ->select('period_close_stores.*')
            ->where('period_close_stores.store_id', '=', $storeId)
            ->where('stores.merchant_account_id', '=', $request->user()->id)
            ->where('period_close_stores.status', '=', 'fechado')
            ->orderByDesc('period_close_stores.created_at')
            ->paginate(20);

        $lastPeriod = PeriodCloseStore::query()
            ->leftJoin('stores', 'stores.id', '=', 'period_close_stores.store_id')
            ->select('period_close_stores.*')
            ->where('period_close_stores.store_id', '=', $storeId)
            ->where('stores.merchant_account_id', '=', $request->user()->id)
            ->get()->last();

        $storeConfig = StoreConfig::query()
            ->where('store_id', '=', $storeId)
            ->first();


        if ($storeConfig) {
            $storeConfig->makeHidden(['id', 'store_id']);

            if (!$lastPeriod) {
                return response()->json(['data' => $transactions, 'lastPeriod' => null, 'storeConfig' => $storeConfig]);
            } else {
                return response()->json(['data' => $transactions, 'lastPeriod' => $lastPeriod, 'storeConfig' => $storeConfig]);
            }
        } else {
            if (!$lastPeriod) {
                return response()->json(['data' => $transactions, 'lastPeriod' => null, 'storeConfig' => null]);
            } else {
                return response()->json(['data' => $transactions, 'lastPeriod' => $lastPeriod, 'storeConfig' => null]);
            }
        }
    }

    public function getPeriodTransactions(Request $request, $storeId, $date1, $date2)
    {

        $payment = Payment::query()
            ->join('stores', 'stores.id', '=', 'payments.store_id')
            ->join('users', 'users.id', '=', 'payments.sender_id')
            ->join('imali_accounts', 'imali_accounts.user_id', '=', 'payments.sender_id')
            ->where('stores.merchant_account_id', '=', $request->user()->id)
            ->where('stores.id', '=', $storeId)
            ->where('payments.created_at', '>=', $date1)
            ->where('payments.created_at', '<=', $date2)
            ->orderByDesc('payments.created_at')
            ->select('payments.*', 'imali_accounts.account_number as imali_account', 'users.name as username')
            ->get();

        return response()->json(['data' => $payment]);
    }

    // Create Partner Services - - - - - - - - - - - - - - - - - - - - - - - -
    public function createPartnerServices(Request $request)
    {

        $this->validate(
            $request,
            [
                'service_name' => 'required',
                'description' => 'required',
                'service_type' => 'required'
            ],
            [
                'startservice_name_date.required' => 'Campo service_name e obrigatorio',
                'description.required' => 'Campo description e obrigatorio',
                'service_type.required' => 'Campo service_type e obrigatorio'
            ]
        );

        $cycle = new PartnerService();
        $cycle->service_key = Str::orderedUuid();
        $cycle->service_name = $request->service_name;
        $cycle->description = $request->description;
        $cycle->service_type = $request->service_type;
        $cycle->save();

        if ($cycle) {
            try {
                return response()->json(['message' => 'Registado com sucesso!'], 200);
            } catch (\Exception $e) {
                return response()->json(['message' => 'Erro ao salvar', 'exception' => $e], 500);
            }
        } else {
            return response()->json(['message' => 'Nao pode registar os dados informados ja estao em uso'], 400);
        }
    }

    // get Cycle list
    public function getPartnerServices()
    {
        $partnerService = PartnerService::all();

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