diff --git a/src/pages/order/List.tsx b/src/pages/order/List.tsx
index 782f017..96c34c5 100644
--- a/src/pages/order/List.tsx
+++ b/src/pages/order/List.tsx
@@ -1,19 +1,21 @@
-import { type FC, useMemo, useState } from "react";
+import { type FC, useCallback, useMemo, useState } from "react";
import { Link } from "react-router-dom";
import { AddSquare, ArrowDown2, Filter } from "iconsax-react";
+import { toast } from "react-toastify";
import Filters from "@/components/Filters";
import Table from "@/components/Table";
import Tabs from "@/components/Tabs";
import Button from "@/components/Button";
import RefreshButton from "@/components/RefreshButton";
import { Paths } from "@/config/Paths";
+import { extractErrorMessage } from "@/config/func";
import { clx } from "@/helpers/utils";
import UserSearch from "../user/UserSearch";
import DesignerSearch from "../designer/DesignerSearch";
import CategoriesSelect from "../product/components/CategoriesSelect";
import { orderListTabs } from "./constants/orderStatus";
-import { orderListColumns } from "./components/OrderListColumns";
-import { useGetOrders } from "./hooks/useOrderData";
+import { getOrderListColumns } from "./components/OrderListColumns";
+import { useDeleteOrder, useGetOrders } from "./hooks/useOrderData";
import {
ORDER_LIST_FILTER_FIELDS,
useOrderListParams,
@@ -45,9 +47,30 @@ const OrdersList: FC = () => {
} = useOrderListParams();
const { data, refetch, isFetching } = useGetOrders(queryParams);
+ const { mutate: deleteOrder, isPending: isDeleting } = useDeleteOrder();
const activeFilterCount = useMemo(() => countActiveFilters(params), [params]);
const hasActiveFilters = activeFilterCount > 0;
+ const handleDelete = useCallback(
+ (id: string) => {
+ deleteOrder(id, {
+ onSuccess: () => {
+ refetch();
+ toast.success("سفارش با موفقیت حذف شد");
+ },
+ onError: (error) => {
+ toast.error(extractErrorMessage(error));
+ },
+ });
+ },
+ [deleteOrder, refetch],
+ );
+
+ const columns = useMemo(
+ () => getOrderListColumns({ onDelete: handleDelete, isDeleting }),
+ [handleDelete, isDeleting],
+ );
+
return (
@@ -158,7 +181,7 @@ const OrdersList: FC = () => {
- columns={orderListColumns}
+ columns={columns}
data={data?.data}
isLoading={isFetching}
noDataMessage="سفارشی یافت نشد"
diff --git a/src/pages/order/OrderDetail.tsx b/src/pages/order/OrderDetail.tsx
index 9643f10..8c03892 100644
--- a/src/pages/order/OrderDetail.tsx
+++ b/src/pages/order/OrderDetail.tsx
@@ -1,185 +1,85 @@
import { type FC } from 'react'
-import { useParams } from 'react-router-dom'
-import moment from 'moment-jalaali'
-import { User } from 'iconsax-react'
+import { Link, useParams } from 'react-router-dom'
+import { Edit2, Printer } from 'iconsax-react'
import BackButton from '@/components/BackButton'
import RefreshButton from '@/components/RefreshButton'
+import Button from '@/components/Button'
import { Paths } from '@/config/Paths'
import { useGetOrderDetails } from './hooks/useOrderData'
import TicketSection from './components/TicketSection'
-import OrderItem from './components/OrderItem'
-import type { OrderDetailDataType, OrderItemType } from './types/Types'
-
-const CARD_CLASS = 'bg-white rounded-2xl border border-border border-opacity-40 shadow-sm overflow-hidden'
-const SECTION_TITLE_CLASS = 'text-lg font-light text-black mb-0'
-const SECTION_HEADER_CLASS = 'border-b border-border border-opacity-40 px-6 py-5'
-
-const InfoRow: FC<{ label: string; value?: string | number | null }> = ({ label, value }) => (
-
- {label}
- {value ?? '—'}
-
-)
+import OrderDetailSidebar from './components/OrderDetailSidebar'
+import InvoiceItemDetailSection from './components/InvoiceItemDetailSection'
+import type { OrderDetailDataType } from './types/Types'
const OrderDetail: FC = () => {
const { id } = useParams()
- const { data, refetch, isFetching } = useGetOrderDetails(id!)
- const order = data?.data as (OrderDetailDataType & { items?: OrderItemType[] }) | undefined
- const creator = order?.creator
- const creatorName = creator ? `${creator.firstName} ${creator.lastName}`.trim() : ''
+ const { data, refetch, isFetching, isPending } = useGetOrderDetails(id!)
+ const order = data?.data as OrderDetailDataType | undefined
+
+ if (isPending) {
+ return (
+
+ )
+ }
return (
-
- {/* Header */}
-
-
-
+
+
+
+
+
+
جزئیات سفارش
+
+ مشاهده اطلاعات سفارش، آیتم پیشفاکتور و گفتگو
+
+
+
+
+
refetch()} isLoading={isFetching} />
- سفارش #{order?.orderNumber}
+
+
+
+
+
+
-
+
- {/* اطلاعات سفارش */}
-
-
-
اطلاعات سفارش
+
+
+
+
+
-
- {/* شماره و وضعیت — برجسته */}
-
-
- شماره سفارش
- #{order?.orderNumber ?? '—'}
-
- {order?.status && (
-
- {order.status}
-
- )}
-
- {/* جزئیات در گرید منظم */}
-
-
-
-
تاریخ ایجاد
-
- {order?.createdAt ? moment(order.createdAt).format('jYYYY/jMM/jDD — HH:mm') : '—'}
-
-
-
-
تخمین زمان (روز)
-
{order?.estimatedDays ?? '—'}
-
-
-
عنوان
-
{order?.title ?? '—'}
-
-
-
-
-
نوع / دستهبندی
-
{order?.type?.title ?? '—'}
-
-
-
محصول
-
{order?.product?.title ?? '—'}
-
-
-
شناسه آیتم فاکتور
-
{order?.invoiceItem ?? '—'}
-
-
-
-
-
- {/* اطلاعات مشتری */}
- {order?.user && (
-
- )}
-
- {/* ایجادکننده سفارش — کارت کامل */}
- {creator && (
-
-
-
ایجادکننده سفارش
-
-
-
- {/* آواتار و نام */}
-
-
-
-
-
-
{creatorName || '—'}
-
ادمین ثبتکننده
-
-
-
-
-
-
- )}
-
- {/* پیوستها */}
- {order?.attachments?.length ? (
-
-
-
پیوستها
-
-
- {order.attachments.map((att, idx) => {
- const url = typeof att === 'string' ? att : (att as { url?: string })?.url
- if (!url) return null
- return (
-
- پیوست {idx + 1}
-
- )
- })}
-
-
- ) : null}
-
- {/* اقلام سفارش */}
- {order?.items?.length ? (
-
-
-
اقلام سفارش
-
-
- {order.items.map((item) => (
-
- ))}
-
-
- ) : null}
-
-
+
+
)
}
-export default OrderDetail
\ No newline at end of file
+export default OrderDetail
diff --git a/src/pages/order/components/InvoiceItemDetailSection.tsx b/src/pages/order/components/InvoiceItemDetailSection.tsx
new file mode 100644
index 0000000..2a84767
--- /dev/null
+++ b/src/pages/order/components/InvoiceItemDetailSection.tsx
@@ -0,0 +1,150 @@
+import { type FC, type ReactNode } from 'react'
+import { Link } from 'react-router-dom'
+import moment from 'moment-jalaali'
+import { DocumentText } from 'iconsax-react'
+import { Paths } from '@/config/Paths'
+import { useGetInvoiceItem } from '@/pages/invoice/hooks/useInvoiceData'
+import { formatItemDiscountDisplay } from '@/pages/invoice/utils/invoiceItem'
+import { getUserDisplayName } from '../utils/orderDetailUtils'
+
+type Props = {
+ invoiceItemId?: string | null
+}
+
+const formatAmount = (amount: number) =>
+ Number(amount).toLocaleString('fa-IR') + ' ریال'
+
+type FieldProps = {
+ label: string
+ children: ReactNode
+ className?: string
+}
+
+const Field: FC = ({ label, children, className }) => (
+
+)
+
+const InvoiceItemDetailSection: FC = ({ invoiceItemId }) => {
+ const { data, isLoading, isError } = useGetInvoiceItem(invoiceItemId ?? null)
+ const invoiceItem = data?.data
+ const discounts = invoiceItem ? formatItemDiscountDisplay(invoiceItem) : null
+ const imageUrl = invoiceItem?.product?.images?.[0]
+
+ if (!invoiceItemId) {
+ return (
+
+ آیتم فاکتوری به این سفارش متصل نیست.
+
+ )
+ }
+
+ if (isLoading) {
+ return (
+
+
+
+
+
+ {Array.from({ length: 6 }).map((_, i) => (
+
+ ))}
+
+
+
+ )
+ }
+
+ if (isError || !invoiceItem) {
+ return (
+
+ آیتم پیشفاکتور یافت نشد.
+
+ )
+ }
+
+ return (
+
+
+
جزئیات آیتم پیشفاکتور
+
+ اطلاعات مالی و محصول مرتبط با این سفارش
+
+
+
+
+
+
+ {imageUrl ? (
+

+ ) : (
+
+
+
+ )}
+
+
+
+
+
+ #{invoiceItem.invoice.invoiceNumber}
+
+
+
+ {getUserDisplayName(invoiceItem.invoice.user)}
+
+
+ {invoiceItem.product?.title ?? '—'}
+
+
+ {invoiceItem.quantity?.toLocaleString('fa-IR') ?? '—'}
+
+
+ {invoiceItem.unitPrice != null
+ ? formatAmount(invoiceItem.unitPrice)
+ : '—'}
+
+
+ {discounts?.value ?? '—'}
+
+
+ {discounts?.percent ?? '—'}
+
+
+
+ {formatAmount(invoiceItem.total ?? 0)}
+
+
+
+ {invoiceItem.confirmedAt
+ ? moment(invoiceItem.confirmedAt).format('jYYYY/jMM/jDD HH:mm')
+ : '—'}
+
+
+
+
+ {invoiceItem.description && (
+
+
توضیحات
+
+ {invoiceItem.description}
+
+
+ )}
+
+
+ )
+}
+
+export default InvoiceItemDetailSection
diff --git a/src/pages/order/components/OrderDetailSidebar.tsx b/src/pages/order/components/OrderDetailSidebar.tsx
new file mode 100644
index 0000000..a508e7a
--- /dev/null
+++ b/src/pages/order/components/OrderDetailSidebar.tsx
@@ -0,0 +1,198 @@
+import { type FC } from 'react'
+import { Link } from 'react-router-dom'
+import { Call, Edit2, Location, Paperclip2, Profile2User, User } from 'iconsax-react'
+import { clx } from '@/helpers/utils'
+import { getFileNameAndExtensionFromUrl } from '@/config/func'
+import { Paths } from '@/config/Paths'
+import {
+ getAttachmentUrl,
+ formatJalaliDateTime,
+ getCreatorDisplayName,
+ getUserDisplayName,
+} from '../utils/orderDetailUtils'
+import {
+ getOrderStatusBadgeClass,
+ getOrderStatusLabel,
+} from '../constants/orderStatus'
+import type { OrderDetailDataType } from '../types/Types'
+
+type Props = {
+ order?: OrderDetailDataType
+}
+
+type InfoRowProps = {
+ label: string
+ value?: string | number | null
+ mono?: boolean
+}
+
+const InfoRow: FC = ({ label, value, mono }) => (
+
+
{label}
+
+ {value ?? '—'}
+
+
+)
+
+const PersonCard: FC<{
+ title: string
+ name: string
+ subtitle?: string
+ phone?: string
+ icon?: 'user' | 'designer'
+}> = ({ title, name, subtitle, phone, icon = 'user' }) => (
+
+
{title}
+
+
+ {icon === 'designer' ? (
+
+ ) : (
+
+ )}
+
+
+
{name}
+ {subtitle &&
{subtitle}
}
+ {phone && (
+
+
+ {phone}
+
+ )}
+
+
+
+)
+
+const OrderDetailSidebar: FC = ({ order }) => {
+ const attachments = (order?.attachments ?? [])
+ .map(getAttachmentUrl)
+ .filter((url): url is string => Boolean(url))
+
+ return (
+
+
+
+
+
شماره سفارش
+
+ #{order?.orderNumber ?? '—'}
+
+
+
+ {order?.id && (
+
+
+
+ )}
+ {order?.status && (
+
+ {getOrderStatusLabel(order.status)}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+ {order?.user && (
+
+ مشتری
+
+ {order.user.addresse && (
+
+
+
{order.user.addresse}
+
+ )}
+
+ )}
+
+ {(order?.creator || order?.designer) && (
+
+ تیم
+ {order.creator && (
+
+ )}
+ {order.designer && (
+
+ )}
+
+ )}
+
+ {attachments.length > 0 && (
+
+ )}
+
+ )
+}
+
+export default OrderDetailSidebar
diff --git a/src/pages/order/components/OrderItem.tsx b/src/pages/order/components/OrderItem.tsx
index bf6891a..c04593c 100644
--- a/src/pages/order/components/OrderItem.tsx
+++ b/src/pages/order/components/OrderItem.tsx
@@ -4,86 +4,134 @@ import { useGetEntityField } from '@/pages/formBuilder/hooks/useFormBuilderData'
import Button from '@/components/Button'
import { Link, useParams } from 'react-router-dom'
import { Paths } from '@/config/Paths'
+import { clx } from '@/helpers/utils'
+import { DocumentText, Printer } from 'iconsax-react'
type Props = {
- item: OrderItemType,
- estimatedDays?: number,
+ item: OrderItemType
+ estimatedDays?: number
+ designerName?: string
+ index?: number
}
-const OrderItem: FC = ({ item, estimatedDays }) => {
+const formatPrice = (value?: number | null) =>
+ value != null ? value.toLocaleString('fa-IR') + ' ریال' : '—'
+const OrderItem: FC = ({ item, estimatedDays, designerName, index }) => {
const { id } = useParams()
const { data: fields } = useGetEntityField(String(item.product?.id ?? ''))
+ const hasPrintForm = Boolean(item.printAttributes?.length)
+ const imageUrl = item.product?.images?.[0]
+ const stats = [
+ { label: 'تعداد', value: item.quantity?.toLocaleString('fa-IR') },
+ { label: 'تخمین زمان', value: estimatedDays != null ? `${estimatedDays} روز` : '—' },
+ { label: 'مبلغ واحد', value: formatPrice(item.unitPrice) },
+ { label: 'تخفیف', value: formatPrice(item.discount) },
+ { label: 'جمع', value: formatPrice(item.total) },
+ ]
return (
-
-
-
#{item.id}
+
+
+
+
+ {index ?? item.id}
+
+
+
+ {item.product?.title ?? '—'}
+
+
شناسه: {item.id}
+
+
+ className={clx(
+ 'w-fit px-4 text-sm',
+ hasPrintForm
+ ? 'bg-blue-50 border border-blue-200 text-blue-700'
+ : 'bg-white border border-gray-200 text-gray-800',
+ )}
+ >
+
+
+ {hasPrintForm ? 'ویرایش فرم پرینت' : 'فرم پرینت'}
+
+
-
- {/* Product Image */}
-
-

-
- {/* Order Details */}
-
-
-
عنوان:
-
{item.product.title}
-
-
-
نام طرح:
-
{'orderData.designer'}
-
-
-
تعداد:
-
{item.quantity}
-
-
-
تخمین زمان:
-
{estimatedDays}
-
-
-
-
- {/* Order Description */}
-
-
شرح سفارش:
-
- {item.description}
-
-
-
-
- ویژگی ها
-
- {
- fields?.data?.map((field) => {
- const value = item.attributes?.find((o) => String(o.attributeId) === String(field.id))
-
-
- return (
-
-
- {field.name} :
-
-
- {value?.value || '-'}
+
+
+
+ {imageUrl ? (
+

+ ) : (
+
+
+ )}
+
+
+
+
+ {stats.map(({ label, value }) => (
+
+ ))}
- )
- })
- }
-
+
+ {designerName && designerName !== '—' && (
+
+ طراح: {designerName}
+
+ )}
+
+
+
+ {item.description && (
+
+
شرح سفارش
+
{item.description}
+
+ )}
+
+ {fields?.data && fields.data.length > 0 && (
+
+
ویژگیها
+
+ {fields.data.map((field) => {
+ const value = item.attributes?.find(
+ (attr) => String(attr.attributeId) === String(field.id),
+ )
+ return (
+
+ {field.name}
+
+ {value?.value || '—'}
+
+
+ )
+ })}
+
+
+ )}
+
+
)
}
-export default OrderItem
\ No newline at end of file
+export default OrderItem
diff --git a/src/pages/order/components/OrderListActions.tsx b/src/pages/order/components/OrderListActions.tsx
new file mode 100644
index 0000000..bc8c69d
--- /dev/null
+++ b/src/pages/order/components/OrderListActions.tsx
@@ -0,0 +1,52 @@
+import { type FC } from "react";
+import { Link } from "react-router-dom";
+import { DocumentText, Edit2, Eye, Printer, Receipt21 } from "iconsax-react";
+import TrashWithConfrim from "@/components/TrashWithConfrim";
+import { Paths } from "@/config/Paths";
+import { getOrderInvoiceItemRef } from "../utils/orderListUtils";
+import type { OrderListItemType } from "../types/Types";
+
+type Props = {
+ item: OrderListItemType;
+ onDelete: (id: string) => void;
+ isDeleting?: boolean;
+};
+
+const OrderListActions: FC
= ({ item, onDelete, isDeleting }) => {
+ const invoiceRef = getOrderInvoiceItemRef(item);
+
+ return (
+
+
+
+
+
+
+
+ {invoiceRef?.invoiceId && (
+
+
+
+ )}
+
+
+
+
+
+
+
+
+
+
onDelete(item.id)}
+ isloading={isDeleting}
+ colorIcon="red"
+ />
+
+ );
+};
+
+export default OrderListActions;
diff --git a/src/pages/order/components/OrderListColumns.tsx b/src/pages/order/components/OrderListColumns.tsx
index c47f11a..849aa3d 100644
--- a/src/pages/order/components/OrderListColumns.tsx
+++ b/src/pages/order/components/OrderListColumns.tsx
@@ -1,12 +1,10 @@
-import { Link } from "react-router-dom";
import moment from "moment-jalaali";
-import { Edit2, Printer } from "iconsax-react";
import type { ColumnType } from "@/components/types/TableTypes";
-import { Paths } from "@/config/Paths";
import {
getOrderStatusBadgeClass,
getOrderStatusLabel,
} from "../constants/orderStatus";
+import OrderListActions from "./OrderListActions";
import type { OrderListItemType } from "../types/Types";
const getCustomerName = (item: OrderListItemType) => {
@@ -27,7 +25,15 @@ const getDesignerName = (item: OrderListItemType) => {
return name || designer.phone || "—";
};
-export const orderListColumns: ColumnType[] = [
+type OrderListColumnsOptions = {
+ onDelete: (id: string) => void;
+ isDeleting?: boolean;
+};
+
+export const getOrderListColumns = ({
+ onDelete,
+ isDeleting,
+}: OrderListColumnsOptions): ColumnType[] => [
{
key: "orderNumber",
title: "شماره",
@@ -35,14 +41,7 @@ export const orderListColumns: ColumnType[] = [
{
key: "title",
title: "عنوان",
- render: (item) => (
-
- {item.title}
-
- ),
+ render: (item) => {item.title},
},
{
key: "customer",
@@ -83,14 +82,11 @@ export const orderListColumns: ColumnType[] = [
key: "actions",
title: "",
render: (item) => (
-
+
),
},
];
diff --git a/src/pages/order/components/TicketSection.tsx b/src/pages/order/components/TicketSection.tsx
index 62a4186..6df98be 100644
--- a/src/pages/order/components/TicketSection.tsx
+++ b/src/pages/order/components/TicketSection.tsx
@@ -88,11 +88,15 @@ const TicketSection: FC = () => {
}
return (
-
-
-
گفتگو
+
+
+
+
گفتگو
+
پیامها و فایلهای مرتبط با سفارش
+
refetch()} isLoading={isFetching} />
+
{
data?.data?.map((item) => {
if (item.user)
@@ -250,6 +254,7 @@ const TicketSection: FC = () => {
isLoading={singleUpload.isPending || multiUpload.isPending || addTicket.isPending}
/>
+
)
}
diff --git a/src/pages/order/hooks/useOrderData.ts b/src/pages/order/hooks/useOrderData.ts
index 4608f29..53848fc 100644
--- a/src/pages/order/hooks/useOrderData.ts
+++ b/src/pages/order/hooks/useOrderData.ts
@@ -1,4 +1,4 @@
-import { useMutation, useQuery } from "@tanstack/react-query";
+import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import * as api from "../service/OrderService";
import type {
AddTicketType,
@@ -121,3 +121,14 @@ export const useGetOrderPrint = (orderId: string) => {
enabled: !!orderId,
});
};
+
+export const useDeleteOrder = () => {
+ const queryClient = useQueryClient();
+
+ return useMutation({
+ mutationFn: api.deleteOrder,
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ["orders"] });
+ },
+ });
+};
diff --git a/src/pages/order/service/OrderService.ts b/src/pages/order/service/OrderService.ts
index 6ec9c3e..42d716e 100644
--- a/src/pages/order/service/OrderService.ts
+++ b/src/pages/order/service/OrderService.ts
@@ -143,3 +143,8 @@ export const getOrderPrint = async (
);
return data;
};
+
+export const deleteOrder = async (orderId: string) => {
+ const { data } = await axios.delete(`/admin/orders/${orderId}`);
+ return data;
+};
diff --git a/src/pages/order/types/Types.ts b/src/pages/order/types/Types.ts
index 1064d42..80e09aa 100644
--- a/src/pages/order/types/Types.ts
+++ b/src/pages/order/types/Types.ts
@@ -73,11 +73,16 @@ export interface OrderItemAttribute {
export type OrderResponseType = BaseResponse
;
+export type OrderListInvoiceItemRef = {
+ id: string;
+ invoice?: { id: string } | string | null;
+};
+
export interface OrderListItemType extends RowDataType {
id: string;
createdAt: string;
deletedAt: string | null;
- invoiceItem: string;
+ invoiceItem: string | OrderListInvoiceItemRef | null;
product: Product | null;
print: string | null;
title: string;
diff --git a/src/pages/order/utils/orderDetailUtils.ts b/src/pages/order/utils/orderDetailUtils.ts
new file mode 100644
index 0000000..4841dbd
--- /dev/null
+++ b/src/pages/order/utils/orderDetailUtils.ts
@@ -0,0 +1,29 @@
+import moment from 'moment-jalaali'
+import type { OrderDetailCreatorType, UserType } from '../types/Types'
+
+export const formatPersonName = (
+ person?: { firstName?: string | null; lastName?: string | null; phone?: string } | null,
+) => {
+ if (!person) return '—'
+ const name = [person.firstName, person.lastName].filter(Boolean).join(' ').trim()
+ return name || person.phone || '—'
+}
+
+export const formatJalaliDateTime = (date?: string | null) =>
+ date ? moment(date).format('jYYYY/jMM/jDD — HH:mm') : '—'
+
+export const formatJalaliDate = (date?: string | null) =>
+ date ? moment(date).format('jYYYY/jMM/jDD') : '—'
+
+export const getAttachmentUrl = (attachment: unknown): string | null => {
+ if (typeof attachment === 'string') return attachment
+ if (attachment && typeof attachment === 'object' && 'url' in attachment) {
+ return (attachment as { url?: string }).url ?? null
+ }
+ return null
+}
+
+export const getUserDisplayName = (user?: UserType | null) => formatPersonName(user)
+
+export const getCreatorDisplayName = (creator?: OrderDetailCreatorType | null) =>
+ formatPersonName(creator)
diff --git a/src/pages/order/utils/orderListUtils.ts b/src/pages/order/utils/orderListUtils.ts
new file mode 100644
index 0000000..0283b94
--- /dev/null
+++ b/src/pages/order/utils/orderListUtils.ts
@@ -0,0 +1,19 @@
+import type { OrderListItemType } from "../types/Types";
+
+export const getOrderInvoiceItemRef = (item: OrderListItemType) => {
+ const invoiceItem = item.invoiceItem;
+ if (!invoiceItem) return null;
+
+ if (typeof invoiceItem === "string") {
+ return { invoiceItemId: invoiceItem, invoiceId: null as string | null };
+ }
+
+ const invoice = invoiceItem.invoice;
+ const invoiceId =
+ typeof invoice === "string" ? invoice : invoice?.id ?? null;
+
+ return {
+ invoiceItemId: invoiceItem.id,
+ invoiceId,
+ };
+};