import type { TableEngineInput } from '@/models/table' export type BoursecuTransactionTabId = | 'trades' | 'deposit' | 'withdrawal' | 'physical' export type BoursecuTradeSide = 'buy' | 'sell' export type BoursecuTransactionFetchMode = 'transaction' | 'deposit' | 'physical' export type BoursecuTradeStatusFilter = 'completed' | 'pending' | 'cancelled' export type BoursecuFulfillmentStatusFilter = 'delivered' | 'registered' | 'cancelled' export type BoursecuTransactionStatusFilter = BoursecuTradeStatusFilter | BoursecuFulfillmentStatusFilter export type BoursecuStatusFilterGroup = 'trade' | 'fulfillment' export interface BoursecuTransactionStatusOption { value: string label: string sts: number } export interface BoursecuTransactionTab { id: BoursecuTransactionTabId label: string emptyText: string showTradeToggle?: boolean showAdvancedFilters?: boolean fetchMode?: BoursecuTransactionFetchMode typeFilters?: number[] } export const BOURSECU_TRADE_STATUS_OPTIONS: BoursecuTransactionStatusOption[] = [ { value: 'completed', label: 'تکمیل شده', sts: 2 }, { value: 'pending', label: 'در انتظار تایید', sts: 1 }, { value: 'cancelled', label: 'لغو شده', sts: 3 }, ] /** وضعیت‌های سند برداشت فیزیکی (Withdraw::$STS) */ export const BOURSECU_FULFILLMENT_STATUS_OPTIONS: BoursecuTransactionStatusOption[] = [ { value: 'registered', label: 'در انتظار ارسال', sts: 50 }, { value: 'delivered', label: 'ارسال شده', sts: 51 }, { value: 'cancelled', label: 'لغو شده', sts: 52 }, ] /** @deprecated Use getBoursecuStatusOptionsForTab instead */ export const BOURSECU_TRANSACTION_STATUS_OPTIONS = BOURSECU_TRADE_STATUS_OPTIONS export const BOURSECU_TRANSACTION_TABS: BoursecuTransactionTab[] = [ { id: 'trades', label: 'معاملات', emptyText: 'معامله‌ای برای شما به ثبت نرسیده است', showTradeToggle: true, showAdvancedFilters: true, typeFilters: [1, 2], }, { id: 'deposit', label: 'واریز', emptyText: 'واریزی برای شما به ثبت نرسیده است', fetchMode: 'deposit', showAdvancedFilters: true, }, { id: 'withdrawal', label: 'برداشت', emptyText: 'برداشتی برای شما به ثبت نرسیده است', showAdvancedFilters: true, typeFilters: [4], }, { id: 'physical', label: 'تحویل فیزیکی', emptyText: 'درخواست تحویل فیزیکی برای شما ثبت نشده است', fetchMode: 'physical', showAdvancedFilters: true, }, ] const TRADE_TYPE_BY_SIDE: Record = { buy: 1, sell: 2, } export function getBoursecuStatusFilterGroup(tab: BoursecuTransactionTab): BoursecuStatusFilterGroup { return tab.id === 'physical' ? 'fulfillment' : 'trade' } export function getBoursecuStatusOptionsForTab( tab: BoursecuTransactionTab, ): BoursecuTransactionStatusOption[] { return getBoursecuStatusFilterGroup(tab) === 'fulfillment' ? BOURSECU_FULFILLMENT_STATUS_OPTIONS : BOURSECU_TRADE_STATUS_OPTIONS } export function boursecuTabSupportsProductFilter(tab: BoursecuTransactionTab): boolean { // فیلتر محصول روی جدول سند برداشت فیزیکی (hasMany Transaction) قابل‌اعتماد نیست return tab.id === 'trades' } function getBoursecuStatusFilterField(tab: BoursecuTransactionTab): string { if (tab.fetchMode === 'deposit' || tab.fetchMode === 'physical') { return 'sts' } if (tab.id === 'withdrawal') { return 'withdraw.sts' } return 'order.sts' } function resolveBoursecuStatusSts( tab: BoursecuTransactionTab, statusFilter?: BoursecuTransactionStatusFilter | string, ): number | undefined { return getBoursecuStatusOptionsForTab(tab).find((option) => option.value === statusFilter)?.sts } export function buildBoursecuTransactionPagination( tab: BoursecuTransactionTab, tradeSide: BoursecuTradeSide, dateFrom?: string, dateTo?: string, statusFilter?: BoursecuTransactionStatusFilter | string, productId?: number, ): TableEngineInput { const filters: TableEngineInput['filters'] = [] if (tab.fetchMode !== 'deposit' && tab.fetchMode !== 'physical' && tab.typeFilters?.length) { const typeValue = tab.showTradeToggle && tab.typeFilters.includes(TRADE_TYPE_BY_SIDE[tradeSide]) ? TRADE_TYPE_BY_SIDE[tradeSide] : tab.typeFilters[0] filters.push({ field: 'type', cr: 'and', type: 'number', op: 'eq', value: typeValue, }) } if (tab.showAdvancedFilters) { if (dateFrom) { filters.push({ field: 'created_at', cr: 'and', type: 'date', op: 'gte', value: dateFrom, }) } if (dateTo) { filters.push({ field: 'created_at', cr: 'and', type: 'date', op: 'lte', value: dateTo, }) } const statusSts = resolveBoursecuStatusSts(tab, statusFilter) if (statusSts != null) { filters.push({ field: getBoursecuStatusFilterField(tab), cr: 'and', type: 'number', op: 'eq', value: statusSts, }) } if (productId != null && boursecuTabSupportsProductFilter(tab)) { filters.push({ field: 'wallet.product_id', cr: 'and', type: 'number', op: 'eq', value: productId, }) } } return { page: 0, limit: 7, filters, } }