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
+ }
+ })
+ }
+ />
+
+ )}
+
+ onFormDataChange({
+ target: {
+ name: "hasPreorderEndDate",
+ value: !data.hasPreorderEndDate
+ }
+ })
+ }
+ >
+ {data.hasPreorderEndDate
+ ? intl.formatMessage({ defaultMessage: "CANCEL END DATE" })
+ : intl.formatMessage({ defaultMessage: "SETUP END DATE" })}
+
+
+ {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 = ({
})}
/>
+
+
+
+
+
+
+
+
+
+
+ Variant currently in preorder
+
+
@@ -195022,6 +195056,40 @@ exports[`Storyshots Views / Products / Create product variant default 1`] = `
+
+
+
+
+
+
+
+
+
+
+ Variant currently in preorder
+
+
@@ -195972,6 +196040,40 @@ exports[`Storyshots Views / Products / Create product variant no warehouses 1`]
+
+
+
+
+
+
+
+
+
+
+ Variant currently in preorder
+
+
@@ -196664,6 +196766,42 @@ exports[`Storyshots Views / Products / Create product variant when loading data
+
+
+
+
+
+
+
+
+
+
+ Variant currently in preorder
+
+
@@ -197626,6 +197764,40 @@ exports[`Storyshots Views / Products / Create product variant with errors 1`] =
+
+
+
+
+
+
+
+
+
+
+ Variant currently in preorder
+
+
@@ -205235,9 +205407,6 @@ exports[`Storyshots Views / Products / Product edit no stock and no variants 1`]
-
@@ -205252,7 +205421,7 @@ exports[`Storyshots Views / Products / Product edit no stock and no variants 1`]
checked=""
class="PrivateSwitchBase-input-id"
data-indeterminate="false"
- name="trackInventory"
+ name="isPreorder"
type="checkbox"
/>
- Track Inventory
-
- Active inventory tracking will automatically calculate changes of stock
-
+ Variant currently in preorder
@@ -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
+
+
+
+ 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.
+
+
-
-
-
-
-
-
-
-
-
- Warehouse Name
-
-
- Allocated
-
-
- Quantity
-
-
-
-
-
-
-
-
- Assign Warehouse
-
-
-
-
-
-
-
-
-
@@ -206863,7 +206995,7 @@ exports[`Storyshots Views / Products / Product edit no stock, no variants and no
checked=""
class="PrivateSwitchBase-input-id"
data-indeterminate="false"
- name="trackInventory"
+ name="isPreorder"
type="checkbox"
/>
- Track Inventory
-
- Active inventory tracking will automatically calculate changes of stock
-
+ Variant currently in preorder
@@ -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
-
+
+ Global threshold
+
+ *
+
+
+
+
+
+
+
+ Global threshold *
+
+
+
+
+
+ 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`] = `
-
@@ -208394,7 +208569,7 @@ exports[`Storyshots Views / Products / Product edit no variants 1`] = `
checked=""
class="PrivateSwitchBase-input-id"
data-indeterminate="false"
- name="trackInventory"
+ name="isPreorder"
type="checkbox"
/>
- Track Inventory
-
- Active inventory tracking will automatically calculate changes of stock
-
+ Variant currently in preorder
@@ -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
+
+
+
+ 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.
+
+
-
-
-
-
-
-
-
-
-
- Warehouse Name
-
-
- Allocated
-
-
- Quantity
-
-
-
-
-
-
-
- C our wares
-
-
- 0
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Be stocked
-
-
- 2
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Assign Warehouse
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+ Variant currently in preorder
+
+
@@ -214472,9 +214507,6 @@ exports[`Storyshots Views / Products / Product edit when product has no variants
-
@@ -214489,7 +214521,7 @@ exports[`Storyshots Views / Products / Product edit when product has no variants
checked=""
class="PrivateSwitchBase-input-id"
data-indeterminate="false"
- name="trackInventory"
+ name="isPreorder"
type="checkbox"
/>
- Track Inventory
-
- Active inventory tracking will automatically calculate changes of stock
-
+ Variant currently in preorder
@@ -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
+
+
+
+ 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.
+
+
-
-
-
-
-
-
-
-
-
- Warehouse Name
-
-
- Allocated
-
-
- Quantity
-
-
-
-
-
-
-
- C our wares
-
-
- 0
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Be stocked
-
-
- 2
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Assign Warehouse
-
-
-
-
-
-
-
-
-
@@ -232266,7 +232119,7 @@ exports[`Storyshots Views / Products / Product variant details attribute errors
checked=""
class="PrivateSwitchBase-input-id"
data-indeterminate="false"
- name="trackInventory"
+ name="isPreorder"
type="checkbox"
/>
- Track Inventory
-
- Active inventory tracking will automatically calculate changes of stock
-
+ Variant currently in preorder
@@ -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
+
+
+
+ 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.
+
+
@@ -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
-
-
-
-
-
-
-
-
-
- Warehouse 2
+ Test channel other
- 2
+ 0
-
-
-
-
-
-
-
-
-
-
-
-
-
- Assign Warehouse
-
-
-
-
-
@@ -234146,9 +233969,6 @@ exports[`Storyshots Views / Products / Product variant details no warehouses 1`]
-
@@ -234163,7 +233983,7 @@ exports[`Storyshots Views / Products / Product variant details no warehouses 1`]
checked=""
class="PrivateSwitchBase-input-id"
data-indeterminate="false"
- name="trackInventory"
+ name="isPreorder"
type="checkbox"
/>
- Track Inventory
-
- Active inventory tracking will automatically calculate changes of stock
-
+ Variant currently in preorder
@@ -234194,30 +234009,227 @@ exports[`Storyshots Views / Products / Product variant details no warehouses 1`]
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 variant please
-
- configure a warehouse
-
+
+ Global threshold
+
+ *
+
+
+
+
+
+
+
+ Global threshold *
+
+
+
+
+
+ Threshold that cannot be exceeded even if per channel thresholds are still available
+
+
+
+ Unlimited
+
+
+
+
+
+
+
+
+
+
+ Channels
+
+
+ Sold units
+
+
+ Channel threshold
+
+
+
+
+
+
+ Test channel
+
+
+ 0
+
+
+
+
+
+
+
+ Test channel other
+
+
+ 0
+
+
+
+
+
+
+
-
@@ -235838,7 +235847,7 @@ exports[`Storyshots Views / Products / Product variant details when loaded data
checked=""
class="PrivateSwitchBase-input-id"
data-indeterminate="false"
- name="trackInventory"
+ name="isPreorder"
type="checkbox"
/>
- Track Inventory
-
- Active inventory tracking will automatically calculate changes of stock
-
+ Variant currently in preorder
@@ -235869,17 +235873,83 @@ exports[`Storyshots Views / Products / Product variant details when loaded data
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
+
+
+
+ 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.
+
+
@@ -235891,10 +235961,10 @@ exports[`Storyshots Views / Products / Product variant details when loaded data
class="ProductStocks-colName-id"
/>
- Warehouse Name
+ Channels
- Allocated
+ Sold units
- Quantity
+ Channel threshold
-
- Warehouse 1
+ Test channel
- 1
+ 0
-
-
-
-
-
-
-
-
-
- Warehouse 2
+ Test channel other
- 2
+ 0
-
-
-
-
-
-
-
-
-
-
-
-
-
- Assign Warehouse
-
-
-
-
-
@@ -236953,6 +236932,42 @@ exports[`Storyshots Views / Products / Product variant details when loading data
+
+
+
+
+
+
+
+
+
+
+ Variant currently in preorder
+
+
diff --git a/src/storybook/stories/products/ProductVariantCreatePage.tsx b/src/storybook/stories/products/ProductVariantCreatePage.tsx
index e8d91c94d..c7a77c6d2 100644
--- a/src/storybook/stories/products/ProductVariantCreatePage.tsx
+++ b/src/storybook/stories/products/ProductVariantCreatePage.tsx
@@ -9,19 +9,11 @@ import { product as productFixture } from "../../../products/fixtures";
import Decorator from "../../Decorator";
const product = productFixture(placeholderImage);
-const channels = product.channelListings.map(listing => ({
- costPrice: null,
- currency: listing.channel.currencyCode,
- id: listing.channel.id,
- name: listing.channel.name,
- price: null
-}));
storiesOf("Views / Products / Create product variant", module)
.addDecorator(Decorator)
.add("default", () => (
(
(
(
(
undefined}
onVariantReorder={() => undefined}
saveButtonBarState="default"
+ variantDeactivatePreoderButtonState="default"
warehouses={warehouseList}
onWarehouseConfigure={() => undefined}
referencePages={[]}
@@ -40,6 +41,7 @@ storiesOf("Views / Products / Product variant details", module)
onAssignReferencesClick={() => undefined}
onCloseDialog={() => undefined}
onAttributeSelectBlur={() => undefined}
+ onVariantPreorderDeactivate={() => undefined}
/>
))
.add("when loading data", () => (
@@ -60,6 +62,7 @@ storiesOf("Views / Products / Product variant details", module)
onVariantClick={() => undefined}
onVariantReorder={() => undefined}
saveButtonBarState="default"
+ variantDeactivatePreoderButtonState="default"
warehouses={warehouseList}
onWarehouseConfigure={() => undefined}
referencePages={[]}
@@ -69,6 +72,7 @@ storiesOf("Views / Products / Product variant details", module)
onAssignReferencesClick={() => undefined}
onCloseDialog={() => undefined}
onAttributeSelectBlur={() => undefined}
+ onVariantPreorderDeactivate={() => undefined}
/>
))
.add("no warehouses", () => (
@@ -88,6 +92,7 @@ storiesOf("Views / Products / Product variant details", module)
onVariantClick={() => undefined}
onVariantReorder={() => undefined}
saveButtonBarState="default"
+ variantDeactivatePreoderButtonState="default"
warehouses={[]}
onWarehouseConfigure={() => undefined}
referencePages={[]}
@@ -97,6 +102,7 @@ storiesOf("Views / Products / Product variant details", module)
onAssignReferencesClick={() => undefined}
onCloseDialog={() => undefined}
onAttributeSelectBlur={() => undefined}
+ onVariantPreorderDeactivate={() => undefined}
/>
))
.add("attribute errors", () => (
@@ -114,6 +120,7 @@ storiesOf("Views / Products / Product variant details", module)
onVariantClick={() => undefined}
onVariantReorder={() => undefined}
saveButtonBarState="default"
+ variantDeactivatePreoderButtonState="default"
errors={[
{
attributes: [variant.selectionAttributes[0].attribute.id],
@@ -153,5 +160,6 @@ storiesOf("Views / Products / Product variant details", module)
onAssignReferencesClick={() => undefined}
onCloseDialog={() => undefined}
onAttributeSelectBlur={() => undefined}
+ onVariantPreorderDeactivate={() => undefined}
/>
));
diff --git a/src/types/globalTypes.ts b/src/types/globalTypes.ts
index 96b9f897f..750f038e9 100644
--- a/src/types/globalTypes.ts
+++ b/src/types/globalTypes.ts
@@ -1628,6 +1628,7 @@ export enum ProductErrorCode {
NOT_FOUND = "NOT_FOUND",
NOT_PRODUCTS_IMAGE = "NOT_PRODUCTS_IMAGE",
NOT_PRODUCTS_VARIANT = "NOT_PRODUCTS_VARIANT",
+ PREORDER_VARIANT_CANNOT_BE_DEACTIVATED = "PREORDER_VARIANT_CANNOT_BE_DEACTIVATED",
PRODUCT_NOT_ASSIGNED_TO_CHANNEL = "PRODUCT_NOT_ASSIGNED_TO_CHANNEL",
PRODUCT_WITHOUT_CATEGORY = "PRODUCT_WITHOUT_CATEGORY",
REQUIRED = "REQUIRED",
@@ -2497,6 +2498,11 @@ export interface PluginUpdateInput {
configuration?: (ConfigurationItemInput | null)[] | null;
}
+export interface PreorderSettingsInput {
+ globalThreshold?: number | null;
+ endDate?: any | null;
+}
+
export interface PriceInput {
currency: string;
amount: any;
@@ -2558,6 +2564,7 @@ export interface ProductFilterInput {
productTypes?: (string | null)[] | null;
giftCard?: boolean | null;
ids?: (string | null)[] | null;
+ hasPreorderedVariants?: boolean | null;
channel?: string | null;
}
@@ -2619,6 +2626,7 @@ export interface ProductVariantBulkCreateInput {
sku?: string | null;
trackInventory?: boolean | null;
weight?: any | null;
+ preorder?: PreorderSettingsInput | null;
stocks?: StockInput[] | null;
channelListings?: ProductVariantChannelListingAddInput[] | null;
}
@@ -2627,6 +2635,7 @@ export interface ProductVariantChannelListingAddInput {
channelId: string;
price: any;
costPrice?: any | null;
+ preorderThreshold?: number | null;
}
export interface ProductVariantCreateInput {
@@ -2634,6 +2643,7 @@ export interface ProductVariantCreateInput {
sku?: string | null;
trackInventory?: boolean | null;
weight?: any | null;
+ preorder?: PreorderSettingsInput | null;
product: string;
stocks?: StockInput[] | null;
}
@@ -2643,6 +2653,7 @@ export interface ProductVariantInput {
sku?: string | null;
trackInventory?: boolean | null;
weight?: any | null;
+ preorder?: PreorderSettingsInput | null;
}
export interface PublishableChannelListingInput {