diff --git a/locale/defaultMessages.json b/locale/defaultMessages.json index defbf4785..3f9a2fde5 100644 --- a/locale/defaultMessages.json +++ b/locale/defaultMessages.json @@ -5653,6 +5653,9 @@ "src_dot_plugins_dot_views_dot_955370043": { "string": "The plugin may stop working after this field is cleared. Are you sure you want to proceed?" }, + "src_dot_preorderEndDateInFutureErrorText": { + "string": "Preorder end time needs to be set in the future" + }, "src_dot_productTypes": { "context": "product types section name", "string": "Product Types" @@ -6109,6 +6112,17 @@ "context": "product weight", "string": "Weight" }, + "src_dot_products_dot_components_dot_ProductStocks_dot_1540024536": { + "context": "product inventory, checkbox", + "string": "Variant currently in preorder" + }, + "src_dot_products_dot_components_dot_ProductStocks_dot_2473321447": { + "string": "CANCEL END DATE" + }, + "src_dot_products_dot_components_dot_ProductStocks_dot_2481295410": { + "context": "app has been installed", + "string": "{unitsLeft} units left" + }, "src_dot_products_dot_components_dot_ProductStocks_dot_2585918415": { "string": "SKU (Stock Keeping Unit)" }, @@ -6116,10 +6130,24 @@ "context": "tabel column header", "string": "Warehouse Name" }, + "src_dot_products_dot_components_dot_ProductStocks_dot_2699291877": { + "string": "SETUP END DATE" + }, "src_dot_products_dot_components_dot_ProductStocks_dot_2796503714": { "context": "header", "string": "Quantity" }, + "src_dot_products_dot_components_dot_ProductStocks_dot_294624093": { + "context": "info text", + "string": "Preordered products will be available in all warehouses. You can set a threshold for sold quantity. Leaving input blank will be interpreted as no limit to sale. Sold items will be allocated at the warehouse assigned to chosen shipping zone." + }, + "src_dot_products_dot_components_dot_ProductStocks_dot_2999762286": { + "string": "Threshold that cannot be exceeded even if per channel thresholds are still available" + }, + "src_dot_products_dot_components_dot_ProductStocks_dot_3420537107": { + "context": "tabel column header", + "string": "Channels" + }, "src_dot_products_dot_components_dot_ProductStocks_dot_3633706025": { "context": "product inventory, checkbox", "string": "Track Inventory" @@ -6128,6 +6156,16 @@ "context": "button", "string": "Assign Warehouse" }, + "src_dot_products_dot_components_dot_ProductStocks_dot_3862021157": { + "context": "info text", + "string": "Set up an end date of preorder. When end date will be reached product will be automatically taken from preorder to standard selling" + }, + "src_dot_products_dot_components_dot_ProductStocks_dot_4187357147": { + "string": "Unlimited" + }, + "src_dot_products_dot_components_dot_ProductStocks_dot_578055997": { + "string": "Global threshold" + }, "src_dot_products_dot_components_dot_ProductStocks_dot_849869830": { "string": "Active inventory tracking will automatically calculate changes of stock" }, @@ -6318,6 +6356,17 @@ "context": "dialog header", "string": "Delete Variant" }, + "src_dot_products_dot_components_dot_ProductVariantEndPreorderDialog_dot_dialogConfirmButtonLabel": { + "context": "button label", + "string": "ACCEPT" + }, + "src_dot_products_dot_components_dot_ProductVariantEndPreorderDialog_dot_dialogMessage": { + "string": "You are about to end your products preorder. You have sold {variantGlobalSoldUnits} units of this variant. Sold units will be allocated at appropriate warehouses. Remember to add remaining threshold stock to warehouses." + }, + "src_dot_products_dot_components_dot_ProductVariantEndPreorderDialog_dot_dialogTitle": { + "context": "dialog header", + "string": "Ending preorder" + }, "src_dot_products_dot_components_dot_ProductVariantImageSelectDialog_dot_2015102342": { "context": "dialog header", "string": "Media Selection" @@ -8101,10 +8150,18 @@ "context": "table column header, allocated product quantity", "string": "Allocated" }, + "tableColChannelThreshold": { + "context": "table column header", + "string": "Channel threshold" + }, "tableColQuantity": { "context": "table column header", "string": "Quantity" }, + "tableColSoldUnits": { + "context": "table column header, sold units preorder quantity", + "string": "Sold units" + }, "transaction reference subtitle": { "context": "transaction reference subtitle", "string": "Transaction reference" @@ -8113,6 +8170,10 @@ "context": "product unavailability", "string": "Unavailable for purchase" }, + "unlimitedUnitsLeft": { + "context": "section header", + "string": "Unlimited" + }, "voucherDetailsUnassignCategory": { "context": "unassign category from voucher, button", "string": "Unassign" diff --git a/schema.graphql b/schema.graphql index 2ad044d03..5cdf4b443 100644 --- a/schema.graphql +++ b/schema.graphql @@ -3795,6 +3795,7 @@ type Mutation { productVariantTranslate(id: ID!, input: NameTranslationInput!, languageCode: LanguageCodeEnum!): ProductVariantTranslate productVariantChannelListingUpdate(id: ID!, input: [ProductVariantChannelListingAddInput!]!): ProductVariantChannelListingUpdate productVariantReorderAttributeValues(attributeId: ID!, moves: [ReorderInput]!, variantId: ID!): ProductVariantReorderAttributeValues + productVariantPreorderDeactivate(id: ID!): ProductVariantPreorderDeactivate variantMediaAssign(mediaId: ID!, variantId: ID!): VariantMediaAssign variantMediaUnassign(mediaId: ID!, variantId: ID!): VariantMediaUnassign paymentCapture(amount: PositiveDecimal, paymentId: ID!): PaymentCapture @@ -5127,6 +5128,22 @@ enum PostalCodeRuleInclusionTypeEnum { EXCLUDE } +type PreorderData { + globalThreshold: Int + globalSoldUnits: Int! + endDate: DateTime +} + +input PreorderSettingsInput { + globalThreshold: Int + endDate: DateTime +} + +type PreorderThreshold { + quantity: Int + soldUnits: Int! +} + input PriceInput { currency: String! amount: PositiveDecimal! @@ -5310,6 +5327,7 @@ enum ProductErrorCode { CANNOT_MANAGE_PRODUCT_WITHOUT_VARIANT PRODUCT_NOT_ASSIGNED_TO_CHANNEL UNSUPPORTED_MEDIA_PROVIDER + PREORDER_VARIANT_CANNOT_BE_DEACTIVATED } enum ProductFieldEnum { @@ -5342,6 +5360,7 @@ input ProductFilterInput { productTypes: [ID] giftCard: Boolean ids: [ID] + hasPreorderedVariants: Boolean channel: String } @@ -5628,6 +5647,7 @@ type ProductVariant implements Node & ObjectWithMetadata { digitalContent: DigitalContent stocks(address: AddressInput, countryCode: CountryCode): [Stock] quantityAvailable(address: AddressInput, countryCode: CountryCode): Int! + preorder: PreorderData } type ProductVariantBulkCreate { @@ -5642,6 +5662,7 @@ input ProductVariantBulkCreateInput { sku: String trackInventory: Boolean weight: WeightScalar + preorder: PreorderSettingsInput stocks: [StockInput!] channelListings: [ProductVariantChannelListingAddInput!] } @@ -5658,12 +5679,14 @@ type ProductVariantChannelListing implements Node { price: Money costPrice: Money margin: Int + preorderThreshold: PreorderThreshold } input ProductVariantChannelListingAddInput { channelId: ID! price: PositiveDecimal! costPrice: PositiveDecimal + preorderThreshold: Int } type ProductVariantChannelListingUpdate { @@ -5694,6 +5717,7 @@ input ProductVariantCreateInput { sku: String trackInventory: Boolean weight: WeightScalar + preorder: PreorderSettingsInput product: ID! stocks: [StockInput!] } @@ -5708,6 +5732,7 @@ input ProductVariantFilterInput { search: String sku: [String] metadata: [MetadataFilter] + isPreorder: Boolean } input ProductVariantInput { @@ -5715,6 +5740,12 @@ input ProductVariantInput { sku: String trackInventory: Boolean weight: WeightScalar + preorder: PreorderSettingsInput +} + +type ProductVariantPreorderDeactivate { + productVariant: ProductVariant + errors: [ProductError!]! } type ProductVariantReorder { diff --git a/src/channels/utils.ts b/src/channels/utils.ts index 07a2a09d1..0ffbdb302 100644 --- a/src/channels/utils.ts +++ b/src/channels/utils.ts @@ -34,6 +34,8 @@ export interface ChannelData { availableForPurchase?: string; isAvailableForPurchase?: boolean; visibleInListings?: boolean; + preorderThreshold?: number; + unitsSold?: number; } export interface ChannelPriceData { @@ -53,6 +55,34 @@ export type ChannelPriceArgs = RequireOnlyOne< "price" | "costPrice" >; +export interface ChannelPreorderArgs { + preorderThreshold: number; + unitsSold: number; + hasPreorderEndDate: boolean; + preorderEndDateTime?: string; +} + +export interface ChannelPriceAndPreorderData { + id: string; + name: string; + currency: string; + price: string; + costPrice?: string; + preorderThreshold?: number | null; + unitsSold?: number; +} + +export interface IChannelPriceAndPreorderArgs { + price: string; + costPrice: string; + preorderThreshold?: number | null; + unitsSold?: number; +} +export type ChannelPriceAndPreorderArgs = IChannelPriceArgs & { + preorderThreshold: number | null; + unitsSold?: number; +}; + export interface ChannelVoucherData { id: string; name: string; @@ -262,6 +292,8 @@ export const createChannelsDataFromProduct = ( productData.variants, channel.id ); + const soldUnits = variantChannel?.preorderThreshold?.soldUnits; + const preorderThreshold = variantChannel?.preorderThreshold?.quantity; return { availableForPurchase, @@ -274,7 +306,9 @@ export const createChannelsDataFromProduct = ( isAvailableForPurchase: !!isAvailableForPurchase, name: channel.name, price: price ? price.amount.toString() : "", - visibleInListings: !!visibleInListings + visibleInListings: !!visibleInListings, + soldUnits, + preorderThreshold }; } ) || []; diff --git a/src/components/DateTimeTimezoneField.tsx b/src/components/DateTimeTimezoneField.tsx new file mode 100644 index 000000000..31168b57c --- /dev/null +++ b/src/components/DateTimeTimezoneField.tsx @@ -0,0 +1,87 @@ +import { TextField } from "@material-ui/core"; +import { TextFieldProps } from "@material-ui/core/TextField"; +import { commonMessages } from "@saleor/intl"; +import { makeStyles } from "@saleor/macaw-ui"; +import { DateTime, joinDateTime, splitDateTime } from "@saleor/misc"; +import React, { useEffect, useState } from "react"; +import { useIntl } from "react-intl"; + +import ErrorNoticeBar from "./ErrorNoticeBar"; + +type DateTimeFieldProps = Omit & { + onChange: (value: string) => void; + error: string | React.ReactNode; + setError?: () => void; + futureDatesOnly?: boolean; + value: string; +}; + +const useStyles = makeStyles( + theme => ({ + dateInput: { + marginRight: theme.spacing(2) + }, + errorNoticeBar: { + marginTop: theme.spacing(2) + } + }), + { name: "DateTimeTimezoneField" } +); + +export const DateTimeTimezoneField: React.FC = ({ + disabled, + name, + onChange, + error, + fullWidth, + value: initialValue +}) => { + const classes = useStyles({}); + const intl = useIntl(); + const [value, setValue] = useState( + initialValue ? splitDateTime(initialValue) : { date: "", time: "" } + ); + + useEffect(() => { + const newDate = joinDateTime(value.date, value.time); + onChange(newDate); + }, [value]); + + return ( + <> + { + const date = event.target.value; + setValue(value => ({ ...value, date })); + }} + type="date" + value={value.date} + InputLabelProps={{ shrink: true }} + /> + { + const time = event.target.value; + setValue(value => ({ ...value, time })); + }} + type="time" + value={value.time} + InputLabelProps={{ shrink: true }} + /> + + {error && ( + + )} + + ); +}; diff --git a/src/components/ErrorNoticeBar/ErrorNoticeBar.tsx b/src/components/ErrorNoticeBar/ErrorNoticeBar.tsx new file mode 100644 index 000000000..18f1e6913 --- /dev/null +++ b/src/components/ErrorNoticeBar/ErrorNoticeBar.tsx @@ -0,0 +1,34 @@ +import { Card, CardContent, Typography } from "@material-ui/core"; +import { makeStyles } from "@saleor/macaw-ui"; +import classNames from "classnames"; +import React from "react"; +interface ErrorNoticeBarProps { + className?: string; + message: string | React.ReactNode; +} + +const useStyles = makeStyles( + theme => ({ + root: { + background: theme.palette.alert.paper.error + } + }), + { + name: "ErrorNoticeBar" + } +); + +const ErrorNoticeBar: React.FC = props => { + const { className, message } = props; + const classes = useStyles(props); + + return ( + + + {message} + + + ); +}; +ErrorNoticeBar.displayName = "ErrorNoticeBar"; +export default ErrorNoticeBar; diff --git a/src/components/ErrorNoticeBar/index.ts b/src/components/ErrorNoticeBar/index.ts new file mode 100644 index 000000000..8e92af0c8 --- /dev/null +++ b/src/components/ErrorNoticeBar/index.ts @@ -0,0 +1 @@ +export { default } from "./ErrorNoticeBar"; diff --git a/src/fragments/orders.ts b/src/fragments/orders.ts index c9a865f33..87f398603 100644 --- a/src/fragments/orders.ts +++ b/src/fragments/orders.ts @@ -81,6 +81,9 @@ export const fragmentOrderLine = gql` variant { id quantityAvailable + preorder { + endDate + } } productName productSku diff --git a/src/fragments/products.ts b/src/fragments/products.ts index 6ed998080..06ec0dc41 100644 --- a/src/fragments/products.ts +++ b/src/fragments/products.ts @@ -27,6 +27,14 @@ export const fragmentMoney = gql` } `; +export const fragmentPreorder = gql` + fragment PreorderFragment on PreorderData { + globalThreshold + globalSoldUnits + endDate + } +`; + export const priceRangeFragment = gql` ${fragmentMoney} fragment PriceRangeFragment on TaxedMoneyRange { @@ -95,6 +103,10 @@ export const channelListingProductVariantFragment = gql` costPrice { ...Money } + preorderThreshold { + quantity + soldUnits + } } `; @@ -178,6 +190,7 @@ export const productVariantAttributesFragment = gql` `; export const productFragmentDetails = gql` + ${fragmentPreorder} ${fragmentProductMedia} ${productVariantAttributesFragment} ${stockFragment} @@ -226,6 +239,9 @@ export const productFragmentDetails = gql` ...StockFragment } trackInventory + preorder { + ...PreorderFragment + } channelListings { ...ChannelListingProductVariantFragment } @@ -282,6 +298,7 @@ export const selectedVariantAttributeFragment = gql` `; export const fragmentVariant = gql` + ${fragmentPreorder} ${fragmentProductMedia} ${selectedVariantAttributeFragment} ${priceRangeFragment} @@ -357,6 +374,9 @@ export const fragmentVariant = gql` ...StockFragment } trackInventory + preorder { + ...PreorderFragment + } weight { ...WeightFragment } diff --git a/src/fragments/types/ChannelListingProductVariantFragment.ts b/src/fragments/types/ChannelListingProductVariantFragment.ts index 4b7ac0b80..c98a063a1 100644 --- a/src/fragments/types/ChannelListingProductVariantFragment.ts +++ b/src/fragments/types/ChannelListingProductVariantFragment.ts @@ -26,9 +26,16 @@ export interface ChannelListingProductVariantFragment_costPrice { currency: string; } +export interface ChannelListingProductVariantFragment_preorderThreshold { + __typename: "PreorderThreshold"; + quantity: number | null; + soldUnits: number; +} + export interface ChannelListingProductVariantFragment { __typename: "ProductVariantChannelListing"; channel: ChannelListingProductVariantFragment_channel; price: ChannelListingProductVariantFragment_price | null; costPrice: ChannelListingProductVariantFragment_costPrice | null; + preorderThreshold: ChannelListingProductVariantFragment_preorderThreshold | null; } diff --git a/src/fragments/types/FulfillmentFragment.ts b/src/fragments/types/FulfillmentFragment.ts index df55a9ac8..93d141f74 100644 --- a/src/fragments/types/FulfillmentFragment.ts +++ b/src/fragments/types/FulfillmentFragment.ts @@ -9,10 +9,16 @@ import { DiscountValueTypeEnum, FulfillmentStatus } from "./../../types/globalTy // GraphQL fragment: FulfillmentFragment // ==================================================== +export interface FulfillmentFragment_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface FulfillmentFragment_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: FulfillmentFragment_lines_orderLine_variant_preorder | null; } export interface FulfillmentFragment_lines_orderLine_unitDiscount { diff --git a/src/fragments/types/OrderDetailsFragment.ts b/src/fragments/types/OrderDetailsFragment.ts index db30463a5..9f871bfdd 100644 --- a/src/fragments/types/OrderDetailsFragment.ts +++ b/src/fragments/types/OrderDetailsFragment.ts @@ -206,10 +206,16 @@ export interface OrderDetailsFragment_events { lines: (OrderDetailsFragment_events_lines | null)[] | null; } +export interface OrderDetailsFragment_fulfillments_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderDetailsFragment_fulfillments_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderDetailsFragment_fulfillments_lines_orderLine_variant_preorder | null; } export interface OrderDetailsFragment_fulfillments_lines_orderLine_unitDiscount { @@ -302,10 +308,16 @@ export interface OrderDetailsFragment_fulfillments { warehouse: OrderDetailsFragment_fulfillments_warehouse | null; } +export interface OrderDetailsFragment_lines_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderDetailsFragment_lines_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderDetailsFragment_lines_variant_preorder | null; } export interface OrderDetailsFragment_lines_unitDiscount { diff --git a/src/fragments/types/OrderLineFragment.ts b/src/fragments/types/OrderLineFragment.ts index 8e2cf1636..278012474 100644 --- a/src/fragments/types/OrderLineFragment.ts +++ b/src/fragments/types/OrderLineFragment.ts @@ -9,10 +9,16 @@ import { DiscountValueTypeEnum } from "./../../types/globalTypes"; // GraphQL fragment: OrderLineFragment // ==================================================== +export interface OrderLineFragment_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderLineFragment_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderLineFragment_variant_preorder | null; } export interface OrderLineFragment_unitDiscount { diff --git a/src/fragments/types/PreorderFragment.ts b/src/fragments/types/PreorderFragment.ts new file mode 100644 index 000000000..23cd59b75 --- /dev/null +++ b/src/fragments/types/PreorderFragment.ts @@ -0,0 +1,15 @@ +/* tslint:disable */ +/* eslint-disable */ +// @generated +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL fragment: PreorderFragment +// ==================================================== + +export interface PreorderFragment { + __typename: "PreorderData"; + globalThreshold: number | null; + globalSoldUnits: number; + endDate: any | null; +} diff --git a/src/fragments/types/Product.ts b/src/fragments/types/Product.ts index 167741d0c..f8ba2bb0c 100644 --- a/src/fragments/types/Product.ts +++ b/src/fragments/types/Product.ts @@ -260,6 +260,13 @@ export interface Product_variants_stocks { warehouse: Product_variants_stocks_warehouse; } +export interface Product_variants_preorder { + __typename: "PreorderData"; + globalThreshold: number | null; + globalSoldUnits: number; + endDate: any | null; +} + export interface Product_variants_channelListings_channel { __typename: "Channel"; id: string; @@ -279,11 +286,18 @@ export interface Product_variants_channelListings_costPrice { currency: string; } +export interface Product_variants_channelListings_preorderThreshold { + __typename: "PreorderThreshold"; + quantity: number | null; + soldUnits: number; +} + export interface Product_variants_channelListings { __typename: "ProductVariantChannelListing"; channel: Product_variants_channelListings_channel; price: Product_variants_channelListings_price | null; costPrice: Product_variants_channelListings_costPrice | null; + preorderThreshold: Product_variants_channelListings_preorderThreshold | null; } export interface Product_variants { @@ -295,6 +309,7 @@ export interface Product_variants { media: Product_variants_media[] | null; stocks: (Product_variants_stocks | null)[] | null; trackInventory: boolean; + preorder: Product_variants_preorder | null; channelListings: Product_variants_channelListings[] | null; } diff --git a/src/fragments/types/ProductVariant.ts b/src/fragments/types/ProductVariant.ts index 75bd18544..a86e0765a 100644 --- a/src/fragments/types/ProductVariant.ts +++ b/src/fragments/types/ProductVariant.ts @@ -299,11 +299,18 @@ export interface ProductVariant_channelListings_costPrice { currency: string; } +export interface ProductVariant_channelListings_preorderThreshold { + __typename: "PreorderThreshold"; + quantity: number | null; + soldUnits: number; +} + export interface ProductVariant_channelListings { __typename: "ProductVariantChannelListing"; channel: ProductVariant_channelListings_channel; price: ProductVariant_channelListings_price | null; costPrice: ProductVariant_channelListings_costPrice | null; + preorderThreshold: ProductVariant_channelListings_preorderThreshold | null; } export interface ProductVariant_stocks_warehouse { @@ -320,6 +327,13 @@ export interface ProductVariant_stocks { warehouse: ProductVariant_stocks_warehouse; } +export interface ProductVariant_preorder { + __typename: "PreorderData"; + globalThreshold: number | null; + globalSoldUnits: number; + endDate: any | null; +} + export interface ProductVariant_weight { __typename: "Weight"; unit: WeightUnitsEnum; @@ -340,5 +354,6 @@ export interface ProductVariant { sku: string | null; stocks: (ProductVariant_stocks | null)[] | null; trackInventory: boolean; + preorder: ProductVariant_preorder | null; weight: ProductVariant_weight | null; } diff --git a/src/intl.ts b/src/intl.ts index 8f43d2e6b..e5b503a53 100644 --- a/src/intl.ts +++ b/src/intl.ts @@ -135,6 +135,9 @@ export const errorMessages = defineMessages({ imageUploadErrorText: { defaultMessage: "There was a poblem with the file you uploaded as an image and it couldn't be used. Please try a different file." + }, + preorderEndDateInFutureErrorText: { + defaultMessage: "Preorder end time needs to be set in the future" } }); diff --git a/src/orders/components/OrderFulfillPage/OrderFulfillPage.tsx b/src/orders/components/OrderFulfillPage/OrderFulfillPage.tsx index ab9aebada..cbbab0ef7 100644 --- a/src/orders/components/OrderFulfillPage/OrderFulfillPage.tsx +++ b/src/orders/components/OrderFulfillPage/OrderFulfillPage.tsx @@ -296,6 +296,7 @@ const OrderFulfillPage: React.FC = props => { 0 ); const overfulfill = remainingQuantity < quantityToFulfill; + const isPreorder = !!line.variant?.preorder; return ( @@ -318,6 +319,18 @@ const OrderFulfillPage: React.FC = props => { {line.variant?.sku} {warehouses?.map(warehouse => { + if (isPreorder) { + return ( + + ); + } + const warehouseStock = line.variant?.stocks?.find( stock => stock.warehouse.id === warehouse.id ); @@ -419,16 +432,20 @@ const OrderFulfillPage: React.FC = props => { className={classes.colQuantityTotal} key="total" > - - {quantityToFulfill} - {" "} - / {remainingQuantity} + {!isPreorder && ( + <> + + {quantityToFulfill} + {" "} + / {remainingQuantity} + + )} ); diff --git a/src/orders/components/OrderFulfillPage/fixtures.ts b/src/orders/components/OrderFulfillPage/fixtures.ts index 7edbecf92..9c0fa54dc 100644 --- a/src/orders/components/OrderFulfillPage/fixtures.ts +++ b/src/orders/components/OrderFulfillPage/fixtures.ts @@ -24,6 +24,7 @@ export const orderToFulfill: OrderFulfillData_order = { id: "UHJvZHVjdFZhcmlhbnQ6Mjk2", name: "S", sku: "62783187", + preorder: null, attributes: [ { __typename: "SelectedAttribute", @@ -87,6 +88,7 @@ export const orderToFulfill: OrderFulfillData_order = { id: "UHJvZHVjdFZhcmlhbnQ6MTgx", name: "2.5l", sku: "998323583", + preorder: null, attributes: [ { __typename: "SelectedAttribute", @@ -143,6 +145,7 @@ export const orderToFulfill: OrderFulfillData_order = { id: "UHJvZHVjdFZhcmlhbnQ6MTgy", name: "5l", sku: "998323584", + preorder: null, attributes: [ { __typename: "SelectedAttribute", diff --git a/src/orders/components/OrderReturnPage/OrderReturnRefundItemsCard/ReturnItemsCard.tsx b/src/orders/components/OrderReturnPage/OrderReturnRefundItemsCard/ReturnItemsCard.tsx index 802e0699d..bd52e0441 100644 --- a/src/orders/components/OrderReturnPage/OrderReturnRefundItemsCard/ReturnItemsCard.tsx +++ b/src/orders/components/OrderReturnPage/OrderReturnRefundItemsCard/ReturnItemsCard.tsx @@ -175,6 +175,7 @@ const ItemsCard: React.FC = ({ .isRefunded; const isReplacable = !!variant && !isRefunded; const isReturnable = !!variant; + const isPreorder = !!variant?.preorder; const lineQuantity = fulfilmentId ? quantity : quantityToFulfill; const isSelected = itemsSelections.find(getById(id))?.value; const currentQuantity = itemsQuantities.find(getById(id))?.value; @@ -233,7 +234,7 @@ const ItemsCard: React.FC = ({ )} - {isReplacable && ( + {isReplacable && !isPreorder && ( onChangeSelected(id, !isSelected)} diff --git a/src/orders/fixtures.ts b/src/orders/fixtures.ts index f319e0509..1322aff27 100644 --- a/src/orders/fixtures.ts +++ b/src/orders/fixtures.ts @@ -1103,7 +1103,8 @@ export const order = (placeholder: string): OrderDetails_order => ({ variant: { __typename: "ProductVariant", id: "dsfsfuhb", - quantityAvailable: 10 + quantityAvailable: 10, + preorder: null } }, quantity: 1 @@ -1172,7 +1173,8 @@ export const order = (placeholder: string): OrderDetails_order => ({ variant: { __typename: "ProductVariant", id: "dsfsfuhb", - quantityAvailable: 10 + quantityAvailable: 10, + preorder: null } }, quantity: 1 @@ -1248,7 +1250,8 @@ export const order = (placeholder: string): OrderDetails_order => ({ variant: { __typename: "ProductVariant", id: "dsfsfuhb", - quantityAvailable: 10 + quantityAvailable: 10, + preorder: null } }, { @@ -1303,7 +1306,8 @@ export const order = (placeholder: string): OrderDetails_order => ({ variant: { __typename: "ProductVariant", id: "dsfsfuhb", - quantityAvailable: 10 + quantityAvailable: 10, + preorder: null } } ], @@ -1491,7 +1495,8 @@ export const draftOrder = (placeholder: string): OrderDetails_order => ({ variant: { __typename: "ProductVariant", id: "dsfsfuhb", - quantityAvailable: 10 + quantityAvailable: 10, + preorder: null } }, { @@ -1545,7 +1550,8 @@ export const draftOrder = (placeholder: string): OrderDetails_order => ({ variant: { __typename: "ProductVariant", id: "dsfsfuhb", - quantityAvailable: 10 + quantityAvailable: 10, + preorder: null } } ], diff --git a/src/orders/queries.ts b/src/orders/queries.ts index 1eb7a9734..f7c5607da 100644 --- a/src/orders/queries.ts +++ b/src/orders/queries.ts @@ -254,6 +254,9 @@ const orderFulfillData = gql` id name sku + preorder { + endDate + } attributes { values { id diff --git a/src/orders/types/FulfillOrder.ts b/src/orders/types/FulfillOrder.ts index b1a97f093..526eff356 100644 --- a/src/orders/types/FulfillOrder.ts +++ b/src/orders/types/FulfillOrder.ts @@ -215,10 +215,16 @@ export interface FulfillOrder_orderFulfill_order_events { lines: (FulfillOrder_orderFulfill_order_events_lines | null)[] | null; } +export interface FulfillOrder_orderFulfill_order_fulfillments_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface FulfillOrder_orderFulfill_order_fulfillments_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: FulfillOrder_orderFulfill_order_fulfillments_lines_orderLine_variant_preorder | null; } export interface FulfillOrder_orderFulfill_order_fulfillments_lines_orderLine_unitDiscount { @@ -311,10 +317,16 @@ export interface FulfillOrder_orderFulfill_order_fulfillments { warehouse: FulfillOrder_orderFulfill_order_fulfillments_warehouse | null; } +export interface FulfillOrder_orderFulfill_order_lines_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface FulfillOrder_orderFulfill_order_lines_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: FulfillOrder_orderFulfill_order_lines_variant_preorder | null; } export interface FulfillOrder_orderFulfill_order_lines_unitDiscount { diff --git a/src/orders/types/OrderCancel.ts b/src/orders/types/OrderCancel.ts index dd2d2d284..8e99e99f9 100644 --- a/src/orders/types/OrderCancel.ts +++ b/src/orders/types/OrderCancel.ts @@ -213,10 +213,16 @@ export interface OrderCancel_orderCancel_order_events { lines: (OrderCancel_orderCancel_order_events_lines | null)[] | null; } +export interface OrderCancel_orderCancel_order_fulfillments_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderCancel_orderCancel_order_fulfillments_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderCancel_orderCancel_order_fulfillments_lines_orderLine_variant_preorder | null; } export interface OrderCancel_orderCancel_order_fulfillments_lines_orderLine_unitDiscount { @@ -309,10 +315,16 @@ export interface OrderCancel_orderCancel_order_fulfillments { warehouse: OrderCancel_orderCancel_order_fulfillments_warehouse | null; } +export interface OrderCancel_orderCancel_order_lines_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderCancel_orderCancel_order_lines_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderCancel_orderCancel_order_lines_variant_preorder | null; } export interface OrderCancel_orderCancel_order_lines_unitDiscount { diff --git a/src/orders/types/OrderCapture.ts b/src/orders/types/OrderCapture.ts index e2072cc06..c945058c5 100644 --- a/src/orders/types/OrderCapture.ts +++ b/src/orders/types/OrderCapture.ts @@ -213,10 +213,16 @@ export interface OrderCapture_orderCapture_order_events { lines: (OrderCapture_orderCapture_order_events_lines | null)[] | null; } +export interface OrderCapture_orderCapture_order_fulfillments_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderCapture_orderCapture_order_fulfillments_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderCapture_orderCapture_order_fulfillments_lines_orderLine_variant_preorder | null; } export interface OrderCapture_orderCapture_order_fulfillments_lines_orderLine_unitDiscount { @@ -309,10 +315,16 @@ export interface OrderCapture_orderCapture_order_fulfillments { warehouse: OrderCapture_orderCapture_order_fulfillments_warehouse | null; } +export interface OrderCapture_orderCapture_order_lines_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderCapture_orderCapture_order_lines_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderCapture_orderCapture_order_lines_variant_preorder | null; } export interface OrderCapture_orderCapture_order_lines_unitDiscount { diff --git a/src/orders/types/OrderConfirm.ts b/src/orders/types/OrderConfirm.ts index b17d08328..2d1ce0394 100644 --- a/src/orders/types/OrderConfirm.ts +++ b/src/orders/types/OrderConfirm.ts @@ -213,10 +213,16 @@ export interface OrderConfirm_orderConfirm_order_events { lines: (OrderConfirm_orderConfirm_order_events_lines | null)[] | null; } +export interface OrderConfirm_orderConfirm_order_fulfillments_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderConfirm_orderConfirm_order_fulfillments_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderConfirm_orderConfirm_order_fulfillments_lines_orderLine_variant_preorder | null; } export interface OrderConfirm_orderConfirm_order_fulfillments_lines_orderLine_unitDiscount { @@ -309,10 +315,16 @@ export interface OrderConfirm_orderConfirm_order_fulfillments { warehouse: OrderConfirm_orderConfirm_order_fulfillments_warehouse | null; } +export interface OrderConfirm_orderConfirm_order_lines_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderConfirm_orderConfirm_order_lines_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderConfirm_orderConfirm_order_lines_variant_preorder | null; } export interface OrderConfirm_orderConfirm_order_lines_unitDiscount { diff --git a/src/orders/types/OrderDetails.ts b/src/orders/types/OrderDetails.ts index 64f1a8c06..906e4158b 100644 --- a/src/orders/types/OrderDetails.ts +++ b/src/orders/types/OrderDetails.ts @@ -206,10 +206,16 @@ export interface OrderDetails_order_events { lines: (OrderDetails_order_events_lines | null)[] | null; } +export interface OrderDetails_order_fulfillments_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderDetails_order_fulfillments_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderDetails_order_fulfillments_lines_orderLine_variant_preorder | null; } export interface OrderDetails_order_fulfillments_lines_orderLine_unitDiscount { @@ -302,10 +308,16 @@ export interface OrderDetails_order_fulfillments { warehouse: OrderDetails_order_fulfillments_warehouse | null; } +export interface OrderDetails_order_lines_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderDetails_order_lines_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderDetails_order_lines_variant_preorder | null; } export interface OrderDetails_order_lines_unitDiscount { diff --git a/src/orders/types/OrderDiscountAdd.ts b/src/orders/types/OrderDiscountAdd.ts index 02232b80f..6cfd523af 100644 --- a/src/orders/types/OrderDiscountAdd.ts +++ b/src/orders/types/OrderDiscountAdd.ts @@ -213,10 +213,16 @@ export interface OrderDiscountAdd_orderDiscountAdd_order_events { lines: (OrderDiscountAdd_orderDiscountAdd_order_events_lines | null)[] | null; } +export interface OrderDiscountAdd_orderDiscountAdd_order_fulfillments_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderDiscountAdd_orderDiscountAdd_order_fulfillments_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderDiscountAdd_orderDiscountAdd_order_fulfillments_lines_orderLine_variant_preorder | null; } export interface OrderDiscountAdd_orderDiscountAdd_order_fulfillments_lines_orderLine_unitDiscount { @@ -309,10 +315,16 @@ export interface OrderDiscountAdd_orderDiscountAdd_order_fulfillments { warehouse: OrderDiscountAdd_orderDiscountAdd_order_fulfillments_warehouse | null; } +export interface OrderDiscountAdd_orderDiscountAdd_order_lines_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderDiscountAdd_orderDiscountAdd_order_lines_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderDiscountAdd_orderDiscountAdd_order_lines_variant_preorder | null; } export interface OrderDiscountAdd_orderDiscountAdd_order_lines_unitDiscount { diff --git a/src/orders/types/OrderDiscountDelete.ts b/src/orders/types/OrderDiscountDelete.ts index 50b2f1ee1..bf24e2eeb 100644 --- a/src/orders/types/OrderDiscountDelete.ts +++ b/src/orders/types/OrderDiscountDelete.ts @@ -213,10 +213,16 @@ export interface OrderDiscountDelete_orderDiscountDelete_order_events { lines: (OrderDiscountDelete_orderDiscountDelete_order_events_lines | null)[] | null; } +export interface OrderDiscountDelete_orderDiscountDelete_order_fulfillments_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderDiscountDelete_orderDiscountDelete_order_fulfillments_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderDiscountDelete_orderDiscountDelete_order_fulfillments_lines_orderLine_variant_preorder | null; } export interface OrderDiscountDelete_orderDiscountDelete_order_fulfillments_lines_orderLine_unitDiscount { @@ -309,10 +315,16 @@ export interface OrderDiscountDelete_orderDiscountDelete_order_fulfillments { warehouse: OrderDiscountDelete_orderDiscountDelete_order_fulfillments_warehouse | null; } +export interface OrderDiscountDelete_orderDiscountDelete_order_lines_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderDiscountDelete_orderDiscountDelete_order_lines_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderDiscountDelete_orderDiscountDelete_order_lines_variant_preorder | null; } export interface OrderDiscountDelete_orderDiscountDelete_order_lines_unitDiscount { diff --git a/src/orders/types/OrderDiscountUpdate.ts b/src/orders/types/OrderDiscountUpdate.ts index 51fbe6e5d..caa2373d5 100644 --- a/src/orders/types/OrderDiscountUpdate.ts +++ b/src/orders/types/OrderDiscountUpdate.ts @@ -213,10 +213,16 @@ export interface OrderDiscountUpdate_orderDiscountUpdate_order_events { lines: (OrderDiscountUpdate_orderDiscountUpdate_order_events_lines | null)[] | null; } +export interface OrderDiscountUpdate_orderDiscountUpdate_order_fulfillments_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderDiscountUpdate_orderDiscountUpdate_order_fulfillments_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderDiscountUpdate_orderDiscountUpdate_order_fulfillments_lines_orderLine_variant_preorder | null; } export interface OrderDiscountUpdate_orderDiscountUpdate_order_fulfillments_lines_orderLine_unitDiscount { @@ -309,10 +315,16 @@ export interface OrderDiscountUpdate_orderDiscountUpdate_order_fulfillments { warehouse: OrderDiscountUpdate_orderDiscountUpdate_order_fulfillments_warehouse | null; } +export interface OrderDiscountUpdate_orderDiscountUpdate_order_lines_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderDiscountUpdate_orderDiscountUpdate_order_lines_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderDiscountUpdate_orderDiscountUpdate_order_lines_variant_preorder | null; } export interface OrderDiscountUpdate_orderDiscountUpdate_order_lines_unitDiscount { diff --git a/src/orders/types/OrderDraftCancel.ts b/src/orders/types/OrderDraftCancel.ts index 4b285a084..d417a68db 100644 --- a/src/orders/types/OrderDraftCancel.ts +++ b/src/orders/types/OrderDraftCancel.ts @@ -213,10 +213,16 @@ export interface OrderDraftCancel_draftOrderDelete_order_events { lines: (OrderDraftCancel_draftOrderDelete_order_events_lines | null)[] | null; } +export interface OrderDraftCancel_draftOrderDelete_order_fulfillments_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderDraftCancel_draftOrderDelete_order_fulfillments_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderDraftCancel_draftOrderDelete_order_fulfillments_lines_orderLine_variant_preorder | null; } export interface OrderDraftCancel_draftOrderDelete_order_fulfillments_lines_orderLine_unitDiscount { @@ -309,10 +315,16 @@ export interface OrderDraftCancel_draftOrderDelete_order_fulfillments { warehouse: OrderDraftCancel_draftOrderDelete_order_fulfillments_warehouse | null; } +export interface OrderDraftCancel_draftOrderDelete_order_lines_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderDraftCancel_draftOrderDelete_order_lines_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderDraftCancel_draftOrderDelete_order_lines_variant_preorder | null; } export interface OrderDraftCancel_draftOrderDelete_order_lines_unitDiscount { diff --git a/src/orders/types/OrderDraftFinalize.ts b/src/orders/types/OrderDraftFinalize.ts index 8fec5525e..b98d107bf 100644 --- a/src/orders/types/OrderDraftFinalize.ts +++ b/src/orders/types/OrderDraftFinalize.ts @@ -213,10 +213,16 @@ export interface OrderDraftFinalize_draftOrderComplete_order_events { lines: (OrderDraftFinalize_draftOrderComplete_order_events_lines | null)[] | null; } +export interface OrderDraftFinalize_draftOrderComplete_order_fulfillments_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderDraftFinalize_draftOrderComplete_order_fulfillments_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderDraftFinalize_draftOrderComplete_order_fulfillments_lines_orderLine_variant_preorder | null; } export interface OrderDraftFinalize_draftOrderComplete_order_fulfillments_lines_orderLine_unitDiscount { @@ -309,10 +315,16 @@ export interface OrderDraftFinalize_draftOrderComplete_order_fulfillments { warehouse: OrderDraftFinalize_draftOrderComplete_order_fulfillments_warehouse | null; } +export interface OrderDraftFinalize_draftOrderComplete_order_lines_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderDraftFinalize_draftOrderComplete_order_lines_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderDraftFinalize_draftOrderComplete_order_lines_variant_preorder | null; } export interface OrderDraftFinalize_draftOrderComplete_order_lines_unitDiscount { diff --git a/src/orders/types/OrderDraftUpdate.ts b/src/orders/types/OrderDraftUpdate.ts index 83a9a9831..0c1f54f70 100644 --- a/src/orders/types/OrderDraftUpdate.ts +++ b/src/orders/types/OrderDraftUpdate.ts @@ -213,10 +213,16 @@ export interface OrderDraftUpdate_draftOrderUpdate_order_events { lines: (OrderDraftUpdate_draftOrderUpdate_order_events_lines | null)[] | null; } +export interface OrderDraftUpdate_draftOrderUpdate_order_fulfillments_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderDraftUpdate_draftOrderUpdate_order_fulfillments_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderDraftUpdate_draftOrderUpdate_order_fulfillments_lines_orderLine_variant_preorder | null; } export interface OrderDraftUpdate_draftOrderUpdate_order_fulfillments_lines_orderLine_unitDiscount { @@ -309,10 +315,16 @@ export interface OrderDraftUpdate_draftOrderUpdate_order_fulfillments { warehouse: OrderDraftUpdate_draftOrderUpdate_order_fulfillments_warehouse | null; } +export interface OrderDraftUpdate_draftOrderUpdate_order_lines_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderDraftUpdate_draftOrderUpdate_order_lines_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderDraftUpdate_draftOrderUpdate_order_lines_variant_preorder | null; } export interface OrderDraftUpdate_draftOrderUpdate_order_lines_unitDiscount { diff --git a/src/orders/types/OrderFulfillData.ts b/src/orders/types/OrderFulfillData.ts index b1224e052..3caf5a247 100644 --- a/src/orders/types/OrderFulfillData.ts +++ b/src/orders/types/OrderFulfillData.ts @@ -33,6 +33,11 @@ export interface OrderFulfillData_order_lines_allocations { warehouse: OrderFulfillData_order_lines_allocations_warehouse; } +export interface OrderFulfillData_order_lines_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderFulfillData_order_lines_variant_attributes_values { __typename: "AttributeValue"; id: string; @@ -63,6 +68,7 @@ export interface OrderFulfillData_order_lines_variant { id: string; name: string; sku: string | null; + preorder: OrderFulfillData_order_lines_variant_preorder | null; attributes: OrderFulfillData_order_lines_variant_attributes[]; stocks: (OrderFulfillData_order_lines_variant_stocks | null)[] | null; trackInventory: boolean; diff --git a/src/orders/types/OrderFulfillmentApprove.ts b/src/orders/types/OrderFulfillmentApprove.ts index 6f14608cb..cc6296740 100644 --- a/src/orders/types/OrderFulfillmentApprove.ts +++ b/src/orders/types/OrderFulfillmentApprove.ts @@ -213,10 +213,16 @@ export interface OrderFulfillmentApprove_orderFulfillmentApprove_order_events { lines: (OrderFulfillmentApprove_orderFulfillmentApprove_order_events_lines | null)[] | null; } +export interface OrderFulfillmentApprove_orderFulfillmentApprove_order_fulfillments_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderFulfillmentApprove_orderFulfillmentApprove_order_fulfillments_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderFulfillmentApprove_orderFulfillmentApprove_order_fulfillments_lines_orderLine_variant_preorder | null; } export interface OrderFulfillmentApprove_orderFulfillmentApprove_order_fulfillments_lines_orderLine_unitDiscount { @@ -309,10 +315,16 @@ export interface OrderFulfillmentApprove_orderFulfillmentApprove_order_fulfillme warehouse: OrderFulfillmentApprove_orderFulfillmentApprove_order_fulfillments_warehouse | null; } +export interface OrderFulfillmentApprove_orderFulfillmentApprove_order_lines_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderFulfillmentApprove_orderFulfillmentApprove_order_lines_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderFulfillmentApprove_orderFulfillmentApprove_order_lines_variant_preorder | null; } export interface OrderFulfillmentApprove_orderFulfillmentApprove_order_lines_unitDiscount { diff --git a/src/orders/types/OrderFulfillmentCancel.ts b/src/orders/types/OrderFulfillmentCancel.ts index 136e4fa75..0f7474854 100644 --- a/src/orders/types/OrderFulfillmentCancel.ts +++ b/src/orders/types/OrderFulfillmentCancel.ts @@ -213,10 +213,16 @@ export interface OrderFulfillmentCancel_orderFulfillmentCancel_order_events { lines: (OrderFulfillmentCancel_orderFulfillmentCancel_order_events_lines | null)[] | null; } +export interface OrderFulfillmentCancel_orderFulfillmentCancel_order_fulfillments_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderFulfillmentCancel_orderFulfillmentCancel_order_fulfillments_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderFulfillmentCancel_orderFulfillmentCancel_order_fulfillments_lines_orderLine_variant_preorder | null; } export interface OrderFulfillmentCancel_orderFulfillmentCancel_order_fulfillments_lines_orderLine_unitDiscount { @@ -309,10 +315,16 @@ export interface OrderFulfillmentCancel_orderFulfillmentCancel_order_fulfillment warehouse: OrderFulfillmentCancel_orderFulfillmentCancel_order_fulfillments_warehouse | null; } +export interface OrderFulfillmentCancel_orderFulfillmentCancel_order_lines_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderFulfillmentCancel_orderFulfillmentCancel_order_lines_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderFulfillmentCancel_orderFulfillmentCancel_order_lines_variant_preorder | null; } export interface OrderFulfillmentCancel_orderFulfillmentCancel_order_lines_unitDiscount { diff --git a/src/orders/types/OrderFulfillmentRefundProducts.ts b/src/orders/types/OrderFulfillmentRefundProducts.ts index 61baa0d88..82352aced 100644 --- a/src/orders/types/OrderFulfillmentRefundProducts.ts +++ b/src/orders/types/OrderFulfillmentRefundProducts.ts @@ -16,10 +16,16 @@ export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_e addressType: AddressTypeEnum | null; } +export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_fulfillment_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_fulfillment_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_fulfillment_lines_orderLine_variant_preorder | null; } export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_fulfillment_lines_orderLine_unitDiscount { @@ -309,10 +315,16 @@ export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_o lines: (OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_events_lines | null)[] | null; } +export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_fulfillments_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_fulfillments_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_fulfillments_lines_orderLine_variant_preorder | null; } export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_fulfillments_lines_orderLine_unitDiscount { @@ -405,10 +417,16 @@ export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_o warehouse: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_fulfillments_warehouse | null; } +export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_lines_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_lines_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_lines_variant_preorder | null; } export interface OrderFulfillmentRefundProducts_orderFulfillmentRefundProducts_order_lines_unitDiscount { diff --git a/src/orders/types/OrderFulfillmentUpdateTracking.ts b/src/orders/types/OrderFulfillmentUpdateTracking.ts index 04f95703e..0672024b6 100644 --- a/src/orders/types/OrderFulfillmentUpdateTracking.ts +++ b/src/orders/types/OrderFulfillmentUpdateTracking.ts @@ -213,10 +213,16 @@ export interface OrderFulfillmentUpdateTracking_orderFulfillmentUpdateTracking_o lines: (OrderFulfillmentUpdateTracking_orderFulfillmentUpdateTracking_order_events_lines | null)[] | null; } +export interface OrderFulfillmentUpdateTracking_orderFulfillmentUpdateTracking_order_fulfillments_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderFulfillmentUpdateTracking_orderFulfillmentUpdateTracking_order_fulfillments_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderFulfillmentUpdateTracking_orderFulfillmentUpdateTracking_order_fulfillments_lines_orderLine_variant_preorder | null; } export interface OrderFulfillmentUpdateTracking_orderFulfillmentUpdateTracking_order_fulfillments_lines_orderLine_unitDiscount { @@ -309,10 +315,16 @@ export interface OrderFulfillmentUpdateTracking_orderFulfillmentUpdateTracking_o warehouse: OrderFulfillmentUpdateTracking_orderFulfillmentUpdateTracking_order_fulfillments_warehouse | null; } +export interface OrderFulfillmentUpdateTracking_orderFulfillmentUpdateTracking_order_lines_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderFulfillmentUpdateTracking_orderFulfillmentUpdateTracking_order_lines_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderFulfillmentUpdateTracking_orderFulfillmentUpdateTracking_order_lines_variant_preorder | null; } export interface OrderFulfillmentUpdateTracking_orderFulfillmentUpdateTracking_order_lines_unitDiscount { diff --git a/src/orders/types/OrderLineDelete.ts b/src/orders/types/OrderLineDelete.ts index dbfd6ec1b..aa9a1a8f6 100644 --- a/src/orders/types/OrderLineDelete.ts +++ b/src/orders/types/OrderLineDelete.ts @@ -213,10 +213,16 @@ export interface OrderLineDelete_orderLineDelete_order_events { lines: (OrderLineDelete_orderLineDelete_order_events_lines | null)[] | null; } +export interface OrderLineDelete_orderLineDelete_order_fulfillments_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderLineDelete_orderLineDelete_order_fulfillments_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderLineDelete_orderLineDelete_order_fulfillments_lines_orderLine_variant_preorder | null; } export interface OrderLineDelete_orderLineDelete_order_fulfillments_lines_orderLine_unitDiscount { @@ -309,10 +315,16 @@ export interface OrderLineDelete_orderLineDelete_order_fulfillments { warehouse: OrderLineDelete_orderLineDelete_order_fulfillments_warehouse | null; } +export interface OrderLineDelete_orderLineDelete_order_lines_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderLineDelete_orderLineDelete_order_lines_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderLineDelete_orderLineDelete_order_lines_variant_preorder | null; } export interface OrderLineDelete_orderLineDelete_order_lines_unitDiscount { diff --git a/src/orders/types/OrderLineDiscountRemove.ts b/src/orders/types/OrderLineDiscountRemove.ts index 6944e1531..ae9e6a8c1 100644 --- a/src/orders/types/OrderLineDiscountRemove.ts +++ b/src/orders/types/OrderLineDiscountRemove.ts @@ -213,10 +213,16 @@ export interface OrderLineDiscountRemove_orderLineDiscountRemove_order_events { lines: (OrderLineDiscountRemove_orderLineDiscountRemove_order_events_lines | null)[] | null; } +export interface OrderLineDiscountRemove_orderLineDiscountRemove_order_fulfillments_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderLineDiscountRemove_orderLineDiscountRemove_order_fulfillments_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderLineDiscountRemove_orderLineDiscountRemove_order_fulfillments_lines_orderLine_variant_preorder | null; } export interface OrderLineDiscountRemove_orderLineDiscountRemove_order_fulfillments_lines_orderLine_unitDiscount { @@ -309,10 +315,16 @@ export interface OrderLineDiscountRemove_orderLineDiscountRemove_order_fulfillme warehouse: OrderLineDiscountRemove_orderLineDiscountRemove_order_fulfillments_warehouse | null; } +export interface OrderLineDiscountRemove_orderLineDiscountRemove_order_lines_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderLineDiscountRemove_orderLineDiscountRemove_order_lines_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderLineDiscountRemove_orderLineDiscountRemove_order_lines_variant_preorder | null; } export interface OrderLineDiscountRemove_orderLineDiscountRemove_order_lines_unitDiscount { diff --git a/src/orders/types/OrderLineDiscountUpdate.ts b/src/orders/types/OrderLineDiscountUpdate.ts index 9e52bb142..86d2addfc 100644 --- a/src/orders/types/OrderLineDiscountUpdate.ts +++ b/src/orders/types/OrderLineDiscountUpdate.ts @@ -213,10 +213,16 @@ export interface OrderLineDiscountUpdate_orderLineDiscountUpdate_order_events { lines: (OrderLineDiscountUpdate_orderLineDiscountUpdate_order_events_lines | null)[] | null; } +export interface OrderLineDiscountUpdate_orderLineDiscountUpdate_order_fulfillments_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderLineDiscountUpdate_orderLineDiscountUpdate_order_fulfillments_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderLineDiscountUpdate_orderLineDiscountUpdate_order_fulfillments_lines_orderLine_variant_preorder | null; } export interface OrderLineDiscountUpdate_orderLineDiscountUpdate_order_fulfillments_lines_orderLine_unitDiscount { @@ -309,10 +315,16 @@ export interface OrderLineDiscountUpdate_orderLineDiscountUpdate_order_fulfillme warehouse: OrderLineDiscountUpdate_orderLineDiscountUpdate_order_fulfillments_warehouse | null; } +export interface OrderLineDiscountUpdate_orderLineDiscountUpdate_order_lines_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderLineDiscountUpdate_orderLineDiscountUpdate_order_lines_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderLineDiscountUpdate_orderLineDiscountUpdate_order_lines_variant_preorder | null; } export interface OrderLineDiscountUpdate_orderLineDiscountUpdate_order_lines_unitDiscount { diff --git a/src/orders/types/OrderLineUpdate.ts b/src/orders/types/OrderLineUpdate.ts index 4a19c6dc7..f11bb28fd 100644 --- a/src/orders/types/OrderLineUpdate.ts +++ b/src/orders/types/OrderLineUpdate.ts @@ -213,10 +213,16 @@ export interface OrderLineUpdate_orderLineUpdate_order_events { lines: (OrderLineUpdate_orderLineUpdate_order_events_lines | null)[] | null; } +export interface OrderLineUpdate_orderLineUpdate_order_fulfillments_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderLineUpdate_orderLineUpdate_order_fulfillments_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderLineUpdate_orderLineUpdate_order_fulfillments_lines_orderLine_variant_preorder | null; } export interface OrderLineUpdate_orderLineUpdate_order_fulfillments_lines_orderLine_unitDiscount { @@ -309,10 +315,16 @@ export interface OrderLineUpdate_orderLineUpdate_order_fulfillments { warehouse: OrderLineUpdate_orderLineUpdate_order_fulfillments_warehouse | null; } +export interface OrderLineUpdate_orderLineUpdate_order_lines_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderLineUpdate_orderLineUpdate_order_lines_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderLineUpdate_orderLineUpdate_order_lines_variant_preorder | null; } export interface OrderLineUpdate_orderLineUpdate_order_lines_unitDiscount { diff --git a/src/orders/types/OrderLinesAdd.ts b/src/orders/types/OrderLinesAdd.ts index d7f678c6c..6efc07acc 100644 --- a/src/orders/types/OrderLinesAdd.ts +++ b/src/orders/types/OrderLinesAdd.ts @@ -213,10 +213,16 @@ export interface OrderLinesAdd_orderLinesCreate_order_events { lines: (OrderLinesAdd_orderLinesCreate_order_events_lines | null)[] | null; } +export interface OrderLinesAdd_orderLinesCreate_order_fulfillments_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderLinesAdd_orderLinesCreate_order_fulfillments_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderLinesAdd_orderLinesCreate_order_fulfillments_lines_orderLine_variant_preorder | null; } export interface OrderLinesAdd_orderLinesCreate_order_fulfillments_lines_orderLine_unitDiscount { @@ -309,10 +315,16 @@ export interface OrderLinesAdd_orderLinesCreate_order_fulfillments { warehouse: OrderLinesAdd_orderLinesCreate_order_fulfillments_warehouse | null; } +export interface OrderLinesAdd_orderLinesCreate_order_lines_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderLinesAdd_orderLinesCreate_order_lines_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderLinesAdd_orderLinesCreate_order_lines_variant_preorder | null; } export interface OrderLinesAdd_orderLinesCreate_order_lines_unitDiscount { diff --git a/src/orders/types/OrderMarkAsPaid.ts b/src/orders/types/OrderMarkAsPaid.ts index 5e1651458..d99cc6b83 100644 --- a/src/orders/types/OrderMarkAsPaid.ts +++ b/src/orders/types/OrderMarkAsPaid.ts @@ -213,10 +213,16 @@ export interface OrderMarkAsPaid_orderMarkAsPaid_order_events { lines: (OrderMarkAsPaid_orderMarkAsPaid_order_events_lines | null)[] | null; } +export interface OrderMarkAsPaid_orderMarkAsPaid_order_fulfillments_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderMarkAsPaid_orderMarkAsPaid_order_fulfillments_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderMarkAsPaid_orderMarkAsPaid_order_fulfillments_lines_orderLine_variant_preorder | null; } export interface OrderMarkAsPaid_orderMarkAsPaid_order_fulfillments_lines_orderLine_unitDiscount { @@ -309,10 +315,16 @@ export interface OrderMarkAsPaid_orderMarkAsPaid_order_fulfillments { warehouse: OrderMarkAsPaid_orderMarkAsPaid_order_fulfillments_warehouse | null; } +export interface OrderMarkAsPaid_orderMarkAsPaid_order_lines_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderMarkAsPaid_orderMarkAsPaid_order_lines_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderMarkAsPaid_orderMarkAsPaid_order_lines_variant_preorder | null; } export interface OrderMarkAsPaid_orderMarkAsPaid_order_lines_unitDiscount { diff --git a/src/orders/types/OrderRefund.ts b/src/orders/types/OrderRefund.ts index ac9f18c2b..3d3b708db 100644 --- a/src/orders/types/OrderRefund.ts +++ b/src/orders/types/OrderRefund.ts @@ -213,10 +213,16 @@ export interface OrderRefund_orderRefund_order_events { lines: (OrderRefund_orderRefund_order_events_lines | null)[] | null; } +export interface OrderRefund_orderRefund_order_fulfillments_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderRefund_orderRefund_order_fulfillments_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderRefund_orderRefund_order_fulfillments_lines_orderLine_variant_preorder | null; } export interface OrderRefund_orderRefund_order_fulfillments_lines_orderLine_unitDiscount { @@ -309,10 +315,16 @@ export interface OrderRefund_orderRefund_order_fulfillments { warehouse: OrderRefund_orderRefund_order_fulfillments_warehouse | null; } +export interface OrderRefund_orderRefund_order_lines_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderRefund_orderRefund_order_lines_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderRefund_orderRefund_order_lines_variant_preorder | null; } export interface OrderRefund_orderRefund_order_lines_unitDiscount { diff --git a/src/orders/types/OrderShippingMethodUpdate.ts b/src/orders/types/OrderShippingMethodUpdate.ts index 0e7a36394..46195a112 100644 --- a/src/orders/types/OrderShippingMethodUpdate.ts +++ b/src/orders/types/OrderShippingMethodUpdate.ts @@ -275,10 +275,16 @@ export interface OrderShippingMethodUpdate_orderUpdateShipping_order_events { lines: (OrderShippingMethodUpdate_orderUpdateShipping_order_events_lines | null)[] | null; } +export interface OrderShippingMethodUpdate_orderUpdateShipping_order_fulfillments_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderShippingMethodUpdate_orderUpdateShipping_order_fulfillments_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderShippingMethodUpdate_orderUpdateShipping_order_fulfillments_lines_orderLine_variant_preorder | null; } export interface OrderShippingMethodUpdate_orderUpdateShipping_order_fulfillments_lines_orderLine_unitDiscount { @@ -371,10 +377,16 @@ export interface OrderShippingMethodUpdate_orderUpdateShipping_order_fulfillment warehouse: OrderShippingMethodUpdate_orderUpdateShipping_order_fulfillments_warehouse | null; } +export interface OrderShippingMethodUpdate_orderUpdateShipping_order_lines_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderShippingMethodUpdate_orderUpdateShipping_order_lines_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderShippingMethodUpdate_orderUpdateShipping_order_lines_variant_preorder | null; } export interface OrderShippingMethodUpdate_orderUpdateShipping_order_lines_unitDiscount { diff --git a/src/orders/types/OrderUpdate.ts b/src/orders/types/OrderUpdate.ts index e73a3321a..d6f922d81 100644 --- a/src/orders/types/OrderUpdate.ts +++ b/src/orders/types/OrderUpdate.ts @@ -213,10 +213,16 @@ export interface OrderUpdate_orderUpdate_order_events { lines: (OrderUpdate_orderUpdate_order_events_lines | null)[] | null; } +export interface OrderUpdate_orderUpdate_order_fulfillments_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderUpdate_orderUpdate_order_fulfillments_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderUpdate_orderUpdate_order_fulfillments_lines_orderLine_variant_preorder | null; } export interface OrderUpdate_orderUpdate_order_fulfillments_lines_orderLine_unitDiscount { @@ -309,10 +315,16 @@ export interface OrderUpdate_orderUpdate_order_fulfillments { warehouse: OrderUpdate_orderUpdate_order_fulfillments_warehouse | null; } +export interface OrderUpdate_orderUpdate_order_lines_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderUpdate_orderUpdate_order_lines_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderUpdate_orderUpdate_order_lines_variant_preorder | null; } export interface OrderUpdate_orderUpdate_order_lines_unitDiscount { diff --git a/src/orders/types/OrderVoid.ts b/src/orders/types/OrderVoid.ts index ef709e5e8..2bc1d236e 100644 --- a/src/orders/types/OrderVoid.ts +++ b/src/orders/types/OrderVoid.ts @@ -213,10 +213,16 @@ export interface OrderVoid_orderVoid_order_events { lines: (OrderVoid_orderVoid_order_events_lines | null)[] | null; } +export interface OrderVoid_orderVoid_order_fulfillments_lines_orderLine_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderVoid_orderVoid_order_fulfillments_lines_orderLine_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderVoid_orderVoid_order_fulfillments_lines_orderLine_variant_preorder | null; } export interface OrderVoid_orderVoid_order_fulfillments_lines_orderLine_unitDiscount { @@ -309,10 +315,16 @@ export interface OrderVoid_orderVoid_order_fulfillments { warehouse: OrderVoid_orderVoid_order_fulfillments_warehouse | null; } +export interface OrderVoid_orderVoid_order_lines_variant_preorder { + __typename: "PreorderData"; + endDate: any | null; +} + export interface OrderVoid_orderVoid_order_lines_variant { __typename: "ProductVariant"; id: string; quantityAvailable: number; + preorder: OrderVoid_orderVoid_order_lines_variant_preorder | null; } export interface OrderVoid_orderVoid_order_lines_unitDiscount { diff --git a/src/orders/utils/data.test.ts b/src/orders/utils/data.test.ts index e963674f0..561728423 100644 --- a/src/orders/utils/data.test.ts +++ b/src/orders/utils/data.test.ts @@ -531,6 +531,7 @@ describe("Get the total value of all replaced products", () => { variant: { id: "UHJvZHVjdFZhcmlhbnQ6MzE3", quantityAvailable: 50, + preorder: null, __typename: "ProductVariant" }, productName: "Lake Tunes", @@ -586,6 +587,7 @@ describe("Get the total value of all replaced products", () => { variant: { id: "UHJvZHVjdFZhcmlhbnQ6MzE3", quantityAvailable: 50, + preorder: null, __typename: "ProductVariant" }, productName: "Lake Tunes", @@ -641,6 +643,7 @@ describe("Get the total value of all replaced products", () => { variant: { id: "UHJvZHVjdFZhcmlhbnQ6Mjg2", quantityAvailable: 50, + preorder: null, __typename: "ProductVariant" }, productName: "T-shirt", @@ -702,6 +705,7 @@ describe("Get the total value of all replaced products", () => { variant: { id: "UHJvZHVjdFZhcmlhbnQ6MzE3", quantityAvailable: 50, + preorder: null, __typename: "ProductVariant" }, productName: "Lake Tunes", @@ -762,6 +766,7 @@ describe("Get the total value of all replaced products", () => { variant: { id: "UHJvZHVjdFZhcmlhbnQ6MzE3", quantityAvailable: 50, + preorder: null, __typename: "ProductVariant" }, productName: "Lake Tunes", @@ -822,6 +827,7 @@ describe("Get the total value of all replaced products", () => { variant: { id: "UHJvZHVjdFZhcmlhbnQ6Mjg2", quantityAvailable: 50, + preorder: null, __typename: "ProductVariant" }, productName: "T-shirt", @@ -882,6 +888,7 @@ describe("Get the total value of all replaced products", () => { variant: { id: "UHJvZHVjdFZhcmlhbnQ6MzE3", quantityAvailable: 50, + preorder: null, __typename: "ProductVariant" }, productName: "Lake Tunes", @@ -942,6 +949,7 @@ describe("Get the total value of all replaced products", () => { variant: { id: "UHJvZHVjdFZhcmlhbnQ6MzE3", quantityAvailable: 50, + preorder: null, __typename: "ProductVariant" }, productName: "Lake Tunes", @@ -1136,6 +1144,7 @@ describe("Get the total value of all selected products", () => { variant: { id: "UHJvZHVjdFZhcmlhbnQ6MzE3", quantityAvailable: 50, + preorder: null, __typename: "ProductVariant" }, productName: "Lake Tunes", @@ -1191,6 +1200,7 @@ describe("Get the total value of all selected products", () => { variant: { id: "UHJvZHVjdFZhcmlhbnQ6MzE3", quantityAvailable: 50, + preorder: null, __typename: "ProductVariant" }, productName: "Lake Tunes", @@ -1246,6 +1256,7 @@ describe("Get the total value of all selected products", () => { variant: { id: "UHJvZHVjdFZhcmlhbnQ6Mjg2", quantityAvailable: 50, + preorder: null, __typename: "ProductVariant" }, productName: "T-shirt", @@ -1307,6 +1318,7 @@ describe("Get the total value of all selected products", () => { variant: { id: "UHJvZHVjdFZhcmlhbnQ6MzE3", quantityAvailable: 50, + preorder: null, __typename: "ProductVariant" }, productName: "Lake Tunes", @@ -1367,6 +1379,7 @@ describe("Get the total value of all selected products", () => { variant: { id: "UHJvZHVjdFZhcmlhbnQ6MzE3", quantityAvailable: 50, + preorder: null, __typename: "ProductVariant" }, productName: "Lake Tunes", @@ -1427,6 +1440,7 @@ describe("Get the total value of all selected products", () => { variant: { id: "UHJvZHVjdFZhcmlhbnQ6Mjg2", quantityAvailable: 50, + preorder: null, __typename: "ProductVariant" }, productName: "T-shirt", @@ -1615,6 +1629,7 @@ describe("Merge repeated order lines of fulfillment lines", () => { variant: { id: "UHJvZHVjdFZhcmlhbnQ6MzE3", quantityAvailable: 50, + preorder: null, __typename: "ProductVariant" }, productName: "Lake Tunes", @@ -1675,6 +1690,7 @@ describe("Merge repeated order lines of fulfillment lines", () => { variant: { id: "UHJvZHVjdFZhcmlhbnQ6MzE3", quantityAvailable: 50, + preorder: null, __typename: "ProductVariant" }, productName: "Lake Tunes", @@ -1735,6 +1751,7 @@ describe("Merge repeated order lines of fulfillment lines", () => { variant: { id: "UHJvZHVjdFZhcmlhbnQ6Mjg2", quantityAvailable: 50, + preorder: null, __typename: "ProductVariant" }, productName: "T-shirt", diff --git a/src/products/components/ProductCreatePage/ProductCreatePage.tsx b/src/products/components/ProductCreatePage/ProductCreatePage.tsx index 431f42d19..8306ee97d 100644 --- a/src/products/components/ProductCreatePage/ProductCreatePage.tsx +++ b/src/products/components/ProductCreatePage/ProductCreatePage.tsx @@ -203,6 +203,7 @@ export const ProductCreatePage: React.FC = ({ {({ change, data, + formErrors, disabled: formDisabled, handlers, hasChanged, @@ -269,9 +270,11 @@ export const ProductCreatePage: React.FC = ({ hasVariants={false} onFormDataChange={change} errors={errors} + formErrors={formErrors} stocks={data.stocks} warehouses={warehouses} onChange={handlers.changeStock} + onChangePreorderEndDate={handlers.changePreorderEndDate} onWarehouseStockAdd={handlers.addStock} onWarehouseStockDelete={handlers.deleteStock} onWarehouseConfigure={onWarehouseConfigure} diff --git a/src/products/components/ProductCreatePage/form.tsx b/src/products/components/ProductCreatePage/form.tsx index bb8f60465..c2193fb17 100644 --- a/src/products/components/ProductCreatePage/form.tsx +++ b/src/products/components/ProductCreatePage/form.tsx @@ -18,11 +18,12 @@ import { MetadataFormData } from "@saleor/components/Metadata"; import { MultiAutocompleteChoiceType } from "@saleor/components/MultiAutocompleteSelectField"; import { RichTextEditorChange } from "@saleor/components/RichTextEditor"; import { SingleAutocompleteChoiceType } from "@saleor/components/SingleAutocompleteSelectField"; -import useForm, { FormChange } from "@saleor/hooks/useForm"; +import useForm, { FormChange, FormErrors } from "@saleor/hooks/useForm"; import useFormset, { FormsetChange, FormsetData } from "@saleor/hooks/useFormset"; +import { errorMessages } from "@saleor/intl"; import { ProductType_productType } from "@saleor/products/types/ProductType"; import { getAttributeInputFromProductType, @@ -47,7 +48,9 @@ import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/single import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger"; import useRichText from "@saleor/utils/richText/useRichText"; import React from "react"; +import { useIntl } from "react-intl"; +import { createPreorderEndDateChangeHandler } from "../../utils/handlers"; import { ProductStockFormsetData, ProductStockInput } from "../ProductStocks"; export interface ProductCreateFormData extends MetadataFormData { @@ -68,6 +71,11 @@ export interface ProductCreateFormData extends MetadataFormData { stockQuantity: number; taxCode: string; trackInventory: boolean; + isPreorder: boolean; + globalThreshold: number; + globalSoldUnits: number; + hasPreorderEndDate: boolean; + preorderEndDateTime: string; weight: string; } export interface ProductCreateData extends ProductCreateFormData { @@ -102,12 +110,14 @@ export interface ProductCreateHandlers Record<"reorderAttributeValue", FormsetChange>, Record<"addStock" | "deleteStock", (id: string) => void> { changeDescription: RichTextEditorChange; + changePreorderEndDate: FormChange; fetchReferences: (value: string) => void; fetchMoreReferences: FetchMoreProps; } export interface UseProductCreateFormResult { change: FormChange; data: ProductCreateData; + formErrors: FormErrors; disabled: boolean; handlers: ProductCreateHandlers; hasChanged: boolean; @@ -151,6 +161,7 @@ function useProductCreateForm( onSubmit: (data: ProductCreateData) => Promise, opts: UseProductCreateFormOpts ): UseProductCreateFormResult { + const intl = useIntl(); const defaultInitialFormData: ProductCreateFormData & Record<"productType", string> = { category: "", @@ -172,7 +183,12 @@ function useProductCreateForm( stockQuantity: null, taxCode: null, trackInventory: false, - weight: "" + weight: "", + globalSoldUnits: 0, + globalThreshold: 0, + isPreorder: false, + hasPreorderEndDate: false, + preorderEndDateTime: "" }; const [changed, setChanged] = React.useState(false); const triggerChange = () => setChanged(true); @@ -289,6 +305,12 @@ function useProductCreateForm( triggerChange ); + const handlePreorderEndDateChange = createPreorderEndDateChangeHandler( + form, + triggerChange, + intl.formatMessage(errorMessages.preorderEndDateInFutureErrorText) + ); + const getData = (): ProductCreateData => ({ ...form.data, attributes: getAttributesDisplayData( @@ -306,17 +328,21 @@ function useProductCreateForm( const submit = () => onSubmit(data); const disabled = - !opts.selectedProductType?.hasVariants && - (data.channelListings.some( - channel => - validatePrice(channel.price) || validateCostPrice(channel.costPrice) - ) || - !data.category); + (!opts.selectedProductType?.hasVariants && + (data.channelListings.some( + channel => + validatePrice(channel.price) || validateCostPrice(channel.costPrice) + ) || + !data.category)) || + (data.isPreorder && + data.hasPreorderEndDate && + !!form.errors.preorderEndDateTime); return { change: handleChange, data, disabled, + formErrors: form.errors, handlers: { addStock: handleStockAdd, changeChannelPrice: handleChannelPriceChange, @@ -324,6 +350,7 @@ function useProductCreateForm( changeDescription, changeMetadata, changeStock: handleStockChange, + changePreorderEndDate: handlePreorderEndDateChange, deleteStock: handleStockDelete, fetchMoreReferences: handleFetchMoreReferences, fetchReferences: handleFetchReferences, diff --git a/src/products/components/ProductStocks/ProductStocks.tsx b/src/products/components/ProductStocks/ProductStocks.tsx index 46890356d..1197c7bd9 100644 --- a/src/products/components/ProductStocks/ProductStocks.tsx +++ b/src/products/components/ProductStocks/ProductStocks.tsx @@ -1,4 +1,5 @@ import { + Button, Card, CardContent, ClickAwayListener, @@ -18,14 +19,19 @@ import { import { fade } from "@material-ui/core/styles/colorManipulator"; import AddIcon from "@material-ui/icons/Add"; import DeleteIcon from "@material-ui/icons/Delete"; +import { + ChannelData, + ChannelPriceAndPreorderArgs +} from "@saleor/channels/utils"; import CardTitle from "@saleor/components/CardTitle"; import ControlledCheckbox from "@saleor/components/ControlledCheckbox"; +import { DateTimeTimezoneField } from "@saleor/components/DateTimeTimezoneField"; import FormSpacer from "@saleor/components/FormSpacer"; import Hr from "@saleor/components/Hr"; import Link from "@saleor/components/Link"; import { ProductErrorFragment } from "@saleor/fragments/types/ProductErrorFragment"; import { WarehouseFragment } from "@saleor/fragments/types/WarehouseFragment"; -import { FormChange } from "@saleor/hooks/useForm"; +import { FormChange, FormErrors } from "@saleor/hooks/useForm"; import { FormsetAtomicData, FormsetChange } from "@saleor/hooks/useFormset"; import { makeStyles } from "@saleor/macaw-ui"; import { ICONBUTTON_SIZE } from "@saleor/macaw-ui"; @@ -35,6 +41,11 @@ import createNonNegativeValueChangeHandler from "@saleor/utils/handlers/nonNegat import React from "react"; import { FormattedMessage, useIntl } from "react-intl"; +import { ProductCreateData } from "../ProductCreatePage"; +import { ProductUpdateSubmitData } from "../ProductUpdatePage/form"; +import { ProductVariantCreateData } from "../ProductVariantCreatePage/form"; +import { ProductVariantUpdateData } from "../ProductVariantPage/form"; + export interface ProductStockFormsetData { quantityAllocated: number; } @@ -45,16 +56,33 @@ export type ProductStockInput = FormsetAtomicData< export interface ProductStockFormData { sku: string; trackInventory: boolean; + isPreorder: boolean; + globalThreshold: number; + globalSoldUnits: number; + hasPreorderEndDate: boolean; + preorderEndDateTime?: string; } export interface ProductStocksProps { + productVariantChannelListings?: ChannelData[]; data: ProductStockFormData; disabled: boolean; errors: ProductErrorFragment[]; + formErrors: + | FormErrors + | FormErrors + | FormErrors + | FormErrors; hasVariants: boolean; stocks: ProductStockInput[]; warehouses: WarehouseFragment[]; + onVariantChannelListingChange?: ( + id: string, + data: Partial + ) => void; onChange: FormsetChange; + onChangePreorderEndDate: FormChange; + onEndPreorderTrigger?: () => void; onFormDataChange: FormChange; onWarehouseStockAdd: (warehouseId: string) => void; onWarehouseStockDelete: (warehouseId: string) => void; @@ -72,6 +100,14 @@ const useStyles = makeStyles( textAlign: "right", width: 150 }, + colSoldUnits: { + textAlign: "right", + width: 150 + }, + colThreshold: { + textAlign: "right", + width: 180 + }, editWarehouses: { marginRight: theme.spacing(-1) }, @@ -107,6 +143,35 @@ const useStyles = makeStyles( display: "grid", gridColumnGap: theme.spacing(3), gridTemplateColumns: "repeat(2, 1fr)" + }, + dateTimeInputs: { + marginTop: theme.spacing(2), + marginBottom: theme.spacing(2) + }, + preorderInfo: { + marginBottom: theme.spacing(2), + marginTop: theme.spacing(2), + display: "block" + }, + caption: { + fontSize: 14 + }, + thresholdRow: { + display: "grid", + gridColumnGap: theme.spacing(3), + gridTemplateColumns: "3fr 1fr", + marginTop: theme.spacing(1) + }, + thresholdInput: { + maxWidth: 400 + }, + preorderItemsLeftCount: { + fontSize: 14, + paddingTop: theme.spacing(2), + textAlign: "center" + }, + preorderLimitInfo: { + marginTop: theme.spacing(3) } }), { @@ -119,10 +184,15 @@ const ProductStocks: React.FC = ({ disabled, hasVariants, errors, + formErrors: localFormErrors, + onChangePreorderEndDate, stocks, warehouses, + productVariantChannelListings = [], onChange, + onEndPreorderTrigger, onFormDataChange, + onVariantChannelListingChange, onWarehouseStockAdd, onWarehouseStockDelete, onWarehouseConfigure @@ -131,6 +201,7 @@ const ProductStocks: React.FC = ({ const intl = useIntl(); const anchor = React.useRef(); const [isExpanded, setExpansionState] = React.useState(false); + const unitsLeft = data.globalThreshold - data.globalSoldUnits; const warehousesToAssign = warehouses?.filter( @@ -138,6 +209,10 @@ const ProductStocks: React.FC = ({ ) || []; const formErrors = getFormErrors(["sku"], errors); + const onThresholdChange = createNonNegativeValueChangeHandler( + onFormDataChange + ); + return ( = ({ value={data.sku} /> - - - - - - + } /> - -
- - -
- - - -
-
- {!warehouses?.length && ( - - {hasVariants ? ( - <> - ( - {chunks} - ) - }} - /> - - ) : ( - <> - ( - {chunks} - ) - }} - /> - - )} - + + {!data.isPreorder && ( + <> + + + + + + + + } + /> + )}
- {warehouses?.length > 0 && ( +
+ {!data.isPreorder && ( + + +
+ + + +
+
+ + {!warehouses?.length && ( + + {hasVariants ? ( + <> + ( + {chunks} + ) + }} + /> + + ) : ( + <> + ( + {chunks} + ) + }} + /> + + )} + + )} +
+ )} + {warehouses?.length > 0 && !data.isPreorder && ( @@ -354,6 +456,181 @@ const ProductStocks: React.FC = ({
)} + {data.isPreorder && ( + + + {intl.formatMessage({ + defaultMessage: + "Set up an end date of preorder. When end date will be reached product will be automatically taken from preorder to standard selling", + description: "info text" + })} + + + {data.hasPreorderEndDate && ( +
+ + onChangePreorderEndDate({ + target: { + name: "preorderEndDateTime", + value: event + } + }) + } + /> +
+ )} + + + {intl.formatMessage({ + defaultMessage: + "Preordered products will be available in all warehouses. You can set a threshold for sold quantity. Leaving input blank will be interpreted as no limit to sale. Sold items will be allocated at the warehouse assigned to chosen shipping zone.", + description: "info text" + })} + +
+ + {productVariantChannelListings?.length > 0 && ( + + {data.globalThreshold + ? intl.formatMessage( + { + defaultMessage: "{unitsLeft} units left", + description: "app has been installed" + }, + { unitsLeft } + ) + : intl.formatMessage({ + defaultMessage: "Unlimited", + id: "unlimitedUnitsLeft", + description: "section header" + })} + + )} +
+
+ )} + + {productVariantChannelListings?.length > 0 && data.isPreorder && ( + + + + + + + + + + + + + + + + + + + + + {renderCollection(productVariantChannelListings, listing => { + if (!listing) { + return; + } + + return ( + + + {listing.name} + + + {listing?.unitsSold || 0} + + + { + onVariantChannelListingChange(listing.id, { + costPrice: listing.costPrice, + price: listing.price, + preorderThreshold: + e.target.value === "" + ? undefined + : Number(e.target.value) + }); + }} + value={listing?.preorderThreshold ?? ""} + /> + + + ); + })} + +
+ )}
); }; diff --git a/src/products/components/ProductUpdatePage/ProductUpdatePage.tsx b/src/products/components/ProductUpdatePage/ProductUpdatePage.tsx index 81017feee..529798670 100644 --- a/src/products/components/ProductUpdatePage/ProductUpdatePage.tsx +++ b/src/products/components/ProductUpdatePage/ProductUpdatePage.tsx @@ -286,6 +286,7 @@ export const ProductUpdatePage: React.FC = ({ {({ change, data, + formErrors, disabled: formDisabled, handlers, hasChanged, @@ -380,14 +381,20 @@ export const ProductUpdatePage: React.FC = ({ /> >, Record<"changeChannelPrice", (id: string, data: ChannelPriceArgs) => void>, + Record< + "changeChannelPreorder", + (id: string, data: ChannelPreorderArgs) => void + >, Record< "changeChannels", ( @@ -122,13 +143,14 @@ export interface ProductUpdateHandlers Record<"reorderAttributeValue", FormsetChange>, Record<"addStock" | "deleteStock", (id: string) => void> { changeDescription: RichTextEditorChange; + changePreorderEndDate: FormChange; fetchReferences: (value: string) => void; fetchMoreReferences: FetchMoreProps; } export interface UseProductUpdateFormResult { change: FormChange; - data: ProductUpdateData; + formErrors: FormErrors; disabled: boolean; handlers: ProductUpdateHandlers; hasChanged: boolean; @@ -198,6 +220,7 @@ function useProductUpdateForm( onSubmit: (data: ProductUpdateSubmitData) => SubmitPromise, opts: UseProductUpdateFormOpts ): UseProductUpdateFormResult { + const intl = useIntl(); const [changed, setChanged] = React.useState(false); const triggerChange = () => setChanged(true); @@ -308,12 +331,24 @@ function useProductUpdateForm( triggerChange ); + const handleChannelPreorderChange = createChannelsPreorderChangeHandler( + opts.isSimpleProduct ? opts.currentChannels : opts.channelsData, + opts.isSimpleProduct ? opts.setChannels : opts.setChannelsData, + triggerChange + ); + const handleChannelPriceChange = createChannelsPriceChangeHandler( opts.isSimpleProduct ? opts.currentChannels : opts.channelsData, opts.isSimpleProduct ? opts.setChannels : opts.setChannelsData, triggerChange ); + const handlePreorderEndDateChange = createPreorderEndDateChangeHandler( + form, + triggerChange, + intl.formatMessage(errorMessages.preorderEndDateInFutureErrorText) + ); + const data: ProductUpdateData = { ...form.data, channelListings: opts.currentChannels, @@ -352,23 +387,29 @@ function useProductUpdateForm( handleFormSubmit(getSubmitData(), handleSubmit, setChanged); const disabled = - !opts.hasVariants && - data.channelListings.some( - channel => - validatePrice(channel.price) || validateCostPrice(channel.costPrice) - ); + (!opts.hasVariants && + data.channelListings.some( + channel => + validatePrice(channel.price) || validateCostPrice(channel.costPrice) + )) || + (data.isPreorder && + data.hasPreorderEndDate && + !!form.errors.preorderEndDateTime); return { change: handleChange, data, disabled, + formErrors: form.errors, handlers: { addStock: handleStockAdd, changeChannelPrice: handleChannelPriceChange, + changeChannelPreorder: handleChannelPreorderChange, changeChannels: handleChannelsChange, changeDescription, changeMetadata, changeStock: handleStockChange, + changePreorderEndDate: handlePreorderEndDateChange, deleteStock: handleStockDelete, fetchMoreReferences: handleFetchMoreReferences, fetchReferences: handleFetchReferences, diff --git a/src/products/components/ProductVariantCreatePage/ProductVariantCreatePage.tsx b/src/products/components/ProductVariantCreatePage/ProductVariantCreatePage.tsx index 4d966701b..b3c343193 100644 --- a/src/products/components/ProductVariantCreatePage/ProductVariantCreatePage.tsx +++ b/src/products/components/ProductVariantCreatePage/ProductVariantCreatePage.tsx @@ -2,7 +2,6 @@ import { getAttributeValuesFromReferences, mergeAttributeValues } from "@saleor/attributes/utils/data"; -import { ChannelPriceData } from "@saleor/channels/utils"; import AssignAttributeValueDialog from "@saleor/components/AssignAttributeValueDialog"; import Attributes, { AttributeInput, @@ -60,7 +59,6 @@ const messages = defineMessages({ }); interface ProductVariantCreatePageProps { - channels: ChannelPriceData[]; disabled: boolean; errors: ProductErrorWithAttributesFragment[]; header: string; @@ -89,7 +87,6 @@ interface ProductVariantCreatePageProps { } const ProductVariantCreatePage: React.FC = ({ - channels, disabled, errors, header, @@ -141,7 +138,6 @@ const ProductVariantCreatePage: React.FC = ({ product={product} onSubmit={onSubmit} warehouses={warehouses} - currentChannels={channels} referencePages={referencePages} referenceProducts={referenceProducts} fetchReferencePages={fetchReferencePages} @@ -153,6 +149,7 @@ const ProductVariantCreatePage: React.FC = ({ {({ change, data, + formErrors, disabled: formDisabled, handlers, hasChanged, @@ -236,10 +233,12 @@ const ProductVariantCreatePage: React.FC = ({ disabled={disabled} hasVariants={true} onFormDataChange={change} + formErrors={formErrors} errors={errors} stocks={data.stocks} warehouses={warehouses} onChange={handlers.changeStock} + onChangePreorderEndDate={handlers.changePreorderEndDate} onWarehouseStockAdd={handlers.addStock} onWarehouseStockDelete={handlers.deleteStock} onWarehouseConfigure={onWarehouseConfigure} diff --git a/src/products/components/ProductVariantCreatePage/form.tsx b/src/products/components/ProductVariantCreatePage/form.tsx index 49f749e2d..4e2d78fc5 100644 --- a/src/products/components/ProductVariantCreatePage/form.tsx +++ b/src/products/components/ProductVariantCreatePage/form.tsx @@ -8,22 +8,24 @@ import { createFetchMoreReferencesHandler, createFetchReferencesHandler } from "@saleor/attributes/utils/handlers"; -import { ChannelPriceData } from "@saleor/channels/utils"; import { AttributeInput } from "@saleor/components/Attributes"; import { MetadataFormData } from "@saleor/components/Metadata"; -import useForm, { FormChange } from "@saleor/hooks/useForm"; +import useForm, { FormChange, FormErrors } from "@saleor/hooks/useForm"; import useFormset, { FormsetChange, FormsetData } from "@saleor/hooks/useFormset"; +import { errorMessages } from "@saleor/intl"; import { ProductVariantCreateData_product } from "@saleor/products/types/ProductVariantCreateData"; import { getVariantAttributeInputFromProduct } from "@saleor/products/utils/data"; +import { createPreorderEndDateChangeHandler } from "@saleor/products/utils/handlers"; import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages"; import { SearchProducts_search_edges_node } from "@saleor/searches/types/SearchProducts"; import { SearchWarehouses_search_edges_node } from "@saleor/searches/types/SearchWarehouses"; import { FetchMoreProps, ReorderEvent } from "@saleor/types"; import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger"; import React from "react"; +import { useIntl } from "react-intl"; import { ProductStockFormsetData, ProductStockInput } from "../ProductStocks"; @@ -31,6 +33,11 @@ export interface ProductVariantCreateFormData extends MetadataFormData { sku: string; trackInventory: boolean; weight: string; + isPreorder: boolean; + globalThreshold: number; + globalSoldUnits: number; + hasPreorderEndDate: boolean; + preorderEndDateTime?: string; } export interface ProductVariantCreateData extends ProductVariantCreateFormData { attributes: AttributeInput[]; @@ -40,7 +47,6 @@ export interface ProductVariantCreateData extends ProductVariantCreateFormData { export interface UseProductVariantCreateFormOpts { warehouses: SearchWarehouses_search_edges_node[]; - currentChannels: ChannelPriceData[]; referencePages: SearchPages_search_edges_node[]; referenceProducts: SearchProducts_search_edges_node[]; fetchReferencePages?: (data: string) => void; @@ -60,6 +66,7 @@ export interface ProductVariantCreateHandlers Record<"reorderAttributeValue", FormsetChange>, Record<"addStock" | "deleteStock", (id: string) => void> { changeMetadata: FormChange; + changePreorderEndDate: FormChange; fetchReferences: (value: string) => void; fetchMoreReferences: FetchMoreProps; } @@ -67,6 +74,7 @@ export interface ProductVariantCreateHandlers export interface UseProductVariantCreateFormResult { change: FormChange; data: ProductVariantCreateData; + formErrors: FormErrors; disabled: boolean; // TODO: type FormsetChange handlers: ProductVariantCreateHandlers; @@ -86,7 +94,12 @@ const initial: ProductVariantCreateFormData = { privateMetadata: [], sku: "", trackInventory: true, - weight: "" + weight: "", + isPreorder: false, + globalThreshold: null, + globalSoldUnits: 0, + hasPreorderEndDate: false, + preorderEndDateTime: "" }; function useProductVariantCreateForm( @@ -94,6 +107,7 @@ function useProductVariantCreateForm( onSubmit: (data: ProductVariantCreateData) => void, opts: UseProductVariantCreateFormOpts ): UseProductVariantCreateFormResult { + const intl = useIntl(); const [changed, setChanged] = React.useState(false); const triggerChange = () => setChanged(true); @@ -169,6 +183,12 @@ function useProductVariantCreateForm( stocks.remove(id); }; + const handlePreorderEndDateChange = createPreorderEndDateChangeHandler( + form, + triggerChange, + intl.formatMessage(errorMessages.preorderEndDateInFutureErrorText) + ); + const data: ProductVariantCreateData = { ...form.data, attributes: getAttributesDisplayData( @@ -186,11 +206,16 @@ function useProductVariantCreateForm( return { change: handleChange, data, - disabled: false, + disabled: + data.isPreorder && + data.hasPreorderEndDate && + !!form.errors.preorderEndDateTime, + formErrors: form.errors, handlers: { addStock: handleStockAdd, changeMetadata, changeStock: handleStockChange, + changePreorderEndDate: handlePreorderEndDateChange, deleteStock: handleStockDelete, fetchMoreReferences: handleFetchMoreReferences, fetchReferences: handleFetchReferences, diff --git a/src/products/components/ProductVariantEndPreorderDialog/ProductVariantEndPreorderDialog.tsx b/src/products/components/ProductVariantEndPreorderDialog/ProductVariantEndPreorderDialog.tsx new file mode 100644 index 000000000..863d46c85 --- /dev/null +++ b/src/products/components/ProductVariantEndPreorderDialog/ProductVariantEndPreorderDialog.tsx @@ -0,0 +1,52 @@ +import { DialogContentText } from "@material-ui/core"; +import ActionDialog from "@saleor/components/ActionDialog"; +import { ConfirmButtonTransitionState } from "@saleor/components/ConfirmButton"; +import React from "react"; +import { useIntl } from "react-intl"; + +import { productVariantEndPreorderDialogMessages } from "./messages"; + +export interface ProductVariantEndPreorderDialogProps { + confirmButtonState: ConfirmButtonTransitionState; + open: boolean; + onClose: () => void; + onConfirm: () => void; + variantGlobalSoldUnits?: number; +} + +const ProductVariantEndPreorderDialog: React.FC = ({ + confirmButtonState, + open, + onClose, + onConfirm, + variantGlobalSoldUnits +}) => { + const intl = useIntl(); + + return ( + + + {intl.formatMessage( + productVariantEndPreorderDialogMessages.dialogMessage, + { + variantGlobalSoldUnits + } + )} + + + ); +}; +ProductVariantEndPreorderDialog.displayName = "ProductVariantEndPreorderDialog"; +export default ProductVariantEndPreorderDialog; diff --git a/src/products/components/ProductVariantEndPreorderDialog/index.ts b/src/products/components/ProductVariantEndPreorderDialog/index.ts new file mode 100644 index 000000000..7fc70672e --- /dev/null +++ b/src/products/components/ProductVariantEndPreorderDialog/index.ts @@ -0,0 +1,2 @@ +export * from "./ProductVariantEndPreorderDialog"; +export { default } from "./ProductVariantEndPreorderDialog"; diff --git a/src/products/components/ProductVariantEndPreorderDialog/messages.ts b/src/products/components/ProductVariantEndPreorderDialog/messages.ts new file mode 100644 index 000000000..b4c3b8087 --- /dev/null +++ b/src/products/components/ProductVariantEndPreorderDialog/messages.ts @@ -0,0 +1,16 @@ +import { defineMessages } from "react-intl"; + +export const productVariantEndPreorderDialogMessages = defineMessages({ + dialogTitle: { + defaultMessage: "Ending preorder", + description: "dialog header" + }, + dialogMessage: { + defaultMessage: + "You are about to end your products preorder. You have sold {variantGlobalSoldUnits} units of this variant. Sold units will be allocated at appropriate warehouses. Remember to add remaining threshold stock to warehouses." + }, + dialogConfirmButtonLabel: { + defaultMessage: "ACCEPT", + description: "button label" + } +}); diff --git a/src/products/components/ProductVariantPage/ProductVariantPage.tsx b/src/products/components/ProductVariantPage/ProductVariantPage.tsx index b24804014..4c626ddd8 100644 --- a/src/products/components/ProductVariantPage/ProductVariantPage.tsx +++ b/src/products/components/ProductVariantPage/ProductVariantPage.tsx @@ -32,6 +32,7 @@ import { defineMessages, useIntl } from "react-intl"; import { maybe } from "../../../misc"; import ProductShipping from "../ProductShipping/ProductShipping"; import ProductStocks, { ProductStockInput } from "../ProductStocks"; +import ProductVariantEndPreorderDialog from "../ProductVariantEndPreorderDialog"; import ProductVariantMediaSelectDialog from "../ProductVariantImageSelectDialog"; import ProductVariantMedia from "../ProductVariantMedia"; import ProductVariantNavigation from "../ProductVariantNavigation"; @@ -97,6 +98,8 @@ interface ProductVariantPageProps { fetchAttributeValues: (query: string, attributeId: string) => void; onAssignReferencesClick: (attribute: AttributeInput) => void; onCloseDialog: () => void; + onVariantPreorderDeactivate: (id: string) => void; + variantDeactivatePreoderButtonState: ConfirmButtonTransitionState; onVariantReorder: ReorderAction; onAttributeSelectBlur: () => void; onAdd(); @@ -130,6 +133,8 @@ const ProductVariantPage: React.FC = ({ onMediaSelect, onSubmit, onVariantClick, + onVariantPreorderDeactivate, + variantDeactivatePreoderButtonState, onVariantReorder, onSetDefaultVariant, onWarehouseConfigure, @@ -149,6 +154,11 @@ const ProductVariantPage: React.FC = ({ const [isModalOpened, setModalStatus] = React.useState(false); const toggleModal = () => setModalStatus(!isModalOpened); + const [ + isEndPreorderModalOpened, + setIsEndPreorderModalOpened + ] = React.useState(false); + const variantMedia = variant?.media?.map(image => image.id); const productMedia = variant?.product?.media?.sort((prev, next) => prev.sortOrder > next.sortOrder ? 1 : -1 @@ -159,6 +169,11 @@ const ProductVariantPage: React.FC = ({ const canOpenAssignReferencesAttributeDialog = !!assignReferencesAttributeId; + const handleDeactivatePreorder = async () => { + await onVariantPreorderDeactivate(variant.id); + setIsEndPreorderModalOpened(false); + }; + const handleAssignReferenceAttribute = ( attributeValues: string[], data: ProductVariantUpdateData, @@ -202,6 +217,7 @@ const ProductVariantPage: React.FC = ({ {({ change, data, + formErrors, disabled: formDisabled, handlers, hasChanged, @@ -305,14 +321,28 @@ const ProductVariantPage: React.FC = ({ /> ({ + ...channel.data, + ...channel.value + }) + )} + onVariantChannelListingChange={handlers.changeChannels} data={data} disabled={loading} hasVariants={true} errors={errors} + formErrors={formErrors} stocks={data.stocks} warehouses={warehouses} onChange={handlers.changeStock} onFormDataChange={change} + onChangePreorderEndDate={handlers.changePreorderEndDate} + onEndPreorderTrigger={ + !!variant?.preorder + ? () => setIsEndPreorderModalOpened(true) + : null + } onWarehouseStockAdd={handlers.addStock} onWarehouseStockDelete={handlers.deleteStock} onWarehouseConfigure={onWarehouseConfigure} @@ -364,6 +394,15 @@ const ProductVariantPage: React.FC = ({ selectedMedia={maybe(() => variant.media.map(image => image.id))} /> )} + {!!variant?.preorder && ( + setIsEndPreorderModalOpened(false)} + onConfirm={handleDeactivatePreorder} + open={isEndPreorderModalOpened} + variantGlobalSoldUnits={variant?.preorder?.globalSoldUnits} + /> + )} ); }; diff --git a/src/products/components/ProductVariantPage/form.tsx b/src/products/components/ProductVariantPage/form.tsx index 285cbf05e..fec4d7ea7 100644 --- a/src/products/components/ProductVariantPage/form.tsx +++ b/src/products/components/ProductVariantPage/form.tsx @@ -8,20 +8,31 @@ import { createFetchMoreReferencesHandler, createFetchReferencesHandler } from "@saleor/attributes/utils/handlers"; -import { ChannelPriceData, IChannelPriceArgs } from "@saleor/channels/utils"; +import { + ChannelPriceAndPreorderData, + IChannelPriceAndPreorderArgs +} from "@saleor/channels/utils"; import { AttributeInput } from "@saleor/components/Attributes"; import { MetadataFormData } from "@saleor/components/Metadata"; import { ProductVariant } from "@saleor/fragments/types/ProductVariant"; -import useForm, { FormChange, SubmitPromise } from "@saleor/hooks/useForm"; +import useForm, { + FormChange, + FormErrors, + SubmitPromise +} from "@saleor/hooks/useForm"; import useFormset, { FormsetChange, FormsetData } from "@saleor/hooks/useFormset"; +import { errorMessages } from "@saleor/intl"; import { getAttributeInputFromVariant, getStockInputFromVariant } from "@saleor/products/utils/data"; -import { getChannelsInput } from "@saleor/products/utils/handlers"; +import { + createPreorderEndDateChangeHandler, + getChannelsInput +} from "@saleor/products/utils/handlers"; import { validateCostPrice, validatePrice @@ -35,6 +46,7 @@ import { mapMetadataItemToInput } from "@saleor/utils/maps"; import getMetadata from "@saleor/utils/metadata/getMetadata"; import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger"; import React from "react"; +import { useIntl } from "react-intl"; import handleFormSubmit from "../../../utils/handlers/handleFormSubmit"; import { ProductStockInput } from "../ProductStocks"; @@ -43,9 +55,17 @@ export interface ProductVariantUpdateFormData extends MetadataFormData { sku: string; trackInventory: boolean; weight: string; + isPreorder: boolean; + globalThreshold: number; + globalSoldUnits: number; + hasPreorderEndDate: boolean; + preorderEndDateTime?: string; } export interface ProductVariantUpdateData extends ProductVariantUpdateFormData { - channelListings: FormsetData; + channelListings: FormsetData< + ChannelPriceAndPreorderData, + IChannelPriceAndPreorderArgs + >; attributes: AttributeInput[]; stocks: ProductStockInput[]; } @@ -54,14 +74,17 @@ export interface ProductVariantUpdateSubmitData attributes: AttributeInput[]; attributesWithNewFileValue: FormsetData; addStocks: ProductStockInput[]; - channelListings: FormsetData; + channelListings: FormsetData< + ChannelPriceAndPreorderData, + IChannelPriceAndPreorderArgs + >; updateStocks: ProductStockInput[]; removeStocks: string[]; } export interface UseProductVariantUpdateFormOpts { warehouses: SearchWarehouses_search_edges_node[]; - currentChannels: ChannelPriceData[]; + currentChannels: ChannelPriceAndPreorderData[]; referencePages: SearchPages_search_edges_node[]; referenceProducts: SearchProducts_search_edges_node[]; fetchReferencePages?: (data: string) => void; @@ -83,6 +106,7 @@ export interface ProductVariantUpdateHandlers Record<"selectAttributeFile", FormsetChange>, Record<"reorderAttributeValue", FormsetChange>, Record<"addStock" | "deleteStock", (id: string) => void> { + changePreorderEndDate: FormChange; changeMetadata: FormChange; fetchReferences: (value: string) => void; fetchMoreReferences: FetchMoreProps; @@ -91,6 +115,7 @@ export interface ProductVariantUpdateHandlers export interface UseProductVariantUpdateFormResult { change: FormChange; data: ProductVariantUpdateData; + formErrors: FormErrors; disabled: boolean; handlers: ProductVariantUpdateHandlers; hasChanged: boolean; @@ -109,18 +134,37 @@ function useProductVariantUpdateForm( onSubmit: (data: ProductVariantUpdateSubmitData) => SubmitPromise, opts: UseProductVariantUpdateFormOpts ): UseProductVariantUpdateFormResult { + const intl = useIntl(); const [changed, setChanged] = React.useState(false); const triggerChange = () => setChanged(true); const attributeInput = getAttributeInputFromVariant(variant); const stockInput = getStockInputFromVariant(variant); - const channelsInput = getChannelsInput(opts.currentChannels); + + const currentChannelsWithPreorderInfo = opts.currentChannels?.map(channel => { + const variantChannel = variant?.channelListings?.find( + channelListing => channelListing.channel.id === channel.id + ); + + return { + ...channel, + preorderThreshold: variantChannel?.preorderThreshold?.quantity, + soldUnits: variantChannel?.preorderThreshold?.soldUnits + }; + }); + + const channelsInput = getChannelsInput(currentChannelsWithPreorderInfo); const initial: ProductVariantUpdateFormData = { metadata: variant?.metadata?.map(mapMetadataItemToInput), privateMetadata: variant?.privateMetadata?.map(mapMetadataItemToInput), sku: variant?.sku || "", trackInventory: variant?.trackInventory, + isPreorder: !!variant?.preorder || false, + globalThreshold: variant?.preorder?.globalThreshold || null, + globalSoldUnits: variant?.preorder?.globalSoldUnits || 0, + hasPreorderEndDate: !!variant?.preorder?.endDate, + preorderEndDateTime: variant?.preorder?.endDate, weight: variant?.weight?.value.toString() || "" }; @@ -204,6 +248,12 @@ function useProductVariantUpdateForm( triggerChange(); }; + const handlePreorderEndDateChange = createPreorderEndDateChangeHandler( + form, + triggerChange, + intl.formatMessage(errorMessages.preorderEndDateInFutureErrorText) + ); + const dataStocks = stocks.data.map(stock => stock.id); const variantStocks = variant?.stocks.map(stock => stock.warehouse.id) || []; const stockDiff = arrayDiff(variantStocks, dataStocks); @@ -215,11 +265,6 @@ function useProductVariantUpdateForm( stock => !stockDiff.added.some(addedStock => addedStock === stock.id) ); - const disabled = channels?.data.some( - channelData => - validatePrice(channelData.value.price) || - validateCostPrice(channelData.value.costPrice) - ); const data: ProductVariantUpdateData = { ...form.data, attributes: getAttributesDisplayData( @@ -231,6 +276,17 @@ function useProductVariantUpdateForm( channelListings: channels.data, stocks: stocks.data }; + + const disabled = + channels?.data.some( + channelData => + validatePrice(channelData.value.price) || + validateCostPrice(channelData.value.costPrice) + ) || + (data.isPreorder && + data.hasPreorderEndDate && + !!form.errors.preorderEndDateTime); + const submitData: ProductVariantUpdateSubmitData = { ...form.data, ...getMetadata(form.data, isMetadataModified, isPrivateMetadataModified), @@ -258,11 +314,13 @@ function useProductVariantUpdateForm( change: handleChange, data, disabled, + formErrors: form.errors, handlers: { addStock: handleStockAdd, changeChannels: handleChannelChange, changeMetadata, changeStock: handleStockChange, + changePreorderEndDate: handlePreorderEndDateChange, deleteStock: handleStockDelete, fetchMoreReferences: handleFetchMoreReferences, fetchReferences: handleFetchReferences, diff --git a/src/products/components/ProductVariantPrice/ProductVariantPrice.tsx b/src/products/components/ProductVariantPrice/ProductVariantPrice.tsx index 5284fef17..21e32299a 100644 --- a/src/products/components/ProductVariantPrice/ProductVariantPrice.tsx +++ b/src/products/components/ProductVariantPrice/ProductVariantPrice.tsx @@ -7,7 +7,11 @@ import { TableRow, Typography } from "@material-ui/core"; -import { ChannelData, ChannelPriceArgs } from "@saleor/channels/utils"; +import { + ChannelData, + ChannelPriceAndPreorderArgs, + ChannelPriceArgs +} from "@saleor/channels/utils"; import CardTitle from "@saleor/components/CardTitle"; import PriceField from "@saleor/components/PriceField"; import ResponsiveTable from "@saleor/components/ResponsiveTable"; @@ -66,7 +70,10 @@ interface ProductVariantPriceProps { errors?: ProductChannelListingErrorFragment[]; loading?: boolean; disabled?: boolean; - onChange?: (id: string, data: ChannelPriceArgs) => void; + onChange?: ( + id: string, + data: ChannelPriceArgs | ChannelPriceAndPreorderArgs + ) => void; disabledMessage?: MessageDescriptor; } @@ -178,7 +185,8 @@ const ProductVariantPrice: React.FC = props => { onChange={e => onChange(listing.id, { costPrice: listing.costPrice, - price: e.target.value + price: e.target.value, + preorderThreshold: listing.preorderThreshold }) } disabled={loading} @@ -207,7 +215,8 @@ const ProductVariantPrice: React.FC = props => { onChange={e => onChange(listing.id, { costPrice: e.target.value, - price: listing.price + price: listing.price, + preorderThreshold: listing.preorderThreshold }) } disabled={loading} diff --git a/src/products/fixtures.ts b/src/products/fixtures.ts index d2e1ad4cf..05cccf8ca 100644 --- a/src/products/fixtures.ts +++ b/src/products/fixtures.ts @@ -631,10 +631,11 @@ export const product: ( } ], trackInventory: true, - weight: { - __typename: "Weight", - unit: WeightUnitsEnum.KG, - value: 3 + preorder: { + __typename: "PreorderData", + endDate: null, + globalSoldUnits: null, + globalThreshold: 0 } }, { @@ -657,6 +658,11 @@ export const product: ( __typename: "Money", amount: 1, currency: "USD" + }, + preorderThreshold: { + __typename: "PreorderThreshold", + quantity: 0, + soldUnits: 0 } }, { @@ -676,6 +682,11 @@ export const product: ( __typename: "Money", amount: 1, currency: "USD" + }, + preorderThreshold: { + __typename: "PreorderThreshold", + quantity: 0, + soldUnits: 0 } } ], @@ -709,10 +720,11 @@ export const product: ( } ], trackInventory: false, - weight: { - __typename: "Weight", - unit: WeightUnitsEnum.KG, - value: 4 + preorder: { + __typename: "PreorderData", + endDate: null, + globalSoldUnits: null, + globalThreshold: 0 } } ], @@ -2940,6 +2952,11 @@ export const variant = (placeholderImage: string): ProductVariant => ({ __typename: "Money", amount: 10, currency: "USD" + }, + preorderThreshold: { + __typename: "PreorderThreshold", + quantity: 0, + soldUnits: 0 } }, { @@ -2959,6 +2976,11 @@ export const variant = (placeholderImage: string): ProductVariant => ({ __typename: "Money", amount: 20, currency: "USD" + }, + preorderThreshold: { + __typename: "PreorderThreshold", + quantity: 0, + soldUnits: 0 } } ], @@ -3502,6 +3524,12 @@ export const variant = (placeholderImage: string): ProductVariant => ({ } ], trackInventory: true, + preorder: { + __typename: "PreorderData", + endDate: null, + globalSoldUnits: null, + globalThreshold: 0 + }, weight: { __typename: "Weight", unit: WeightUnitsEnum.KG, diff --git a/src/products/mutations.ts b/src/products/mutations.ts index 5b137e58b..0445c3cb0 100644 --- a/src/products/mutations.ts +++ b/src/products/mutations.ts @@ -11,6 +11,7 @@ import { channelListingProductFragment, channelListingProductVariantFragment, exportFileFragment, + fragmentPreorder, fragmentProductMedia, fragmentVariant, productFragmentDetails @@ -66,6 +67,10 @@ import { ProductVariantChannelListingUpdate, ProductVariantChannelListingUpdateVariables } from "./types/ProductVariantChannelListingUpdate"; +import { + ProductVariantPreorderDeactivate, + ProductVariantPreorderDeactivateVariables +} from "./types/ProductVariantPreorderDeactivate"; import { ProductVariantReorder, ProductVariantReorderVariables @@ -334,6 +339,7 @@ export const variantUpdateMutation = gql` $sku: String $trackInventory: Boolean! $stocks: [StockInput!]! + $preorder: PreorderSettingsInput $weight: WeightScalar $firstValues: Int $afterValues: String @@ -346,6 +352,7 @@ export const variantUpdateMutation = gql` attributes: $attributes sku: $sku trackInventory: $trackInventory + preorder: $preorder weight: $weight } ) { @@ -686,3 +693,25 @@ export const useProductVariantChannelListingUpdate = makeMutation< ProductVariantChannelListingUpdate, ProductVariantChannelListingUpdateVariables >(ProductVariantChannelListingUpdateMutation); + +export const ProductVariantPreorderDeactivateMutation = gql` + ${fragmentPreorder} + ${productErrorFragment} + mutation ProductVariantPreorderDeactivate($id: ID!) { + productVariantPreorderDeactivate(id: $id) { + productVariant { + id + preorder { + ...PreorderFragment + } + } + errors { + ...ProductErrorFragment + } + } + } +`; +export const useProductVariantPreorderDeactivateMutation = makeMutation< + ProductVariantPreorderDeactivate, + ProductVariantPreorderDeactivateVariables +>(ProductVariantPreorderDeactivateMutation); diff --git a/src/products/types/ProductChannelListingUpdate.ts b/src/products/types/ProductChannelListingUpdate.ts index fab3ae318..a65d2d155 100644 --- a/src/products/types/ProductChannelListingUpdate.ts +++ b/src/products/types/ProductChannelListingUpdate.ts @@ -79,11 +79,18 @@ export interface ProductChannelListingUpdate_productChannelListingUpdate_product currency: string; } +export interface ProductChannelListingUpdate_productChannelListingUpdate_product_variants_channelListings_preorderThreshold { + __typename: "PreorderThreshold"; + quantity: number | null; + soldUnits: number; +} + export interface ProductChannelListingUpdate_productChannelListingUpdate_product_variants_channelListings { __typename: "ProductVariantChannelListing"; channel: ProductChannelListingUpdate_productChannelListingUpdate_product_variants_channelListings_channel; price: ProductChannelListingUpdate_productChannelListingUpdate_product_variants_channelListings_price | null; costPrice: ProductChannelListingUpdate_productChannelListingUpdate_product_variants_channelListings_costPrice | null; + preorderThreshold: ProductChannelListingUpdate_productChannelListingUpdate_product_variants_channelListings_preorderThreshold | null; } export interface ProductChannelListingUpdate_productChannelListingUpdate_product_variants { diff --git a/src/products/types/ProductDetails.ts b/src/products/types/ProductDetails.ts index e499e68ae..66e3dfe62 100644 --- a/src/products/types/ProductDetails.ts +++ b/src/products/types/ProductDetails.ts @@ -260,6 +260,13 @@ export interface ProductDetails_product_variants_stocks { warehouse: ProductDetails_product_variants_stocks_warehouse; } +export interface ProductDetails_product_variants_preorder { + __typename: "PreorderData"; + globalThreshold: number | null; + globalSoldUnits: number; + endDate: any | null; +} + export interface ProductDetails_product_variants_channelListings_channel { __typename: "Channel"; id: string; @@ -279,11 +286,18 @@ export interface ProductDetails_product_variants_channelListings_costPrice { currency: string; } +export interface ProductDetails_product_variants_channelListings_preorderThreshold { + __typename: "PreorderThreshold"; + quantity: number | null; + soldUnits: number; +} + export interface ProductDetails_product_variants_channelListings { __typename: "ProductVariantChannelListing"; channel: ProductDetails_product_variants_channelListings_channel; price: ProductDetails_product_variants_channelListings_price | null; costPrice: ProductDetails_product_variants_channelListings_costPrice | null; + preorderThreshold: ProductDetails_product_variants_channelListings_preorderThreshold | null; } export interface ProductDetails_product_variants { @@ -295,6 +309,7 @@ export interface ProductDetails_product_variants { media: ProductDetails_product_variants_media[] | null; stocks: (ProductDetails_product_variants_stocks | null)[] | null; trackInventory: boolean; + preorder: ProductDetails_product_variants_preorder | null; channelListings: ProductDetails_product_variants_channelListings[] | null; } diff --git a/src/products/types/ProductUpdate.ts b/src/products/types/ProductUpdate.ts index a43410220..328fbefa3 100644 --- a/src/products/types/ProductUpdate.ts +++ b/src/products/types/ProductUpdate.ts @@ -267,6 +267,13 @@ export interface ProductUpdate_productUpdate_product_variants_stocks { warehouse: ProductUpdate_productUpdate_product_variants_stocks_warehouse; } +export interface ProductUpdate_productUpdate_product_variants_preorder { + __typename: "PreorderData"; + globalThreshold: number | null; + globalSoldUnits: number; + endDate: any | null; +} + export interface ProductUpdate_productUpdate_product_variants_channelListings_channel { __typename: "Channel"; id: string; @@ -286,11 +293,18 @@ export interface ProductUpdate_productUpdate_product_variants_channelListings_co currency: string; } +export interface ProductUpdate_productUpdate_product_variants_channelListings_preorderThreshold { + __typename: "PreorderThreshold"; + quantity: number | null; + soldUnits: number; +} + export interface ProductUpdate_productUpdate_product_variants_channelListings { __typename: "ProductVariantChannelListing"; channel: ProductUpdate_productUpdate_product_variants_channelListings_channel; price: ProductUpdate_productUpdate_product_variants_channelListings_price | null; costPrice: ProductUpdate_productUpdate_product_variants_channelListings_costPrice | null; + preorderThreshold: ProductUpdate_productUpdate_product_variants_channelListings_preorderThreshold | null; } export interface ProductUpdate_productUpdate_product_variants { @@ -302,6 +316,7 @@ export interface ProductUpdate_productUpdate_product_variants { media: ProductUpdate_productUpdate_product_variants_media[] | null; stocks: (ProductUpdate_productUpdate_product_variants_stocks | null)[] | null; trackInventory: boolean; + preorder: ProductUpdate_productUpdate_product_variants_preorder | null; channelListings: ProductUpdate_productUpdate_product_variants_channelListings[] | null; } diff --git a/src/products/types/ProductVariantChannelListingUpdate.ts b/src/products/types/ProductVariantChannelListingUpdate.ts index 6343a3c2f..608087d92 100644 --- a/src/products/types/ProductVariantChannelListingUpdate.ts +++ b/src/products/types/ProductVariantChannelListingUpdate.ts @@ -28,11 +28,18 @@ export interface ProductVariantChannelListingUpdate_productVariantChannelListing currency: string; } +export interface ProductVariantChannelListingUpdate_productVariantChannelListingUpdate_variant_channelListings_preorderThreshold { + __typename: "PreorderThreshold"; + quantity: number | null; + soldUnits: number; +} + export interface ProductVariantChannelListingUpdate_productVariantChannelListingUpdate_variant_channelListings { __typename: "ProductVariantChannelListing"; channel: ProductVariantChannelListingUpdate_productVariantChannelListingUpdate_variant_channelListings_channel; price: ProductVariantChannelListingUpdate_productVariantChannelListingUpdate_variant_channelListings_price | null; costPrice: ProductVariantChannelListingUpdate_productVariantChannelListingUpdate_variant_channelListings_costPrice | null; + preorderThreshold: ProductVariantChannelListingUpdate_productVariantChannelListingUpdate_variant_channelListings_preorderThreshold | null; } export interface ProductVariantChannelListingUpdate_productVariantChannelListingUpdate_variant_product_channelListings_channel { diff --git a/src/products/types/ProductVariantDetails.ts b/src/products/types/ProductVariantDetails.ts index c113ee058..4aa1a0461 100644 --- a/src/products/types/ProductVariantDetails.ts +++ b/src/products/types/ProductVariantDetails.ts @@ -299,11 +299,18 @@ export interface ProductVariantDetails_productVariant_channelListings_costPrice currency: string; } +export interface ProductVariantDetails_productVariant_channelListings_preorderThreshold { + __typename: "PreorderThreshold"; + quantity: number | null; + soldUnits: number; +} + export interface ProductVariantDetails_productVariant_channelListings { __typename: "ProductVariantChannelListing"; channel: ProductVariantDetails_productVariant_channelListings_channel; price: ProductVariantDetails_productVariant_channelListings_price | null; costPrice: ProductVariantDetails_productVariant_channelListings_costPrice | null; + preorderThreshold: ProductVariantDetails_productVariant_channelListings_preorderThreshold | null; } export interface ProductVariantDetails_productVariant_stocks_warehouse { @@ -320,6 +327,13 @@ export interface ProductVariantDetails_productVariant_stocks { warehouse: ProductVariantDetails_productVariant_stocks_warehouse; } +export interface ProductVariantDetails_productVariant_preorder { + __typename: "PreorderData"; + globalThreshold: number | null; + globalSoldUnits: number; + endDate: any | null; +} + export interface ProductVariantDetails_productVariant_weight { __typename: "Weight"; unit: WeightUnitsEnum; @@ -340,6 +354,7 @@ export interface ProductVariantDetails_productVariant { sku: string | null; stocks: (ProductVariantDetails_productVariant_stocks | null)[] | null; trackInventory: boolean; + preorder: ProductVariantDetails_productVariant_preorder | null; weight: ProductVariantDetails_productVariant_weight | null; } diff --git a/src/products/types/ProductVariantPreorderDeactivate.ts b/src/products/types/ProductVariantPreorderDeactivate.ts new file mode 100644 index 000000000..6c2977563 --- /dev/null +++ b/src/products/types/ProductVariantPreorderDeactivate.ts @@ -0,0 +1,43 @@ +/* tslint:disable */ +/* eslint-disable */ +// @generated +// This file was automatically generated and should not be edited. + +import { ProductErrorCode } from "./../../types/globalTypes"; + +// ==================================================== +// GraphQL mutation operation: ProductVariantPreorderDeactivate +// ==================================================== + +export interface ProductVariantPreorderDeactivate_productVariantPreorderDeactivate_productVariant_preorder { + __typename: "PreorderData"; + globalThreshold: number | null; + globalSoldUnits: number; + endDate: any | null; +} + +export interface ProductVariantPreorderDeactivate_productVariantPreorderDeactivate_productVariant { + __typename: "ProductVariant"; + id: string; + preorder: ProductVariantPreorderDeactivate_productVariantPreorderDeactivate_productVariant_preorder | null; +} + +export interface ProductVariantPreorderDeactivate_productVariantPreorderDeactivate_errors { + __typename: "ProductError"; + code: ProductErrorCode; + field: string | null; +} + +export interface ProductVariantPreorderDeactivate_productVariantPreorderDeactivate { + __typename: "ProductVariantPreorderDeactivate"; + productVariant: ProductVariantPreorderDeactivate_productVariantPreorderDeactivate_productVariant | null; + errors: ProductVariantPreorderDeactivate_productVariantPreorderDeactivate_errors[]; +} + +export interface ProductVariantPreorderDeactivate { + productVariantPreorderDeactivate: ProductVariantPreorderDeactivate_productVariantPreorderDeactivate | null; +} + +export interface ProductVariantPreorderDeactivateVariables { + id: string; +} diff --git a/src/products/types/SimpleProductUpdate.ts b/src/products/types/SimpleProductUpdate.ts index 3f3225560..d4c0ed5b0 100644 --- a/src/products/types/SimpleProductUpdate.ts +++ b/src/products/types/SimpleProductUpdate.ts @@ -267,6 +267,13 @@ export interface SimpleProductUpdate_productUpdate_product_variants_stocks { warehouse: SimpleProductUpdate_productUpdate_product_variants_stocks_warehouse; } +export interface SimpleProductUpdate_productUpdate_product_variants_preorder { + __typename: "PreorderData"; + globalThreshold: number | null; + globalSoldUnits: number; + endDate: any | null; +} + export interface SimpleProductUpdate_productUpdate_product_variants_channelListings_channel { __typename: "Channel"; id: string; @@ -286,11 +293,18 @@ export interface SimpleProductUpdate_productUpdate_product_variants_channelListi currency: string; } +export interface SimpleProductUpdate_productUpdate_product_variants_channelListings_preorderThreshold { + __typename: "PreorderThreshold"; + quantity: number | null; + soldUnits: number; +} + export interface SimpleProductUpdate_productUpdate_product_variants_channelListings { __typename: "ProductVariantChannelListing"; channel: SimpleProductUpdate_productUpdate_product_variants_channelListings_channel; price: SimpleProductUpdate_productUpdate_product_variants_channelListings_price | null; costPrice: SimpleProductUpdate_productUpdate_product_variants_channelListings_costPrice | null; + preorderThreshold: SimpleProductUpdate_productUpdate_product_variants_channelListings_preorderThreshold | null; } export interface SimpleProductUpdate_productUpdate_product_variants { @@ -302,6 +316,7 @@ export interface SimpleProductUpdate_productUpdate_product_variants { media: SimpleProductUpdate_productUpdate_product_variants_media[] | null; stocks: (SimpleProductUpdate_productUpdate_product_variants_stocks | null)[] | null; trackInventory: boolean; + preorder: SimpleProductUpdate_productUpdate_product_variants_preorder | null; channelListings: SimpleProductUpdate_productUpdate_product_variants_channelListings[] | null; } @@ -645,11 +660,18 @@ export interface SimpleProductUpdate_productVariantUpdate_productVariant_channel currency: string; } +export interface SimpleProductUpdate_productVariantUpdate_productVariant_channelListings_preorderThreshold { + __typename: "PreorderThreshold"; + quantity: number | null; + soldUnits: number; +} + export interface SimpleProductUpdate_productVariantUpdate_productVariant_channelListings { __typename: "ProductVariantChannelListing"; channel: SimpleProductUpdate_productVariantUpdate_productVariant_channelListings_channel; price: SimpleProductUpdate_productVariantUpdate_productVariant_channelListings_price | null; costPrice: SimpleProductUpdate_productVariantUpdate_productVariant_channelListings_costPrice | null; + preorderThreshold: SimpleProductUpdate_productVariantUpdate_productVariant_channelListings_preorderThreshold | null; } export interface SimpleProductUpdate_productVariantUpdate_productVariant_stocks_warehouse { @@ -666,6 +688,13 @@ export interface SimpleProductUpdate_productVariantUpdate_productVariant_stocks warehouse: SimpleProductUpdate_productVariantUpdate_productVariant_stocks_warehouse; } +export interface SimpleProductUpdate_productVariantUpdate_productVariant_preorder { + __typename: "PreorderData"; + globalThreshold: number | null; + globalSoldUnits: number; + endDate: any | null; +} + export interface SimpleProductUpdate_productVariantUpdate_productVariant_weight { __typename: "Weight"; unit: WeightUnitsEnum; @@ -686,6 +715,7 @@ export interface SimpleProductUpdate_productVariantUpdate_productVariant { sku: string | null; stocks: (SimpleProductUpdate_productVariantUpdate_productVariant_stocks | null)[] | null; trackInventory: boolean; + preorder: SimpleProductUpdate_productVariantUpdate_productVariant_preorder | null; weight: SimpleProductUpdate_productVariantUpdate_productVariant_weight | null; } @@ -992,11 +1022,18 @@ export interface SimpleProductUpdate_productVariantStocksCreate_productVariant_c currency: string; } +export interface SimpleProductUpdate_productVariantStocksCreate_productVariant_channelListings_preorderThreshold { + __typename: "PreorderThreshold"; + quantity: number | null; + soldUnits: number; +} + export interface SimpleProductUpdate_productVariantStocksCreate_productVariant_channelListings { __typename: "ProductVariantChannelListing"; channel: SimpleProductUpdate_productVariantStocksCreate_productVariant_channelListings_channel; price: SimpleProductUpdate_productVariantStocksCreate_productVariant_channelListings_price | null; costPrice: SimpleProductUpdate_productVariantStocksCreate_productVariant_channelListings_costPrice | null; + preorderThreshold: SimpleProductUpdate_productVariantStocksCreate_productVariant_channelListings_preorderThreshold | null; } export interface SimpleProductUpdate_productVariantStocksCreate_productVariant_stocks_warehouse { @@ -1013,6 +1050,13 @@ export interface SimpleProductUpdate_productVariantStocksCreate_productVariant_s warehouse: SimpleProductUpdate_productVariantStocksCreate_productVariant_stocks_warehouse; } +export interface SimpleProductUpdate_productVariantStocksCreate_productVariant_preorder { + __typename: "PreorderData"; + globalThreshold: number | null; + globalSoldUnits: number; + endDate: any | null; +} + export interface SimpleProductUpdate_productVariantStocksCreate_productVariant_weight { __typename: "Weight"; unit: WeightUnitsEnum; @@ -1033,6 +1077,7 @@ export interface SimpleProductUpdate_productVariantStocksCreate_productVariant { sku: string | null; stocks: (SimpleProductUpdate_productVariantStocksCreate_productVariant_stocks | null)[] | null; trackInventory: boolean; + preorder: SimpleProductUpdate_productVariantStocksCreate_productVariant_preorder | null; weight: SimpleProductUpdate_productVariantStocksCreate_productVariant_weight | null; } @@ -1338,11 +1383,18 @@ export interface SimpleProductUpdate_productVariantStocksDelete_productVariant_c currency: string; } +export interface SimpleProductUpdate_productVariantStocksDelete_productVariant_channelListings_preorderThreshold { + __typename: "PreorderThreshold"; + quantity: number | null; + soldUnits: number; +} + export interface SimpleProductUpdate_productVariantStocksDelete_productVariant_channelListings { __typename: "ProductVariantChannelListing"; channel: SimpleProductUpdate_productVariantStocksDelete_productVariant_channelListings_channel; price: SimpleProductUpdate_productVariantStocksDelete_productVariant_channelListings_price | null; costPrice: SimpleProductUpdate_productVariantStocksDelete_productVariant_channelListings_costPrice | null; + preorderThreshold: SimpleProductUpdate_productVariantStocksDelete_productVariant_channelListings_preorderThreshold | null; } export interface SimpleProductUpdate_productVariantStocksDelete_productVariant_stocks_warehouse { @@ -1359,6 +1411,13 @@ export interface SimpleProductUpdate_productVariantStocksDelete_productVariant_s warehouse: SimpleProductUpdate_productVariantStocksDelete_productVariant_stocks_warehouse; } +export interface SimpleProductUpdate_productVariantStocksDelete_productVariant_preorder { + __typename: "PreorderData"; + globalThreshold: number | null; + globalSoldUnits: number; + endDate: any | null; +} + export interface SimpleProductUpdate_productVariantStocksDelete_productVariant_weight { __typename: "Weight"; unit: WeightUnitsEnum; @@ -1379,6 +1438,7 @@ export interface SimpleProductUpdate_productVariantStocksDelete_productVariant { sku: string | null; stocks: (SimpleProductUpdate_productVariantStocksDelete_productVariant_stocks | null)[] | null; trackInventory: boolean; + preorder: SimpleProductUpdate_productVariantStocksDelete_productVariant_preorder | null; weight: SimpleProductUpdate_productVariantStocksDelete_productVariant_weight | null; } @@ -1685,11 +1745,18 @@ export interface SimpleProductUpdate_productVariantStocksUpdate_productVariant_c currency: string; } +export interface SimpleProductUpdate_productVariantStocksUpdate_productVariant_channelListings_preorderThreshold { + __typename: "PreorderThreshold"; + quantity: number | null; + soldUnits: number; +} + export interface SimpleProductUpdate_productVariantStocksUpdate_productVariant_channelListings { __typename: "ProductVariantChannelListing"; channel: SimpleProductUpdate_productVariantStocksUpdate_productVariant_channelListings_channel; price: SimpleProductUpdate_productVariantStocksUpdate_productVariant_channelListings_price | null; costPrice: SimpleProductUpdate_productVariantStocksUpdate_productVariant_channelListings_costPrice | null; + preorderThreshold: SimpleProductUpdate_productVariantStocksUpdate_productVariant_channelListings_preorderThreshold | null; } export interface SimpleProductUpdate_productVariantStocksUpdate_productVariant_stocks_warehouse { @@ -1706,6 +1773,13 @@ export interface SimpleProductUpdate_productVariantStocksUpdate_productVariant_s warehouse: SimpleProductUpdate_productVariantStocksUpdate_productVariant_stocks_warehouse; } +export interface SimpleProductUpdate_productVariantStocksUpdate_productVariant_preorder { + __typename: "PreorderData"; + globalThreshold: number | null; + globalSoldUnits: number; + endDate: any | null; +} + export interface SimpleProductUpdate_productVariantStocksUpdate_productVariant_weight { __typename: "Weight"; unit: WeightUnitsEnum; @@ -1726,6 +1800,7 @@ export interface SimpleProductUpdate_productVariantStocksUpdate_productVariant { sku: string | null; stocks: (SimpleProductUpdate_productVariantStocksUpdate_productVariant_stocks | null)[] | null; trackInventory: boolean; + preorder: SimpleProductUpdate_productVariantStocksUpdate_productVariant_preorder | null; weight: SimpleProductUpdate_productVariantStocksUpdate_productVariant_weight | null; } diff --git a/src/products/types/VariantCreate.ts b/src/products/types/VariantCreate.ts index 6897ef690..29058c958 100644 --- a/src/products/types/VariantCreate.ts +++ b/src/products/types/VariantCreate.ts @@ -306,11 +306,18 @@ export interface VariantCreate_productVariantCreate_productVariant_channelListin currency: string; } +export interface VariantCreate_productVariantCreate_productVariant_channelListings_preorderThreshold { + __typename: "PreorderThreshold"; + quantity: number | null; + soldUnits: number; +} + export interface VariantCreate_productVariantCreate_productVariant_channelListings { __typename: "ProductVariantChannelListing"; channel: VariantCreate_productVariantCreate_productVariant_channelListings_channel; price: VariantCreate_productVariantCreate_productVariant_channelListings_price | null; costPrice: VariantCreate_productVariantCreate_productVariant_channelListings_costPrice | null; + preorderThreshold: VariantCreate_productVariantCreate_productVariant_channelListings_preorderThreshold | null; } export interface VariantCreate_productVariantCreate_productVariant_stocks_warehouse { @@ -327,6 +334,13 @@ export interface VariantCreate_productVariantCreate_productVariant_stocks { warehouse: VariantCreate_productVariantCreate_productVariant_stocks_warehouse; } +export interface VariantCreate_productVariantCreate_productVariant_preorder { + __typename: "PreorderData"; + globalThreshold: number | null; + globalSoldUnits: number; + endDate: any | null; +} + export interface VariantCreate_productVariantCreate_productVariant_weight { __typename: "Weight"; unit: WeightUnitsEnum; @@ -347,6 +361,7 @@ export interface VariantCreate_productVariantCreate_productVariant { sku: string | null; stocks: (VariantCreate_productVariantCreate_productVariant_stocks | null)[] | null; trackInventory: boolean; + preorder: VariantCreate_productVariantCreate_productVariant_preorder | null; weight: VariantCreate_productVariantCreate_productVariant_weight | null; } diff --git a/src/products/types/VariantUpdate.ts b/src/products/types/VariantUpdate.ts index dd85ed2cf..0c3654ef2 100644 --- a/src/products/types/VariantUpdate.ts +++ b/src/products/types/VariantUpdate.ts @@ -3,7 +3,7 @@ // @generated // This file was automatically generated and should not be edited. -import { StockInput, AttributeValueInput, ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum, ProductMediaType, WeightUnitsEnum, StockErrorCode } from "./../../types/globalTypes"; +import { StockInput, AttributeValueInput, PreorderSettingsInput, ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, MeasurementUnitsEnum, ProductMediaType, WeightUnitsEnum, StockErrorCode } from "./../../types/globalTypes"; // ==================================================== // GraphQL mutation operation: VariantUpdate @@ -306,11 +306,18 @@ export interface VariantUpdate_productVariantUpdate_productVariant_channelListin currency: string; } +export interface VariantUpdate_productVariantUpdate_productVariant_channelListings_preorderThreshold { + __typename: "PreorderThreshold"; + quantity: number | null; + soldUnits: number; +} + export interface VariantUpdate_productVariantUpdate_productVariant_channelListings { __typename: "ProductVariantChannelListing"; channel: VariantUpdate_productVariantUpdate_productVariant_channelListings_channel; price: VariantUpdate_productVariantUpdate_productVariant_channelListings_price | null; costPrice: VariantUpdate_productVariantUpdate_productVariant_channelListings_costPrice | null; + preorderThreshold: VariantUpdate_productVariantUpdate_productVariant_channelListings_preorderThreshold | null; } export interface VariantUpdate_productVariantUpdate_productVariant_stocks_warehouse { @@ -327,6 +334,13 @@ export interface VariantUpdate_productVariantUpdate_productVariant_stocks { warehouse: VariantUpdate_productVariantUpdate_productVariant_stocks_warehouse; } +export interface VariantUpdate_productVariantUpdate_productVariant_preorder { + __typename: "PreorderData"; + globalThreshold: number | null; + globalSoldUnits: number; + endDate: any | null; +} + export interface VariantUpdate_productVariantUpdate_productVariant_weight { __typename: "Weight"; unit: WeightUnitsEnum; @@ -347,6 +361,7 @@ export interface VariantUpdate_productVariantUpdate_productVariant { sku: string | null; stocks: (VariantUpdate_productVariantUpdate_productVariant_stocks | null)[] | null; trackInventory: boolean; + preorder: VariantUpdate_productVariantUpdate_productVariant_preorder | null; weight: VariantUpdate_productVariantUpdate_productVariant_weight | null; } @@ -653,11 +668,18 @@ export interface VariantUpdate_productVariantStocksUpdate_productVariant_channel currency: string; } +export interface VariantUpdate_productVariantStocksUpdate_productVariant_channelListings_preorderThreshold { + __typename: "PreorderThreshold"; + quantity: number | null; + soldUnits: number; +} + export interface VariantUpdate_productVariantStocksUpdate_productVariant_channelListings { __typename: "ProductVariantChannelListing"; channel: VariantUpdate_productVariantStocksUpdate_productVariant_channelListings_channel; price: VariantUpdate_productVariantStocksUpdate_productVariant_channelListings_price | null; costPrice: VariantUpdate_productVariantStocksUpdate_productVariant_channelListings_costPrice | null; + preorderThreshold: VariantUpdate_productVariantStocksUpdate_productVariant_channelListings_preorderThreshold | null; } export interface VariantUpdate_productVariantStocksUpdate_productVariant_stocks_warehouse { @@ -674,6 +696,13 @@ export interface VariantUpdate_productVariantStocksUpdate_productVariant_stocks warehouse: VariantUpdate_productVariantStocksUpdate_productVariant_stocks_warehouse; } +export interface VariantUpdate_productVariantStocksUpdate_productVariant_preorder { + __typename: "PreorderData"; + globalThreshold: number | null; + globalSoldUnits: number; + endDate: any | null; +} + export interface VariantUpdate_productVariantStocksUpdate_productVariant_weight { __typename: "Weight"; unit: WeightUnitsEnum; @@ -694,6 +723,7 @@ export interface VariantUpdate_productVariantStocksUpdate_productVariant { sku: string | null; stocks: (VariantUpdate_productVariantStocksUpdate_productVariant_stocks | null)[] | null; trackInventory: boolean; + preorder: VariantUpdate_productVariantStocksUpdate_productVariant_preorder | null; weight: VariantUpdate_productVariantStocksUpdate_productVariant_weight | null; } @@ -783,6 +813,7 @@ export interface VariantUpdateVariables { sku?: string | null; trackInventory: boolean; stocks: StockInput[]; + preorder?: PreorderSettingsInput | null; weight?: any | null; firstValues?: number | null; afterValues?: string | null; diff --git a/src/products/utils/data.ts b/src/products/utils/data.ts index c9cf67c01..09cc02433 100644 --- a/src/products/utils/data.ts +++ b/src/products/utils/data.ts @@ -21,6 +21,7 @@ import { } from "@saleor/products/types/ProductDetails"; import { StockInput } from "@saleor/types/globalTypes"; import { mapEdgesToItems, mapMetadataItemToInput } from "@saleor/utils/maps"; +import moment from "moment"; import { ProductStockInput } from "../components/ProductStocks"; import { ProductType_productType_productAttributes } from "../types/ProductType"; @@ -225,6 +226,11 @@ export interface ProductUpdatePageFormData extends MetadataFormData { taxCode: string; trackInventory: boolean; weight: string; + isPreorder: boolean; + globalThreshold: number; + globalSoldUnits: number; + hasPreorderEndDate: boolean; + preorderEndDateTime?: string; } export function getProductUpdatePageFormData( @@ -234,6 +240,7 @@ export function getProductUpdatePageFormData( channelsData: ChannelData[], channelsWithVariants: ChannelsWithVariantsData ): ProductUpdatePageFormData { + const variant = product?.variants[0]; return { channelsWithVariants, channelsData, @@ -244,7 +251,7 @@ export function getProductUpdatePageFormData( () => product.collections.map(collection => collection.id), [] ), - channelListings: currentChannels, + channelListings: currentChannels.map(listing => ({ ...listing })), isAvailable: !!product?.isAvailable, metadata: product?.metadata?.map(mapMetadataItemToInput), name: maybe(() => product.name, ""), @@ -263,8 +270,13 @@ export function getProductUpdatePageFormData( ), slug: product?.slug || "", taxCode: product?.taxType.taxCode, - trackInventory: !!product?.variants[0]?.trackInventory, - weight: product?.weight?.value.toString() || "" + trackInventory: !!variant?.trackInventory, + weight: product?.weight?.value.toString() || "", + isPreorder: !!variant?.preorder || false, + globalThreshold: variant?.preorder?.globalThreshold || 0, + globalSoldUnits: variant?.preorder?.globalSoldUnits || 0, + hasPreorderEndDate: !!variant?.preorder?.endDate, + preorderEndDateTime: variant?.preorder?.endDate }; } @@ -276,3 +288,9 @@ export function mapFormsetStockToStockInput( warehouse: stock.id }; } + +export const getPreorderEndDateFormData = (endDate?: string) => + endDate ? moment(endDate).format("YYYY-MM-DD") : ""; + +export const getPreorderEndHourFormData = (endDate?: string) => + endDate ? moment(endDate).format("HH:mm") : ""; diff --git a/src/products/utils/handlers.ts b/src/products/utils/handlers.ts index 49f9666cc..efc8993eb 100644 --- a/src/products/utils/handlers.ts +++ b/src/products/utils/handlers.ts @@ -1,9 +1,12 @@ import { ChannelData, + ChannelPreorderArgs, + ChannelPriceAndPreorderData, ChannelPriceArgs, ChannelPriceData } from "@saleor/channels/utils"; -import { FormChange } from "@saleor/hooks/useForm"; +import { FormChange, UseFormResult } from "@saleor/hooks/useForm"; +import moment from "moment"; export function createChannelsPriceChangeHandler( channelListings: ChannelData[], @@ -12,20 +15,29 @@ export function createChannelsPriceChangeHandler( ) { return (id: string, priceData: ChannelPriceArgs) => { const { costPrice, price } = priceData; - const channelIndex = channelListings.findIndex( - channel => channel.id === id - ); - const channel = channelListings[channelIndex]; - const updatedChannels = [ - ...channelListings.slice(0, channelIndex), - { - ...channel, - costPrice, - price - }, - ...channelListings.slice(channelIndex + 1) - ]; + const updatedChannels = channelListings.map(channel => + channel.id === id ? { ...channel, costPrice, price } : channel + ); + + updateChannels(updatedChannels); + + triggerChange(); + }; +} + +export function createChannelsPreorderChangeHandler( + channelListings: ChannelData[], + updateChannels: (data: ChannelData[]) => void, + triggerChange: () => void +) { + return (id: string, preorderData: ChannelPreorderArgs) => { + const { preorderThreshold, unitsSold } = preorderData; + + const updatedChannels = channelListings.map(channel => + channel.id === id ? { ...channel, preorderThreshold, unitsSold } : channel + ); + updateChannels(updatedChannels); triggerChange(); @@ -96,14 +108,15 @@ export function createProductTypeSelectHandler( }; } -export const getChannelsInput = (channels: ChannelPriceData[]) => +export const getChannelsInput = (channels: ChannelPriceAndPreorderData[]) => channels?.map(channel => ({ data: channel, id: channel.id, label: channel.name, value: { costPrice: channel.costPrice || "", - price: channel.price || "" + price: channel.price || "", + preorderThreshold: channel.preorderThreshold || null } })); @@ -127,3 +140,17 @@ export const getAvailabilityVariables = (channels: ChannelData[]) => visibleInListings: channel.visibleInListings }; }); + +export const createPreorderEndDateChangeHandler = ( + form: UseFormResult<{ preorderEndDateTime?: string }>, + triggerChange: () => void, + preorderPastDateErrorMessage: string +): FormChange => (event, cb) => { + form.change(event, cb); + if (moment(event.target.value).isSameOrBefore(Date.now())) { + form.setError("preorderEndDateTime", preorderPastDateErrorMessage); + } else { + form.clearErrors("preorderEndDateTime"); + } + triggerChange(); +}; diff --git a/src/products/views/ProductUpdate/handlers/utils.ts b/src/products/views/ProductUpdate/handlers/utils.ts index f0e603920..a69c539f3 100644 --- a/src/products/views/ProductUpdate/handlers/utils.ts +++ b/src/products/views/ProductUpdate/handlers/utils.ts @@ -36,7 +36,11 @@ export const getSimpleProductVariables = ( productVariantId: productId, productVariantInput: { sku: data.sku, - trackInventory: data.trackInventory + trackInventory: data.trackInventory, + preorder: { + globalThreshold: data.globalThreshold, + endDate: data.preorderEndDateTime + } }, updateStocks: data.updateStocks.map(mapFormsetStockToStockInput) }); @@ -188,5 +192,6 @@ export const getVariantChannelsInput = ({ channelListings.map(listing => ({ channelId: listing.id, costPrice: listing.costPrice || null, - price: listing.price + price: listing.price, + preorderThreshold: listing.preorderThreshold })); diff --git a/src/products/views/ProductVariant.tsx b/src/products/views/ProductVariant.tsx index 88b9bd1a9..a06e09284 100644 --- a/src/products/views/ProductVariant.tsx +++ b/src/products/views/ProductVariant.tsx @@ -21,7 +21,10 @@ import useNotifier from "@saleor/hooks/useNotifier"; import useOnSetDefaultVariant from "@saleor/hooks/useOnSetDefaultVariant"; import useShop from "@saleor/hooks/useShop"; import { commonMessages } from "@saleor/intl"; -import { useProductVariantChannelListingUpdate } from "@saleor/products/mutations"; +import { + useProductVariantChannelListingUpdate, + useProductVariantPreorderDeactivateMutation +} from "@saleor/products/mutations"; import { ProductVariantDetails_productVariant } from "@saleor/products/types/ProductVariantDetails"; import usePageSearch from "@saleor/searches/usePageSearch"; import useProductSearch from "@saleor/searches/useProductSearch"; @@ -155,23 +158,36 @@ export const ProductVariant: React.FC = ({ data: ProductVariantUpdateSubmitData, variant: ProductVariantDetails_productVariant ) => { - const isChannelPriceChange = data.channelListings.some(channel => { + const channelsHaveChanged = data.channelListings.some(channel => { const variantChannel = variant.channelListings.find( variantChannel => variantChannel.channel.id === channel.id ); + + const priceHasChanged = + channel.value.price !== variantChannel?.price?.amount.toString(); + + const costPriceHasChanged = + channel.value.costPrice !== + variantChannel?.costPrice?.amount.toString(); + + const preorderThresholdHasChanged = + channel.value?.preorderThreshold !== + variantChannel.preorderThreshold.quantity; + return ( - channel.value.price !== variantChannel?.price?.amount.toString() || - channel.value.costPrice !== variantChannel?.costPrice?.amount.toString() + priceHasChanged || costPriceHasChanged || preorderThresholdHasChanged ); }); - if (isChannelPriceChange) { + + if (channelsHaveChanged) { await updateChannels({ variables: { id: variant.id, input: data.channelListings.map(listing => ({ channelId: listing.id, costPrice: listing.value.costPrice || null, - price: listing.value.price + price: listing.value.price, + preorderThreshold: listing.value.preorderThreshold })) } }); @@ -185,6 +201,13 @@ export const ProductVariant: React.FC = ({ return ; } + const [ + deactivatePreorder, + deactivatePreoderOpts + ] = useProductVariantPreorderDeactivateMutation({}); + const handleDeactivateVariantPreorder = async (id: string) => + deactivatePreorder({ variables: { id } }); + const [ reorderProductVariants, reorderProductVariantsOpts @@ -204,6 +227,7 @@ export const ProductVariant: React.FC = ({ updateVariantOpts.loading || assignMediaOpts.loading || unassignMediaOpts.loading || + deactivatePreoderOpts.loading || reorderProductVariantsOpts.loading || deleteAttributeValueOpts.loading; @@ -256,6 +280,12 @@ export const ProductVariant: React.FC = ({ sku: data.sku, stocks: data.updateStocks.map(mapFormsetStockToStockInput), trackInventory: data.trackInventory, + preorder: data.isPreorder + ? { + globalThreshold: data.globalThreshold, + endDate: data?.preorderEndDateTime || null + } + : null, weight: weight(data.weight), firstValues: 10 } @@ -359,6 +389,8 @@ export const ProductVariant: React.FC = ({ onVariantClick={variantId => { navigate(productVariantEditUrl(productId, variantId)); }} + onVariantPreorderDeactivate={handleDeactivateVariantPreorder} + variantDeactivatePreoderButtonState={deactivatePreoderOpts.status} onVariantReorder={handleVariantReorder} assignReferencesAttributeId={ params.action === "assign-attribute-value" && params.id diff --git a/src/products/views/ProductVariantCreate.tsx b/src/products/views/ProductVariantCreate.tsx index fa2e0a0f1..701ec28f0 100644 --- a/src/products/views/ProductVariantCreate.tsx +++ b/src/products/views/ProductVariantCreate.tsx @@ -3,7 +3,6 @@ import { handleUploadMultipleFiles, prepareAttributesInput } from "@saleor/attributes/utils/handlers"; -import { ChannelPriceData } from "@saleor/channels/utils"; import { AttributeInput } from "@saleor/components/Attributes"; import NotFoundPage from "@saleor/components/NotFoundPage"; import { WindowTitle } from "@saleor/components/WindowTitle"; @@ -73,16 +72,6 @@ export const ProductVariant: React.FC = ({ const product = data?.product; - const channels: ChannelPriceData[] = product?.channelListings.map( - listing => ({ - costPrice: null, - currency: listing.channel.currencyCode, - id: listing.channel.id, - name: listing.channel.name, - price: null - }) - ); - const [variantCreate, variantCreateResult] = useVariantCreateMutation({}); const [updateMetadata] = useMetadataUpdate({}); @@ -129,7 +118,11 @@ export const ProductVariant: React.FC = ({ warehouse: stock.id })), trackInventory: true, - weight: weight(formData.weight) + weight: weight(formData.weight), + preorder: { + globalThreshold: formData.globalThreshold, + endDate: formData.preorderEndDateTime + } }, firstValues: 10 } @@ -210,7 +203,6 @@ export const ProductVariant: React.FC = ({ })} /> +
@@ -195022,6 +195056,40 @@ exports[`Storyshots Views / Products / Create product variant default 1`] = `
+
@@ -195972,6 +196040,40 @@ exports[`Storyshots Views / Products / Create product variant no warehouses 1`]
+
@@ -196664,6 +196766,42 @@ exports[`Storyshots Views / Products / Create product variant when loading data
+
@@ -197626,6 +197764,40 @@ exports[`Storyshots Views / Products / Create product variant with errors 1`] =

+
@@ -205235,9 +205407,6 @@ exports[`Storyshots Views / Products / Product edit no stock and no variants 1`]
-
@@ -205283,110 +205447,81 @@ exports[`Storyshots Views / Products / Product edit no stock and no variants 1`] class="Hr-root-id" />
+ Set up an end date of preorder. When end date will be reached product will be automatically taken from preorder to standard selling +
+ +
+ Preordered products will be available in all warehouses. You can set a threshold for sold quantity. Leaving input blank will be interpreted as no limit to sale. Sold items will be allocated at the warehouse assigned to chosen shipping zone. +
+
- - Quantity - + +
+ + +
+

+ Threshold that cannot be exceeded even if per channel thresholds are still available +

- - - - - - - - - - - - - - - - - - - -
- Warehouse Name - - Allocated - - Quantity - -
-
- Assign Warehouse -
-
-
- -
-
-
@@ -206894,28 +207021,79 @@ exports[`Storyshots Views / Products / Product edit no stock, no variants and no class="Hr-root-id" />
-
+
+ SETUP END DATE + + +
+ Preordered products will be available in all warehouses. You can set a threshold for sold quantity. Leaving input blank will be interpreted as no limit to sale. Sold items will be allocated at the warehouse assigned to chosen shipping zone.
- There are no warehouses set up for your store. To add stock quantity to the product please - - configure a warehouse - + +
+ + +
+

+ Threshold that cannot be exceeded even if per channel thresholds are still available +

+
@@ -208377,9 +208555,6 @@ exports[`Storyshots Views / Products / Product edit no variants 1`] = ` -
@@ -208425,252 +208595,81 @@ exports[`Storyshots Views / Products / Product edit no variants 1`] = ` class="Hr-root-id" />
+ Set up an end date of preorder. When end date will be reached product will be automatically taken from preorder to standard selling +
+ +
+ Preordered products will be available in all warehouses. You can set a threshold for sold quantity. Leaving input blank will be interpreted as no limit to sale. Sold items will be allocated at the warehouse assigned to chosen shipping zone. +
+
- - Quantity - + +
+ + +
+

+ Threshold that cannot be exceeded even if per channel thresholds are still available +

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Warehouse Name - - Allocated - - Quantity - -
- C our wares - - 0 - -
-
- - -
-
-
- -
- Be stocked - - 2 - -
-
- - -
-
-
- -
-
- Assign Warehouse -
-
-
- -
-
+
@@ -214472,9 +214507,6 @@ exports[`Storyshots Views / Products / Product edit when product has no variants
-
@@ -214520,252 +214547,81 @@ exports[`Storyshots Views / Products / Product edit when product has no variants class="Hr-root-id" />
+ Set up an end date of preorder. When end date will be reached product will be automatically taken from preorder to standard selling +
+ +
+ Preordered products will be available in all warehouses. You can set a threshold for sold quantity. Leaving input blank will be interpreted as no limit to sale. Sold items will be allocated at the warehouse assigned to chosen shipping zone. +
+
- - Quantity - + +
+ + +
+

+ Threshold that cannot be exceeded even if per channel thresholds are still available +

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Warehouse Name - - Allocated - - Quantity - -
- C our wares - - 0 - -
-
- - -
-
-
- -
- Be stocked - - 2 - -
-
- - -
-
-
- -
-
- Assign Warehouse -
-
-
- -
-
-
@@ -232297,17 +232145,83 @@ exports[`Storyshots Views / Products / Product variant details attribute errors class="Hr-root-id" />
+ Set up an end date of preorder. When end date will be reached product will be automatically taken from preorder to standard selling +
+ +
+ Preordered products will be available in all warehouses. You can set a threshold for sold quantity. Leaving input blank will be interpreted as no limit to sale. Sold items will be allocated at the warehouse assigned to chosen shipping zone. +
+
- - Quantity - + +
+ + +
+

+ Threshold that cannot be exceeded even if per channel thresholds are still available +

+
+
+ Unlimited
@@ -232319,10 +232233,10 @@ exports[`Storyshots Views / Products / Product variant details attribute errors class="ProductStocks-colName-id" /> - Warehouse Name + Channels - Allocated + Sold units - Quantity + Channel threshold - - Warehouse 1 + Test channel - 1 + 0