102 lines
3.0 KiB
TypeScript
102 lines
3.0 KiB
TypeScript
import { PackageName } from './user';
|
|
|
|
// Nested user on a purchase (subset of the full User model)
|
|
export interface PurchaseUser {
|
|
id: number;
|
|
uuid: string;
|
|
first_name: string | null;
|
|
last_name: string | null;
|
|
full_name: string | null;
|
|
email: string | null;
|
|
mobile: string | null;
|
|
}
|
|
|
|
// Nested product on a purchase, with its package
|
|
export interface PurchaseProduct {
|
|
id: number;
|
|
title: string | null;
|
|
price: number | null;
|
|
type: number | null;
|
|
package_name_id: number;
|
|
package_name: PackageName | null;
|
|
// Display-only pricing (متن نمایشی — بدون محاسبه)
|
|
discounted_price: string | null; // قیمت کلی تخفیفخورده
|
|
discount: string | null; // تخفیف
|
|
}
|
|
|
|
// A purchase = a subscription transaction
|
|
export interface Purchase {
|
|
id: number;
|
|
user_id: number;
|
|
product_id: number | null;
|
|
amount: number;
|
|
uuid: string;
|
|
status: number;
|
|
authority: string | null;
|
|
ref_id: string | null;
|
|
gateway: number;
|
|
created_at: string;
|
|
updated_at: string;
|
|
user: PurchaseUser | null;
|
|
product: PurchaseProduct | null;
|
|
}
|
|
|
|
// Laravel length-aware paginator envelope
|
|
export interface Paginated<T> {
|
|
current_page: number;
|
|
data: T[];
|
|
last_page: number;
|
|
per_page: number;
|
|
total: number;
|
|
from: number | null;
|
|
to: number | null;
|
|
next_page_url: string | null;
|
|
prev_page_url: string | null;
|
|
}
|
|
|
|
// Payment source (gateway) — matches backend Transaction::GATEWAYS
|
|
export const PAYMENT_GATEWAYS = {
|
|
asanpardakht: { code: 1, label: 'آسانپرداخت' },
|
|
zarinpal: { code: 2, label: 'زرینپال' },
|
|
digipay: { code: 3, label: 'دیجیپی' },
|
|
cafe: { code: 4, label: 'کافه بازار' },
|
|
myket: { code: 5, label: 'مایکت' },
|
|
} as const;
|
|
|
|
export type PaymentGatewayKey = keyof typeof PAYMENT_GATEWAYS;
|
|
|
|
export const getGatewayLabel = (gateway: number | null): string => {
|
|
const found = Object.values(PAYMENT_GATEWAYS).find((g) => g.code === gateway);
|
|
return found ? found.label : 'نامشخص';
|
|
};
|
|
|
|
// Purchase status — matches backend Transaction::STATUSES
|
|
export const PURCHASE_STATUSES: Record<number, string> = {
|
|
1: 'در انتظار پرداخت',
|
|
2: 'موفق',
|
|
3: 'مصرفشده',
|
|
};
|
|
|
|
export const getPurchaseStatusLabel = (status: number | null): string => {
|
|
if (status === null || status === undefined) return 'نامشخص';
|
|
return PURCHASE_STATUSES[status] || 'نامشخص';
|
|
};
|
|
|
|
// Filters sent to the purchases endpoint
|
|
export interface PurchaseFilters {
|
|
email?: string;
|
|
mobile?: string;
|
|
package_name?: string;
|
|
gateway?: string; // gateway name key (e.g. "zarinpal")
|
|
status?: number;
|
|
product_id?: number; // filter by a specific product
|
|
// Date/time window on created_at (Y-m-d dates, H:i(:s) times, Tehran-local —
|
|
// same values the accounting filters use). Times only apply with their date.
|
|
date_from?: string;
|
|
date_to?: string;
|
|
time_from?: string;
|
|
time_to?: string;
|
|
per_page?: number;
|
|
page?: number;
|
|
}
|