• File: User.php
  • Full Path: /var/www/sandbox/app/User.php
  • Date Modified: 04/03/2025 5:58 PM
  • File size: 21.28 KB
  • MIME-type: text/x-php
  • Charset: utf-8
<?php

namespace App;

use App\Bank\HistoryPayment;
use App\Bank\Payment;
use App\Imali\BusinessAccount;
use App\Imali\ImaliAccount;
use App\Imali\Transfer;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens;
use Illuminate\Foundation\Auth\User as Authenticatable;
use DateTimeInterface;
use Illuminate\Database\Eloquent\SoftDeletes;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Traits\LogsActivity;

class User extends Authenticatable
{
    use HasApiTokens, Notifiable, SoftDeletes;
    use LogsActivity;

    protected static $logAttributes = [
        'name',
        'bi',
        'email',
        'password',
        'phone',
        'level',
        'user_id',
        'photo',
        'points',
        'status',
        'birthday',
        'account_number',
        'balance',
        'is_Active',
        'pin',
        'text',
        'firebase_token',
        'phone_reference',
        'country_code',
        'balance_visibility',
        'terminalCompanyName',
        'terminalChannel',
        'terminalID',
        'client_id',
        'document_id',
        'user_update_info_status',
        'update_info_status',

        'profile',
        'username',
        'is_online',
        'last_name',
        'login_attempts',
        'pin_attempts',
        'lang'
    ];

    protected $fillable = [
        'name',
        'bi',
        'email',
        'password',
        'phone',
        'level',
        'user_id',
        'photo',
        'points',
        'status',
        'birthday',
        'account_number',
        'balance',
        'is_Active',
        'pin',
        'text',
        'firebase_token',
        'phone_reference',
        'country_code',
        'balance_visibility',
        'terminalCompanyName',
        'terminalChannel',
        'terminalID',
        'client_id',
        'document_id',
        'user_update_info_status',
        'update_info_status',

        'profile',
        'username',
        'is_online',
        'last_name',
        'login_attempts',
        'pin_attempts',
        'lang'
    ];

    protected $logAttribute = [
        'name',
        'last_name',
        'profile',
        'bi',
        'email',
        'password',
        'phone',
        'level',
        'user_id',
        'photo',
        'points',
        'status',
        'birthday',
        'account_number',
        'balance',
        'is_Active',
        'text',
        'user.name',
        'firebase_token',
        'phone_reference',
        'country_code',
        'balance_visibility',
        'terminalCompanyName',
        'terminalChannel',
        'terminalID',
        'client_id',
        'document_id',
        'user_update_info_status',
        'update_info_status'
    ];

    public function getDescriptionForEvent(string $eventName): string
    {
        return "This model has been {$eventName}";
    }

    public function user()
    {
        return $this->belongsTo(User::class);
    }

    protected static $logName = 'user';

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password',
        'remember_token',
        'pin',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    public function setNameAttribute($value)
    {
        return $this->attributes['name'] = ucwords(strtolower($value));
    }

    public function setEmailAttribute($value)
    {
        $this->attributes['email'] = strtolower($value);
    }

    public function setBiAttribute($value)
    {
        $this->attributes['bi'] = strtoupper($value);
    }


    function bankAccounts()
    {
        return $this->hasMany(BankAccount::class);
    }

    function payments()
    {
        return $this->hasMany(Payment::class);
    }
    function paymentsGenerated()
    {
        return $this->hasMany(PaymentGeneration::class);
    }

    function paymentsHistory()
    {
        return $this->hasMany(HistoryPayment::class);
    }

    // Get iMaliAccount & BusinessAccount
    function account()
    {
        if ($this->profile === 'client') return $this->imaliAccount();
        else return $this->imaliBusinessAccount();

        // return $this->imaliAccount || $this->imaliBusinessAccount;
    }

    function imaliAccount()
    {
        return $this->hasOne(ImaliAccount::class);
    }
    // todo actualizado 15-12-2023
    function imaliBusinessAccount()
    {
        return $this->hasOne(BusinessAccount::class);
    }

