<?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;
}
}