import NotFoundPage from "@saleor/components/NotFoundPage"; import { WindowTitle } from "@saleor/components/WindowTitle"; import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config"; import useNavigator from "@saleor/hooks/useNavigator"; import useUser from "@saleor/hooks/useUser"; import OrderCannotCancelOrderDialog from "@saleor/orders/components/OrderCannotCancelOrderDialog"; import useCustomerSearch from "@saleor/searches/useCustomerSearch"; import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers"; import { useWarehouseList } from "@saleor/warehouses/queries"; import React from "react"; import { useIntl } from "react-intl"; import { customerUrl } from "../../../customers/urls"; import { getStringOrPlaceholder, maybe, transformAddressToForm, } from "../../../misc"; import { productUrl } from "../../../products/urls"; import { FulfillmentStatus, OrderStatus } from "../../../types/globalTypes"; import OrderAddressEditDialog from "../../components/OrderAddressEditDialog"; import OrderCancelDialog from "../../components/OrderCancelDialog"; import OrderDetailsPage from "../../components/OrderDetailsPage"; import OrderDraftCancelDialog from "../../components/OrderDraftCancelDialog/OrderDraftCancelDialog"; import OrderDraftFinalizeDialog, { OrderDraftFinalizeWarning, } from "../../components/OrderDraftFinalizeDialog"; import OrderDraftPage from "../../components/OrderDraftPage"; import OrderFulfillmentCancelDialog from "../../components/OrderFulfillmentCancelDialog"; import OrderFulfillmentTrackingDialog from "../../components/OrderFulfillmentTrackingDialog"; import OrderMarkAsPaidDialog from "../../components/OrderMarkAsPaidDialog/OrderMarkAsPaidDialog"; import OrderPaymentDialog from "../../components/OrderPaymentDialog"; import OrderPaymentVoidDialog from "../../components/OrderPaymentVoidDialog"; import OrderProductAddDialog from "../../components/OrderProductAddDialog"; import OrderShippingMethodEditDialog from "../../components/OrderShippingMethodEditDialog"; import OrderOperations from "../../containers/OrderOperations"; import { TypedOrderDetailsQuery, useOrderVariantSearch } from "../../queries"; import { OrderDetails_order } from "../../types/OrderDetails"; import { orderFulfillUrl, orderListUrl, orderUrl, OrderUrlDialog, OrderUrlQueryParams, } from "../../urls"; import { OrderDetailsMessages } from "./OrderDetailsMessages"; const orderDraftFinalizeWarnings = (order: OrderDetails_order) => { const warnings = [] as OrderDraftFinalizeWarning[]; if (!(order && order.shippingAddress)) { warnings.push(OrderDraftFinalizeWarning.NO_SHIPPING); } if (!(order && order.billingAddress)) { warnings.push(OrderDraftFinalizeWarning.NO_BILLING); } if (!(order && (order.user || order.userEmail))) { warnings.push(OrderDraftFinalizeWarning.NO_USER); } if ( order && order.lines && order.lines.filter((line) => line.isShippingRequired).length > 0 && order.shippingMethod === null ) { warnings.push(OrderDraftFinalizeWarning.NO_SHIPPING_METHOD); } if ( order && order.lines && order.lines.filter((line) => line.isShippingRequired).length === 0 && order.shippingMethod !== null ) { warnings.push(OrderDraftFinalizeWarning.UNNECESSARY_SHIPPING_METHOD); } return warnings; }; interface OrderDetailsProps { id: string; params: OrderUrlQueryParams; } export const OrderDetails: React.FC = ({ id, params }) => { const navigate = useNavigator(); const { user } = useUser(); const { loadMore: loadMoreCustomers, search: searchUsers, result: users, } = useCustomerSearch({ variables: DEFAULT_INITIAL_SEARCH_DATA, }); const { loadMore, search: variantSearch, result: variantSearchOpts, } = useOrderVariantSearch({ variables: DEFAULT_INITIAL_SEARCH_DATA, }); const warehouses = useWarehouseList({ displayLoader: true, variables: { first: 30, }, }); const intl = useIntl(); const [openModal, closeModal] = createDialogActionHandlers< OrderUrlDialog, OrderUrlQueryParams >(navigate, (params) => orderUrl(id, params), params); const handleBack = () => navigate(orderListUrl()); return ( {({ data, loading }) => { const order = data?.order; if (order === null) { return ; } return ( {(orderMessages) => ( null} onInvoiceSend={() => null} > {({ orderAddNote, orderCancel, orderDraftUpdate, orderLinesAdd, orderLineDelete, orderLineUpdate, orderPaymentCapture, orderPaymentRefund, orderVoid, orderShippingMethodUpdate, orderUpdate, orderFulfillmentCancel, orderFulfillmentUpdateTracking, orderDraftCancel, orderDraftFinalize, orderPaymentMarkAsPaid, orderInvoiceRequest, orderInvoiceSend, }) => ( <> {order?.status !== OrderStatus.DRAFT ? ( <> orderAddNote.mutate({ input: variables, order: id, }) } onBack={handleBack} order={order} shippingMethods={maybe( () => data.order.availableShippingMethods, [] )} userPermissions={user?.userPermissions || []} onOrderCancel={() => openModal("cancel")} onOrderFulfill={() => navigate(orderFulfillUrl(id))} onFulfillmentCancel={(fulfillmentId) => navigate( orderUrl(id, { action: "cancel-fulfillment", id: fulfillmentId, }) ) } onFulfillmentTrackingNumberUpdate={(fulfillmentId) => navigate( orderUrl(id, { action: "edit-fulfillment", id: fulfillmentId, }) ) } onPaymentCapture={() => openModal("capture")} onPaymentVoid={() => openModal("void")} onPaymentRefund={() => openModal("refund")} onProductClick={(id) => () => navigate(productUrl(id))} onBillingAddressEdit={() => openModal("edit-billing-address") } onShippingAddressEdit={() => openModal("edit-shipping-address") } onPaymentPaid={() => openModal("mark-paid")} onProfileView={() => navigate(customerUrl(order.user.id)) } onInvoiceClick={(invoice) => window.open(invoice.url, "_blank") } onGenerateInvoice={() => orderInvoiceRequest.mutate({ orderId: id, }) } onSendInvoice={(invoice) => orderInvoiceSend.mutate({ id: invoice.id }) } /> fulfillment.status === FulfillmentStatus.FULFILLED ) } /> orderCancel.mutate({ id, }) } /> orderPaymentMarkAsPaid.mutate({ id, }) } open={params.action === "mark-paid"} /> orderVoid.mutate({ id })} /> orderPaymentCapture.mutate({ ...variables, id, }) } /> orderPaymentRefund.mutate({ ...variables, id, }) } /> edge.node ) || [] } onConfirm={(variables) => orderFulfillmentCancel.mutate({ id: params.id, input: variables, }) } onClose={closeModal} /> fulfillment.id === params.id )?.trackingNumber )} onConfirm={(variables) => orderFulfillmentUpdateTracking.mutate({ id: params.id, input: { ...variables, notifyCustomer: true, }, }) } onClose={closeModal} /> ) : ( <> orderAddNote.mutate({ input: variables, order: id, }) } users={maybe( () => users.data.search.edges.map((edge) => edge.node), [] )} hasMore={maybe( () => users.data.search.pageInfo.hasNextPage, false )} onFetchMore={loadMoreCustomers} fetchUsers={searchUsers} loading={users.loading} usersLoading={users.loading} onCustomerEdit={(data) => orderDraftUpdate.mutate({ id, input: data, }) } onDraftFinalize={() => openModal("finalize")} onDraftRemove={() => openModal("cancel")} onOrderLineAdd={() => openModal("add-order-line")} onBack={() => navigate(orderListUrl())} order={order} countries={maybe(() => data.shop.countries, []).map( (country) => ({ code: country.code, label: country.country, }) )} onProductClick={(id) => () => navigate(productUrl(encodeURIComponent(id)))} onBillingAddressEdit={() => openModal("edit-billing-address") } onShippingAddressEdit={() => openModal("edit-shipping-address") } onShippingMethodEdit={() => openModal("edit-shipping") } onOrderLineRemove={(id) => orderLineDelete.mutate({ id }) } onOrderLineChange={(id, data) => orderLineUpdate.mutate({ id, input: data, }) } saveButtonBarState="default" onProfileView={() => navigate(customerUrl(order.user.id)) } userPermissions={user?.userPermissions || []} /> orderDraftCancel.mutate({ id })} open={params.action === "cancel"} orderNumber={getStringOrPlaceholder(order?.number)} /> orderDraftFinalize.mutate({ id })} open={params.action === "finalize"} orderNumber={getStringOrPlaceholder(order?.number)} warnings={orderDraftFinalizeWarnings(order)} /> orderShippingMethodUpdate.mutate({ id, input: { shippingMethod: variables.shippingMethod, }, }) } /> edge.node )} onClose={closeModal} onFetch={variantSearch} onFetchMore={loadMore} onSubmit={(variants) => orderLinesAdd.mutate({ id, input: variants.map((variant) => ({ quantity: 1, variantId: variant.id, })), }) } /> )} ({ code: country.code, label: country.country, })) || [] } errors={orderUpdate.opts.data?.orderUpdate.errors || []} open={params.action === "edit-shipping-address"} variant="shipping" onClose={closeModal} onConfirm={(shippingAddress) => orderUpdate.mutate({ id, input: { shippingAddress, }, }) } /> ({ code: country.code, label: country.country, })) || [] } errors={orderUpdate.opts.data?.orderUpdate.errors || []} open={params.action === "edit-billing-address"} variant="billing" onClose={closeModal} onConfirm={(billingAddress) => orderUpdate.mutate({ id, input: { billingAddress, }, }) } /> )} )} ); }} ); }; export default OrderDetails;