    function documents()
    {
        // return $this->hasMany(UserDocument::class)->latestOfMany();
        return $this->hasOne(UserDocument::class)->latestOfMany();
    }

    // new 14/nov/2024
    function document()
    {
        return $this->documents();
    }

    function transferencias()
    {
        return $this->hasMany(Transfer::class);
    }

    protected function serializeDate(DateTimeInterface $date)
    {
        return $date->format('d-m-Y H:i:s');
    }

    function transactionHistories()
    {
        return $this->hasMany(TransactionHistory::class);
    }

    function transferHistories()
    {
        return $this->hasMany(TransferHistory::class);
    }

    function voucherHistory()
    {
        return $this->hasMany(VoucherHistory::class, 'user_id');
    }

    public function getActivitylogOptions(): LogOptions
    {
        return LogOptions::defaults()->logOnly($this->logAttribute);
    }

    public function findForPassport($username)
    {
        return $this->orWhere('email', $username)->orWhere('username', $username)->first();
    }

    // todo ---- OK
    /**
     * GET DADOS DO USER autenticado
     * 
     *  @return User::getUserAccount(); // User Autenticado 
     */
    public static function getUserAccount()
    {
        return User::getUserDetails(auth()->user()->id);
    }

    // todo ---- OK
    public static function is_subAccount($subaccount_number_or_card_number)
    {
        // $is_subaccount_number = ImaliSubAccount::query()->where('account_number', $subaccount_number_or_card_number)->orWhere('id', $subaccount_number_or_card_number)->first();
        $is_subaccount_number = ImaliSubAccount::query()->where('account_number', $subaccount_number_or_card_number)->first();
        if ($is_subaccount_number) return true;

        $is_card_number = ImaliSubAccount::query()->where('card_number', $subaccount_number_or_card_number)->first();
        if ($is_card_number) return true;

        return false;
    }

    // todo OK
    private static function is_client($reference_or_account_number)
    {
        $is_client = ImaliAccount::query()
            ->where('account_number', $reference_or_account_number)
            ->orWhere('reference', $reference_or_account_number)
            // ->orWhere('id', $reference_or_account_number)
            ->first();
        if ($is_client) return true;

        return false;
    }

    // todo OK
    private static function is_business($reference_or_account_number)
    {
        $is_business = BusinessAccount::query()
            ->where('account_number', $reference_or_account_number)
            ->orWhere('reference', $reference_or_account_number)
            // ->orWhere('id', $reference_or_account_number)
            ->first();
        if ($is_business) return true;

        return false;
    }


    // todo --- NOVO -- retorna os dados das contas CLIENT e EMPRESA atraves do User -- substituimos o metodo getImaliOrBusinessAccount
    // todo OK
    public static function getAccountByUser($userId, $account_id)
    {
        $user = User::query()->where('id', $userId)->first();

        if (!$user) return null;

        if ($user->profile == 'client') return ImaliAccount::query()->where('user_id', $userId)->where('id', $account_id)->first();
        if ($user->profile == 'business') return BusinessAccount::query()->where('user_id', $userId)->where('id', $account_id)->first();

        return null;
    }

    // todo OK
    public static function getSubAccountByUser($user_id, $account_id)
    {
        $user = User::query()->where('id', $user_id)->first();

        if (!$user) return null;

        return ImaliSubAccount::query()->where('user_id', $user_id)->where('id', $account_id)->first();
    }

    // todo -- Novo actualizado vai substituir getAccountByUserByAccountNumber -- retorna as contas CLIENT, BUSINESS e SUBACCOUNT... atraves do numero de conta
    // todo OK

