diff --git a/generated/graphql.ts b/generated/graphql.ts index dbcba00..32803d0 100644 --- a/generated/graphql.ts +++ b/generated/graphql.ts @@ -32216,7 +32216,7 @@ export type _Service = { export type OrderCancelledWebhookPayloadFragment = { readonly order?: { readonly id: string, readonly number: string, readonly created: string, readonly status: OrderStatus, readonly userEmail?: string | null, readonly languageCode: string, readonly channel: { readonly slug: string }, readonly user?: { readonly email: string, readonly firstName: string, readonly lastName: string } | null, readonly shippingAddress?: { readonly firstName: string, readonly lastName: string, readonly streetAddress1: string, readonly streetAddress2: string, readonly city: string, readonly postalCode: string, readonly phone?: string | null, readonly country: { readonly country: string } } | null, readonly billingAddress?: { readonly firstName: string, readonly lastName: string, readonly streetAddress1: string, readonly streetAddress2: string, readonly city: string, readonly postalCode: string, readonly phone?: string | null, readonly country: { readonly country: string } } | null, readonly lines: ReadonlyArray<{ readonly id: string, readonly quantity: number, readonly unitPrice: { readonly gross: { readonly amount: number, readonly currency: string } }, readonly totalPrice: { readonly gross: { readonly amount: number, readonly currency: string } }, readonly variant?: { readonly name: string, readonly sku?: string | null, readonly product: { readonly name: string, readonly media?: ReadonlyArray<{ readonly url: string }> | null } } | null }>, readonly subtotal: { readonly gross: { readonly amount: number, readonly currency: string } }, readonly shippingPrice: { readonly gross: { readonly amount: number, readonly currency: string } }, readonly total: { readonly gross: { readonly amount: number, readonly currency: string } }, readonly metadata: ReadonlyArray<{ readonly key: string, readonly value: string }> } | null }; -export type OrderCreatedWebhookPayloadFragment = { readonly order?: { readonly id: string, readonly number: string, readonly created: string, readonly status: OrderStatus, readonly userEmail?: string | null, readonly languageCode: string, readonly channel: { readonly slug: string }, readonly user?: { readonly email: string, readonly firstName: string, readonly lastName: string } | null, readonly shippingAddress?: { readonly firstName: string, readonly lastName: string, readonly streetAddress1: string, readonly streetAddress2: string, readonly city: string, readonly postalCode: string, readonly phone?: string | null, readonly country: { readonly country: string } } | null, readonly billingAddress?: { readonly firstName: string, readonly lastName: string, readonly streetAddress1: string, readonly streetAddress2: string, readonly city: string, readonly postalCode: string, readonly phone?: string | null, readonly country: { readonly country: string } } | null, readonly lines: ReadonlyArray<{ readonly id: string, readonly quantity: number, readonly unitPrice: { readonly gross: { readonly amount: number, readonly currency: string } }, readonly totalPrice: { readonly gross: { readonly amount: number, readonly currency: string } }, readonly variant?: { readonly name: string, readonly sku?: string | null, readonly product: { readonly name: string, readonly media?: ReadonlyArray<{ readonly url: string }> | null } } | null }>, readonly subtotal: { readonly gross: { readonly amount: number, readonly currency: string } }, readonly shippingPrice: { readonly gross: { readonly amount: number, readonly currency: string } }, readonly total: { readonly gross: { readonly amount: number, readonly currency: string } }, readonly metadata: ReadonlyArray<{ readonly key: string, readonly value: string }> } | null }; +export type OrderCreatedWebhookPayloadFragment = { readonly order?: { readonly id: string, readonly number: string, readonly created: string, readonly status: OrderStatus, readonly userEmail?: string | null, readonly languageCode: string, readonly channel: { readonly slug: string }, readonly user?: { readonly email: string, readonly firstName: string, readonly lastName: string } | null, readonly shippingAddress?: { readonly firstName: string, readonly lastName: string, readonly streetAddress1: string, readonly streetAddress2: string, readonly city: string, readonly postalCode: string, readonly phone?: string | null, readonly country: { readonly country: string } } | null, readonly billingAddress?: { readonly firstName: string, readonly lastName: string, readonly streetAddress1: string, readonly streetAddress2: string, readonly city: string, readonly postalCode: string, readonly phone?: string | null, readonly country: { readonly country: string } } | null, readonly lines: ReadonlyArray<{ readonly id: string, readonly quantity: number, readonly unitPrice: { readonly gross: { readonly amount: number, readonly currency: string } }, readonly totalPrice: { readonly gross: { readonly amount: number, readonly currency: string } }, readonly variant?: { readonly name: string, readonly sku?: string | null, readonly product: { readonly name: string, readonly media?: ReadonlyArray<{ readonly url: string }> | null } } | null }>, readonly subtotal: { readonly gross: { readonly amount: number, readonly currency: string } }, readonly shippingPrice: { readonly gross: { readonly amount: number, readonly currency: string } }, readonly total: { readonly gross: { readonly amount: number, readonly currency: string } }, readonly metadata: ReadonlyArray<{ readonly key: string, readonly value: string }>, readonly transactions: ReadonlyArray<{ readonly id: string, readonly message: string, readonly externalUrl: string, readonly events: ReadonlyArray<{ readonly message: string, readonly type?: TransactionEventTypeEnum | null }> }> } | null }; export type OrderFilterShippingMethodsPayloadFragment = { readonly order?: { readonly id: string } | null, readonly shippingMethods?: ReadonlyArray<{ readonly id: string, readonly name: string }> | null }; @@ -32242,7 +32242,7 @@ export type OrderCancelledSubscriptionSubscription = { readonly event?: { readon export type OrderCreatedSubscriptionSubscriptionVariables = Exact<{ [key: string]: never; }>; -export type OrderCreatedSubscriptionSubscription = { readonly event?: { readonly order?: { readonly id: string, readonly number: string, readonly created: string, readonly status: OrderStatus, readonly userEmail?: string | null, readonly languageCode: string, readonly channel: { readonly slug: string }, readonly user?: { readonly email: string, readonly firstName: string, readonly lastName: string } | null, readonly shippingAddress?: { readonly firstName: string, readonly lastName: string, readonly streetAddress1: string, readonly streetAddress2: string, readonly city: string, readonly postalCode: string, readonly phone?: string | null, readonly country: { readonly country: string } } | null, readonly billingAddress?: { readonly firstName: string, readonly lastName: string, readonly streetAddress1: string, readonly streetAddress2: string, readonly city: string, readonly postalCode: string, readonly phone?: string | null, readonly country: { readonly country: string } } | null, readonly lines: ReadonlyArray<{ readonly id: string, readonly quantity: number, readonly unitPrice: { readonly gross: { readonly amount: number, readonly currency: string } }, readonly totalPrice: { readonly gross: { readonly amount: number, readonly currency: string } }, readonly variant?: { readonly name: string, readonly sku?: string | null, readonly product: { readonly name: string, readonly media?: ReadonlyArray<{ readonly url: string }> | null } } | null }>, readonly subtotal: { readonly gross: { readonly amount: number, readonly currency: string } }, readonly shippingPrice: { readonly gross: { readonly amount: number, readonly currency: string } }, readonly total: { readonly gross: { readonly amount: number, readonly currency: string } }, readonly metadata: ReadonlyArray<{ readonly key: string, readonly value: string }> } | null } | {} | null }; +export type OrderCreatedSubscriptionSubscription = { readonly event?: { readonly order?: { readonly id: string, readonly number: string, readonly created: string, readonly status: OrderStatus, readonly userEmail?: string | null, readonly languageCode: string, readonly channel: { readonly slug: string }, readonly user?: { readonly email: string, readonly firstName: string, readonly lastName: string } | null, readonly shippingAddress?: { readonly firstName: string, readonly lastName: string, readonly streetAddress1: string, readonly streetAddress2: string, readonly city: string, readonly postalCode: string, readonly phone?: string | null, readonly country: { readonly country: string } } | null, readonly billingAddress?: { readonly firstName: string, readonly lastName: string, readonly streetAddress1: string, readonly streetAddress2: string, readonly city: string, readonly postalCode: string, readonly phone?: string | null, readonly country: { readonly country: string } } | null, readonly lines: ReadonlyArray<{ readonly id: string, readonly quantity: number, readonly unitPrice: { readonly gross: { readonly amount: number, readonly currency: string } }, readonly totalPrice: { readonly gross: { readonly amount: number, readonly currency: string } }, readonly variant?: { readonly name: string, readonly sku?: string | null, readonly product: { readonly name: string, readonly media?: ReadonlyArray<{ readonly url: string }> | null } } | null }>, readonly subtotal: { readonly gross: { readonly amount: number, readonly currency: string } }, readonly shippingPrice: { readonly gross: { readonly amount: number, readonly currency: string } }, readonly total: { readonly gross: { readonly amount: number, readonly currency: string } }, readonly metadata: ReadonlyArray<{ readonly key: string, readonly value: string }>, readonly transactions: ReadonlyArray<{ readonly id: string, readonly message: string, readonly externalUrl: string, readonly events: ReadonlyArray<{ readonly message: string, readonly type?: TransactionEventTypeEnum | null }> }> } | null } | {} | null }; export type OrderFilterShippingMethodsSubscriptionSubscriptionVariables = Exact<{ [key: string]: never; }>; @@ -105612,6 +105612,15 @@ export const UntypedOrderCreatedWebhookPayloadFragmentDoc = gql` key value } + transactions { + id + message + externalUrl + events { + message + type + } + } } } `; @@ -105816,12 +105825,12 @@ export function useOrderFulfilledSubscriptionSubscription({ query: UntypedOrderFulfilledSubscriptionDocument, ...options }, handler); }; export const OrderCancelledWebhookPayloadFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"OrderCancelledWebhookPayload"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"OrderCancelled"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"order"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"number"}},{"kind":"Field","name":{"kind":"Name","value":"created"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"userEmail"}},{"kind":"Field","name":{"kind":"Name","value":"languageCode"}},{"kind":"Field","name":{"kind":"Name","value":"channel"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}}]}},{"kind":"Field","name":{"kind":"Name","value":"shippingAddress"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress1"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress2"}},{"kind":"Field","name":{"kind":"Name","value":"city"}},{"kind":"Field","name":{"kind":"Name","value":"postalCode"}},{"kind":"Field","name":{"kind":"Name","value":"country"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"country"}}]}},{"kind":"Field","name":{"kind":"Name","value":"phone"}}]}},{"kind":"Field","name":{"kind":"Name","value":"billingAddress"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress1"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress2"}},{"kind":"Field","name":{"kind":"Name","value":"city"}},{"kind":"Field","name":{"kind":"Name","value":"postalCode"}},{"kind":"Field","name":{"kind":"Name","value":"country"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"country"}}]}},{"kind":"Field","name":{"kind":"Name","value":"phone"}}]}},{"kind":"Field","name":{"kind":"Name","value":"lines"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"unitPrice"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"totalPrice"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"variant"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"sku"}},{"kind":"Field","name":{"kind":"Name","value":"product"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"media"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"subtotal"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"shippingPrice"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"total"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"metadata"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}}]}}]}}]}}]} as unknown as DocumentNode; -export const OrderCreatedWebhookPayloadFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"OrderCreatedWebhookPayload"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"OrderCreated"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"order"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"number"}},{"kind":"Field","name":{"kind":"Name","value":"created"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"userEmail"}},{"kind":"Field","name":{"kind":"Name","value":"languageCode"}},{"kind":"Field","name":{"kind":"Name","value":"channel"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}}]}},{"kind":"Field","name":{"kind":"Name","value":"shippingAddress"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress1"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress2"}},{"kind":"Field","name":{"kind":"Name","value":"city"}},{"kind":"Field","name":{"kind":"Name","value":"postalCode"}},{"kind":"Field","name":{"kind":"Name","value":"country"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"country"}}]}},{"kind":"Field","name":{"kind":"Name","value":"phone"}}]}},{"kind":"Field","name":{"kind":"Name","value":"billingAddress"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress1"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress2"}},{"kind":"Field","name":{"kind":"Name","value":"city"}},{"kind":"Field","name":{"kind":"Name","value":"postalCode"}},{"kind":"Field","name":{"kind":"Name","value":"country"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"country"}}]}},{"kind":"Field","name":{"kind":"Name","value":"phone"}}]}},{"kind":"Field","name":{"kind":"Name","value":"lines"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"unitPrice"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"totalPrice"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"variant"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"sku"}},{"kind":"Field","name":{"kind":"Name","value":"product"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"media"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"subtotal"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"shippingPrice"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"total"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"metadata"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}}]}}]}}]}}]} as unknown as DocumentNode; +export const OrderCreatedWebhookPayloadFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"OrderCreatedWebhookPayload"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"OrderCreated"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"order"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"number"}},{"kind":"Field","name":{"kind":"Name","value":"created"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"userEmail"}},{"kind":"Field","name":{"kind":"Name","value":"languageCode"}},{"kind":"Field","name":{"kind":"Name","value":"channel"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}}]}},{"kind":"Field","name":{"kind":"Name","value":"shippingAddress"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress1"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress2"}},{"kind":"Field","name":{"kind":"Name","value":"city"}},{"kind":"Field","name":{"kind":"Name","value":"postalCode"}},{"kind":"Field","name":{"kind":"Name","value":"country"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"country"}}]}},{"kind":"Field","name":{"kind":"Name","value":"phone"}}]}},{"kind":"Field","name":{"kind":"Name","value":"billingAddress"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress1"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress2"}},{"kind":"Field","name":{"kind":"Name","value":"city"}},{"kind":"Field","name":{"kind":"Name","value":"postalCode"}},{"kind":"Field","name":{"kind":"Name","value":"country"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"country"}}]}},{"kind":"Field","name":{"kind":"Name","value":"phone"}}]}},{"kind":"Field","name":{"kind":"Name","value":"lines"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"unitPrice"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"totalPrice"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"variant"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"sku"}},{"kind":"Field","name":{"kind":"Name","value":"product"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"media"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"subtotal"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"shippingPrice"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"total"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"metadata"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}}]}},{"kind":"Field","name":{"kind":"Name","value":"transactions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"externalUrl"}},{"kind":"Field","name":{"kind":"Name","value":"events"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"type"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const OrderFilterShippingMethodsPayloadFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"OrderFilterShippingMethodsPayload"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"OrderFilterShippingMethods"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"order"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"shippingMethods"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]} as unknown as DocumentNode; export const OrderFulfilledWebhookPayloadFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"OrderFulfilledWebhookPayload"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"OrderFulfilled"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"order"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"number"}},{"kind":"Field","name":{"kind":"Name","value":"created"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"userEmail"}},{"kind":"Field","name":{"kind":"Name","value":"languageCode"}},{"kind":"Field","name":{"kind":"Name","value":"channel"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}}]}},{"kind":"Field","name":{"kind":"Name","value":"shippingAddress"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress1"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress2"}},{"kind":"Field","name":{"kind":"Name","value":"city"}},{"kind":"Field","name":{"kind":"Name","value":"postalCode"}},{"kind":"Field","name":{"kind":"Name","value":"country"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"country"}}]}},{"kind":"Field","name":{"kind":"Name","value":"phone"}}]}},{"kind":"Field","name":{"kind":"Name","value":"billingAddress"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress1"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress2"}},{"kind":"Field","name":{"kind":"Name","value":"city"}},{"kind":"Field","name":{"kind":"Name","value":"postalCode"}},{"kind":"Field","name":{"kind":"Name","value":"country"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"country"}}]}},{"kind":"Field","name":{"kind":"Name","value":"phone"}}]}},{"kind":"Field","name":{"kind":"Name","value":"lines"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"unitPrice"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"totalPrice"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"variant"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"sku"}},{"kind":"Field","name":{"kind":"Name","value":"product"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"media"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"subtotal"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"shippingPrice"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"total"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"metadata"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}}]}},{"kind":"Field","name":{"kind":"Name","value":"fulfillments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"created"}},{"kind":"Field","name":{"kind":"Name","value":"trackingNumber"}}]}}]}}]}}]} as unknown as DocumentNode; export const LastOrderDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"LastOrder"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"orders"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"first"},"value":{"kind":"IntValue","value":"1"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"number"}},{"kind":"Field","name":{"kind":"Name","value":"created"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}}]}},{"kind":"Field","name":{"kind":"Name","value":"shippingAddress"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"country"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"country"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"total"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"lines"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const ProductTimestampsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProductTimestamps"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"product"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"created"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode; export const OrderCancelledSubscriptionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"subscription","name":{"kind":"Name","value":"OrderCancelledSubscription"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"event"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"OrderCancelledWebhookPayload"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"OrderCancelledWebhookPayload"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"OrderCancelled"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"order"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"number"}},{"kind":"Field","name":{"kind":"Name","value":"created"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"userEmail"}},{"kind":"Field","name":{"kind":"Name","value":"languageCode"}},{"kind":"Field","name":{"kind":"Name","value":"channel"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}}]}},{"kind":"Field","name":{"kind":"Name","value":"shippingAddress"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress1"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress2"}},{"kind":"Field","name":{"kind":"Name","value":"city"}},{"kind":"Field","name":{"kind":"Name","value":"postalCode"}},{"kind":"Field","name":{"kind":"Name","value":"country"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"country"}}]}},{"kind":"Field","name":{"kind":"Name","value":"phone"}}]}},{"kind":"Field","name":{"kind":"Name","value":"billingAddress"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress1"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress2"}},{"kind":"Field","name":{"kind":"Name","value":"city"}},{"kind":"Field","name":{"kind":"Name","value":"postalCode"}},{"kind":"Field","name":{"kind":"Name","value":"country"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"country"}}]}},{"kind":"Field","name":{"kind":"Name","value":"phone"}}]}},{"kind":"Field","name":{"kind":"Name","value":"lines"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"unitPrice"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"totalPrice"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"variant"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"sku"}},{"kind":"Field","name":{"kind":"Name","value":"product"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"media"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"subtotal"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"shippingPrice"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"total"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"metadata"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}}]}}]}}]}}]} as unknown as DocumentNode; -export const OrderCreatedSubscriptionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"subscription","name":{"kind":"Name","value":"OrderCreatedSubscription"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"event"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"OrderCreatedWebhookPayload"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"OrderCreatedWebhookPayload"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"OrderCreated"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"order"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"number"}},{"kind":"Field","name":{"kind":"Name","value":"created"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"userEmail"}},{"kind":"Field","name":{"kind":"Name","value":"languageCode"}},{"kind":"Field","name":{"kind":"Name","value":"channel"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}}]}},{"kind":"Field","name":{"kind":"Name","value":"shippingAddress"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress1"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress2"}},{"kind":"Field","name":{"kind":"Name","value":"city"}},{"kind":"Field","name":{"kind":"Name","value":"postalCode"}},{"kind":"Field","name":{"kind":"Name","value":"country"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"country"}}]}},{"kind":"Field","name":{"kind":"Name","value":"phone"}}]}},{"kind":"Field","name":{"kind":"Name","value":"billingAddress"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress1"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress2"}},{"kind":"Field","name":{"kind":"Name","value":"city"}},{"kind":"Field","name":{"kind":"Name","value":"postalCode"}},{"kind":"Field","name":{"kind":"Name","value":"country"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"country"}}]}},{"kind":"Field","name":{"kind":"Name","value":"phone"}}]}},{"kind":"Field","name":{"kind":"Name","value":"lines"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"unitPrice"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"totalPrice"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"variant"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"sku"}},{"kind":"Field","name":{"kind":"Name","value":"product"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"media"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"subtotal"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"shippingPrice"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"total"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"metadata"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}}]}}]}}]}}]} as unknown as DocumentNode; +export const OrderCreatedSubscriptionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"subscription","name":{"kind":"Name","value":"OrderCreatedSubscription"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"event"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"OrderCreatedWebhookPayload"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"OrderCreatedWebhookPayload"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"OrderCreated"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"order"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"number"}},{"kind":"Field","name":{"kind":"Name","value":"created"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"userEmail"}},{"kind":"Field","name":{"kind":"Name","value":"languageCode"}},{"kind":"Field","name":{"kind":"Name","value":"channel"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}}]}},{"kind":"Field","name":{"kind":"Name","value":"shippingAddress"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress1"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress2"}},{"kind":"Field","name":{"kind":"Name","value":"city"}},{"kind":"Field","name":{"kind":"Name","value":"postalCode"}},{"kind":"Field","name":{"kind":"Name","value":"country"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"country"}}]}},{"kind":"Field","name":{"kind":"Name","value":"phone"}}]}},{"kind":"Field","name":{"kind":"Name","value":"billingAddress"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress1"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress2"}},{"kind":"Field","name":{"kind":"Name","value":"city"}},{"kind":"Field","name":{"kind":"Name","value":"postalCode"}},{"kind":"Field","name":{"kind":"Name","value":"country"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"country"}}]}},{"kind":"Field","name":{"kind":"Name","value":"phone"}}]}},{"kind":"Field","name":{"kind":"Name","value":"lines"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"unitPrice"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"totalPrice"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"variant"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"sku"}},{"kind":"Field","name":{"kind":"Name","value":"product"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"media"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"subtotal"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"shippingPrice"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"total"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"metadata"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}}]}},{"kind":"Field","name":{"kind":"Name","value":"transactions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"externalUrl"}},{"kind":"Field","name":{"kind":"Name","value":"events"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"type"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const OrderFilterShippingMethodsSubscriptionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"subscription","name":{"kind":"Name","value":"OrderFilterShippingMethodsSubscription"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"event"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"OrderFilterShippingMethodsPayload"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"OrderFilterShippingMethodsPayload"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"OrderFilterShippingMethods"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"order"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"shippingMethods"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]} as unknown as DocumentNode; export const OrderFulfilledSubscriptionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"subscription","name":{"kind":"Name","value":"OrderFulfilledSubscription"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"event"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"OrderFulfilledWebhookPayload"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"OrderFulfilledWebhookPayload"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"OrderFulfilled"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"order"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"number"}},{"kind":"Field","name":{"kind":"Name","value":"created"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"userEmail"}},{"kind":"Field","name":{"kind":"Name","value":"languageCode"}},{"kind":"Field","name":{"kind":"Name","value":"channel"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}}]}},{"kind":"Field","name":{"kind":"Name","value":"shippingAddress"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress1"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress2"}},{"kind":"Field","name":{"kind":"Name","value":"city"}},{"kind":"Field","name":{"kind":"Name","value":"postalCode"}},{"kind":"Field","name":{"kind":"Name","value":"country"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"country"}}]}},{"kind":"Field","name":{"kind":"Name","value":"phone"}}]}},{"kind":"Field","name":{"kind":"Name","value":"billingAddress"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress1"}},{"kind":"Field","name":{"kind":"Name","value":"streetAddress2"}},{"kind":"Field","name":{"kind":"Name","value":"city"}},{"kind":"Field","name":{"kind":"Name","value":"postalCode"}},{"kind":"Field","name":{"kind":"Name","value":"country"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"country"}}]}},{"kind":"Field","name":{"kind":"Name","value":"phone"}}]}},{"kind":"Field","name":{"kind":"Name","value":"lines"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"unitPrice"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"totalPrice"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"variant"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"sku"}},{"kind":"Field","name":{"kind":"Name","value":"product"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"media"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"subtotal"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"shippingPrice"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"total"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gross"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"metadata"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}}]}},{"kind":"Field","name":{"kind":"Name","value":"fulfillments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"created"}},{"kind":"Field","name":{"kind":"Name","value":"trackingNumber"}}]}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file diff --git a/graphql/fragments/order-created.graphql b/graphql/fragments/order-created.graphql index c1a595e..1fe6f4d 100644 --- a/graphql/fragments/order-created.graphql +++ b/graphql/fragments/order-created.graphql @@ -86,5 +86,14 @@ fragment OrderCreatedWebhookPayload on OrderCreated { key value } + transactions { + id + message + externalUrl + events { + message + type + } + } } } \ No newline at end of file diff --git a/src/lib/email-templates/order-cancelled.ts b/src/lib/email-templates/order-cancelled.ts index c37b2c6..05136a3 100644 --- a/src/lib/email-templates/order-cancelled.ts +++ b/src/lib/email-templates/order-cancelled.ts @@ -1,7 +1,14 @@ -import Handlebars from "handlebars"; +/** + * Order Cancelled Email Template + * + * Refactored to use the abstracted email service architecture. + */ -// Translations for Order Cancelled emails -const translations = { +import Handlebars from "handlebars"; +import { emailServiceConfig, DEFAULT_LANGUAGE } from "@/lib/email/config"; + +// Cancelled order specific translations +const cancelledTranslations = { en: { subject: "Order {{orderNumber}} Cancelled", title: "Order Cancelled", @@ -14,8 +21,8 @@ const translations = { itemsLabel: "Items", contactButton: "Contact Us", thankYou: "Thank you!", - companyName: "ManoonOils", - footerText: "support@manoonoils.com" + companyName: emailServiceConfig.companyName, + footerText: emailServiceConfig.fromEmail, }, sr: { subject: "Porudžbina {{orderNumber}} Otkazana", @@ -29,8 +36,8 @@ const translations = { itemsLabel: "Artikli", contactButton: "Kontaktirajte Nas", thankYou: "Hvala vam!", - companyName: "ManoonOils", - footerText: "support@manoonoils.com" + companyName: emailServiceConfig.companyName, + footerText: emailServiceConfig.fromEmail, }, de: { subject: "Bestellung {{orderNumber}} Storniert", @@ -44,8 +51,8 @@ const translations = { itemsLabel: "Artikel", contactButton: "Kontaktieren Sie Uns", thankYou: "Vielen Dank!", - companyName: "ManoonOils", - footerText: "support@manoonoils.com" + companyName: emailServiceConfig.companyName, + footerText: emailServiceConfig.fromEmail, }, fr: { subject: "Commande {{orderNumber}} Annulée", @@ -59,13 +66,13 @@ const translations = { itemsLabel: "Articles", contactButton: "Contactez-Nous", thankYou: "Merci!", - companyName: "ManoonOils", - footerText: "support@manoonoils.com" - } + companyName: emailServiceConfig.companyName, + footerText: emailServiceConfig.fromEmail, + }, }; -// Customer email template -const customerEmailTemplate = ` +// Template +const cancelledEmailTemplate = ` @@ -74,7 +81,7 @@ const customerEmailTemplate = `
- {{companyName}} + {{companyName}}

{{title}}

@@ -96,7 +103,7 @@ const customerEmailTemplate = `

{{footerText}}

@@ -110,98 +117,50 @@ const customerEmailTemplate = ` `; -// Admin email template -const adminEmailTemplate = ` - - - - - - -
-

Order Cancelled

- -
-

Order #{{orderNumber}}

-

Date: {{orderDate}}

-

Reason: {{cancellationReason}}

-
- -
-

Customer

-

Name: {{customerName}}

-

Email: {{customerEmail}}

-

Phone: {{#if phone}}{{phone}}{{else}}Not provided{{/if}}

-
- -

Items

-
- {{#each items}} -

{{quantity}}x {{name}} - {{price}}

- {{/each}} -
- -
- Dashboard -
-
- - -`; - -// Compile templates -const compileCustomerEmail = Handlebars.compile(customerEmailTemplate); -const compileAdminEmail = Handlebars.compile(adminEmailTemplate); +const compileCancelledEmail = Handlebars.compile(cancelledEmailTemplate); export function getOrderCancelledEmails(order: any) { - // Detect language - const lang = order.languageCode?.toLowerCase() || "en"; - const t = translations[lang as keyof typeof translations] || translations.en; + const lang = (order.languageCode?.toLowerCase() || DEFAULT_LANGUAGE) as keyof typeof cancelledTranslations; + const t = cancelledTranslations[lang] || cancelledTranslations[DEFAULT_LANGUAGE]; - // Format data const customerName = order.shippingAddress?.firstName ? `${order.shippingAddress.firstName} ${order.shippingAddress.lastName || ""}`.trim() : order.userEmail?.split("@")[0] || "Customer"; const currency = order.total?.gross?.currency || "EUR"; - + const orderDate = order.created + ? new Date(order.created).toLocaleString(lang === "sr" ? "sr-RS" : lang === "de" ? "de-DE" : lang === "fr" ? "fr-FR" : "en-US") + : new Date().toLocaleString(); + const cancellationReason = order.metadata?.find((m: { key: string; value: string }) => m.key === "cancellation_reason")?.value || t.noReason; + + const greeting = Handlebars.compile(t.greeting)({ customerName }); + const subject = Handlebars.compile(t.subject)({ orderNumber: order.number || order.id }); + const items = (order.lines || []).map((line: any) => ({ name: line.variant?.product?.name || line.variant?.name || "Product", quantity: line.quantity || 0, price: `${line.totalPrice?.gross?.amount?.toFixed(2) || "0.00"} ${currency}` })); - - const orderDate = order.created - ? new Date(order.created).toLocaleString(lang === "sr" ? "sr-RS" : lang === "de" ? "de-DE" : lang === "fr" ? "fr-FR" : "en-US") - : new Date().toLocaleString(); - - const cancellationReason = order.cancellationReason || t.noReason; - // Customer email data - const customerData = { + const emailData = { ...t, + greeting, orderNumber: order.number || order.id, - customerName, orderDate, cancellationReason, - items - }; - - // Admin email data (English) - const adminData = { - orderNumber: order.number || order.id, - customerName, - customerEmail: order.userEmail || "", - orderDate, - cancellationReason, - phone: order.shippingAddress?.phone || "", - items + items, + companyLogoUrl: emailServiceConfig.companyLogoUrl, + storefrontUrl: emailServiceConfig.storefrontUrl, }; return { - customerSubject: Handlebars.compile(t.subject)({ orderNumber: order.number || order.id }), - customerHtml: compileCustomerEmail(customerData), + customerSubject: subject, + customerHtml: compileCancelledEmail(emailData), adminSubject: `Order Cancelled #${order.number || order.id}`, - adminHtml: compileAdminEmail(adminData) + adminHtml: compileCancelledEmail({ + ...emailData, + title: `Order Cancelled - #${order.number || order.id}`, + body: `Order has been cancelled. Customer: ${order.userEmail}. Reason: ${cancellationReason}`, + }), }; } diff --git a/src/lib/email-templates/order-created.ts b/src/lib/email-templates/order-created.ts index bd26770..867815f 100644 --- a/src/lib/email-templates/order-created.ts +++ b/src/lib/email-templates/order-created.ts @@ -1,287 +1,37 @@ -import Handlebars from "handlebars"; +/** + * Order Created Email Template + * + * This module is now a thin wrapper around the abstracted email service architecture. + * All hardcoded values have been moved to configuration files. + * + * Architecture: + * - types.ts: Type definitions + * - config.ts: All configurable values (translations, URLs, etc.) + * - services/paymentMethodService.ts: Payment method detection logic + * - services/orderTransformerService.ts: Order data transformation + * - services/emailBuilderService.ts: Email template compilation + */ -// Translations for Order Created emails -const translations = { - en: { - subject: "Order {{orderNumber}} Confirmed", - title: "Order Confirmed", - greeting: "Dear {{customerName}},", - body: "Thank you for your order! We have received it and it is now being processed.", - orderLabel: "Order:", - dateLabel: "Date:", - statusLabel: "Status:", - itemsLabel: "Items", - subtotalLabel: "Subtotal:", - shippingLabel: "Shipping:", - taxLabel: "Tax:", - totalLabel: "Total:", - shippingAddressLabel: "Shipping Address", - phoneLabel: "Phone:", - phoneNotProvided: "Not provided", - viewOrderButton: "View Order", - thankYou: "Thank you!", - companyName: "ManoonOils", - footerText: "support@manoonoils.com" - }, - sr: { - subject: "Porudžbina {{orderNumber}} Potvrđena", - title: "Porudžbina Potvrđena", - greeting: "Poštovani {{customerName}},", - body: "Hvala vam na porudžbini! Primili smo je i sada je obrađujemo.", - orderLabel: "Porudžbina:", - dateLabel: "Datum:", - statusLabel: "Status:", - itemsLabel: "Artikli", - subtotalLabel: "Međuzbir:", - shippingLabel: "Dostava:", - taxLabel: "Porez:", - totalLabel: "Ukupno:", - shippingAddressLabel: "Adresa za Dostavu", - phoneLabel: "Telefon:", - phoneNotProvided: "Nije navedeno", - viewOrderButton: "Pogledaj Porudžbinu", - thankYou: "Hvala vam!", - companyName: "ManoonOils", - footerText: "support@manoonoils.com" - }, - de: { - subject: "Bestellung {{orderNumber}} Bestätigt", - title: "Bestellung Bestätigt", - greeting: "Sehr geehrte/r {{customerName}},", - body: "Vielen Dank für Ihre Bestellung! Wir haben sie erhalten und bearbeiten sie jetzt.", - orderLabel: "Bestellung:", - dateLabel: "Datum:", - statusLabel: "Status:", - itemsLabel: "Artikel", - subtotalLabel: "Zwischensumme:", - shippingLabel: "Versand:", - taxLabel: "Steuer:", - totalLabel: "Gesamt:", - shippingAddressLabel: "Lieferadresse", - phoneLabel: "Telefon:", - phoneNotProvided: "Nicht angegeben", - viewOrderButton: "Bestellung Ansehen", - thankYou: "Vielen Dank!", - companyName: "ManoonOils", - footerText: "support@manoonoils.com" - }, - fr: { - subject: "Commande {{orderNumber}} Confirmée", - title: "Commande Confirmée", - greeting: "Cher/Chère {{customerName}},", - body: "Merci pour votre commande! Nous l'avons reçue et elle est en cours de traitement.", - orderLabel: "Commande:", - dateLabel: "Date:", - statusLabel: "Statut:", - itemsLabel: "Articles", - subtotalLabel: "Sous-total:", - shippingLabel: "Livraison:", - taxLabel: "Taxe:", - totalLabel: "Total:", - shippingAddressLabel: "Adresse de Livraison", - phoneLabel: "Téléphone:", - phoneNotProvided: "Non fourni", - viewOrderButton: "Voir la Commande", - thankYou: "Merci!", - companyName: "ManoonOils", - footerText: "support@manoonoils.com" - } -}; - -// Customer email template -const customerEmailTemplate = ` - - - - - - -
-
- {{companyName}} -
- -

{{title}}

- -

{{greeting}}

-

{{body}}

- -
-

{{orderLabel}} {{orderNumber}}

-

{{dateLabel}} {{orderDate}}

-

{{statusLabel}} {{orderStatus}}

-
- -

{{itemsLabel}}

-
- {{#each items}} -

{{quantity}}x {{name}} - {{price}}

- {{/each}} -
- -
-

{{subtotalLabel}} {{subtotal}}

-

{{shippingLabel}} {{shipping}}

-

{{taxLabel}} {{tax}}

-
-

{{totalLabel}} {{total}}

-
- - {{#if shippingAddress}} -
-

{{shippingAddressLabel}}

-

{{shippingAddress}}

-

{{phoneLabel}} {{#if phone}}{{phone}}{{else}}{{phoneNotProvided}}{{/if}}

-
- {{/if}} - - - -

{{footerText}}

-

{{thankYou}}

- -
-

{{companyName}}

-
-
- - -`; - -// Admin email template -const adminEmailTemplate = ` - - - - - - -
-

{{adminTitle}}

- -
-

{{adminOrderLabel}} #{{orderNumber}}

-

{{dateLabel}} {{orderDate}}

-

{{statusLabel}} {{orderStatus}}

-

{{paymentLabel}} {{paymentMethod}}

-
- -
-

{{customerLabel}}

-

{{nameLabel}} {{customerName}}

-

{{emailLabel}} {{customerEmail}}

-

{{phoneLabel}} {{#if phone}}{{phone}}{{else}}{{phoneNotProvided}}{{/if}}

-
- -

{{itemsLabel}}

-
- {{#each items}} -

{{quantity}}x {{name}} - {{price}}

- {{/each}} -
- -
-

{{subtotalLabel}} {{subtotal}}

-

{{shippingLabel}} {{shipping}}

-

{{taxLabel}} {{tax}}

-
-

{{totalLabel}} {{total}}

-
- - {{#if shippingAddress}} -
-

{{shippingAddressLabel}}

-

{{shippingAddress}}

-
- {{/if}} - -
- Dashboard -
-
- - -`; - -// Compile templates -const compileCustomerEmail = Handlebars.compile(customerEmailTemplate); -const compileAdminEmail = Handlebars.compile(adminEmailTemplate); - -// Admin translations (always in English) -const adminTranslations = { - adminTitle: "New Order! 🎉", - adminOrderLabel: "Order", - customerLabel: "Customer", - paymentLabel: "Payment:", - paymentMethod: "Card" -}; +import { EmailBuilderService } from "@/lib/email/services/emailBuilderService"; +import { emailServiceConfig } from "@/lib/email/config"; +/** + * Generate order created emails (customer + admin) + * + * @param order - Saleor order object + * @returns EmailResult with customer and admin email content + * + * @example + * const { customerSubject, customerHtml, adminSubject, adminHtml } = getOrderCreatedEmails(order); + */ export function getOrderCreatedEmails(order: any) { - // Detect language - const lang = order.languageCode?.toLowerCase() || "en"; - const t = translations[lang as keyof typeof translations] || translations.en; - - // Format data - const customerName = order.shippingAddress?.firstName - ? `${order.shippingAddress.firstName} ${order.shippingAddress.lastName || ""}`.trim() - : order.userEmail?.split("@")[0] || "Customer"; - - const currency = order.total?.gross?.currency || "EUR"; - - const items = (order.lines || []).map((line: any) => ({ - name: line.variant?.product?.name || line.variant?.name || "Product", - quantity: line.quantity || 0, - price: `${line.totalPrice?.gross?.amount?.toFixed(2) || "0.00"} ${currency}` - })); - - const shippingAddress = order.shippingAddress - ? `${order.shippingAddress.firstName || ""} ${order.shippingAddress.lastName || ""}\n${order.shippingAddress.streetAddress1 || ""}\n${order.shippingAddress.city || ""}, ${order.shippingAddress.postalCode || ""}\n${order.shippingAddress.country?.country || ""}` - : ""; - - const orderDate = order.created - ? new Date(order.created).toLocaleString(lang === "sr" ? "sr-RS" : lang === "de" ? "de-DE" : lang === "fr" ? "fr-FR" : "en-US") - : new Date().toLocaleString(); - - // Customer email data - const customerData = { - ...t, - orderNumber: order.number || order.id, - customerName, - orderDate, - orderStatus: order.status || "unfulfilled", - items, - subtotal: `${order.subtotal?.gross?.amount?.toFixed(2) || "0.00"} ${currency}`, - shipping: `${order.shippingPrice?.gross?.amount?.toFixed(2) || "0.00"} ${currency}`, - tax: `${order.total?.tax?.amount?.toFixed(2) || "0.00"} ${currency}`, - total: `${order.total?.gross?.amount?.toFixed(2) || "0.00"} ${currency}`, - shippingAddress, - phone: order.shippingAddress?.phone || "" - }; - - // Admin email data (English) - const adminData = { - ...t, - ...adminTranslations, - orderNumber: order.number || order.id, - customerName, - customerEmail: order.userEmail || "", - orderDate, - orderStatus: order.status || "unfulfilled", - items, - subtotal: `${order.subtotal?.gross?.amount?.toFixed(2) || "0.00"} ${currency}`, - shipping: `${order.shippingPrice?.gross?.amount?.toFixed(2) || "0.00"} ${currency}`, - tax: `${order.total?.tax?.amount?.toFixed(2) || "0.00"} ${currency}`, - total: `${order.total?.gross?.amount?.toFixed(2) || "0.00"} ${currency}`, - shippingAddress, - phone: order.shippingAddress?.phone || "" - }; - - return { - customerSubject: Handlebars.compile(t.subject)({ orderNumber: order.number || order.id }), - customerHtml: compileCustomerEmail(customerData), - adminSubject: `New Order! 🎉 #${order.number || order.id}`, - adminHtml: compileAdminEmail(adminData) - }; + return EmailBuilderService.buildOrderCreatedEmails(order, { + companyLogoUrl: emailServiceConfig.companyLogoUrl, + companyName: emailServiceConfig.companyName, + storefrontUrl: emailServiceConfig.storefrontUrl, + dashboardUrl: emailServiceConfig.dashboardUrl, + }); } + +// Re-export types for consumers +export type { EmailResult } from "@/lib/email/types"; diff --git a/src/lib/email-templates/order-shipped.ts b/src/lib/email-templates/order-shipped.ts index 0128270..638c37a 100644 --- a/src/lib/email-templates/order-shipped.ts +++ b/src/lib/email-templates/order-shipped.ts @@ -183,9 +183,13 @@ export function getOrderShippedEmails(order: any, fulfillment?: any) { ? `https://track.manoonoils.com/${trackingNumber}` : "https://manoonoils.com"; + // Compile greeting with customer name + const greeting = Handlebars.compile(t.greeting)({ customerName }); + // Customer email data const customerData = { ...t, + greeting, orderNumber: order.number || order.id, customerName, orderDate, diff --git a/src/lib/email/config.ts b/src/lib/email/config.ts new file mode 100644 index 0000000..20d1cbe --- /dev/null +++ b/src/lib/email/config.ts @@ -0,0 +1,170 @@ +/** + * Email Configuration - All configurable values extracted from hardcoded locations + * This makes the system configurable without changing code + */ + +import type { + LanguageCode, + EmailTemplateConfig, + AdminEmailTemplateConfig, + PaymentMethodConfig, + EmailServiceConfig +} from "./types"; + +// Payment method configurations - easily extendable +export const paymentMethodConfigs: Record = { + card: { + id: "card", + label: "Card", + }, + cod: { + id: "cod", + label: "Cash on Delivery", + }, + paypal: { + id: "paypal", + label: "PayPal", + }, + bank_transfer: { + id: "bank_transfer", + label: "Bank Transfer", + }, + unknown: { + id: "unknown", + label: "Unknown", + }, +}; + +// Customer email translations - configuration driven +export const emailTranslations: Record = { + en: { + subject: "Order {{orderNumber}} Confirmed", + title: "Order Confirmed", + greeting: "Dear {{customerName}},", + body: "Thank you for your order! We have received it and it is now being processed.", + orderLabel: "Order:", + dateLabel: "Date:", + statusLabel: "Status:", + itemsLabel: "Items", + subtotalLabel: "Subtotal:", + shippingLabel: "Shipping:", + taxLabel: "Tax:", + totalLabel: "Total:", + shippingAddressLabel: "Shipping Address", + phoneLabel: "Phone:", + phoneNotProvided: "Not provided", + viewOrderButton: "View Order", + thankYou: "Thank you!", + companyName: "ManoonOils", + footerText: "support@manoonoils.com", + }, + sr: { + subject: "Porudžbina {{orderNumber}} Potvrđena", + title: "Porudžbina Potvrđena", + greeting: "Poštovani {{customerName}},", + body: "Hvala vam na porudžbini! Primili smo je i sada je obrađujemo.", + orderLabel: "Porudžbina:", + dateLabel: "Datum:", + statusLabel: "Status:", + itemsLabel: "Artikli", + subtotalLabel: "Međuzbir:", + shippingLabel: "Dostava:", + taxLabel: "Porez:", + totalLabel: "Ukupno:", + shippingAddressLabel: "Adresa za Dostavu", + phoneLabel: "Telefon:", + phoneNotProvided: "Nije navedeno", + viewOrderButton: "Pogledaj Porudžbinu", + thankYou: "Hvala vam!", + companyName: "ManoonOils", + footerText: "support@manoonoils.com", + }, + de: { + subject: "Bestellung {{orderNumber}} Bestätigt", + title: "Bestellung Bestätigt", + greeting: "Sehr geehrte/r {{customerName}},", + body: "Vielen Dank für Ihre Bestellung! Wir haben sie erhalten und bearbeiten sie jetzt.", + orderLabel: "Bestellung:", + dateLabel: "Datum:", + statusLabel: "Status:", + itemsLabel: "Artikel", + subtotalLabel: "Zwischensumme:", + shippingLabel: "Versand:", + taxLabel: "Steuer:", + totalLabel: "Gesamt:", + shippingAddressLabel: "Lieferadresse", + phoneLabel: "Telefon:", + phoneNotProvided: "Nicht angegeben", + viewOrderButton: "Bestellung Ansehen", + thankYou: "Vielen Dank!", + companyName: "ManoonOils", + footerText: "support@manoonoils.com", + }, + fr: { + subject: "Commande {{orderNumber}} Confirmée", + title: "Commande Confirmée", + greeting: "Cher/Chère {{customerName}},", + body: "Merci pour votre commande! Nous l'avons reçue et elle est en cours de traitement.", + orderLabel: "Commande:", + dateLabel: "Date:", + statusLabel: "Statut:", + itemsLabel: "Articles", + subtotalLabel: "Sous-total:", + shippingLabel: "Livraison:", + taxLabel: "Taxe:", + totalLabel: "Total:", + shippingAddressLabel: "Adresse de Livraison", + phoneLabel: "Téléphone:", + phoneNotProvided: "Non fourni", + viewOrderButton: "Voir la Commande", + thankYou: "Merci!", + companyName: "ManoonOils", + footerText: "support@manoonoils.com", + }, +}; + +// Admin email translations - always in English but configurable +export const adminEmailTranslations: AdminEmailTemplateConfig = { + adminTitle: "New Order! 🎉", + adminOrderLabel: "Order", + customerLabel: "Customer", + nameLabel: "Name:", + emailLabel: "Email:", + dashboardButton: "Dashboard", +}; + +// Default payment label for admin emails +export const adminPaymentConfig = { + paymentLabel: "Payment:", +}; + +// Email service configuration - loaded from environment or defaults +export const emailServiceConfig: EmailServiceConfig = { + fromEmail: process.env.EMAIL_FROM_ADDRESS || "support@mail.manoonoils.com", + fromName: process.env.EMAIL_FROM_NAME || "Manoon Oils", + adminEmails: process.env.ADMIN_EMAILS?.split(",") || [ + "me@hytham.me", + "tamara@hytham.me", + ], + companyName: process.env.COMPANY_NAME || "ManoonOils", + companyLogoUrl: + process.env.COMPANY_LOGO_URL || + "https://minio-api.nodecrew.me/manoon-media/2024/09/cropped-manoon-logo_256x-1-1.png", + dashboardUrl: process.env.DASHBOARD_URL || "https://dashboard.manoonoils.com", + storefrontUrl: process.env.STOREFRONT_URL || "https://manoonoils.com", + trackingUrl: process.env.TRACKING_URL || "https://track.manoonoils.com", +}; + +// Locale configurations for date formatting +export const localeConfigs: Record = { + en: "en-US", + sr: "sr-RS", + de: "de-DE", + fr: "fr-FR", +}; + +// Default fallback language +export const DEFAULT_LANGUAGE: LanguageCode = "en"; + +// Default currency +export const DEFAULT_CURRENCY = "EUR"; diff --git a/src/lib/email/index.ts b/src/lib/email/index.ts new file mode 100644 index 0000000..bfd5f66 --- /dev/null +++ b/src/lib/email/index.ts @@ -0,0 +1,14 @@ +/** + * Email Module - Centralized exports for the email system + */ + +// Types +export * from "./types"; + +// Configuration +export * from "./config"; + +// Services +export { PaymentMethodService } from "./services/paymentMethodService"; +export { OrderTransformerService } from "./services/orderTransformerService"; +export { EmailBuilderService } from "./services/emailBuilderService"; diff --git a/src/lib/email/services/emailBuilderService.ts b/src/lib/email/services/emailBuilderService.ts new file mode 100644 index 0000000..4730e00 --- /dev/null +++ b/src/lib/email/services/emailBuilderService.ts @@ -0,0 +1,197 @@ +/** + * Email Builder Service - Compiles email templates with data + * Handles template compilation and rendering + */ + +import Handlebars from "handlebars"; +import type { SaleorOrder, EmailResult } from "../types"; +import { OrderTransformerService } from "./orderTransformerService"; +import { + emailTranslations, + adminEmailTranslations, + adminPaymentConfig, + DEFAULT_LANGUAGE, +} from "../config"; + +// Customer email template +const customerEmailTemplate = ` + + + + + + +
+
+ {{companyName}} +
+ +

{{title}}

+ +

{{greeting}}

+

{{body}}

+ +
+

{{orderLabel}} {{orderNumber}}

+

{{dateLabel}} {{orderDate}}

+

{{statusLabel}} {{orderStatus}}

+
+ +

{{itemsLabel}}

+
+ {{#each items}} +

{{quantity}}x {{name}} - {{price}}

+ {{/each}} +
+ +
+

{{subtotalLabel}} {{subtotal}}

+

{{shippingLabel}} {{shipping}}

+

{{taxLabel}} {{tax}}

+
+

{{totalLabel}} {{total}}

+
+ + {{#if shippingAddress}} +
+

{{shippingAddressLabel}}

+

{{shippingAddress}}

+

{{phoneLabel}} {{#if phone}}{{phone}}{{else}}{{phoneNotProvided}}{{/if}}

+
+ {{/if}} + + + +

{{footerText}}

+

{{thankYou}}

+ +
+

{{companyName}}

+
+
+ + +`; + +// Admin email template +const adminEmailTemplate = ` + + + + + + +
+

{{adminTitle}}

+ +
+

{{adminOrderLabel}} #{{orderNumber}}

+

{{dateLabel}} {{orderDate}}

+

{{statusLabel}} {{orderStatus}}

+

{{paymentLabel}} {{paymentMethod}}

+
+ +
+

{{customerLabel}}

+

{{nameLabel}} {{customerName}}

+

{{emailLabel}} {{customerEmail}}

+

{{phoneLabel}} {{#if phone}}{{phone}}{{else}}{{phoneNotProvided}}{{/if}}

+
+ +

{{itemsLabel}}

+
+ {{#each items}} +

{{quantity}}x {{name}} - {{price}}

+ {{/each}} +
+ +
+

{{subtotalLabel}} {{subtotal}}

+

{{shippingLabel}} {{shipping}}

+

{{taxLabel}} {{tax}}

+
+

{{totalLabel}} {{total}}

+
+ + {{#if shippingAddress}} +
+

{{shippingAddressLabel}}

+

{{shippingAddress}}

+
+ {{/if}} + + +
+ + +`; + +export class EmailBuilderService { + private static compileCustomerEmail = Handlebars.compile(customerEmailTemplate); + private static compileAdminEmail = Handlebars.compile(adminEmailTemplate); + + /** + * Build order created emails (customer + admin) + */ + static buildOrderCreatedEmails( + order: SaleorOrder, + config: { + companyLogoUrl: string; + companyName: string; + storefrontUrl: string; + dashboardUrl: string; + } + ): EmailResult { + const languageCode = OrderTransformerService.getLanguageCode(order); + const translations = emailTranslations[languageCode] || emailTranslations[DEFAULT_LANGUAGE]; + + // Compile greeting and subject with Handlebars + const greeting = Handlebars.compile(translations.greeting)({ + customerName: OrderTransformerService.extractCustomerName(order), + }); + const subject = Handlebars.compile(translations.subject)({ + orderNumber: order.number || order.id, + }); + + // Build customer email data + const customerData = { + ...OrderTransformerService.transformToEmailData(order, translations), + greeting, + subject, + companyLogoUrl: config.companyLogoUrl, + storefrontUrl: config.storefrontUrl, + }; + + // Build admin email data + const adminTranslationsRecord: Record = { + adminTitle: adminEmailTranslations.adminTitle, + adminOrderLabel: adminEmailTranslations.adminOrderLabel, + customerLabel: adminEmailTranslations.customerLabel, + nameLabel: adminEmailTranslations.nameLabel, + emailLabel: adminEmailTranslations.emailLabel, + dashboardButton: adminEmailTranslations.dashboardButton, + }; + + const adminData = { + ...OrderTransformerService.transformToAdminEmailData( + order, + translations, + adminTranslationsRecord + ), + ...adminPaymentConfig, + dashboardUrl: config.dashboardUrl, + companyLogoUrl: config.companyLogoUrl, + }; + + return { + customerSubject: subject, + customerHtml: this.compileCustomerEmail(customerData), + adminSubject: `${adminEmailTranslations.adminTitle} #${order.number || order.id}`, + adminHtml: this.compileAdminEmail(adminData), + }; + } +} diff --git a/src/lib/email/services/orderTransformerService.ts b/src/lib/email/services/orderTransformerService.ts new file mode 100644 index 0000000..bdee894 --- /dev/null +++ b/src/lib/email/services/orderTransformerService.ts @@ -0,0 +1,167 @@ +/** + * Order Transformer Service - Transforms Saleor order data into normalized email data + * All transformation logic abstracted here instead of inline in templates + */ + +import type { + SaleorOrder, + EmailData, + AdminEmailData, + LanguageCode, + OrderLine +} from "../types"; +import { + localeConfigs, + DEFAULT_LANGUAGE, + DEFAULT_CURRENCY +} from "../config"; +import { PaymentMethodService } from "./paymentMethodService"; + +export class OrderTransformerService { + /** + * Extract and format customer name from order + */ + static extractCustomerName(order: SaleorOrder): string { + if (order.shippingAddress?.firstName) { + return `${order.shippingAddress.firstName} ${order.shippingAddress.lastName || ""}`.trim(); + } + if (order.billingAddress?.firstName) { + return `${order.billingAddress.firstName} ${order.billingAddress.lastName || ""}`.trim(); + } + if (order.userEmail) { + return order.userEmail.split("@")[0]; + } + return "Customer"; + } + + /** + * Format shipping address for display + */ + static formatShippingAddress(order: SaleorOrder): string { + const address = order.shippingAddress; + if (!address) return ""; + + const parts = [ + `${address.firstName || ""} ${address.lastName || ""}`.trim(), + address.streetAddress1, + address.streetAddress2, + `${address.city || ""}${address.postalCode ? `, ${address.postalCode}` : ""}`, + address.country?.country || address.country?.code, + ].filter(Boolean); + + return parts.join("\n"); + } + + /** + * Extract phone number with fallback + */ + static extractPhone(order: SaleorOrder): string { + return ( + order.shippingAddress?.phone || + order.billingAddress?.phone || + "" + ); + } + + /** + * Format order items for email + */ + static formatItems(order: SaleorOrder): Array<{ + name: string; + quantity: number; + price: string; + }> { + const currency = order.total?.gross?.currency || DEFAULT_CURRENCY; + + return (order.lines || []).map((line: OrderLine) => { + const productName = line.variant?.product?.name || line.variant?.name || "Product"; + const amount = line.totalPrice?.gross?.amount?.toFixed(2) || "0.00"; + + return { + name: productName, + quantity: line.quantity || 0, + price: `${amount} ${currency}`, + }; + }); + } + + /** + * Format money amount with currency + */ + static formatMoney(amount: number | undefined, currency: string): string { + const value = amount?.toFixed(2) || "0.00"; + return `${value} ${currency}`; + } + + /** + * Format order date for display + */ + static formatOrderDate(order: SaleorOrder, languageCode: LanguageCode): string { + const date = order.created ? new Date(order.created) : new Date(); + const locale = localeConfigs[languageCode] || localeConfigs[DEFAULT_LANGUAGE]; + return date.toLocaleString(locale); + } + + /** + * Get language code with fallback + */ + static getLanguageCode(order: SaleorOrder): LanguageCode { + const lang = order.languageCode?.toLowerCase() as LanguageCode; + if (["en", "sr", "de", "fr"].includes(lang)) { + return lang; + } + return DEFAULT_LANGUAGE; + } + + /** + * Transform order into email data structure + */ + static transformToEmailData( + order: SaleorOrder, + translations: Record + ): EmailData { + const languageCode = this.getLanguageCode(order); + const currency = order.total?.gross?.currency || DEFAULT_CURRENCY; + const customerName = this.extractCustomerName(order); + const paymentMethod = PaymentMethodService.detectPaymentMethod(order); + + return { + ...translations, + orderNumber: order.number || order.id, + customerName, + greeting: "", // Will be compiled by email builder + subject: "", // Will be compiled by email builder + orderDate: this.formatOrderDate(order, languageCode), + orderStatus: order.status || "unfulfilled", + items: this.formatItems(order), + subtotal: this.formatMoney(order.subtotal?.gross?.amount, currency), + shipping: this.formatMoney(order.shippingPrice?.gross?.amount, currency), + tax: this.formatMoney(order.total?.tax?.amount, currency), + total: this.formatMoney(order.total?.gross?.amount, currency), + shippingAddress: this.formatShippingAddress(order), + phone: this.extractPhone(order), + paymentMethod: PaymentMethodService.getPaymentLabel(paymentMethod), + paymentLabel: "Payment:", // Can be moved to config if needed per language + }; + } + + /** + * Transform order into admin email data structure + */ + static transformToAdminEmailData( + order: SaleorOrder, + translations: Record, + adminTranslations: Record + ): Record { + const baseData = this.transformToEmailData(order, translations); + const paymentMethod = PaymentMethodService.detectPaymentMethod(order); + + return { + ...baseData, + ...adminTranslations, + customerEmail: order.userEmail || "", + paymentMethod: PaymentMethodService.getPaymentLabel(paymentMethod), + paymentLabel: "Payment:", + }; + } +} diff --git a/src/lib/email/services/paymentMethodService.ts b/src/lib/email/services/paymentMethodService.ts new file mode 100644 index 0000000..4b2f8e1 --- /dev/null +++ b/src/lib/email/services/paymentMethodService.ts @@ -0,0 +1,71 @@ +/** + * Payment Method Service - Detects payment method from order data + * Abstracted logic for determining how an order was paid + */ + +import type { SaleorOrder, PaymentMethod } from "../types"; +import { paymentMethodConfigs } from "../config"; + +export class PaymentMethodService { + /** + * Detect payment method from order transactions and metadata + */ + static detectPaymentMethod(order: SaleorOrder): PaymentMethod { + // Check transactions first + if (order.transactions && order.transactions.length > 0) { + const transaction = order.transactions[0]; + const message = transaction.message?.toLowerCase() || ""; + + // Check transaction events for payment type + const event = transaction.events?.[0]; + const eventMessage = event?.message?.toLowerCase() || ""; + const eventType = event?.type?.toLowerCase() || ""; + + const combinedText = `${message} ${eventMessage} ${eventType}`; + + if (combinedText.includes("cash") || combinedText.includes("cod")) { + return "cod"; + } + if (combinedText.includes("card") || combinedText.includes("stripe")) { + return "card"; + } + if (combinedText.includes("paypal")) { + return "paypal"; + } + if (combinedText.includes("bank") || combinedText.includes("transfer")) { + return "bank_transfer"; + } + } + + // Check metadata for payment method + if (order.metadata) { + const paymentMeta = order.metadata.find( + (m) => m.key === "payment_method" || m.key === "paymentMethod" + ); + if (paymentMeta) { + const value = paymentMeta.value.toLowerCase(); + if (value.includes("cash") || value.includes("cod")) return "cod"; + if (value.includes("card")) return "card"; + if (value.includes("paypal")) return "paypal"; + if (value.includes("bank")) return "bank_transfer"; + } + } + + // Default to unknown if no payment method detected + return "unknown"; + } + + /** + * Get display label for a payment method + */ + static getPaymentLabel(method: PaymentMethod): string { + return paymentMethodConfigs[method]?.label || paymentMethodConfigs.unknown.label; + } + + /** + * Get full payment method configuration + */ + static getPaymentConfig(method: PaymentMethod) { + return paymentMethodConfigs[method] || paymentMethodConfigs.unknown; + } +} diff --git a/src/lib/email/types.ts b/src/lib/email/types.ts new file mode 100644 index 0000000..42afe12 --- /dev/null +++ b/src/lib/email/types.ts @@ -0,0 +1,169 @@ +/** + * Email Types - Type definitions for the email system + * All data structures are strictly typed with no hardcoded values + */ + +export type LanguageCode = "en" | "sr" | "de" | "fr"; +export type PaymentMethod = "card" | "cod" | "paypal" | "bank_transfer" | "unknown"; +export type OrderStatus = "draft" | "unconfirmed" | "unfulfilled" | "partially_fulfilled" | "fulfilled" | "canceled"; + +export interface Money { + amount: number; + currency: string; +} + +export interface Address { + firstName?: string | null; + lastName?: string | null; + streetAddress1?: string | null; + streetAddress2?: string | null; + city?: string | null; + postalCode?: string | null; + country?: { + country?: string | null; + code?: string | null; + } | null; + phone?: string | null; +} + +export interface OrderLine { + quantity: number; + variant?: { + name?: string; + product?: { + name?: string; + }; + }; + totalPrice?: { + gross?: Money; + }; +} + +export interface Transaction { + id?: string; + message?: string; + externalUrl?: string; + events?: TransactionEvent[]; +} + +export interface TransactionEvent { + id?: string; + message?: string; + type?: string; + amount?: Money; +} + +export interface SaleorOrder { + id: string; + number?: string | null; + created?: string | null; + status?: string | null; + languageCode?: string | null; + userEmail?: string | null; + shippingAddress?: Address | null; + billingAddress?: Address | null; + lines?: OrderLine[] | null; + subtotal?: { + gross?: Money | null; + } | null; + shippingPrice?: { + gross?: Money | null; + } | null; + total?: { + gross?: Money | null; + tax?: Money | null; + } | null; + transactions?: Transaction[] | null; + metadata?: Array<{ + key: string; + value: string; + }> | null; +} + +export interface PaymentMethodConfig { + id: PaymentMethod; + label: string; + icon?: string; +} + +export interface EmailTemplateConfig { + subject: string; + title: string; + greeting: string; + body: string; + orderLabel: string; + dateLabel: string; + statusLabel: string; + itemsLabel: string; + subtotalLabel: string; + shippingLabel: string; + taxLabel: string; + totalLabel: string; + shippingAddressLabel: string; + phoneLabel: string; + phoneNotProvided: string; + viewOrderButton: string; + thankYou: string; + companyName: string; + footerText: string; +} + +export interface AdminEmailTemplateConfig { + adminTitle: string; + adminOrderLabel: string; + customerLabel: string; + nameLabel: string; + emailLabel: string; + dashboardButton: string; +} + +export interface EmailData { + orderNumber: string; + customerName: string; + greeting: string; + subject: string; + orderDate: string; + orderStatus: string; + items: Array<{ + name: string; + quantity: number; + price: string; + }>; + subtotal: string; + shipping: string; + tax: string; + total: string; + shippingAddress: string; + phone: string; + paymentMethod?: string; + paymentLabel?: string; + [key: string]: any; +} + +export interface AdminEmailData extends EmailData { + customerEmail: string; + adminTitle: string; + adminOrderLabel: string; + customerLabel: string; + nameLabel: string; + emailLabel: string; + dashboardButton: string; +} + +export interface EmailResult { + customerSubject: string; + customerHtml: string; + adminSubject: string; + adminHtml: string; +} + +export interface EmailServiceConfig { + fromEmail: string; + fromName: string; + adminEmails: string[]; + companyName: string; + companyLogoUrl: string; + dashboardUrl: string; + storefrontUrl: string; + trackingUrl?: string; +} diff --git a/src/pages/api/webhooks/order-cancelled.ts b/src/pages/api/webhooks/order-cancelled.ts index 1c4ad24..528b946 100644 --- a/src/pages/api/webhooks/order-cancelled.ts +++ b/src/pages/api/webhooks/order-cancelled.ts @@ -4,7 +4,7 @@ import { OrderCancelledWebhookPayloadFragment, } from "@/generated/graphql"; import { saleorApp } from "@/saleor-app"; -import { getOrderCancelledEmails } from "@/lib/email-templates"; +import { getOrderCancelledEmails } from "@/lib/email-templates/order-cancelled"; import { Resend } from "resend"; const resend = new Resend(process.env.RESEND_API_KEY);