/** * Import types from Nadal. */ import type { PaymentBankAccountResponseData, PaymentDepositBankRequestPayload, } from '@kira-dancer/nadal' import type { AddBankRequest, BankInfoData, BankListItem, BaseNadalResponse, } from '#lib/types' import { useCancelPromotion, useNadal, usePromotion } from '#lib/composables' import { useUserBankStore } from '#lib/stores' import { computed, ref } from 'vue' import { valueToNumber } from '#lib/utils/number' interface PaymentBankAccountResponseDataExtend extends PaymentBankAccountResponseData { qr_code?: string } /** * Provides functions and state for managing banking operations. * * This composable handles fetching bank lists, creating deposits, retrieving bank information, * and managing bank accounts. * * @returns {Object} An object with functions for banking operations and reactive state. * @namespace */ export function useBanking() { const { payment, account } = useNadal() const { isUsingPromotion, promotionPackages, fetchPromotionPackages } = usePromotion() const { openModalCancelPromotion } = useCancelPromotion() const bankStore = useUserBankStore() const isLoading = ref(false) const banks = computed(() => bankStore.banks) /** * Fetches and updates the list of banks. * * This function retrieves bank data and processes it to include additional information * before storing it in the bank store. * * @returns {Promise} A promise that resolves once the banks are fetched and stored. */ const fetchBanks = async () => { const data = await payment.bankList() const banks = (data ?? [])?.map((bank) => ({ ...bank, name: bank.bank_name, bankName: `${bank.bank_name}${bank.isMaintained ? ' (Bảo trì)' : ''}`, })) bankStore.setBanks(banks) } /** * Creates a deposit request with the specified data. * * If the current promotion type is a welcome promotion, it opens a modal for cancellation. * Otherwise, it processes the deposit request. * * PaymentDepositBankRequestPayload type is imported from the Nadal module. * * @param {PaymentDepositBankRequestPayload} data - The data required to create a deposit. * @returns {Promise} A promise that resolves with the response from the deposit request. */ const onCreateDeposit = async ( data: PaymentDepositBankRequestPayload, ): Promise => { if (isUsingPromotion.value) { openModalCancelPromotion() return } return await payment.depositBank< PaymentDepositBankRequestPayload, BaseNadalResponse >({ ...data, amount: valueToNumber(data.amount!.toString(), 1000), }) } /** * Retrieves information about a bank account based on the bank code. * * This function fetches account details and formats them for display. * * PaymentBankAccountResponseData type is imported from the Nadal module. * * @param {string} bankCode - The code of the bank to retrieve information for. * @returns {Promise} A promise that resolves with the bank information or null if not found. */ const getBankInfoByBankCode = async (bankCode: string) => { const data = await payment.bankAccount< { bank_code: string }, PaymentBankAccountResponseDataExtend >({ bank_code: bankCode }) if (data) { const informationBanks: BankInfoData = { ...data, account_name: data.account_name, account_no: data.account_no?.replace(/[^0-9]/g, ''), branch_name: data.branch_name ? `${data.bank_name ? data.bank_name : data.bank_code} - ${ data.branch_name }` : '', qr_code: data.qr_code ?? '', } return informationBanks } return null } /** * Adds a new bank account with the provided details. * * @param {AddBankRequest} request - The details of the bank account to add. * @returns {Promise} A promise that resolves with the response from the account addition request. */ const addBankAccount = async ({ withdrawBankCode, accountName, accountNumber, }: AddBankRequest) => { return await account.addBankAccount({ bank_code: withdrawBankCode, bank_account_name: accountName, bank_account_no: accountNumber, }) } /** * Fetches bank lists and promotion packages. * * @returns {Promise} A promise that resolves once both the bank lists and promotion packages are fetched. */ const fetchData = async () => { await Promise.all([fetchBanks(), fetchPromotionPackages()]) } return { isLoading, banks, promotionPackages, getBankInfoByBankCode, fetchData, addBankAccount, onCreateDeposit, } }