    /**
     * GET DADOS DO USER pelos numeros de conta
     * @return User::getAccount(210000002); // GET cliente by account number
     * @return User::getAccount(240000010); // GET conta Empresa by account number
     * @return User::getAccount(211000004); // GET subconta by account number
     * @return User::getAccount(21000000218); // GET cliente by reference
     * @return User::getAccount(24000001086); // GET conta Empresa by reference
     * @return User::getAccount(1253097845800); // GET subconta by card number
     */
    public static function getAccount($account_number)
    {

        if (User::is_subAccount($account_number)) return ImaliSubAccount::query()->where('card_number', $account_number)->orWhere('account_number', $account_number)->first();

        if (User::is_client($account_number)) return ImaliAccount::query()->where('account_number', $account_number)->orWhere('reference', $account_number)->first();

        if (User::is_business($account_number)) return BusinessAccount::query()->where('account_number', $account_number)->orWhere('reference', $account_number)->first();

        return null;
    }

    /**
     * GET DADOS DO USER pelo ID, telefone
     * @return User::getUserDetails(1181); // Get User pelo ID
     * @return User::getUserDetails(849231169); // Get User pelo Telefone
     * @return User::getUserDetails(4, 2); // Get User by ID and subaccount ID
     * @return User::getUserDetails(4, 261); // Get User by ID and subaccount Card Number
     * @return User::getUserDetails(4, 211000004); // Get User by ID and subaccount Number
     */

    // todo OK
    public static function getUserDetails($userIdOrPhone, $cardNumber_or_subAccountNumber = 0)
    {

        // Get enviromment values
        $assistant_id = $_ENV['ASSISTANT_ID'];
        $ai_key = $_ENV['AI_KEY'];

        $user = User::query()->where('id', $userIdOrPhone)->orWhere('phone', $userIdOrPhone)->first();

        $new_user = null;

        if (!$user) return null;

        if (($cardNumber_or_subAccountNumber != 0) && User::is_subAccount($cardNumber_or_subAccountNumber)) {
            $new_user = User::getUserBySubAccount($userIdOrPhone, $cardNumber_or_subAccountNumber);
            return $new_user->makeHidden(User::hiddenProps());
        } else if (($cardNumber_or_subAccountNumber != 0) && !User::is_subAccount($cardNumber_or_subAccountNumber)) {
            return null;
        } else {
            if ($user->profile == 'client') {
                $new_user = User::getUserByClient($userIdOrPhone);
            } else if ($user->profile == 'business') {
                $new_user = User::getUserByBusiness($userIdOrPhone);
            }
        }

        if (!$new_user) return null;

        // Definindo os atributos extras antes de retornar
        $new_user->setAttribute('ai_key', $ai_key);
        $new_user->setAttribute('assistant_id', $assistant_id);

        return $new_user->makeHidden(User::hiddenProps());
    }

    public static function getUserDetailsORIGINAL($userIdOrPhone, $cardNumber_or_subAccountNumber = 0)
    {

        $user = User::query()->where('id', $userIdOrPhone)->orWhere('phone', $userIdOrPhone)->first();

        $new_user = null;

        if (!$user) return null;

        if (($cardNumber_or_subAccountNumber != 0) && User::is_subAccount($cardNumber_or_subAccountNumber)) {
            $new_user = User::getUserBySubAccount($userIdOrPhone, $cardNumber_or_subAccountNumber);
            return $new_user->makeHidden(User::hiddenProps());
        } else if (($cardNumber_or_subAccountNumber != 0) && !User::is_subAccount($cardNumber_or_subAccountNumber)) {
            return null;
        }

        if ($user->profile == 'client') $new_user = User::getUserByClient($userIdOrPhone);

        else if ($user->profile == 'business') $new_user = User::getUserByBusiness($userIdOrPhone);

        else return $new_user;

        return $new_user->makeHidden(User::hiddenProps());
    }

