*/ function appLocales(): array { return is_array(config('app.locales')) ? config('app.locales') : []; } /** * Modules directory path */ function modules_path(string $path = ''): string { return app_path('Modules/'.$path); } /** * Check if module exists */ function module_exists(string $module): bool { return is_dir(modules_path(ucfirst($module))); } /** * Check if a client IP is in our Server subnet * * @param string $ip */ function isLocalIp(string $ip = ''): bool { return ! filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE); } /** * Is turkmen ip */ function isTurkmenIp(string $ip = ''): bool { return IpUtils::checkIp($ip, [ '95.85.192.0/19', '95.85.224.0/20', '95.85.240.0/21', '95.85.248.0/22', '95.85.252.0/22', '217.174.224.0/19', '91.207.136.0/22', ]); } /** * Un mask phone from "+(993)-xx-xx-xx-xx" */ function unMaskPhone(string|int $phone): string { return substr(str_replace(['+', '(', ')', '-', '_'], '', strval($phone)), 3); } /** * Send a sms * * @return mixed|void */ function sendSMS(string|int $phone, string|int $message) { if (! app()->isProduction()) { return; } $client = new Client; $headers = [ 'Content-Type' => 'application/json;charset=utf-8;', 'Charset' => 'UTF-8', ]; $body = 'JSON={ "SendRequest": { "TerminalID": "Online_PANEL", "Version": "1", "Lang": "EN", "MobilePhone": "993'.$phone.'", "Text": "'.$message.'" } }'; // 10.3.158.103 $request = new GuzzleRequest('POST', 'http://10.3.158.28:8080/kpsmsroute/online.request', $headers, $body); try { $res = $client->sendAsync($request)->wait(); return $res->getBody(); } catch (Exception $e) { Log::error($e); } } /** * Send a sms verification code */ function sendSMSVerification(string|int $phone_number): ?Verification { $phone_code = rand(100000, 999999); $verification = Verification::where(['username' => $phone_number])->first(); $verification ? $verification->update(['code' => $phone_code]) : Verification::create(['username' => $phone_number, 'code' => $phone_code]); sendSMS($phone_number, 'Tassyklaýyş belgi: '.$phone_code); return $verification; } /** * Store auth events */ function storeAuthEvent(string $name, Request $request): void { Log::channel('auth_activity') ->{EventType::logType($name)}(sprintf( '%s, APP_NAME: %s, REQUEST_TYPE: %s, SOURCE_IP: %s, SOURCE_PORT: %s, SOURCE_URL: %s, DESTINATION_IP: %s, DESTINATION_PORT: %s, DESTINATION_COUNTRY: %s, USER_ID: %s', $name, config('app.name'), $request->method(), $request->ip(), $_SERVER['REMOTE_PORT'], $request->url(), $request->host(), $request->getPort(), isLocalIp($request->ip()) ? 'TM' : Location::get($request->ip())?->countryCode ?? 'TM', $request->user()->id ?? '-', )); } /** * Store resource events * * @param string $name Event name * @param array $data Event data * @param Request $request */ function storeResourceEvent(string $name, array $data, Request $request): void { if ($name === EventType::laravelNovaActionEvent() || empty($data)) { return; } try { $before = []; $after = []; foreach ($data[0]->getChanges() as $key => $value) { try { if (array_key_exists($key, $data[0]->getOriginal())) { $before[] = [$key => $data[0]->getOriginal()[$key]]; } $after[] = [$key => $value]; } catch (Exception $e) { Log::error($e->getMessage(), ['trace' => $e->getTraceAsString()]); } } Log::channel('resource_activity') ->{EventType::logType($name)}(sprintf( '%s, APP_NAME: %s, REQUEST_TYPE: %s, SOURCE_IP: %s, SOURCE_PORT: %s, SOURCE_URL: %s, DESTINATION_IP: %s, DESTINATION_PORT: %s, DESTINATION_COUNTRY: %s, USER_ID: %s, MODEL_NAME: %s, BEFORE: %s, AFTER: %s', $name, config('app.name'), $request->method(), $request->ip(), $_SERVER['REMOTE_PORT'] ?? '-', $request->url(), $request->host(), $request->getPort(), isLocalIp($request->ip()) ? 'TM' : Location::get($request->ip())?->countryCode ?? 'TM', $request->user()->id ?? '-', get_class($data[0]), json_encode($before), json_encode($after), )); } catch (Exception $e) { Log::error('Error in storeResourceEvent() helpers', ['error' => $e]); } } /** * Locale app path */ function localeAppPath(): string { return config('app.locale_app.path'); } /** * Locale app url */ function localeAppUrl(): string { return config('app.locale_app.url'); } /** * Original quality :D */ function convertToOriginalFormat(int|float|string $apiPrice): string { $originalPrice = intval($apiPrice) / 100; return number_format($originalPrice, 2, '.', ''); } /** * Date day mf * * @param string $month * @param string $year */ function lastDayOfMonth(string $month, int|string $year): DateTime { $date = new DateTime("$year-$month-01"); $date->modify('last day of this month'); return $date; } /** * Get index by value from array * * @param mixed $value Value to be searched * @param array $array Array * @return null|int */ function indexByValue(mixed $value, array $array): ?int { for ($i = 0; $i < count($array); $i++) { if ($array[$i] == $value) { return $i; } } return null; } /** * Convert db type to php type */ function dbTypeToPhp(string $type): string { return match ($type) { 'bigint' => 'int', 'varchar' => 'string', 'boolean' => 'bool', 'timestamp(0) without time zone' => 'string', 'json' => 'string', 'jsonb' => 'string', default => 'string', }; } /** * Cached value * * @param string $name * @param mixed $value * @param int $seconds */ function cached(string $name, mixed $value, int $seconds = 60): mixed { return cache()->has($name) ? cache($name) : cache()->remember( key: $name, ttl: $seconds, callback: fn () => is_callable($value) ? call_user_func($value) : $value ); } /** * view-loan-order-permission-id */ function view_loan_order_permission_id(): int { return Cache::rememberForever('view_loan_order_permission_id', function () { return Permission::query()->where('name', 'ViewLoanOrders')->first(['id', 'name'])->id; }); } /** * VP fetch client info all * * @param $model * @param $start_date * @param $end_date */ function vp_fetch_ClientInfoAll($model, $start_date, $end_date) { $response = DownloadCardTransaction::make()->fetchApi( passport_serie: $model->passport_serie, passport_id: $model->passport_id, card_number_masked: Str::mask($model->card_number, '*', 6, 6), card_expire_date: $model->card_month.'/'.substr($model->card_year, 2), start_date: $start_date, end_date: $end_date, ); return Str::isJson($response) ? json_decode($response) : emptyClass(errCode: 1, message: 'Connection issue to VP'); } /** * Create an anonymous class that acts as a dynamic object. * * @param mixed ...$arguments Key-value pairs passed as an associative array. * @return object Anonymous class instance with dynamic properties. */ function emptyClass(...$arguments): object { /** * @var array $arguments */ return new class($arguments) { /** * Internal data storage. * * @var array */ private array $data = []; /** * Constructor that sets properties. * * @param array $props */ public function __construct(array $props) { foreach ($props as $key => $value) { $this->data[$key] = $value; } } /** * Magic getter. * * @param string $key * @return mixed|null */ public function __get(string $key): mixed { return $this->data[$key] ?? null; } /** * Magic setter. * * @param string $key * @param mixed $value * @return void */ public function __set(string $key, mixed $value): void { $this->data[$key] = $value; } /** * Magic isset. * * @param string $key * @return bool */ public function __isset(string $key): bool { return isset($this->data[$key]); } }; } /** * Check online payment * * @param string $orderId * @param int|string $username * @param string $password * * @return mixed */ function checkOnlinePayment(string $orderId, int|string $username, string $password): mixed { $response = Http::asForm()->post('https://mpi.gov.tm/payment/rest/getOrderStatusExtended.do', [ 'language' => 'ru', 'orderId' => $orderId, 'userName' => $username, 'password' => $password, ]); return $response; } /** * Sync with bank system * * @param string $online_payment_order_uuid * @param string $bank_unique_code * @param string $online_payment_terminal_id * @param string $user_deposit_account * @param string $online_payment_auth_ref_num * @param string $online_payment_tmt_amount * @param string $pay_purpose * * @return mixed */ function syncWithBankSystem( $online_payment_order_uuid, $bank_unique_code, $online_payment_terminal_id, $user_deposit_account, $online_payment_auth_ref_num, $online_payment_tmt_amount, $pay_purpose ): mixed { $ecomId = $online_payment_order_uuid; $agentId = $bank_unique_code; $eposId = $online_payment_terminal_id; $account = $user_deposit_account; $rrn = $online_payment_auth_ref_num; $amount = $online_payment_tmt_amount; $payPurpose = $pay_purpose; $client = new Client([ 'timeout' => 5, // seconds before it fails 'connect_timeout' => 1, // seconds to wait for connection ]); $headers = [ 'Content-Type' => 'application/json', 'Authorization' => 'Basic YWRtaW46UUFad3N4MTIz', ]; $body = sprintf('{ "ecomId": "%s", "agentId": "%s", "eposId": "%s", "account": "%s", "rrn": "%s", "amount": "%s", "payPurpose": "%s" }', $ecomId, $agentId, $eposId, $account, $rrn, $amount, $payPurpose); $request = new GuzzleRequest('POST', 'http://10.3.158.102:8888/api/paytrn/new', $headers, $body); try { $res = $client->sendAsync($request)->wait(); return (string) $res->getBody(); } catch (Exception $e) { info([$e->getMessage(), $e->getTraceAsString()]); return null; } } /** * Get Sber credentials for a given payment item. * * @param SberPaymentOrderItem $item * @return array{username?: string, password?: string, onlinePaymentResource?: OnlinePaymentHistory, relatedResource?: mixed, error?: string, type?: 'danger'|'modal'} */ function getSberCredentials(SberPaymentOrderItem $item): array { /** @var \App\Models\Payment\OnlinePaymentHistory|null $onlinePaymentResource */ $onlinePaymentResource = OnlinePaymentHistory::find($item->online_payment_history_id); if (! $onlinePaymentResource) { return ['error' => 'Online payment resource tapylmady', 'type' => 'danger']; } $relatedResource = (new $onlinePaymentResource->online_paymantable_type) ->find(id: $onlinePaymentResource->online_paymantable_id); if (! $relatedResource) { return ['error' => 'Bu resource tapylmady', 'type' => 'danger']; } $relatedResource->loadMissing(['branch']); if (! $relatedResource->branch) { return ['error' => 'Şahamça bilen birikdirilmedik', 'type' => 'danger']; } $username = $relatedResource->branch->billing_sber_username; $password = $relatedResource->branch->billing_sber_password; if (empty($username) || empty($password)) { return ['error' => 'Ulanyjy ady bilen açar sözi gabat gelmedi', 'type' => 'modal']; } return [ 'username' => $username, 'password' => $password, 'onlinePaymentResource' => $onlinePaymentResource, 'relatedResource' => $relatedResource, ]; }