2026-08-06 17:12:28 +03:30
|
|
|
import { computed, inject, onMounted, provide, reactive, ref, type InjectionKey } from 'vue'
|
2026-08-03 12:14:12 +02:00
|
|
|
import { useRouter } from 'vue-router'
|
2026-08-06 17:12:28 +03:30
|
|
|
import { companiesApi, mapAdminOrder, ordersApi } from '@/services/api'
|
|
|
|
|
import { ApiError } from '@/services/http'
|
|
|
|
|
import type { Company, Order, SettlementMethod } from '@/types'
|
2026-08-03 12:14:12 +02:00
|
|
|
|
|
|
|
|
import { useToast } from '@/composables/useToast'
|
|
|
|
|
|
|
|
|
|
export function useOrdersPage() {
|
|
|
|
|
const router = useRouter()
|
|
|
|
|
const toast = useToast()
|
|
|
|
|
|
2026-08-06 17:12:28 +03:30
|
|
|
const companies = ref<Company[]>([])
|
|
|
|
|
const orderList = ref<Order[]>([])
|
2026-08-03 12:14:12 +02:00
|
|
|
const activeTab = ref('all')
|
|
|
|
|
const selectedOrderId = ref<string>('')
|
|
|
|
|
const searchQuery = ref('')
|
|
|
|
|
const showAddModal = ref(false)
|
|
|
|
|
const showDetailPanel = ref(false)
|
|
|
|
|
const showDetailModal = ref(false)
|
|
|
|
|
const formError = ref('')
|
2026-08-06 17:12:28 +03:30
|
|
|
const saving = ref(false)
|
2026-08-03 12:14:12 +02:00
|
|
|
|
|
|
|
|
const emptyForm = () => ({
|
|
|
|
|
customerName: '',
|
2026-08-06 17:12:28 +03:30
|
|
|
companyId: companies.value[0]?.id ?? '',
|
2026-08-03 12:14:12 +02:00
|
|
|
settlementMethod: 'check' as SettlementMethod,
|
|
|
|
|
meterage: 1000,
|
|
|
|
|
customerPhone: '',
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const form = reactive(emptyForm())
|
|
|
|
|
|
|
|
|
|
const isFormValid = computed(
|
|
|
|
|
() => form.customerName.trim().length > 0 && form.companyId.length > 0,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const filteredOrders = computed(() => {
|
|
|
|
|
let list = orderList.value
|
|
|
|
|
if (activeTab.value !== 'all') {
|
|
|
|
|
list = list.filter((o) => o.status === activeTab.value)
|
|
|
|
|
}
|
|
|
|
|
if (searchQuery.value.trim()) {
|
|
|
|
|
const q = searchQuery.value.trim()
|
|
|
|
|
list = list.filter(
|
|
|
|
|
(o) => o.orderNumber.includes(q) || o.customerName.includes(q),
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
return list
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const selectedOrder = computed(() =>
|
|
|
|
|
orderList.value.find((o) => o.id === selectedOrderId.value) ?? null,
|
|
|
|
|
)
|
|
|
|
|
|
2026-08-06 17:12:28 +03:30
|
|
|
async function loadData() {
|
|
|
|
|
try {
|
|
|
|
|
const [ordersData, companiesData] = await Promise.all([
|
|
|
|
|
ordersApi.list(),
|
|
|
|
|
companiesApi.list(),
|
|
|
|
|
])
|
|
|
|
|
orderList.value = ordersData.map((o) => mapAdminOrder(o) as Order)
|
|
|
|
|
companies.value = companiesData
|
|
|
|
|
if (!form.companyId && companiesData[0]) {
|
|
|
|
|
form.companyId = companiesData[0].id
|
|
|
|
|
}
|
|
|
|
|
} catch (err) {
|
|
|
|
|
toast.error(err instanceof ApiError ? err.message : 'بارگذاری سفارشها انجام نشد.')
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
void loadData()
|
|
|
|
|
})
|
|
|
|
|
|
2026-08-03 12:14:12 +02:00
|
|
|
function selectOrder(order: Order, openDetail = false) {
|
|
|
|
|
selectedOrderId.value = order.id
|
|
|
|
|
if (openDetail) {
|
|
|
|
|
showDetailPanel.value = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function openOrderDetail(order: Order) {
|
|
|
|
|
selectedOrderId.value = order.id
|
|
|
|
|
showDetailModal.value = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function closeDetailPanel() {
|
|
|
|
|
showDetailPanel.value = false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function closeDetailModal() {
|
|
|
|
|
showDetailModal.value = false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function settlementLabel(method: string) {
|
|
|
|
|
return method === 'check' ? 'چکی' : 'نقدی'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function goPricing(order: Order) {
|
|
|
|
|
router.push(`/orders/${order.id}/pricing`)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function goChecks(order: Order) {
|
|
|
|
|
router.push(`/orders/${order.id}/checks`)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function openAddModal() {
|
|
|
|
|
Object.assign(form, emptyForm())
|
|
|
|
|
formError.value = ''
|
|
|
|
|
showAddModal.value = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function closeAddModal() {
|
|
|
|
|
showAddModal.value = false
|
|
|
|
|
formError.value = ''
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-06 17:12:28 +03:30
|
|
|
async function submitAddOrder() {
|
2026-08-03 12:14:12 +02:00
|
|
|
if (!isFormValid.value) {
|
|
|
|
|
formError.value = 'نام مشتری و شرکت الزامی هستند.'
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-06 17:12:28 +03:30
|
|
|
saving.value = true
|
|
|
|
|
try {
|
|
|
|
|
const created = await ordersApi.create({
|
|
|
|
|
companyId: form.companyId,
|
|
|
|
|
customerName: form.customerName.trim(),
|
|
|
|
|
customerPhone: form.customerPhone.trim() || undefined,
|
|
|
|
|
settlementMethod: form.settlementMethod,
|
|
|
|
|
meterage: form.meterage,
|
|
|
|
|
})
|
|
|
|
|
const mapped = mapAdminOrder(created) as Order
|
|
|
|
|
orderList.value.unshift(mapped)
|
|
|
|
|
selectedOrderId.value = mapped.id
|
|
|
|
|
toast.success('سفارش جدید ثبت شد.')
|
|
|
|
|
closeAddModal()
|
|
|
|
|
} catch (err) {
|
|
|
|
|
toast.error(err instanceof ApiError ? err.message : 'ثبت سفارش انجام نشد.')
|
|
|
|
|
} finally {
|
|
|
|
|
saving.value = false
|
2026-08-03 12:14:12 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
companies,
|
|
|
|
|
orderList,
|
|
|
|
|
activeTab,
|
|
|
|
|
selectedOrderId,
|
|
|
|
|
searchQuery,
|
|
|
|
|
showAddModal,
|
|
|
|
|
showDetailPanel,
|
|
|
|
|
showDetailModal,
|
|
|
|
|
formError,
|
|
|
|
|
form,
|
|
|
|
|
isFormValid,
|
|
|
|
|
filteredOrders,
|
|
|
|
|
selectedOrder,
|
|
|
|
|
selectOrder,
|
|
|
|
|
openOrderDetail,
|
|
|
|
|
closeDetailPanel,
|
|
|
|
|
closeDetailModal,
|
|
|
|
|
settlementLabel,
|
|
|
|
|
goPricing,
|
|
|
|
|
goChecks,
|
|
|
|
|
openAddModal,
|
|
|
|
|
closeAddModal,
|
|
|
|
|
submitAddOrder,
|
2026-08-06 17:12:28 +03:30
|
|
|
saving,
|
2026-08-03 12:14:12 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export type OrdersPageContext = ReturnType<typeof useOrdersPage>
|
|
|
|
|
|
|
|
|
|
export const ORDERS_PAGE_KEY: InjectionKey<OrdersPageContext> = Symbol('orders-page')
|
|
|
|
|
|
|
|
|
|
export function provideOrdersPage() {
|
|
|
|
|
const ctx = useOrdersPage()
|
|
|
|
|
provide(ORDERS_PAGE_KEY, ctx)
|
|
|
|
|
return ctx
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function useOrdersPageContext() {
|
|
|
|
|
const ctx = inject(ORDERS_PAGE_KEY)
|
|
|
|
|
if (!ctx) throw new Error('Orders page context is missing')
|
|
|
|
|
return ctx
|
|
|
|
|
}
|