    // todo ---- OK
    private static function getUserBySubAccount($userIdOrPhone, $cardNumber_or_subAccountNumber)
    {
        return User::query()
            ->join('imali_accounts', 'imali_accounts.user_id', '=', 'users.id')
            ->join('imali_sub_accounts', 'imali_sub_accounts.user_id', '=', 'users.id')
            ->join('imali_account_configs', 'imali_accounts.imali_account_config', '=', 'imali_account_configs.id')
            ->where('imali_sub_accounts.user_id', $userIdOrPhone)
            ->where('imali_sub_accounts.card_number', $cardNumber_or_subAccountNumber)
            ->orWhere('users.phone', $userIdOrPhone)
            // ->orWhere('imali_sub_accounts.id', $cardNumber_or_subAccountNumber)
            ->orWhere('imali_sub_accounts.account_number', $cardNumber_or_subAccountNumber)
            ->select(User::selectImaliSubAccount())
            ->first();
    }

    // todo OK
    private static function getUserByClient($userId_or_Phone)
    {
        return User::query()
            ->join('imali_accounts', 'imali_accounts.user_id', '=', 'users.id')
            ->join('imali_account_configs', 'imali_accounts.imali_account_config', '=', 'imali_account_configs.id')
            ->where('users.id', $userId_or_Phone)
            ->orWhere('users.phone', '=', $userId_or_Phone)
            //->orWhere('imali_accounts.account_number', $userId_or_Phone)
            // ->orWhere('imali_accounts.account_number', $userId_or_Phone)
            ->select(User::selectImaliAccount())->first();
    }

    // todo OK
    private static function getUserByBusiness($userId_or_Phone)
    {
        return User::query()
            ->join('business_accounts', 'business_accounts.user_id', '=', 'users.id')
            ->join('imali_account_configs', 'business_accounts.imali_account_config', '=', 'imali_account_configs.id')
            ->where('users.id', $userId_or_Phone)
            ->orWhere('users.phone', '=', $userId_or_Phone)
            //->orWhere('business_accounts.account_number', $userId_or_Phone)
            // ->orWhere('business_accounts.reference', $userId_or_Phone)
            ->select(User::selectBusinessAccount())->first();
    }

    // todo OK
    // todo COMPLEMENTOS DE getUserByBusiness, getUserByClient e getUserBySubAccount
    private static function selectImaliSubAccount()
    {
        return array(
            'users.*',
            'imali_sub_accounts.name as sub_account_name',
            'imali_sub_accounts.captive_balance',
            'imali_sub_accounts.account_number',
            'imali_sub_accounts.card_number',
            'imali_sub_accounts.main_account_number',
            'imali_sub_accounts.main_account_id',
            'imali_sub_accounts.balance',
            'imali_sub_accounts.accounting_balance',

            'imali_account_configs.nr_transaction',
            'imali_account_configs.max_value_operation',
            'imali_account_configs.level',
            'imali_account_configs.taxa',
            'imali_account_configs.point_value',
            'imali_account_configs.min_value_operation',
            'imali_account_configs.max_value_year',
            'imali_account_configs.max_balance'
        );
    }

    // todo OK
    private static function selectImaliAccount()
    {
        return array(
            'users.*',
            'users.user_id as fingerprint',
            'imali_accounts.id as account_id',
            'imali_accounts.account_number',
            'imali_accounts.balance',
            'imali_accounts.accounting_balance',
            'imali_accounts.points',
            'imali_accounts.reference',

            'imali_account_configs.nr_transaction',
            'imali_account_configs.max_value_operation',
            'imali_account_configs.level',

            'imali_account_configs.id as imali_account_config',

            'imali_account_configs.taxa',
            'imali_account_configs.point_value',
            'imali_account_configs.min_value_operation',
            'imali_account_configs.max_value_year',
            'imali_account_configs.max_balance'
        );
    }

