Surface Meshkee transaction id, ZarinPal track/authority, card pan, and paid time in the transactions modal. Co-authored-by: Cursor <cursoragent@cursor.com>
185 lines
4.7 KiB
TypeScript
185 lines
4.7 KiB
TypeScript
import { apiRequest } from '../lib/api'
|
|
import { getActiveBusinessId } from '../lib/businessContext'
|
|
|
|
export type OrderStatus =
|
|
| 'pending'
|
|
| 'confirmed'
|
|
| 'processing'
|
|
| 'shipped'
|
|
| 'delivered'
|
|
| 'cancelled'
|
|
|
|
export type OrderSource = 'website' | 'admin' | 'app'
|
|
|
|
export interface OrderItem {
|
|
id: string
|
|
storeItemVariantId: string | null
|
|
productId: string
|
|
productTitle: string
|
|
productImage: string | null
|
|
variantSku: string | null
|
|
unitPrice: number
|
|
compareAtPrice: number | null
|
|
quantity: number
|
|
lineTotal: number
|
|
selections: {
|
|
variationId: string
|
|
variationName: string
|
|
optionId: string
|
|
value: string
|
|
}[]
|
|
}
|
|
|
|
export interface OrderCustomer {
|
|
id: string
|
|
firstName: string | null
|
|
lastName: string | null
|
|
cellNumber: string
|
|
email: string | null
|
|
}
|
|
|
|
export type TransactionType = 'pos' | 'cash' | 'transfer' | 'e_payment_gate'
|
|
|
|
export type TransactionStatus = 'pending' | 'completed' | 'failed' | 'refunded'
|
|
|
|
export interface OrderTransaction {
|
|
id: string
|
|
type: TransactionType
|
|
status: TransactionStatus
|
|
amount: number
|
|
posType: string | null
|
|
gatewayType: string | null
|
|
gatewayRef: string | null
|
|
gatewayTrackId: string | null
|
|
cardPan: string | null
|
|
paidAt: string | null
|
|
transferAccount: string | null
|
|
transferRefNumber: string | null
|
|
notes: string | null
|
|
createdBy: string | null
|
|
createdAt: string
|
|
updatedAt: string
|
|
}
|
|
|
|
export interface Order {
|
|
id: string
|
|
businessId: string
|
|
orderNumber: string
|
|
status: OrderStatus
|
|
processStepId: string
|
|
processStepLabel?: string | null
|
|
processStepLabelFa?: string | null
|
|
processStepColor?: string | null
|
|
source: OrderSource
|
|
subtotal: number
|
|
shippingTotal: number
|
|
discountTotal: number
|
|
total: number
|
|
shippingAddress: Record<string, unknown>
|
|
addressId: string | null
|
|
customerNotes: string | null
|
|
adminNotes: string | null
|
|
createdBy: string | null
|
|
createdAt: string
|
|
updatedAt: string
|
|
customer: OrderCustomer
|
|
items: OrderItem[]
|
|
transactions?: OrderTransaction[]
|
|
}
|
|
|
|
export interface OrdersListResponse {
|
|
items: Order[]
|
|
total: number
|
|
page: number
|
|
pageSize: number
|
|
}
|
|
|
|
export interface ListOrdersParams {
|
|
page?: number
|
|
pageSize?: number
|
|
status?: OrderStatus
|
|
orderNumber?: string
|
|
customerQuery?: string
|
|
dateFrom?: string
|
|
dateTo?: string
|
|
minTotal?: number
|
|
maxTotal?: number
|
|
}
|
|
|
|
export interface CreateAdminOrderPayment {
|
|
type: 'pos' | 'cash' | 'transfer' | 'e_payment_gate'
|
|
amount: number
|
|
posType?: string
|
|
gatewayType?: string
|
|
transferAccount?: string
|
|
transferRefNumber?: string
|
|
notes?: string
|
|
}
|
|
|
|
export interface CreateAdminOrderPayload {
|
|
customerUserId: string
|
|
items: { storeItemVariantId: string; quantity: number }[]
|
|
customerNotes?: string
|
|
adminNotes?: string
|
|
status?: OrderStatus
|
|
payments?: CreateAdminOrderPayment[]
|
|
}
|
|
|
|
function businessPath(suffix = '') {
|
|
const businessId = getActiveBusinessId()
|
|
if (!businessId) {
|
|
throw new Error('No active business selected. Please sign in again.')
|
|
}
|
|
return `/businesses/${businessId}/orders${suffix}`
|
|
}
|
|
|
|
export async function listOrders(params: ListOrdersParams = {}, signal?: AbortSignal) {
|
|
const q = new URLSearchParams()
|
|
if (params.page !== undefined) q.set('page', String(params.page))
|
|
if (params.pageSize !== undefined) q.set('pageSize', String(params.pageSize))
|
|
if (params.status) q.set('status', params.status)
|
|
if (params.orderNumber) q.set('orderNumber', params.orderNumber)
|
|
if (params.customerQuery) q.set('customerQuery', params.customerQuery)
|
|
if (params.dateFrom) q.set('dateFrom', params.dateFrom)
|
|
if (params.dateTo) q.set('dateTo', params.dateTo)
|
|
if (params.minTotal !== undefined) q.set('minTotal', String(params.minTotal))
|
|
if (params.maxTotal !== undefined) q.set('maxTotal', String(params.maxTotal))
|
|
|
|
const query = q.toString()
|
|
const path = `${businessPath()}${query ? `?${query}` : ''}`
|
|
return apiRequest<OrdersListResponse>(path, { auth: true, signal })
|
|
}
|
|
|
|
export async function getOrder(orderId: string, signal?: AbortSignal) {
|
|
return apiRequest<{ order: Order }>(businessPath(`/${orderId}`), { auth: true, signal })
|
|
}
|
|
|
|
export async function createAdminOrder(payload: CreateAdminOrderPayload) {
|
|
return apiRequest<{ message: string; order: Order }>(businessPath(), {
|
|
method: 'POST',
|
|
auth: true,
|
|
body: payload,
|
|
})
|
|
}
|
|
|
|
export async function removeOrder(orderId: string) {
|
|
return apiRequest<{ message: string }>(businessPath(`/${orderId}`), {
|
|
method: 'DELETE',
|
|
auth: true,
|
|
})
|
|
}
|
|
|
|
export interface UpdateOrderPayload {
|
|
processStepId?: string
|
|
status?: OrderStatus
|
|
adminNotes?: string
|
|
}
|
|
|
|
export async function updateOrder(orderId: string, payload: UpdateOrderPayload) {
|
|
return apiRequest<{ message: string; order: Order }>(businessPath(`/${orderId}`), {
|
|
method: 'PATCH',
|
|
auth: true,
|
|
body: payload,
|
|
})
|
|
}
|