"use client"; import type { HospitalityListConfig } from "@/modules/hospitality/components/HospitalityListCrudPage"; import { hospitalityApi } from "@/modules/hospitality/services/hospitality-api"; import { auditColumns, codeNameCreateFields, codeNameStatusColumns, lifecycleStatusOptions, venueIdField, } from "@/modules/hospitality/constants/fieldHelpers"; import { venueFormatLabels } from "@/modules/hospitality/design-system/tokens"; const venueFormatOptions = Object.entries(venueFormatLabels).map(([value, label]) => ({ value, label, })); const menuStatusOptions = [ { value: "draft", label: "پیش‌نویس" }, { value: "published", label: "منتشر شده" }, { value: "archived", label: "آرشیو" }, ]; const tableStatusOptions = [ { value: "available", label: "آزاد" }, { value: "occupied", label: "اشغال" }, { value: "reserved", label: "رزرو" }, { value: "cleaning", label: "نظافت" }, { value: "out_of_service", label: "خارج از سرویس" }, ]; const posPaymentMethodOptions = [ { value: "cash", label: "نقد" }, { value: "card", label: "کارت" }, { value: "other", label: "سایر" }, ]; const posDiscountKindOptions = [ { value: "percent", label: "درصدی" }, { value: "fixed", label: "مبلغ ثابت" }, ]; const connectorKindFilter = (kind: string) => (row: Record) => String(row.kind) === kind; const connectorColumns = [ { key: "code", header: "کد" }, { key: "name", header: "نام" }, { key: "kind", header: "نوع" }, { key: "external_ref", header: "ارجاع خارجی" }, { key: "status", header: "وضعیت", type: "status" as const }, ...auditColumns(), ]; const connectorCreateFields = (kind: string, kindLabel: string) => codeNameCreateFields([ { name: "kind", label: "نوع کانکتور", type: "select", required: true, options: [{ value: kind, label: kindLabel }], }, venueIdField(false), ]); export const hospitalityResources = { venues: { title: "مکان‌ها (Venues)", description: "مدیریت مکان‌های مهمان‌نوازی — کافه، رستوران، فست‌فود و …", breadcrumb: "مکان‌ها", resourceKey: "venues", bundleFeature: null, permission: "hospitality.venues.view", api: hospitalityApi.venues, columns: [ { key: "code", header: "کد" }, { key: "name", header: "نام" }, { key: "venue_format", header: "نوع", render: (r) => venueFormatLabels[String(r.venue_format)] ?? String(r.venue_format), }, { key: "status", header: "وضعیت", type: "status" }, { key: "currency_code", header: "ارز" }, ...auditColumns(), ], createFields: [ { name: "code", label: "کد", required: true }, { name: "name", label: "نام", required: true }, { name: "venue_format", label: "نوع کسب‌وکار", type: "select", required: true, options: venueFormatOptions, }, ], editFields: [ { name: "name", label: "نام", required: true }, { name: "status", label: "وضعیت", type: "select", options: lifecycleStatusOptions, }, ], filterDeleted: true, } satisfies HospitalityListConfig, branches: { title: "شعب", breadcrumb: "شعب", resourceKey: "branches", bundleFeature: null, permission: "hospitality.view", api: hospitalityApi.branches, columns: codeNameStatusColumns([{ key: "venue_id", header: "مکان" }]), createFields: codeNameCreateFields([venueIdField(), { name: "timezone", label: "منطقه زمانی" }]), editFields: [ { name: "name", label: "نام", required: true }, { name: "status", label: "وضعیت", type: "select", options: lifecycleStatusOptions }, ], filterDeleted: true, } satisfies HospitalityListConfig, diningAreas: { title: "سالن‌ها", breadcrumb: "سالن‌ها", resourceKey: "diningAreas", bundleFeature: null, permission: "hospitality.view", api: hospitalityApi.diningAreas, columns: codeNameStatusColumns([ { key: "venue_id", header: "مکان" }, { key: "sort_order", header: "ترتیب", type: "text" }, ]), createFields: codeNameCreateFields([venueIdField(), { name: "sort_order", label: "ترتیب", type: "number" }]), filterDeleted: true, } satisfies HospitalityListConfig, tables: { title: "میزها", breadcrumb: "میزها", resourceKey: "tables", bundleFeature: null, permission: "hospitality.view", api: hospitalityApi.tables, columns: [ { key: "code", header: "کد" }, { key: "name", header: "نام" }, { key: "capacity", header: "ظرفیت" }, { key: "status", header: "وضعیت", type: "status" }, { key: "dining_area_id", header: "سالن" }, { key: "qr_token", header: "توکن QR", defaultVisible: false }, ...auditColumns(), ], createFields: codeNameCreateFields([ venueIdField(), { name: "capacity", label: "ظرفیت", type: "number", required: true }, { name: "dining_area_id", label: "شناسه سالن" }, { name: "status", label: "وضعیت", type: "select", options: tableStatusOptions, }, ]), filterDeleted: true, } satisfies HospitalityListConfig, posFloorPlans: { title: "نقشه سالن", breadcrumb: "نقشه سالن", resourceKey: "posFloorPlans", bundleFeature: "pos_pro", permission: "hospitality.view", api: hospitalityApi.posFloorPlans, columns: codeNameStatusColumns([ { key: "venue_id", header: "مکان" }, { key: "dining_area_id", header: "سالن" }, ]), createFields: codeNameCreateFields([ venueIdField(), { name: "dining_area_id", label: "شناسه سالن" }, ]), filterDeleted: true, } satisfies HospitalityListConfig, reservations: { title: "رزروها", breadcrumb: "رزروها", resourceKey: "reservations", bundleFeature: "reservation", permission: "hospitality.view", api: hospitalityApi.reservations, columns: [ { key: "code", header: "کد" }, { key: "guest_name", header: "مهمان", searchable: true }, { key: "guest_phone", header: "تلفن", defaultVisible: false }, { key: "party_size", header: "تعداد نفر" }, { key: "reserved_from", header: "از", type: "datetime" }, { key: "reserved_to", header: "تا", type: "datetime" }, { key: "status", header: "وضعیت", type: "status" }, { key: "table_id", header: "میز", defaultVisible: false }, ...auditColumns(), ], createFields: [ venueIdField(), { name: "code", label: "کد", required: true }, { name: "guest_name", label: "نام مهمان", required: true }, { name: "guest_phone", label: "تلفن", type: "tel" }, { name: "party_size", label: "تعداد نفر", type: "number", required: true }, { name: "reserved_from", label: "شروع رزرو", type: "datetime-local", required: true }, { name: "reserved_to", label: "پایان رزرو", type: "datetime-local", required: true }, { name: "notes", label: "یادداشت", type: "textarea" }, ], rowActions: [ { label: "تأیید", onClick: async (tenantId, row) => { await hospitalityApi.reservations.updateStatus(tenantId, String(row.id), { status: "confirmed" }); }, }, ], filterDeleted: true, } satisfies HospitalityListConfig, waitlist: { title: "صف انتظار", breadcrumb: "صف انتظار", resourceKey: "waitlist", bundleFeature: "table_service", permission: "hospitality.view", api: hospitalityApi.waitlist, columns: [ { key: "code", header: "کد" }, { key: "guest_name", header: "مهمان", searchable: true }, { key: "party_size", header: "تعداد نفر" }, { key: "phone", header: "تلفن" }, { key: "status", header: "وضعیت", type: "status" }, ...auditColumns(), ], createFields: [ venueIdField(), { name: "code", label: "کد", required: true }, { name: "guest_name", label: "نام مهمان", required: true }, { name: "party_size", label: "تعداد نفر", type: "number", required: true }, { name: "phone", label: "تلفن", type: "tel" }, { name: "notes", label: "یادداشت", type: "textarea" }, ], rowActions: [ { label: "نشست", onClick: async (tenantId, row) => { await hospitalityApi.waitlist.updateStatus(tenantId, String(row.id), { status: "seated" }); }, }, ], filterDeleted: true, } satisfies HospitalityListConfig, menus: { title: "منوی دیجیتال", breadcrumb: "منوی دیجیتال", resourceKey: "menus", bundleFeature: "digital_menu", permission: "hospitality.view", api: hospitalityApi.menus, columns: [ { key: "code", header: "کد" }, { key: "name", header: "نام" }, { key: "status", header: "وضعیت", type: "status" }, { key: "currency_code", header: "ارز" }, { key: "is_default", header: "پیش‌فرض", render: (r) => (r.is_default ? "بله" : "خیر") }, ...auditColumns(), ], createFields: codeNameCreateFields([ venueIdField(), { name: "currency_code", label: "ارز", required: true }, { name: "is_default", label: "پیش‌فرض (true/false)" }, ]), editFields: [ { name: "name", label: "نام", required: true }, { name: "status", label: "وضعیت", type: "select", options: menuStatusOptions }, ], filterDeleted: true, } satisfies HospitalityListConfig, menuCategories: { title: "دسته‌بندی منو", breadcrumb: "دسته‌بندی منو", resourceKey: "menuCategories", bundleFeature: "digital_menu", permission: "hospitality.view", api: hospitalityApi.menuCategories, columns: [ { key: "code", header: "کد" }, { key: "name", header: "نام" }, { key: "menu_id", header: "منو" }, { key: "sort_order", header: "ترتیب" }, { key: "status", header: "وضعیت", type: "status" }, ...auditColumns(), ], createFields: codeNameCreateFields([ venueIdField(), { name: "menu_id", label: "شناسه منو", required: true }, { name: "sort_order", label: "ترتیب", type: "number" }, ]), filterDeleted: true, } satisfies HospitalityListConfig, menuItems: { title: "آیتم‌های منو", breadcrumb: "آیتم‌های منو", resourceKey: "menuItems", bundleFeature: "digital_menu", permission: "hospitality.view", api: hospitalityApi.menuItems, columns: [ { key: "code", header: "کد" }, { key: "name", header: "نام", searchable: true }, { key: "base_price", header: "قیمت پایه", type: "money" }, { key: "is_available", header: "موجود", render: (r) => (r.is_available ? "بله" : "خیر") }, { key: "status", header: "وضعیت", type: "status" }, { key: "menu_id", header: "منو", defaultVisible: false }, { key: "category_id", header: "دسته", defaultVisible: false }, ...auditColumns(), ], createFields: codeNameCreateFields([ venueIdField(), { name: "menu_id", label: "شناسه منو", required: true }, { name: "category_id", label: "شناسه دسته" }, { name: "base_price", label: "قیمت پایه", type: "number", required: true }, { name: "is_available", label: "موجود (true/false)" }, ]), filterDeleted: true, } satisfies HospitalityListConfig, modifierGroups: { title: "گروه افزودنی", breadcrumb: "گروه افزودنی", resourceKey: "modifierGroups", bundleFeature: "digital_menu", permission: "hospitality.view", api: hospitalityApi.modifierGroups, columns: codeNameStatusColumns([ { key: "selection_mode", header: "حالت انتخاب" }, { key: "min_select", header: "حداقل" }, { key: "max_select", header: "حداکثر" }, { key: "is_required", header: "اجباری", render: (r) => (r.is_required ? "بله" : "خیر") }, ]), createFields: codeNameCreateFields([ venueIdField(), { name: "selection_mode", label: "حالت انتخاب", required: true }, { name: "min_select", label: "حداقل انتخاب", type: "number" }, { name: "max_select", label: "حداکثر انتخاب", type: "number" }, { name: "is_required", label: "اجباری (true/false)" }, ]), filterDeleted: true, } satisfies HospitalityListConfig, modifierOptions: { title: "گزینه افزودنی", breadcrumb: "گزینه افزودنی", resourceKey: "modifierOptions", bundleFeature: "digital_menu", permission: "hospitality.view", api: hospitalityApi.modifierOptions, columns: [ { key: "code", header: "کد" }, { key: "name", header: "نام" }, { key: "modifier_group_id", header: "گروه" }, { key: "price_delta", header: "تغییر قیمت", type: "money" }, { key: "is_default", header: "پیش‌فرض", render: (r) => (r.is_default ? "بله" : "خیر") }, { key: "status", header: "وضعیت", type: "status" }, ...auditColumns(), ], createFields: [ venueIdField(), { name: "modifier_group_id", label: "شناسه گروه", required: true }, { name: "code", label: "کد", required: true }, { name: "name", label: "نام", required: true }, { name: "price_delta", label: "تغییر قیمت", type: "number" }, { name: "currency_code", label: "ارز" }, ], filterDeleted: true, } satisfies HospitalityListConfig, availabilityWindows: { title: "قوانین دسترسی", breadcrumb: "قوانین دسترسی", resourceKey: "availabilityWindows", bundleFeature: "digital_menu", permission: "hospitality.view", api: hospitalityApi.availabilityWindows, columns: [ { key: "code", header: "کد" }, { key: "name", header: "نام" }, { key: "scope", header: "دامنه" }, { key: "target_id", header: "هدف" }, { key: "weekday", header: "روز هفته" }, { key: "start_time", header: "شروع" }, { key: "end_time", header: "پایان" }, { key: "status", header: "وضعیت", type: "status" }, ...auditColumns(), ], createFields: codeNameCreateFields([ venueIdField(), { name: "scope", label: "دامنه", required: true }, { name: "target_id", label: "شناسه هدف", required: true }, { name: "weekday", label: "روز هفته (0-6)", type: "number" }, { name: "start_time", label: "ساعت شروع", required: true }, { name: "end_time", label: "ساعت پایان", required: true }, ]), filterDeleted: true, } satisfies HospitalityListConfig, menuMediaRefs: { title: "کتابخانه رسانه", breadcrumb: "کتابخانه رسانه", resourceKey: "menuMediaRefs", bundleFeature: "digital_menu", permission: "hospitality.view", api: hospitalityApi.menuMediaRefs, columns: [ { key: "kind", header: "نوع رسانه" }, { key: "file_ref", header: "فایل" }, { key: "alt_text", header: "متن جایگزین" }, { key: "menu_id", header: "منو", defaultVisible: false }, { key: "menu_item_id", header: "آیتم", defaultVisible: false }, { key: "sort_order", header: "ترتیب" }, { key: "status", header: "وضعیت", type: "status" }, ...auditColumns(), ], createFields: [ venueIdField(), { name: "kind", label: "نوع رسانه", required: true }, { name: "file_ref", label: "مرجع فایل", required: true }, { name: "alt_text", label: "متن جایگزین" }, { name: "menu_id", label: "شناسه منو" }, { name: "menu_item_id", label: "شناسه آیتم" }, { name: "sort_order", label: "ترتیب", type: "number" }, ], filterDeleted: true, } satisfies HospitalityListConfig, qrCodes: { title: "منوی QR", breadcrumb: "منوی QR", resourceKey: "qrCodes", bundleFeature: "qr_menu", permission: "hospitality.view", api: hospitalityApi.qrCodes, columns: [ { key: "code", header: "کد" }, { key: "name", header: "نام" }, { key: "token", header: "توکن" }, { key: "target_type", header: "نوع هدف" }, { key: "ordering_enabled", header: "سفارش", render: (r) => (r.ordering_enabled ? "فعال" : "غیرفعال") }, { key: "status", header: "وضعیت", type: "status" }, ...auditColumns(), ], createFields: codeNameCreateFields([ venueIdField(), { name: "target_type", label: "نوع هدف", required: true }, { name: "menu_id", label: "شناسه منو" }, { name: "table_id", label: "شناسه میز" }, { name: "ordering_enabled", label: "سفارش فعال (true/false)" }, ]), filterDeleted: true, } satisfies HospitalityListConfig, qrMenuSessions: { title: "پروفایل مهمان", breadcrumb: "پروفایل مهمان", resourceKey: "qrMenuSessions", bundleFeature: "qr_menu", permission: "hospitality.view", api: hospitalityApi.qrMenuSessions, columns: [ { key: "session_token", header: "توکن نشست" }, { key: "guest_label", header: "مهمان" }, { key: "locale", header: "زبان" }, { key: "status", header: "وضعیت", type: "status" }, { key: "qr_code_id", header: "QR", defaultVisible: false }, { key: "table_id", header: "میز", defaultVisible: false }, ...auditColumns(), ], createFields: [ venueIdField(), { name: "qr_code_id", label: "شناسه QR", required: true }, { name: "guest_label", label: "برچسب مهمان" }, { name: "locale", label: "زبان" }, { name: "menu_id", label: "شناسه منو" }, { name: "table_id", label: "شناسه میز" }, ], filterDeleted: true, } satisfies HospitalityListConfig, qrOrderingSessions: { title: "سفارش QR", breadcrumb: "سفارش QR", resourceKey: "qrOrderingSessions", bundleFeature: "qr_ordering", permission: "hospitality.view", api: hospitalityApi.qrOrderingSessions, columns: [ { key: "session_token", header: "توکن نشست" }, { key: "guest_label", header: "مهمان" }, { key: "status", header: "وضعیت", type: "status" }, { key: "qr_code_id", header: "QR", defaultVisible: false }, { key: "table_id", header: "میز" }, ...auditColumns(), ], createFields: [ venueIdField(), { name: "qr_code_id", label: "شناسه QR", required: true }, { name: "guest_label", label: "برچسب مهمان" }, { name: "notes", label: "یادداشت", type: "textarea" }, ], rowActions: [ { label: "ثبت سفارش", onClick: async (tenantId, row) => { await hospitalityApi.qrOrderingSessions.submit(tenantId, String(row.id)); }, }, ], filterDeleted: true, } satisfies HospitalityListConfig, carts: { title: "سبد خرید", breadcrumb: "سبد خرید", resourceKey: "carts", bundleFeature: "qr_ordering", permission: "hospitality.view", api: hospitalityApi.carts, columns: [ { key: "ordering_session_id", header: "نشست سفارش" }, { key: "status", header: "وضعیت", type: "status" }, { key: "currency_code", header: "ارز" }, { key: "notes", header: "یادداشت", defaultVisible: false }, ...auditColumns(), ], createFields: [ venueIdField(), { name: "ordering_session_id", label: "شناسه نشست سفارش", required: true }, { name: "currency_code", label: "ارز" }, { name: "notes", label: "یادداشت", type: "textarea" }, ], filterDeleted: true, } satisfies HospitalityListConfig, cartLines: { title: "تسویه", breadcrumb: "تسویه", resourceKey: "cartLines", bundleFeature: "qr_ordering", permission: "hospitality.view", api: hospitalityApi.cartLines, columns: [ { key: "cart_id", header: "سبد" }, { key: "menu_item_id", header: "آیتم" }, { key: "quantity", header: "تعداد" }, { key: "unit_price", header: "قیمت واحد", type: "money" }, { key: "line_notes", header: "یادداشت", defaultVisible: false }, ...auditColumns(), ], createFields: [ venueIdField(), { name: "cart_id", label: "شناسه سبد", required: true }, { name: "menu_item_id", label: "شناسه آیتم", required: true }, { name: "quantity", label: "تعداد", type: "number", required: true }, { name: "line_notes", label: "یادداشت خط", type: "textarea" }, ], filterDeleted: true, } satisfies HospitalityListConfig, kitchenTickets: { title: "نمایشگر آشپزخانه", breadcrumb: "نمایشگر آشپزخانه", resourceKey: "kitchenTickets", bundleFeature: "kitchen", permission: "hospitality.view", api: hospitalityApi.kitchenTickets, refreshIntervalMs: 5000, columns: [ { key: "code", header: "کد" }, { key: "source_type", header: "منبع" }, { key: "source_id", header: "شناسه منبع", defaultVisible: false }, { key: "status", header: "وضعیت", type: "status" }, { key: "station_id", header: "ایستگاه", defaultVisible: false }, ...auditColumns(), ], createFields: [ venueIdField(), { name: "code", label: "کد", required: true }, { name: "source_type", label: "نوع منبع", required: true }, { name: "source_id", label: "شناسه منبع", required: true }, { name: "station_id", label: "شناسه ایستگاه" }, { name: "notes", label: "یادداشت", type: "textarea" }, ], rowActions: [ { label: "آماده", onClick: async (tenantId, row) => { await hospitalityApi.kitchenTickets.updateStatus(tenantId, String(row.id), { status: "ready" }); }, }, { label: "تکمیل", onClick: async (tenantId, row) => { await hospitalityApi.kitchenTickets.updateStatus(tenantId, String(row.id), { status: "bumped" }); }, }, ], filterDeleted: true, } satisfies HospitalityListConfig, kitchenTicketItems: { title: "صف آشپزخانه", breadcrumb: "صف آشپزخانه", resourceKey: "kitchenTicketItems", bundleFeature: "kitchen", permission: "hospitality.view", api: hospitalityApi.kitchenTicketItems, refreshIntervalMs: 5000, columns: [ { key: "kitchen_ticket_id", header: "تیکت" }, { key: "menu_item_id", header: "آیتم" }, { key: "quantity", header: "تعداد" }, { key: "status", header: "وضعیت", type: "status" }, { key: "sort_order", header: "ترتیب", defaultVisible: false }, ...auditColumns(), ], createFields: [ venueIdField(), { name: "kitchen_ticket_id", label: "شناسه تیکت", required: true }, { name: "menu_item_id", label: "شناسه آیتم", required: true }, { name: "quantity", label: "تعداد", type: "number", required: true }, ], rowActions: [ { label: "آماده", onClick: async (tenantId, row) => { await hospitalityApi.kitchenTicketItems.updateStatus(tenantId, String(row.id), { status: "ready" }); }, }, ], filterDeleted: true, } satisfies HospitalityListConfig, kitchenTicketsPrep: { title: "وضعیت آماده‌سازی", breadcrumb: "وضعیت آماده‌سازی", resourceKey: "kitchenTicketsPrep", bundleFeature: "kitchen", permission: "hospitality.view", api: hospitalityApi.kitchenTickets, refreshIntervalMs: 5000, listFilter: (row) => String(row.status) === "preparing", columns: [ { key: "code", header: "کد" }, { key: "source_type", header: "منبع" }, { key: "status", header: "وضعیت", type: "status" }, { key: "station_id", header: "ایستگاه" }, ...auditColumns(), ], rowActions: [ { label: "آماده", onClick: async (tenantId, row) => { await hospitalityApi.kitchenTickets.updateStatus(tenantId, String(row.id), { status: "ready" }); }, }, ], readOnly: true, } satisfies HospitalityListConfig, posTickets: { title: "POS Lite", breadcrumb: "POS Lite", resourceKey: "posTickets", bundleFeature: "pos_lite", permission: "hospitality.view", api: hospitalityApi.posTickets, columns: [ { key: "code", header: "کد" }, { key: "register_id", header: "صندوق" }, { key: "status", header: "وضعیت", type: "status" }, { key: "currency_code", header: "ارز" }, { key: "table_id", header: "میز", defaultVisible: false }, ...auditColumns(), ], createFields: [ venueIdField(), { name: "code", label: "کد", required: true }, { name: "register_id", label: "شناسه صندوق", required: true }, { name: "currency_code", label: "ارز" }, { name: "table_id", label: "شناسه میز" }, ], filterDeleted: true, } satisfies HospitalityListConfig, posRegisters: { title: "صندوق", breadcrumb: "صندوق", resourceKey: "posRegisters", bundleFeature: "pos_lite", permission: "hospitality.view", api: hospitalityApi.posRegisters, columns: codeNameStatusColumns([{ key: "venue_id", header: "مکان" }]), createFields: codeNameCreateFields([venueIdField()]), filterDeleted: true, } satisfies HospitalityListConfig, posPayments: { title: "POS Pro", breadcrumb: "POS Pro", resourceKey: "posPayments", bundleFeature: "pos_pro", permission: "hospitality.view", api: hospitalityApi.posPayments, columns: [ { key: "ticket_id", header: "تیکت" }, { key: "method", header: "روش پرداخت" }, { key: "amount", header: "مبلغ", type: "money" }, { key: "currency_code", header: "ارز" }, { key: "status", header: "وضعیت", type: "status" }, { key: "external_payment_ref", header: "ارجاع خارجی", defaultVisible: false }, ...auditColumns(), ], createFields: [ venueIdField(), { name: "ticket_id", label: "شناسه تیکت", required: true }, { name: "method", label: "روش پرداخت", type: "select", required: true, options: posPaymentMethodOptions, }, { name: "amount", label: "مبلغ", type: "number", required: true }, { name: "currency_code", label: "ارز" }, ], filterDeleted: true, } satisfies HospitalityListConfig, posPaymentsList: { title: "پرداخت‌ها", breadcrumb: "پرداخت‌ها", resourceKey: "posPaymentsList", bundleFeature: "pos_pro", permission: "hospitality.view", api: hospitalityApi.posPayments, columns: [ { key: "ticket_id", header: "تیکت" }, { key: "method", header: "روش" }, { key: "amount", header: "مبلغ", type: "money" }, { key: "currency_code", header: "ارز" }, { key: "status", header: "وضعیت", type: "status" }, { key: "created_at", header: "زمان", type: "datetime" }, ], createFields: [ venueIdField(), { name: "ticket_id", label: "شناسه تیکت", required: true }, { name: "method", label: "روش پرداخت", type: "select", required: true, options: posPaymentMethodOptions, }, { name: "amount", label: "مبلغ", type: "number", required: true }, ], filterDeleted: true, } satisfies HospitalityListConfig, posDiscounts: { title: "تخفیف‌ها", breadcrumb: "تخفیف‌ها", resourceKey: "posDiscounts", bundleFeature: "pos_pro", permission: "hospitality.view", api: hospitalityApi.posDiscounts, listFilter: (row) => !String(row.code ?? "").toUpperCase().startsWith("CPN"), columns: [ { key: "code", header: "کد" }, { key: "name", header: "نام" }, { key: "ticket_id", header: "تیکت" }, { key: "kind", header: "نوع" }, { key: "value", header: "مقدار" }, ...auditColumns(), ], createFields: [ venueIdField(), { name: "ticket_id", label: "شناسه تیکت", required: true }, { name: "code", label: "کد", required: true }, { name: "kind", label: "نوع", type: "select", required: true, options: posDiscountKindOptions, }, { name: "value", label: "مقدار", type: "number", required: true }, { name: "name", label: "نام" }, ], filterDeleted: true, } satisfies HospitalityListConfig, posDiscountsCoupons: { title: "کوپن‌ها", breadcrumb: "کوپن‌ها", resourceKey: "posDiscountsCoupons", bundleFeature: "pos_pro", permission: "hospitality.view", api: hospitalityApi.posDiscounts, listFilter: (row) => String(row.code ?? "").toUpperCase().startsWith("CPN"), columns: [ { key: "code", header: "کد کوپن" }, { key: "name", header: "نام" }, { key: "kind", header: "نوع" }, { key: "value", header: "مقدار" }, { key: "ticket_id", header: "تیکت", defaultVisible: false }, ...auditColumns(), ], createFields: [ venueIdField(), { name: "ticket_id", label: "شناسه تیکت", required: true }, { name: "code", label: "کد کوپن (CPN-…)", required: true }, { name: "kind", label: "نوع", type: "select", required: true, options: posDiscountKindOptions, }, { name: "value", label: "مقدار", type: "number", required: true }, { name: "name", label: "نام", required: true }, ], filterDeleted: true, } satisfies HospitalityListConfig, featureTogglesPromo: { title: "پروموشن‌ها", breadcrumb: "پروموشن‌ها", resourceKey: "featureTogglesPromo", bundleFeature: "pos_pro", permission: "hospitality.view", api: hospitalityApi.featureToggles, useUpsert: true, listFilter: (row) => String(row.feature_key ?? "").toLowerCase().includes("promo"), columns: [ { key: "feature_key", header: "کلید قابلیت" }, { key: "enabled", header: "فعال", render: (r) => (r.enabled ? "بله" : "خیر") }, { key: "bundle_key", header: "بسته", defaultVisible: false }, { key: "venue_id", header: "مکان", defaultVisible: false }, ...auditColumns(), ], createFields: [ { name: "feature_key", label: "کلید قابلیت", required: true, placeholder: "hospitality.promo.*" }, { name: "enabled", label: "فعال", type: "select", required: true, options: [ { value: "true", label: "بله" }, { value: "false", label: "خیر" }, ], }, venueIdField(false), ], } satisfies HospitalityListConfig, connectorRegistrationsCrm: { title: "مشتریان", breadcrumb: "مشتریان", resourceKey: "connectorRegistrationsCrm", bundleFeature: "crm_connector", permission: "hospitality.view", api: hospitalityApi.connectorRegistrations, listFilter: connectorKindFilter("crm"), columns: connectorColumns, createFields: connectorCreateFields("crm", "CRM"), filterDeleted: true, } satisfies HospitalityListConfig, connectorCrm: { title: "CRM", breadcrumb: "CRM", resourceKey: "connectorCrm", bundleFeature: "crm_connector", permission: "hospitality.view", api: hospitalityApi.connectorRegistrations, listFilter: connectorKindFilter("crm"), columns: connectorColumns, createFields: connectorCreateFields("crm", "CRM"), filterDeleted: true, } satisfies HospitalityListConfig, connectorLoyalty: { title: "وفاداری", breadcrumb: "وفاداری", resourceKey: "connectorLoyalty", bundleFeature: "loyalty_connector", permission: "hospitality.view", api: hospitalityApi.connectorRegistrations, listFilter: connectorKindFilter("loyalty"), columns: connectorColumns, createFields: connectorCreateFields("loyalty", "وفاداری"), filterDeleted: true, } satisfies HospitalityListConfig, connectorCommunication: { title: "ارتباطات", breadcrumb: "ارتباطات", resourceKey: "connectorCommunication", bundleFeature: "communication_connector", permission: "hospitality.view", api: hospitalityApi.connectorRegistrations, listFilter: connectorKindFilter("communication"), columns: connectorColumns, createFields: connectorCreateFields("communication", "ارتباطات"), filterDeleted: true, } satisfies HospitalityListConfig, connectorWebsite: { title: "وب‌سایت", breadcrumb: "وب‌سایت", resourceKey: "connectorWebsite", bundleFeature: "website_connector", permission: "hospitality.view", api: hospitalityApi.connectorRegistrations, listFilter: connectorKindFilter("website"), columns: connectorColumns, createFields: connectorCreateFields("website", "وب‌سایت"), filterDeleted: true, } satisfies HospitalityListConfig, connectorDelivery: { title: "پیک", breadcrumb: "پیک", resourceKey: "connectorDelivery", bundleFeature: "delivery_connector", permission: "hospitality.view", api: hospitalityApi.connectorRegistrations, listFilter: connectorKindFilter("delivery"), columns: connectorColumns, createFields: connectorCreateFields("delivery", "پیک"), filterDeleted: true, } satisfies HospitalityListConfig, connectorDispatches: { title: "مارکت‌پلیس", breadcrumb: "مارکت‌پلیس", resourceKey: "connectorDispatches", bundleFeature: null, permission: "hospitality.view", api: hospitalityApi.connectorDispatches, columns: [ { key: "event_type", header: "نوع رویداد" }, { key: "direction", header: "جهت" }, { key: "status", header: "وضعیت", type: "status" }, { key: "registration_id", header: "ثبت‌نام" }, { key: "payload_ref", header: "Payload", defaultVisible: false }, ...auditColumns(), ], createFields: [ venueIdField(false), { name: "registration_id", label: "شناسه ثبت‌نام", required: true }, { name: "event_type", label: "نوع رویداد", required: true }, { name: "direction", label: "جهت", required: true }, { name: "payload_ref", label: "مرجع Payload" }, ], filterDeleted: true, } satisfies HospitalityListConfig, pickupOrders: { title: "سفارش بیرون‌بر", breadcrumb: "سفارش بیرون‌بر", resourceKey: "pickupOrders", bundleFeature: "qr_ordering", permission: "hospitality.view", api: hospitalityApi.qrOrderingSessions, listFilter: (row) => row.table_id == null, columns: [ { key: "session_token", header: "توکن" }, { key: "guest_label", header: "مهمان" }, { key: "status", header: "وضعیت", type: "status" }, { key: "notes", header: "یادداشت", defaultVisible: false }, ...auditColumns(), ], readOnly: true, } satisfies HospitalityListConfig, onlineOrders: { title: "سفارش آنلاین", breadcrumb: "سفارش آنلاین", resourceKey: "onlineOrders", bundleFeature: "qr_ordering", permission: "hospitality.view", api: hospitalityApi.qrOrderingSessions, listFilter: (row) => row.table_id != null, columns: [ { key: "session_token", header: "توکن" }, { key: "guest_label", header: "مهمان" }, { key: "table_id", header: "میز" }, { key: "status", header: "وضعیت", type: "status" }, ...auditColumns(), ], readOnly: true, } satisfies HospitalityListConfig, orderTimeline: { title: "خط زمانی سفارش", breadcrumb: "خط زمانی سفارش", resourceKey: "orderTimeline", bundleFeature: "kitchen", permission: "hospitality.view", api: hospitalityApi.kitchenTickets, refreshIntervalMs: 10000, columns: [ { key: "code", header: "کد" }, { key: "source_type", header: "منبع" }, { key: "status", header: "وضعیت", type: "status" }, { key: "created_at", header: "ایجاد", type: "datetime" }, { key: "updated_at", header: "به‌روزرسانی", type: "datetime" }, ], readOnly: true, } satisfies HospitalityListConfig, invoices: { title: "فاکتورها", breadcrumb: "فاکتورها", resourceKey: "invoices", bundleFeature: "pos_lite", permission: "hospitality.view", api: hospitalityApi.posTickets, listFilter: (row) => !["void", "cancelled"].includes(String(row.status)), columns: [ { key: "code", header: "کد فاکتور" }, { key: "register_id", header: "صندوق" }, { key: "status", header: "وضعیت", type: "status" }, { key: "currency_code", header: "ارز" }, { key: "created_at", header: "تاریخ", type: "datetime" }, ], readOnly: true, } satisfies HospitalityListConfig, receipts: { title: "رسیدها", breadcrumb: "رسیدها", resourceKey: "receipts", bundleFeature: "pos_lite", permission: "hospitality.view", api: hospitalityApi.posTickets, listFilter: (row) => String(row.status) === "paid", columns: [ { key: "code", header: "کد رسید" }, { key: "register_id", header: "صندوق" }, { key: "currency_code", header: "ارز" }, { key: "created_at", header: "تاریخ پرداخت", type: "datetime" }, ], readOnly: true, } satisfies HospitalityListConfig, analyticsReports: { title: "گزارش‌ها", breadcrumb: "گزارش‌ها", resourceKey: "analyticsReports", bundleFeature: "analytics", permission: "hospitality.view", api: hospitalityApi.analyticsReports, columns: [ { key: "code", header: "کد" }, { key: "name", header: "نام" }, { key: "metric_keys", header: "متریک‌ها", render: (r) => (Array.isArray(r.metric_keys) ? (r.metric_keys as string[]).join(", ") : "—"), }, { key: "status", header: "وضعیت", type: "status" }, ...auditColumns(), ], createFields: codeNameCreateFields([ venueIdField(false), { name: "metric_keys", label: "متریک‌ها (جدا با کاما)", required: true }, ]), filterDeleted: true, } satisfies HospitalityListConfig, analyticsSnapshots: { title: "آنالیتیکس", breadcrumb: "آنالیتیکس", resourceKey: "analyticsSnapshots", bundleFeature: "analytics", permission: "hospitality.view", api: hospitalityApi.analyticsSnapshots, columns: [ { key: "report_id", header: "گزارش" }, { key: "period_start", header: "شروع دوره" }, { key: "period_end", header: "پایان دوره" }, { key: "status", header: "وضعیت", type: "status" }, { key: "metrics", header: "متریک‌ها", render: (r) => r.metrics && typeof r.metrics === "object" ? String(Object.keys(r.metrics as object).length) : "0", }, ...auditColumns(), ], readOnly: true, } satisfies HospitalityListConfig, inventoryOverview: { title: "موجودی", breadcrumb: "موجودی", resourceKey: "inventoryOverview", bundleFeature: "analytics", permission: "hospitality.view", api: hospitalityApi.analyticsSnapshots, listFilter: (row) => { const metrics = row.metrics as Record | null | undefined; if (!metrics) return false; return Object.keys(metrics).some((k) => k.toLowerCase().includes("inventory") || k.toLowerCase().includes("stock")); }, columns: [ { key: "period_start", header: "شروع" }, { key: "period_end", header: "پایان" }, { key: "metrics", header: "موجودی", render: (r) => { const metrics = r.metrics as Record | undefined; if (!metrics) return "—"; const inv = Object.entries(metrics).find(([k]) => k.toLowerCase().includes("inventory") || k.toLowerCase().includes("stock") ); return inv ? String(inv[1]) : "—"; }, }, { key: "status", header: "وضعیت", type: "status" }, ], readOnly: true, } satisfies HospitalityListConfig, settings: { title: "تنظیمات", breadcrumb: "تنظیمات", resourceKey: "settings", bundleFeature: null, permission: "hospitality.view", api: hospitalityApi.settings, useUpsert: true, columns: [ { key: "key", header: "کلید", searchable: true }, { key: "value", header: "مقدار", render: (r) => (r.value != null ? JSON.stringify(r.value) : "—"), }, { key: "venue_id", header: "مکان", defaultVisible: false }, ...auditColumns(), ], createFields: [ { name: "key", label: "کلید", required: true }, { name: "value", label: "مقدار (JSON)", type: "textarea", placeholder: '{"enabled": true}' }, venueIdField(false), ], } satisfies HospitalityListConfig, permissions: { title: "مجوزها", breadcrumb: "مجوزها", resourceKey: "permissions", bundleFeature: null, permission: "hospitality.view", api: hospitalityApi.permissions, columns: [ { key: "code", header: "کد" }, { key: "name", header: "نام" }, { key: "bundle_key", header: "بسته", defaultVisible: false }, { key: "status", header: "وضعیت", type: "status" }, ...auditColumns(), ], createFields: [ { name: "code", label: "کد", required: true }, { name: "name", label: "نام", required: true }, { name: "description", label: "توضیح", type: "textarea" }, { name: "bundle_key", label: "کلید بسته" }, ], filterDeleted: true, } satisfies HospitalityListConfig, roles: { title: "نقش‌ها", breadcrumb: "نقش‌ها", resourceKey: "roles", bundleFeature: null, permission: "hospitality.view", api: hospitalityApi.roles, columns: codeNameStatusColumns([ { key: "venue_id", header: "مکان", defaultVisible: false }, { key: "permission_keys", header: "مجوزها", render: (r) => (Array.isArray(r.permission_keys) ? (r.permission_keys as string[]).join(", ") : "—"), defaultVisible: false, }, ]), createFields: codeNameCreateFields([ venueIdField(false), { name: "description", label: "توضیح", type: "textarea" }, { name: "permission_keys", label: "مجوزها (جدا با کاما)" }, ]), filterDeleted: true, } satisfies HospitalityListConfig, events: { title: "لاگ ممیزی", breadcrumb: "لاگ ممیزی", resourceKey: "events", bundleFeature: null, permission: "hospitality.view", api: hospitalityApi.events, columns: [ { key: "event_type", header: "نوع رویداد", searchable: true }, { key: "title", header: "عنوان", searchable: true }, { key: "status", header: "وضعیت", type: "status" }, { key: "venue_id", header: "مکان", defaultVisible: false }, ...auditColumns(), ], createFields: [ venueIdField(), { name: "event_type", label: "نوع رویداد", required: true }, { name: "title", label: "عنوان", required: true }, { name: "payload", label: "Payload (JSON)", type: "textarea" }, ], filterDeleted: true, } satisfies HospitalityListConfig, notifications: { title: "اعلان‌ها", breadcrumb: "اعلان‌ها", resourceKey: "notifications", bundleFeature: null, permission: "hospitality.view", api: hospitalityApi.events, listFilter: (row) => { const t = String(row.event_type ?? ""); return ( t.includes("status_changed") || t.includes("submitted") || t.includes("payment") || t.includes("waitlist") ); }, columns: [ { key: "event_type", header: "نوع" }, { key: "title", header: "اعلان" }, { key: "created_at", header: "زمان", type: "datetime" }, { key: "status", header: "وضعیت", type: "status", defaultVisible: false }, ], readOnly: true, } satisfies HospitalityListConfig, tenantBundles: { title: "بسته‌های فعال", breadcrumb: "بسته‌های فعال", resourceKey: "tenantBundles", bundleFeature: null, permission: "hospitality.view", api: hospitalityApi.tenantBundles, readOnly: true, columns: [ { key: "bundle_key", header: "بسته" }, { key: "status", header: "وضعیت", type: "status" }, { key: "venue_id", header: "مکان", defaultVisible: false }, { key: "activated_by", header: "فعال‌ساز", defaultVisible: false }, { key: "bundle_definition_id", header: "تعریف بسته", defaultVisible: false }, ...auditColumns(), ], rowActions: [ { label: "غیرفعال", variant: "danger", onClick: async (tenantId, row) => { await hospitalityApi.tenantBundles.deactivate(tenantId, String(row.id)); }, }, ], } satisfies HospitalityListConfig, } as const satisfies Record;