    // todo OK
    private static function selectBusinessAccount()
    {
        return array(
            'users.*',
            'users.user_id as fingerprint',
            'business_accounts.id as account_id',
            'business_accounts.account_number',
            'business_accounts.balance',
            'business_accounts.accounting_balance',
            'business_accounts.points',
            'business_accounts.reference',
            'business_accounts.user_id',

            'business_accounts.company_name',
            'business_accounts.company_logo',
            'business_accounts.company_address',
            'business_accounts.company_nuit',
            'business_accounts.company_phone',
            'business_accounts.company_email',
            'business_accounts.activity_branch',
            'business_accounts.country_id',
            'business_accounts.province_id',
            'business_accounts.district_id',
            'business_accounts.municipal_license',
            'business_accounts.alvara',
            'business_accounts.owner_name',
            'business_accounts.owner_phone',
            'business_accounts.owner_email',

            'imali_account_configs.nr_transaction',
            'imali_account_configs.max_value_operation',
            'imali_account_configs.level',
            'imali_account_configs.taxa',

            'imali_account_configs.id as imali_account_config',

            'imali_account_configs.point_value',
            'imali_account_configs.min_value_operation',
            'imali_account_configs.max_value_year',
            'imali_account_configs.max_balance'
        );
    }

    // todo COMPLEMENTOS DE getUserByBusiness, getUserByClient e getUserBySubAccount
    // todo OK
    private static function hiddenProps()
    {
        return [
            'password',
            'pin',
            'firebase_token',
            'created_at',
            'updated_at',
            'phone_reference',
            'user_id',
            'bi',
            'document_id',
            'remember_token',
            'email_verified_at'
        ];
    }
    // todo OK
    private static function getSubAccounts($imali_account_number)
    {
        return ImaliSubAccount::query()
            ->join('sub_account_types', 'sub_account_types.id', 'imali_sub_accounts.sub_account_types_id')
            ->where('main_account_number', $imali_account_number)
            ->where('sub_account_types.can_pay', 1)
            ->select(
                'imali_sub_accounts.id',
                'imali_sub_accounts.name',
                'imali_sub_accounts.captive_balance',
                'imali_sub_accounts.account_number',
                'imali_sub_accounts.main_account_number',
                'imali_sub_accounts.main_account_id',
                'imali_sub_accounts.card_number',
                'imali_sub_accounts.has_card_associated',
                'imali_sub_accounts.is_credit_allowed',
                'imali_sub_accounts.is_debit_allowed',
                'imali_sub_accounts.balance',
                'imali_sub_accounts.status',
                'imali_sub_accounts.sub_account_types_id',
                'imali_sub_accounts.user_id',
                'imali_sub_accounts.accounting_balance',
                'imali_sub_accounts.store_id',
                'imali_sub_accounts.created_at',
                'imali_sub_accounts.updated_at',

                'sub_account_types.short_description',
                'sub_account_types.long_description',
                'sub_account_types.type_id',
                'sub_account_types.can_pay'
            )
            ->get()
            ->toArray();
    }

    // todo OK
    public static function getMyAccounts()
    {
        $user = User::getUserDetails(auth()->user()->id);
        // $imaliAccount = User::getAccount($user->account_number);
        $imaliAccount = User::getAccount($user->account_number); //! novo metodo substituido
        $subAccounts = User::getSubAccounts($imaliAccount->account_number);
        $accounts = array_merge([$imaliAccount], $subAccounts);
        return $accounts;
    }

    // todo OK
    public static function getMyAccountsByUser($userID)
    {
        $user = User::getUserDetails($userID);
        // $imaliAccount = User::getAccount($user->account_number);
        $imaliAccount = User::getAccount($user->account_number); //! novo metodo substituido
        $subAccounts = User::getSubAccounts($imaliAccount->account_number);
        $accounts = array_merge([$imaliAccount], $subAccounts);
        return $accounts;
    }

    // todo OK
    public static function validateCheckDigit($numero)
    {
        // Verifica se o número tem 11 dígitos
        if (strlen($numero) != 11) {
            return false;
        }

        $entity = env('SIMO_ENTITY');
        $ref = (float)substr($numero, 0, 9);
        $cd = (float)substr($numero, 9, 2);

        $check_digit = 98 - (($entity . $ref) * 100) % 97;

        if ($check_digit == $cd) return true;
        return false;
    }


    public function getPhotoAttribute($photo)
    {
        return $_ENV['IMG_AVATAR_URL'] . $photo;
    }
}