From 8a756f539b3c16e2c98a1ba78cc3c00e416743f1 Mon Sep 17 00:00:00 2001 From: Dawid Tarasiuk Date: Wed, 24 Jun 2020 17:29:13 +0200 Subject: [PATCH] Create invoice email send dialog --- .../OrderInvoiceEmailSendDialog.tsx | 93 +++++++++++++++++++ .../OrderInvoiceEmailSendDialog/index.ts | 2 + src/orders/urls.ts | 3 +- src/orders/views/OrderDetails/index.tsx | 22 ++++- src/utils/errors/invoice.ts | 44 +++++++++ 5 files changed, 160 insertions(+), 4 deletions(-) create mode 100644 src/orders/components/OrderInvoiceEmailSendDialog/OrderInvoiceEmailSendDialog.tsx create mode 100644 src/orders/components/OrderInvoiceEmailSendDialog/index.ts create mode 100644 src/utils/errors/invoice.ts diff --git a/src/orders/components/OrderInvoiceEmailSendDialog/OrderInvoiceEmailSendDialog.tsx b/src/orders/components/OrderInvoiceEmailSendDialog/OrderInvoiceEmailSendDialog.tsx new file mode 100644 index 000000000..0c55b7809 --- /dev/null +++ b/src/orders/components/OrderInvoiceEmailSendDialog/OrderInvoiceEmailSendDialog.tsx @@ -0,0 +1,93 @@ +import Button from "@material-ui/core/Button"; +import Dialog from "@material-ui/core/Dialog"; +import DialogActions from "@material-ui/core/DialogActions"; +import DialogContent from "@material-ui/core/DialogContent"; +import DialogContentText from "@material-ui/core/DialogContentText"; +import DialogTitle from "@material-ui/core/DialogTitle"; +import ConfirmButton, { + ConfirmButtonTransitionState +} from "@saleor/components/ConfirmButton"; +import Form from "@saleor/components/Form"; +import FormSpacer from "@saleor/components/FormSpacer"; +import { buttonMessages } from "@saleor/intl"; +import { InvoiceErrorFragment } from "@saleor/orders/types/InvoiceErrorFragment"; +import { InvoiceFragment } from "@saleor/orders/types/InvoiceFragment"; +import getInvoiceErrorMessage from "@saleor/utils/errors/invoice"; +import React from "react"; +import { FormattedMessage, useIntl } from "react-intl"; + +export interface FormData { + amount: number; +} + +export interface OrderInvoiceEmailSendDialogProps { + confirmButtonState: ConfirmButtonTransitionState; + errors: InvoiceErrorFragment[]; + open: boolean; + invoice: InvoiceFragment; + onClose: () => void; + onSubmit: () => void; +} + +const OrderInvoiceEmailSendDialog: React.FC = ({ + confirmButtonState, + errors, + open, + invoice, + onClose, + onSubmit +}) => { + const intl = useIntl(); + + return ( + +
+ {({ submit }) => ( + <> + + {intl.formatMessage({ + defaultMessage: "Send Invoice", + description: "dialog header" + })} + + + + {invoice?.number} + }} + /> + + {errors.length > 0 && ( + <> + + {errors.map(err => ( + + {getInvoiceErrorMessage(err, intl)} + + ))} + + )} + + + + + + + + + )} +
+
+ ); +}; +OrderInvoiceEmailSendDialog.displayName = "OrderInvoiceEmailSendDialog"; +export default OrderInvoiceEmailSendDialog; diff --git a/src/orders/components/OrderInvoiceEmailSendDialog/index.ts b/src/orders/components/OrderInvoiceEmailSendDialog/index.ts new file mode 100644 index 000000000..62455152a --- /dev/null +++ b/src/orders/components/OrderInvoiceEmailSendDialog/index.ts @@ -0,0 +1,2 @@ +export { default } from "./OrderInvoiceEmailSendDialog"; +export * from "./OrderInvoiceEmailSendDialog"; diff --git a/src/orders/urls.ts b/src/orders/urls.ts index e4935f6f9..0efa7ffde 100644 --- a/src/orders/urls.ts +++ b/src/orders/urls.ts @@ -99,7 +99,8 @@ export type OrderUrlDialog = | "finalize" | "mark-paid" | "refund" - | "void"; + | "void" + | "invoice-send"; export type OrderUrlQueryParams = Dialog & SingleAction; export const orderUrl = (id: string, params?: OrderUrlQueryParams) => orderPath(encodeURIComponent(id)) + "?" + stringifyQs(params); diff --git a/src/orders/views/OrderDetails/index.tsx b/src/orders/views/OrderDetails/index.tsx index 820eea9c1..e6f020422 100644 --- a/src/orders/views/OrderDetails/index.tsx +++ b/src/orders/views/OrderDetails/index.tsx @@ -4,6 +4,7 @@ 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 OrderInvoiceEmailSendDialog from "@saleor/orders/components/OrderInvoiceEmailSendDialog"; import useCustomerSearch from "@saleor/searches/useCustomerSearch"; import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers"; import { useWarehouseList } from "@saleor/warehouses/queries"; @@ -237,13 +238,13 @@ export const OrderDetails: React.FC = ({ id, params }) => { onInvoiceClick={(invoice) => window.open(invoice.url, "_blank") } - onGenerateInvoice={() => + onInvoiceGenerate={() => orderInvoiceRequest.mutate({ orderId: id, }) } - onSendInvoice={(invoice) => - orderInvoiceSend.mutate({ id: invoice.id }) + onInvoiceSend={(invoice) => + openModal("invoice-send", { id: invoice.id }) } /> = ({ id, params }) => { } onClose={closeModal} /> + invoice.id === params.id + )} + onClose={closeModal} + onSubmit={() => + orderInvoiceSend.mutate({ id: params.id }) + } + /> ) : ( <> diff --git a/src/utils/errors/invoice.ts b/src/utils/errors/invoice.ts new file mode 100644 index 000000000..9dd750b61 --- /dev/null +++ b/src/utils/errors/invoice.ts @@ -0,0 +1,44 @@ +import { commonMessages } from "@saleor/intl"; +import { InvoiceErrorFragment } from "@saleor/orders/types/InvoiceErrorFragment"; +import { InvoiceErrorCode } from "@saleor/types/globalTypes"; +import { defineMessages, IntlShape } from "react-intl"; + +import commonErrorMessages from "./common"; + +const messages = defineMessages({ + emailNotSet: { + defaultMessage: "Email address is not set", + description: "error message" + } +}); + +function getInvoiceErrorMessage( + err: InvoiceErrorFragment, + intl: IntlShape +): string { + if (err) { + switch (err.code) { + case InvoiceErrorCode.EMAIL_NOT_SET: + return intl.formatMessage(messages.emailNotSet); + case InvoiceErrorCode.INVALID_STATUS: + // TODO: update error messages + return intl.formatMessage({ defaultMessage: "" }); + case InvoiceErrorCode.NOT_FOUND: + return intl.formatMessage({ defaultMessage: "" }); + case InvoiceErrorCode.NOT_READY: + return intl.formatMessage({ defaultMessage: "" }); + case InvoiceErrorCode.NUMBER_NOT_SET: + return intl.formatMessage({ defaultMessage: "" }); + case InvoiceErrorCode.URL_NOT_SET: + return intl.formatMessage({ defaultMessage: "" }); + case InvoiceErrorCode.REQUIRED: + return intl.formatMessage(commonMessages.requiredField); + default: + return intl.formatMessage(commonErrorMessages.unknownError); + } + } + + return undefined; +} + +export default getInvoiceErrorMessage;