Queue invoice status check
This commit is contained in:
parent
18603cd97a
commit
c88572356f
7 changed files with 181 additions and 9 deletions
|
@ -1,21 +1,21 @@
|
|||
import { IMessageContext } from "@saleor/components/messages";
|
||||
import useNotifier from "@saleor/hooks/useNotifier";
|
||||
import { checkOrderInvoicesStatus } from "@saleor/orders/queries";
|
||||
import ApolloClient from "apollo-client";
|
||||
import React from "react";
|
||||
import { useApolloClient } from "react-apollo";
|
||||
import { IntlShape, useIntl } from "react-intl";
|
||||
|
||||
import BackgroundTasksContext from "./context";
|
||||
import { handleTask, queueCustom } from "./tasks";
|
||||
import { handleTask, queueCustom, queueInvoiceGenerate } from "./tasks";
|
||||
import { QueuedTask, Task, TaskData, TaskStatus } from "./types";
|
||||
|
||||
export const backgroundTasksRefreshTime = 15 * 1000;
|
||||
|
||||
// TODO: Remove underscores when working on #575 or similar PR
|
||||
export function useBackgroundTasks(
|
||||
_apolloClient: ApolloClient<any>,
|
||||
_notify: IMessageContext,
|
||||
_intl: IntlShape
|
||||
apolloClient: ApolloClient<any>,
|
||||
notify: IMessageContext,
|
||||
intl: IntlShape
|
||||
) {
|
||||
const idCounter = React.useRef(0);
|
||||
const tasks = React.useRef<QueuedTask[]>([]);
|
||||
|
@ -64,6 +64,23 @@ export function useBackgroundTasks(
|
|||
case Task.CUSTOM:
|
||||
queueCustom(idCounter.current, tasks, data);
|
||||
break;
|
||||
case Task.INVOICE_GENERATE:
|
||||
queueInvoiceGenerate(
|
||||
idCounter.current,
|
||||
data.generateInvoice,
|
||||
tasks,
|
||||
() =>
|
||||
apolloClient.query({
|
||||
fetchPolicy: "network-only",
|
||||
query: checkOrderInvoicesStatus,
|
||||
variables: {
|
||||
id: data.generateInvoice.orderId
|
||||
}
|
||||
}),
|
||||
notify,
|
||||
intl
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
return idCounter.current;
|
||||
|
|
|
@ -1,4 +1,31 @@
|
|||
import { QueuedTask, TaskData, TaskStatus } from "./types";
|
||||
import { IMessageContext } from "@saleor/components/messages";
|
||||
import { commonMessages } from "@saleor/intl";
|
||||
import { CheckOrderInvoicesStatus } from "@saleor/orders/types/CheckOrderInvoicesStatus";
|
||||
import { JobStatusEnum } from "@saleor/types/globalTypes";
|
||||
import { ApolloQueryResult } from "apollo-client";
|
||||
import { defineMessages, IntlShape } from "react-intl";
|
||||
|
||||
import {
|
||||
InvoiceGenerateParams,
|
||||
QueuedTask,
|
||||
TaskData,
|
||||
TaskStatus
|
||||
} from "./types";
|
||||
|
||||
export const messages = defineMessages({
|
||||
invoiceGenerateFinishedText: {
|
||||
defaultMessage:
|
||||
"Requested Invoice was generated. It was added to the top of the invoice list on this view. Enjoy!"
|
||||
},
|
||||
invoiceGenerateFinishedTitle: {
|
||||
defaultMessage: "Invoice Generated",
|
||||
description: "invoice generating has finished, header"
|
||||
},
|
||||
invoiceGenerationFailedTitle: {
|
||||
defaultMessage: "Invoice Generation",
|
||||
description: "dialog header, title"
|
||||
}
|
||||
});
|
||||
|
||||
export async function handleTask(task: QueuedTask): Promise<TaskStatus> {
|
||||
let status = TaskStatus.PENDING;
|
||||
|
@ -41,3 +68,46 @@ export function queueCustom(
|
|||
}
|
||||
];
|
||||
}
|
||||
|
||||
export function queueInvoiceGenerate(
|
||||
id: number,
|
||||
generateInvoice: InvoiceGenerateParams,
|
||||
tasks: React.MutableRefObject<QueuedTask[]>,
|
||||
fetch: () => Promise<ApolloQueryResult<CheckOrderInvoicesStatus>>,
|
||||
notify: IMessageContext,
|
||||
intl: IntlShape
|
||||
) {
|
||||
if (!generateInvoice) {
|
||||
throw new Error("generateInvoice is required when creating custom task");
|
||||
}
|
||||
tasks.current = [
|
||||
...tasks.current,
|
||||
{
|
||||
handle: async () => {
|
||||
const result = await fetch();
|
||||
const status = result.data.order.invoices.find(
|
||||
invoice => invoice.id === generateInvoice.invoiceId
|
||||
).status;
|
||||
|
||||
return status === JobStatusEnum.SUCCESS
|
||||
? TaskStatus.SUCCESS
|
||||
: status === JobStatusEnum.PENDING
|
||||
? TaskStatus.PENDING
|
||||
: TaskStatus.FAILURE;
|
||||
},
|
||||
id,
|
||||
onCompleted: data =>
|
||||
data.status === TaskStatus.SUCCESS
|
||||
? notify({
|
||||
text: intl.formatMessage(messages.invoiceGenerateFinishedText),
|
||||
title: intl.formatMessage(messages.invoiceGenerateFinishedTitle)
|
||||
})
|
||||
: notify({
|
||||
text: intl.formatMessage(commonMessages.somethingWentWrong),
|
||||
title: intl.formatMessage(messages.invoiceGenerationFailedTitle)
|
||||
}),
|
||||
onError: handleError,
|
||||
status: TaskStatus.PENDING
|
||||
}
|
||||
];
|
||||
}
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
export enum Task {
|
||||
CUSTOM
|
||||
CUSTOM,
|
||||
INVOICE_GENERATE
|
||||
}
|
||||
export enum TaskStatus {
|
||||
FAILURE,
|
||||
PENDING,
|
||||
SUCCESS
|
||||
}
|
||||
export interface InvoiceGenerateParams {
|
||||
orderId: string;
|
||||
invoiceId: string;
|
||||
}
|
||||
|
||||
export interface OnCompletedTaskData {
|
||||
status: TaskStatus;
|
||||
|
@ -21,6 +26,7 @@ export interface QueuedTask {
|
|||
}
|
||||
|
||||
export interface TaskData {
|
||||
generateInvoice?: InvoiceGenerateParams;
|
||||
id?: string;
|
||||
handle?: () => Promise<TaskStatus>;
|
||||
onCompleted?: OnCompletedTaskFn;
|
||||
|
|
|
@ -228,3 +228,15 @@ export const useOrderFulfillData = makeQuery<
|
|||
OrderFulfillData,
|
||||
OrderFulfillDataVariables
|
||||
>(orderFulfillData);
|
||||
|
||||
export const checkOrderInvoicesStatus = gql`
|
||||
${fragmentInvoice}
|
||||
query CheckOrderInvoicesStatus($id: ID!) {
|
||||
order(id: $id) {
|
||||
id
|
||||
invoices {
|
||||
...InvoiceFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
|
32
src/orders/types/CheckOrderInvoicesStatus.ts
Normal file
32
src/orders/types/CheckOrderInvoicesStatus.ts
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { JobStatusEnum } from "./../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL query operation: CheckOrderInvoicesStatus
|
||||
// ====================================================
|
||||
|
||||
export interface CheckOrderInvoicesStatus_order_invoices {
|
||||
__typename: "Invoice";
|
||||
id: string;
|
||||
number: string | null;
|
||||
createdAt: any;
|
||||
url: string | null;
|
||||
status: JobStatusEnum;
|
||||
}
|
||||
|
||||
export interface CheckOrderInvoicesStatus_order {
|
||||
__typename: "Order";
|
||||
id: string;
|
||||
invoices: (CheckOrderInvoicesStatus_order_invoices | null)[] | null;
|
||||
}
|
||||
|
||||
export interface CheckOrderInvoicesStatus {
|
||||
order: CheckOrderInvoicesStatus_order | null;
|
||||
}
|
||||
|
||||
export interface CheckOrderInvoicesStatusVariables {
|
||||
id: string;
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
import { messages } from "@saleor/containers/BackgroundTasks/tasks";
|
||||
import useNavigator from "@saleor/hooks/useNavigator";
|
||||
import useNotifier from "@saleor/hooks/useNotifier";
|
||||
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
||||
|
@ -45,6 +46,7 @@ interface OrderDetailsMessages {
|
|||
handleShippingMethodUpdate: (data: OrderShippingMethodUpdate) => void;
|
||||
handleUpdate: (data: OrderUpdate) => void;
|
||||
handleInvoiceGeneratePending: (data: InvoiceRequest) => void;
|
||||
handleInvoiceGenerateFinished: (data: InvoiceRequest) => void;
|
||||
handleInvoiceSend: (data: InvoiceEmailSend) => void;
|
||||
}) => React.ReactElement;
|
||||
id: string;
|
||||
|
@ -270,6 +272,16 @@ export const OrderDetailsMessages: React.FC<OrderDetailsMessages> = ({
|
|||
closeModal();
|
||||
}
|
||||
};
|
||||
const handleInvoiceGenerateFinished = (data: InvoiceRequest) => {
|
||||
const errs = data.invoiceRequest?.errors;
|
||||
if (errs.length === 0) {
|
||||
pushMessage({
|
||||
text: intl.formatMessage(messages.invoiceGenerateFinishedText),
|
||||
title: intl.formatMessage(messages.invoiceGenerateFinishedTitle)
|
||||
});
|
||||
closeModal();
|
||||
}
|
||||
};
|
||||
const handleInvoiceSend = (data: InvoiceEmailSend) => {
|
||||
const errs = data.invoiceSendEmail?.errors;
|
||||
if (errs.length === 0) {
|
||||
|
@ -286,6 +298,7 @@ export const OrderDetailsMessages: React.FC<OrderDetailsMessages> = ({
|
|||
handleDraftCancel,
|
||||
handleDraftFinalize,
|
||||
handleDraftUpdate,
|
||||
handleInvoiceGenerateFinished,
|
||||
handleInvoiceGeneratePending,
|
||||
handleInvoiceSend,
|
||||
handleNoteAdd,
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
import NotFoundPage from "@saleor/components/NotFoundPage";
|
||||
import { WindowTitle } from "@saleor/components/WindowTitle";
|
||||
import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config";
|
||||
import { Task } from "@saleor/containers/BackgroundTasks/types";
|
||||
import useBackgroundTask from "@saleor/hooks/useBackgroundTask";
|
||||
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 { InvoiceRequest } from "@saleor/orders/types/InvoiceRequest";
|
||||
import useCustomerSearch from "@saleor/searches/useCustomerSearch";
|
||||
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
||||
import { useWarehouseList } from "@saleor/warehouses/queries";
|
||||
|
@ -18,7 +21,11 @@ import {
|
|||
transformAddressToForm,
|
||||
} from "../../../misc";
|
||||
import { productUrl } from "../../../products/urls";
|
||||
import { FulfillmentStatus, OrderStatus } from "../../../types/globalTypes";
|
||||
import {
|
||||
FulfillmentStatus,
|
||||
JobStatusEnum,
|
||||
OrderStatus,
|
||||
} from "../../../types/globalTypes";
|
||||
import OrderAddressEditDialog from "../../components/OrderAddressEditDialog";
|
||||
import OrderCancelDialog from "../../components/OrderCancelDialog";
|
||||
import OrderDetailsPage from "../../components/OrderDetailsPage";
|
||||
|
@ -104,6 +111,7 @@ export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
|
|||
first: 30,
|
||||
},
|
||||
});
|
||||
const { queue } = useBackgroundTask();
|
||||
const intl = useIntl();
|
||||
|
||||
const [openModal, closeModal] = createDialogActionHandlers<
|
||||
|
@ -149,7 +157,21 @@ export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
|
|||
onDraftFinalize={orderMessages.handleDraftFinalize}
|
||||
onDraftCancel={orderMessages.handleDraftCancel}
|
||||
onOrderMarkAsPaid={orderMessages.handleOrderMarkAsPaid}
|
||||
onInvoiceRequest={orderMessages.handleInvoiceGeneratePending}
|
||||
onInvoiceRequest={(data: InvoiceRequest) => {
|
||||
if (
|
||||
data.invoiceRequest.invoice.status === JobStatusEnum.SUCCESS
|
||||
) {
|
||||
orderMessages.handleInvoiceGenerateFinished(data);
|
||||
} else {
|
||||
orderMessages.handleInvoiceGeneratePending(data);
|
||||
queue(Task.INVOICE_GENERATE, {
|
||||
params: {
|
||||
invoiceId: data.invoiceRequest.invoice.id,
|
||||
orderId: id,
|
||||
},
|
||||
});
|
||||
}
|
||||
}}
|
||||
onInvoiceSend={orderMessages.handleInvoiceSend}
|
||||
>
|
||||
{({
|
||||
|
|
Loading…
Reference in a new issue