• File: StoreController.php
  • Full Path: /var/www/imaliapi/app/Http/Controllers/StoreController.php
  • Date Modified: 09/16/2024 1:54 AM
  • File size: 27.96 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\MerchantContract;
use App\ImaliSubAccount;
use App\Store;
use App\StoreDevice;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Http;
use Webpatser\Uuid\Uuid;

class StoreController extends Controller
{

    public function changePassword(Request $request)
    {

        $this->validate(
            $request,
            [
                'new_password' => ['required', 'min:8', 'confirmed'],
                'new_password_confirmation' => 'required|min:8',
            ],
            [

                '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',
                '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->new_password, $request->user()->password)) {

            return response()->json(['message' => 'Não deve usar a senha anterior'], 400);
        } else {
            $request->user()->update([
                'password' => bcrypt($request->new_password),
                'session_status' => 1
            ]);

            return response()->json(['message' => 'Senha Actualizada Com Sucesso!'], 200);
        }
    }

    public function getStoreTransactions($id)
    {
        $payments = Payment::query()
            ->join('users', 'users.id', '=', 'payments.sender_id')
            ->join('stores', 'stores.id', '=', 'payments.store_id')
            ->where('payments.store_id', $id)
            ->select('payments.*', 'users.name as client', 'stores.name as store_name')
            ->get();

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

    public function getUser(Request $request)
    {

        $store = Store::query()
            ->join('merchant_accounts', 'merchant_accounts.id', '=', 'stores.merchant_account_id')
            ->join('ramo_activities', 'ramo_activities.id', '=', 'stores.industry_activity')
            ->leftJoin('store_devices', 'store_devices.store_id', '=', 'stores.id')
            ->where('stores.id', $request->user()->id)
            ->select(
                'merchant_accounts.institution as institution_name',
                'ramo_activities.nome as industry',
                'ramo_activities.nome as category',
                'ramo_activities.logo as logo_category',
                'stores.*',
                'stores.name as institution',
                'store_devices.device_name as storeDeviceName',
                'store_devices.status as storeDeviceStatus',
                'store_devices.firebase_token as storeDeviceFirebaseToken'
            )
            ->first();

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

    public function getUserStore(Request $request)
    {
        $store = Store::query()
            ->leftJoin('merchant_accounts', 'merchant_accounts.id', '=', 'stores.merchant_account_id')
            ->join('ramo_activities', 'ramo_activities.id', '=', 'stores.industry_activity')
            ->leftJoin('store_devices', 'store_devices.store_id', '=', 'stores.id')
            // ->where('stores.id', $request->user()->id)
            ->where('stores.id', $request->store_id)
            ->select(
                'merchant_accounts.institution as institution_name',
                'ramo_activities.nome as industry',
                'ramo_activities.nome as category',
                'ramo_activities.logo as logo_category',
                'stores.*',
                'stores.name as institution',
                'store_devices.device_name as storeDeviceName',
                'store_devices.status as storeDeviceStatus',
                'store_devices.firebase_token as storeDeviceFirebaseToken'
            )
            ->first();

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

    public function getTransactions($id)
    {
        $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')
            ->leftJoin('store_configs', 'store_configs.store_id', '=', 'payments.store_id')
            ->where('stores.id', '=', $id)
            ->whereDate('payments.created_at', '=', date('Y-m-d'))
            ->orderByDesc('payments.created_at')
            ->select('payments.*', 'imali_accounts.account_number as imali_account', 'users.name as username', 'store_configs.use_refund', 'store_configs.use_period')
            ->take(5)
            ->get();

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

    public function getTransactionsStore(Request $request)
    {

        $size = $request->per_page ?? 5;

        $payment = Payment::query()
            ->join('stores', 'stores.id', 'payments.store_id')
            ->where('stores.id', $request->store_id)
            ->whereDate('payments.created_at', date('Y-m-d'))
            ->orderByDesc('payments.created_at')
            ->select(
                'payments.id',
                'payments.transaction_id as reference',
                'payments.source as serviceName',
                'payments.sender_account_number as clientNumber',
                'payments.amount as amount',
                'payments.created_at as date',
                'payments.estado as status'
            )
            // ->take(5)
            // ->get();
            ->paginate($size);

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

    // todo -- 15-Setembro-2024
    public function subAccountReport()
    {
        $subaccounts = ImaliSubAccount::query()
            ->leftJoin('users', 'users.id', 'imali_sub_accounts.user_id')
            ->select('imali_sub_accounts.*', 'users.email', 'users.name as username')
            ->where('balance', '<=', 300)
            ->get();

        foreach ($subaccounts as $subaccount) {
            $message = 'Sr/a ' . $subaccount->username . ' a tua subconta '
                . $subaccount->name . ' de número ' . $subaccount->card_number . ' está com saldo ' . $subaccount->balance . ', abaixo de 300MZN. Por favor recarregue para evitar questões de dívida.';

            $is_sent = $this->sendEmail([$subaccount->email], $message);
            if ($is_sent) continue;
        }
        return response()->json(['message' => 'Email enviado com sucesso.']);
    }

    protected $portAppNotification = 3001;

    // todo -- 15-Setembro-2024
    private function sendEmail($emails, $message)
    {
        $response = Http::post('http://localhost:' . $this->portAppNotification . '/api/send/email', [
            'messageType' => 'text',
            'to' => $emails,
            'from' => 'ivo.naftal@paytek-africa.com',
            'subject' => 'Aviso de Saldo',
            'message' => $message,
        ]);

        if ($response->status() == 200) {
            return true;
        } else {
            return false;
        }
    }

    public function getPeriodTransactions(Request $request, $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.id', '=', $request->user()->id)
            ->where('payments.created_at', '>=', $date1)
            ->where('payments.created_at', '<=', $date2)
            //            ->whereDate('payments.created_at', '>=',$date1)
            //            ->whereDate('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]);
    }

    public function getPeriodTransactionsMerchant($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.id', '=', $storeId)
            ->where('payments.created_at', '>=', $date1)
            ->where('payments.created_at', '<=', $date2)
            //            ->whereDate('payments.created_at', '>=',$date1)
            //            ->whereDate('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]);
    }

    public function getAllTransactions(Request $request)
    {

        $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', $request->user()->id)
            ->whereDate('payments.created_at', date('Y-m-d'))
            ->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 getClosedTransactions(Request $request)
    {

        $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', $request->user()->id)
            ->whereDate('payments.created_at', $request->date_reference)
            ->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 getDashboard($id)
    {
        $payment = Payment::query()
            ->join('stores', 'stores.id', '=', 'payments.store_id')
            ->where('stores.id', $id)
            ->whereDate('payments.created_at', date('Y-m-d'))
            ->count();

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

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

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

    public function getDailyDashboard(Request $request)
    {
        $payment = Payment::query()
            ->join('stores', 'stores.id', '=', 'payments.store_id')
            ->where('stores.id', '=', $request->user()->id)
            ->where('payments.payment_type', '=', 'directo')
            ->whereDate('payments.created_at', date('Y-m-d'))
            ->count();

        $countRefund = Payment::query()
            ->join('stores', 'stores.id', '=', 'payments.store_id')
            ->where('stores.id', '=', $request->user()->id)
            ->where('payments.payment_type', '=', 'reembolso')
            ->whereDate('payments.created_at', date('Y-m-d'))
            ->count();

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

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

        $commission = Payment::query()
            ->join('stores', 'stores.id', '=', 'payments.store_id')
            ->where('stores.id', '=', $request->user()->id)
            ->where('payments.payment_type', '=', 'directo')
            ->whereDate('payments.created_at', date('Y-m-d'))
            ->sum('payments.comissao');

        $feeRefund = Payment::query()
            ->join('stores', 'stores.id', '=', 'payments.store_id')
            ->where('stores.id', '=', $request->user()->id)
            ->where('payments.payment_type', '=', 'reembolso')
            ->whereDate('payments.created_at', date('Y-m-d'))
            ->sum('payments.comissao');

        return response()->json([
            'amount' => $amount,
            'payments' => $payment,
            'commission' => $commission,
            'amountRefund' => $amountRefund,
            'feeRefund' => $feeRefund,
            'refunds' => $countRefund
        ]);
    }

    public function getDashboard2(Request $request)
    {
        $payment = Payment::query()
            ->join('stores', 'stores.id', '=', 'payments.store_id')
            ->where('stores.id', $request->user()->id)
            ->whereDate('payments.created_at', $request->date_reference)
            ->count();

        $amount = Payment::query()
            ->join('stores', 'stores.id', '=', 'payments.store_id')
            ->where('stores.id', $request->user()->id)
            ->whereDate('payments.created_at', $request->date_reference)
            ->sum('payments.amount');

        $comissao = Payment::query()
            ->join('stores', 'stores.id', '=', 'payments.store_id')
            ->where('stores.id', $request->user()->id)
            ->whereDate('payments.created_at', $request->date_reference)
            ->sum('payments.comissao');

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

    public function getStoreDayCloses(Request $request)
    {
        $transactions = DayCloseStore::query()
            ->join('stores', 'stores.id', '=', 'day_close_stores.store_id')
            ->select('day_close_stores.*')
            ->where('day_close_stores.store_id', $request->user()->id)
            ->orderByDesc('day_close_stores.created_at')
            ->get();

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

    public function getStoreCloses($store_id)
    {
        $transactions = DayCloseStore::query()
            ->join('stores', 'stores.id', '=', 'day_close_stores.store_id')
            ->select('day_close_stores.*', 'stores.name as store_name')
            ->where('day_close_stores.store_id', $store_id)
            ->orderByDesc('day_close_stores.created_at')
            ->get();

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

    public function getAdminStoresCloses($date1, $date2)
    {
        if ($date1 === 'null' || $date2 === 'null') {

            $transactions = DayCloseStore::query()
                ->join('stores', 'stores.id', '=', 'day_close_stores.store_id')
                ->select('day_close_stores.*', 'stores.name as store_name')
                ->orderByDesc('day_close_stores.created_at')
                ->get();

            return response()->json(['data' => $transactions]);
        } else {

            if ($date1 == $date2) {

                $transactions = DayCloseStore::query()
                    ->join('stores', 'stores.id', '=', 'day_close_stores.store_id')
                    ->select('day_close_stores.*', 'stores.name as store_name')
                    ->whereDate('day_close_stores.created_at', $date1)
                    ->orderByDesc('day_close_stores.created_at')
                    ->get();

                return response()->json(['data' => $transactions]);
            } else {
                $transactions = DayCloseStore::query()
                    ->join('stores', 'stores.id', '=', 'day_close_stores.store_id')
                    ->select('day_close_stores.*', 'stores.name as store_name')
                    ->whereDate('day_close_stores.created_at', '>=', $date1)
                    ->whereDate('day_close_stores.created_at', '<=', $date2)
                    ->orderByDesc('day_close_stores.created_at')
                    ->get();

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

    public function getStoresCloses(Request $request)
    {
        $transactions = DayCloseStore::query()
            ->join('stores', 'stores.id', '=', 'day_close_stores.store_id')
            ->select('day_close_stores.*')
            ->orderByDesc('day_close_stores.created_at')
            ->get();

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

    public function getChartDashboard(Request $request)
    {
        //        $amount  = Payment::query()
        //            ->join('stores', 'stores.id', '=', 'payments.store_id')
        //            ->where('stores.id', $request->user()->id)
        ////            ->whereDate('payments.created_at', date('Y-m-d'))
        //            ->where('payments.created_at', 1)
        //            ->sum('payments.amount');

        $amount = Payment::query()
            ->join('stores', 'stores.id', '=', 'payments.store_id')
            ->where('stores.id', 1)
            //            ->whereDate('payments.created_at', date('Y-m-d'))
            ->whereDay('payments.created_at', 22)
            ->sum('payments.amount');

        $weekMap = [
            0 => 'SU',
            1 => 'MO',
            2 => 'TU',
            3 => 'WE',
            4 => 'TH',
            5 => 'FR',
            6 => 'SA',
        ];
        $dayOfTheWeek = Carbon::now()->dayOfWeek;
        $weekday = $weekMap[$dayOfTheWeek];

        $records = Payment::all();
        $filteredArraySunday = array();
        $filteredArrayMonday = array();
        $filteredArrayTusday = array();
        $filteredArrayWenesday = array();
        $filteredArrayThusday = array();
        $filteredArrayFriday = array();
        $filteredArraySaturday = array();

        foreach ($records as $record) {
            if (Carbon::parse($record->created_at)->dayOfWeek == Carbon::SUNDAY) {
                $filteredArraySunday[] = $record;
            }
            if (Carbon::parse($record->created_at)->dayOfWeek == Carbon::MONDAY) {
                $filteredArrayMonday[] = $record;
            }
            if (Carbon::parse($record->created_at)->dayOfWeek == Carbon::TUESDAY) {
                $filteredArrayTusday[] = $record;
            }
            if (Carbon::parse($record->created_at)->dayOfWeek == Carbon::WEDNESDAY) {
                $filteredArrayWenesday[] = $record;
            }
            if (Carbon::parse($record->created_at)->dayOfWeek == Carbon::THURSDAY) {
                $filteredArrayThusday[] = $record;
            }
            if (Carbon::parse($record->created_at)->dayOfWeek == Carbon::FRIDAY) {
                $filteredArrayFriday[] = $record;
            }
            if (Carbon::parse($record->created_at)->dayOfWeek == Carbon::SATURDAY) {
                $filteredArraySaturday[] = $record;
            }
        }

        return response()->json(['amount' => $amount, $dayOfTheWeek, $weekday, $filteredArrayFriday]);
    }

    public function getStores(Request $request)
    {
        $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')
            ->select(
                'stores.*',
                'ramo_activities.nome as industry',
                'merchant_contracts.id as merchant_contract_id',
                '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'
            )
            ->orderBy($orderBy, $orderType)
            ->paginate($perPage);


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

    public function getStorePayments($datainicial, $datafinal, $id)
    {
        if ($datainicial === $datafinal) {

            $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')
                ->orderBy('payments.created_at', 'desc')
                ->whereDate('payments.created_at', $datafinal)
                ->where('stores.id', $id)
                ->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')
                ->orderBy('payments.created_at', 'desc')
                //                ->whereBetween('payments.created_at', [$datainicial, $datafinal])
                ->whereDate('payments.created_at', '>=', $datainicial)
                ->whereDate('payments.created_at', '<=', $datafinal)
                ->where('stores.id', $id)
                ->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 updateStore(Request $request)
    {
        $store = Store::query()->where('id', $request->id)->first();

        if ($store) {

            $store->update([
                'name' => $request->name,
                'nuit' => $request->nuit,
                'nib' => $request->nib,
                'username' => $request->username,
                'address' => $request->address,
                'balance' => 0,
                'manager' => $request->manager,
                'manager_phone_number' => $request->manager_phone_number,
                'mobile_phone' => $request->mobile_phone,
                'email' => $request->email,
                'merchant_account_id' => $request->merchant_account_id,
                //                'merchant_contract_id' => $request->merchant_contract_id,
                'industry_activity' => $request->industry_activity,
                'longitude' => $request->longitude,
                'latitude' => $request->latitude,
            ]);

            $contract = MerchantContract::query()->where('id', $store->merchant_contract_id)->first();

            $contract->update([
                'taxa' => $request->taxa,
                'max_balance' => $request->max_balance,
                'nr_transaction' => $request->nr_transaction,
                'status' => 'activo',
                'min_amount' => $request->min_amount,
                'max_amount' => $request->max_amount,
                'use_point' => true,
                'use_point_limit' => $request->use_point_limit,
                'merchant_account_id' => $request->merchant_account_id,
            ]);
            return response()->json(['message' => 'Loja ' . $store->name . ' Actualizada com Sucesso por ' . $request->user()->name]);
        } else {

            return response()->json(['message' => 'Loja Não Encontrada'], 404);
        }
    }

    public function updateFirebaseToken(Request $request)
    {

        $devices = StoreDevice::query()
            ->join('stores', 'stores.id', '=', 'store_devices.store_id')
            ->where('store_devices.store_id', $request->user()->id)
            ->select('store_devices.*')
            ->get();

        if ($devices->count() === 0) {

            StoreDevice::create([
                'device_name' => $request->device_name,
                'firebase_token' => $request->firebase_token,
                'store_id' => $request->user()->id
            ]);
            return response()->json(['message' => 'Token Gerado com Sucesso']);
        } else {

            $devicesCheck = StoreDevice::query()
                ->join('stores', 'stores.id', '=', 'store_devices.store_id')
                ->where('store_devices.store_id', $request->user()->id)
                ->where('store_devices.firebase_token', $request->firebase_token)
                ->select('store_devices.*')
                ->first();

            if ($devicesCheck) {
            } else {
                StoreDevice::create([
                    'device_name' => $request->device_name,
                    'firebase_token' => $request->firebase_token,
                    'store_id' => $request->user()->id
                ]);
                return response()->json(['message' => 'Token Gerado com Sucesso']);
            }
        }
    }

    public function updateStoreImage(Request $request)
    {
        $this->validate($request, [
            'imagem' => 'required'
        ]);

        //        $data = new Store();
        $store = Store::query()->where('id', $request->id)->first();

        if ($store) {

            if ($request->file('imagem')) {
                $file = $request->file('imagem');
                $filename = date('YmdHi') . $store->id . $file->getClientOriginalName();
                $file->move(public_path('/images/comerciante/logo'), $filename);
                //            $data['logo'] = $filename;
                //            $data['photo'] = $filename;
                $store->update([
                    'logo' => url('/') . '/images/comerciante/logo/' . $filename,
                    'photo' => url('/') . '/images/comerciante/logo/' . $filename
                ]);
            }
            //        $data->save();

            return response()->json(['message' => 'Actualizado com sucesso']);
        } else {
            return response()->json(['message' => 'Loja invalida'], 400);
        }
    }
}