Preorders (#1426)
* Feed preorder data to product variant forms * Add end preorder date input and handle date data * Translate strings, refactor date parsing * Fix snapshots * CR response * CR response * CR response * Fix negative threshold, product variant preorder toggle, product variant update, and simple product creation * Make preorder data optional * Prevent setting past date as preorder end * Disable replacing preorder variant in order * Adjust fulfill view to preorder in variant * CR response + prevent subbmiting form when endPreorderDate is in the past and display warning * Add ErrorNoticeBar * Translate preorder end date in past error message, fix form submissison disabling logic * Rebase fixes * Fix preorder form disabling logic, remove isPreorder field * Fix edge cases aroud preorder inputs * Update storyshots
This commit is contained in:
parent
6ddb537445
commit
25f7c8e4d8
82 changed files with 2714 additions and 1074 deletions
|
@ -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"
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
};
|
||||
}
|
||||
) || [];
|
||||
|
|
87
src/components/DateTimeTimezoneField.tsx
Normal file
87
src/components/DateTimeTimezoneField.tsx
Normal file
|
@ -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<TextFieldProps, "label" | "error"> & {
|
||||
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<DateTimeFieldProps> = ({
|
||||
disabled,
|
||||
name,
|
||||
onChange,
|
||||
error,
|
||||
fullWidth,
|
||||
value: initialValue
|
||||
}) => {
|
||||
const classes = useStyles({});
|
||||
const intl = useIntl();
|
||||
const [value, setValue] = useState<DateTime>(
|
||||
initialValue ? splitDateTime(initialValue) : { date: "", time: "" }
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const newDate = joinDateTime(value.date, value.time);
|
||||
onChange(newDate);
|
||||
}, [value]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<TextField
|
||||
className={classes.dateInput}
|
||||
fullWidth={fullWidth}
|
||||
disabled={disabled}
|
||||
error={!!error}
|
||||
label={intl.formatMessage(commonMessages.date)}
|
||||
name={`${name}:date`}
|
||||
onChange={event => {
|
||||
const date = event.target.value;
|
||||
setValue(value => ({ ...value, date }));
|
||||
}}
|
||||
type="date"
|
||||
value={value.date}
|
||||
InputLabelProps={{ shrink: true }}
|
||||
/>
|
||||
<TextField
|
||||
fullWidth={fullWidth}
|
||||
disabled={disabled}
|
||||
error={!!error}
|
||||
label={intl.formatMessage(commonMessages.time)}
|
||||
name={`${name}:time`}
|
||||
onChange={event => {
|
||||
const time = event.target.value;
|
||||
setValue(value => ({ ...value, time }));
|
||||
}}
|
||||
type="time"
|
||||
value={value.time}
|
||||
InputLabelProps={{ shrink: true }}
|
||||
/>
|
||||
|
||||
{error && (
|
||||
<ErrorNoticeBar className={classes.errorNoticeBar} message={error} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
34
src/components/ErrorNoticeBar/ErrorNoticeBar.tsx
Normal file
34
src/components/ErrorNoticeBar/ErrorNoticeBar.tsx
Normal file
|
@ -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<ErrorNoticeBarProps> = props => {
|
||||
const { className, message } = props;
|
||||
const classes = useStyles(props);
|
||||
|
||||
return (
|
||||
<Card className={classNames(classes.root, className)}>
|
||||
<CardContent>
|
||||
<Typography variant="body1">{message}</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
ErrorNoticeBar.displayName = "ErrorNoticeBar";
|
||||
export default ErrorNoticeBar;
|
1
src/components/ErrorNoticeBar/index.ts
Normal file
1
src/components/ErrorNoticeBar/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export { default } from "./ErrorNoticeBar";
|
|
@ -81,6 +81,9 @@ export const fragmentOrderLine = gql`
|
|||
variant {
|
||||
id
|
||||
quantityAvailable
|
||||
preorder {
|
||||
endDate
|
||||
}
|
||||
}
|
||||
productName
|
||||
productSku
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
15
src/fragments/types/PreorderFragment.ts
Normal file
15
src/fragments/types/PreorderFragment.ts
Normal file
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -296,6 +296,7 @@ const OrderFulfillPage: React.FC<OrderFulfillPageProps> = props => {
|
|||
0
|
||||
);
|
||||
const overfulfill = remainingQuantity < quantityToFulfill;
|
||||
const isPreorder = !!line.variant?.preorder;
|
||||
|
||||
return (
|
||||
<TableRow key={line.id}>
|
||||
|
@ -318,6 +319,18 @@ const OrderFulfillPage: React.FC<OrderFulfillPageProps> = props => {
|
|||
{line.variant?.sku}
|
||||
</TableCell>
|
||||
{warehouses?.map(warehouse => {
|
||||
if (isPreorder) {
|
||||
return (
|
||||
<TableCell
|
||||
key="skeleton"
|
||||
className={classNames(
|
||||
classes.colQuantity,
|
||||
classes.error
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const warehouseStock = line.variant?.stocks?.find(
|
||||
stock => stock.warehouse.id === warehouse.id
|
||||
);
|
||||
|
@ -419,16 +432,20 @@ const OrderFulfillPage: React.FC<OrderFulfillPageProps> = props => {
|
|||
className={classes.colQuantityTotal}
|
||||
key="total"
|
||||
>
|
||||
<span
|
||||
className={classNames({
|
||||
[classes.error]: overfulfill,
|
||||
[classes.full]:
|
||||
remainingQuantity <= quantityToFulfill
|
||||
})}
|
||||
>
|
||||
{quantityToFulfill}
|
||||
</span>{" "}
|
||||
/ {remainingQuantity}
|
||||
{!isPreorder && (
|
||||
<>
|
||||
<span
|
||||
className={classNames({
|
||||
[classes.error]: overfulfill,
|
||||
[classes.full]:
|
||||
remainingQuantity <= quantityToFulfill
|
||||
})}
|
||||
>
|
||||
{quantityToFulfill}
|
||||
</span>{" "}
|
||||
/ {remainingQuantity}
|
||||
</>
|
||||
)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -175,6 +175,7 @@ const ItemsCard: React.FC<OrderReturnRefundLinesCardProps> = ({
|
|||
.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<OrderReturnRefundLinesCardProps> = ({
|
|||
)}
|
||||
</TableCell>
|
||||
<TableCell align="center">
|
||||
{isReplacable && (
|
||||
{isReplacable && !isPreorder && (
|
||||
<Checkbox
|
||||
checked={isSelected}
|
||||
onChange={() => onChangeSelected(id, !isSelected)}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -254,6 +254,9 @@ const orderFulfillData = gql`
|
|||
id
|
||||
name
|
||||
sku
|
||||
preorder {
|
||||
endDate
|
||||
}
|
||||
attributes {
|
||||
values {
|
||||
id
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -203,6 +203,7 @@ export const ProductCreatePage: React.FC<ProductCreatePageProps> = ({
|
|||
{({
|
||||
change,
|
||||
data,
|
||||
formErrors,
|
||||
disabled: formDisabled,
|
||||
handlers,
|
||||
hasChanged,
|
||||
|
@ -269,9 +270,11 @@ export const ProductCreatePage: React.FC<ProductCreatePageProps> = ({
|
|||
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}
|
||||
|
|
|
@ -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<ReorderEvent>>,
|
||||
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<ProductCreateData>;
|
||||
disabled: boolean;
|
||||
handlers: ProductCreateHandlers;
|
||||
hasChanged: boolean;
|
||||
|
@ -151,6 +161,7 @@ function useProductCreateForm(
|
|||
onSubmit: (data: ProductCreateData) => Promise<boolean>,
|
||||
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,
|
||||
|
|
|
@ -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<ProductVariantCreateData>
|
||||
| FormErrors<ProductVariantUpdateData>
|
||||
| FormErrors<ProductUpdateSubmitData>
|
||||
| FormErrors<ProductCreateData>;
|
||||
hasVariants: boolean;
|
||||
stocks: ProductStockInput[];
|
||||
warehouses: WarehouseFragment[];
|
||||
onVariantChannelListingChange?: (
|
||||
id: string,
|
||||
data: Partial<ChannelPriceAndPreorderArgs>
|
||||
) => 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<ProductStocksProps> = ({
|
|||
disabled,
|
||||
hasVariants,
|
||||
errors,
|
||||
formErrors: localFormErrors,
|
||||
onChangePreorderEndDate,
|
||||
stocks,
|
||||
warehouses,
|
||||
productVariantChannelListings = [],
|
||||
onChange,
|
||||
onEndPreorderTrigger,
|
||||
onFormDataChange,
|
||||
onVariantChannelListingChange,
|
||||
onWarehouseStockAdd,
|
||||
onWarehouseStockDelete,
|
||||
onWarehouseConfigure
|
||||
|
@ -131,6 +201,7 @@ const ProductStocks: React.FC<ProductStocksProps> = ({
|
|||
const intl = useIntl();
|
||||
const anchor = React.useRef<HTMLDivElement>();
|
||||
const [isExpanded, setExpansionState] = React.useState(false);
|
||||
const unitsLeft = data.globalThreshold - data.globalSoldUnits;
|
||||
|
||||
const warehousesToAssign =
|
||||
warehouses?.filter(
|
||||
|
@ -138,6 +209,10 @@ const ProductStocks: React.FC<ProductStocksProps> = ({
|
|||
) || [];
|
||||
const formErrors = getFormErrors(["sku"], errors);
|
||||
|
||||
const onThresholdChange = createNonNegativeValueChangeHandler(
|
||||
onFormDataChange
|
||||
);
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardTitle
|
||||
|
@ -162,70 +237,97 @@ const ProductStocks: React.FC<ProductStocksProps> = ({
|
|||
value={data.sku}
|
||||
/>
|
||||
</div>
|
||||
<FormSpacer />
|
||||
<ControlledCheckbox
|
||||
checked={data.trackInventory}
|
||||
name="trackInventory"
|
||||
onChange={onFormDataChange}
|
||||
checked={data.isPreorder}
|
||||
name="isPreorder"
|
||||
onChange={
|
||||
onEndPreorderTrigger && data.isPreorder
|
||||
? onEndPreorderTrigger
|
||||
: onFormDataChange
|
||||
}
|
||||
disabled={disabled}
|
||||
label={
|
||||
<>
|
||||
<FormattedMessage
|
||||
defaultMessage="Track Inventory"
|
||||
description="product inventory, checkbox"
|
||||
/>
|
||||
<Typography variant="caption">
|
||||
<FormattedMessage defaultMessage="Active inventory tracking will automatically calculate changes of stock" />
|
||||
</Typography>
|
||||
</>
|
||||
<FormattedMessage
|
||||
defaultMessage="Variant currently in preorder"
|
||||
description="product inventory, checkbox"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</CardContent>
|
||||
<Hr />
|
||||
<CardContent className={classes.quantityContainer}>
|
||||
<Typography>
|
||||
<div className={classes.quantityHeader}>
|
||||
<span>
|
||||
<FormattedMessage
|
||||
defaultMessage="Quantity"
|
||||
description="header"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</Typography>
|
||||
{!warehouses?.length && (
|
||||
<Typography color="textSecondary" className={classes.noWarehouseInfo}>
|
||||
{hasVariants ? (
|
||||
<>
|
||||
<FormattedMessage
|
||||
defaultMessage="There are no warehouses set up for your store. To add stock quantity to the variant please <a>configure a warehouse</a>"
|
||||
description="no warehouses info"
|
||||
id="productVariantWarehouseSectionDescription"
|
||||
values={{
|
||||
a: chunks => (
|
||||
<Link onClick={onWarehouseConfigure}>{chunks}</Link>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<FormattedMessage
|
||||
defaultMessage="There are no warehouses set up for your store. To add stock quantity to the product please <a>configure a warehouse</a>"
|
||||
description="no warehouses info"
|
||||
id="productWarehouseSectionDescription"
|
||||
values={{
|
||||
a: chunks => (
|
||||
<Link onClick={onWarehouseConfigure}>{chunks}</Link>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Typography>
|
||||
|
||||
{!data.isPreorder && (
|
||||
<>
|
||||
<FormSpacer />
|
||||
<ControlledCheckbox
|
||||
checked={data.trackInventory}
|
||||
name="trackInventory"
|
||||
onChange={onFormDataChange}
|
||||
disabled={disabled}
|
||||
label={
|
||||
<>
|
||||
<FormattedMessage
|
||||
defaultMessage="Track Inventory"
|
||||
description="product inventory, checkbox"
|
||||
/>
|
||||
<Typography variant="caption">
|
||||
<FormattedMessage defaultMessage="Active inventory tracking will automatically calculate changes of stock" />
|
||||
</Typography>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</CardContent>
|
||||
{warehouses?.length > 0 && (
|
||||
<Hr />
|
||||
{!data.isPreorder && (
|
||||
<CardContent className={classes.quantityContainer}>
|
||||
<Typography>
|
||||
<div className={classes.quantityHeader}>
|
||||
<span>
|
||||
<FormattedMessage
|
||||
defaultMessage="Quantity"
|
||||
description="header"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</Typography>
|
||||
|
||||
{!warehouses?.length && (
|
||||
<Typography
|
||||
color="textSecondary"
|
||||
className={classes.noWarehouseInfo}
|
||||
>
|
||||
{hasVariants ? (
|
||||
<>
|
||||
<FormattedMessage
|
||||
defaultMessage="There are no warehouses set up for your store. To add stock quantity to the variant please <a>configure a warehouse</a>"
|
||||
description="no warehouses info"
|
||||
id="productVariantWarehouseSectionDescription"
|
||||
values={{
|
||||
a: chunks => (
|
||||
<Link onClick={onWarehouseConfigure}>{chunks}</Link>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<FormattedMessage
|
||||
defaultMessage="There are no warehouses set up for your store. To add stock quantity to the product please <a>configure a warehouse</a>"
|
||||
description="no warehouses info"
|
||||
id="productWarehouseSectionDescription"
|
||||
values={{
|
||||
a: chunks => (
|
||||
<Link onClick={onWarehouseConfigure}>{chunks}</Link>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Typography>
|
||||
)}
|
||||
</CardContent>
|
||||
)}
|
||||
{warehouses?.length > 0 && !data.isPreorder && (
|
||||
<Table>
|
||||
<colgroup>
|
||||
<col className={classes.colName} />
|
||||
|
@ -354,6 +456,181 @@ const ProductStocks: React.FC<ProductStocksProps> = ({
|
|||
</TableBody>
|
||||
</Table>
|
||||
)}
|
||||
{data.isPreorder && (
|
||||
<CardContent>
|
||||
<Typography variant="caption" className={classes.caption}>
|
||||
{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"
|
||||
})}
|
||||
</Typography>
|
||||
|
||||
{data.hasPreorderEndDate && (
|
||||
<div className={classes.dateTimeInputs}>
|
||||
<DateTimeTimezoneField
|
||||
name={"preorderEndDateTime"}
|
||||
disabled={disabled}
|
||||
futureDatesOnly
|
||||
fullWidth={false}
|
||||
error={localFormErrors.preorderEndDateTime}
|
||||
value={data?.preorderEndDateTime}
|
||||
onChange={event =>
|
||||
onChangePreorderEndDate({
|
||||
target: {
|
||||
name: "preorderEndDateTime",
|
||||
value: event
|
||||
}
|
||||
})
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<Button
|
||||
name="hasPreorderEndDate"
|
||||
color="primary"
|
||||
variant="text"
|
||||
disabled={disabled}
|
||||
onClick={() =>
|
||||
onFormDataChange({
|
||||
target: {
|
||||
name: "hasPreorderEndDate",
|
||||
value: !data.hasPreorderEndDate
|
||||
}
|
||||
})
|
||||
}
|
||||
>
|
||||
{data.hasPreorderEndDate
|
||||
? intl.formatMessage({ defaultMessage: "CANCEL END DATE" })
|
||||
: intl.formatMessage({ defaultMessage: "SETUP END DATE" })}
|
||||
</Button>
|
||||
<Typography variant="caption" className={classes.preorderLimitInfo}>
|
||||
{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"
|
||||
})}
|
||||
</Typography>
|
||||
<div className={classes.thresholdRow}>
|
||||
<TextField
|
||||
inputProps={{
|
||||
min: 0
|
||||
}}
|
||||
disabled={disabled}
|
||||
fullWidth
|
||||
helperText={intl.formatMessage({
|
||||
defaultMessage:
|
||||
"Threshold that cannot be exceeded even if per channel thresholds are still available"
|
||||
})}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Global threshold"
|
||||
})}
|
||||
name="globalThreshold"
|
||||
required
|
||||
onChange={onThresholdChange}
|
||||
value={data.globalThreshold ?? ""}
|
||||
className={classes.thresholdInput}
|
||||
/>
|
||||
{productVariantChannelListings?.length > 0 && (
|
||||
<Typography
|
||||
variant="caption"
|
||||
className={classes.preorderItemsLeftCount}
|
||||
>
|
||||
{data.globalThreshold
|
||||
? intl.formatMessage(
|
||||
{
|
||||
defaultMessage: "{unitsLeft} units left",
|
||||
description: "app has been installed"
|
||||
},
|
||||
{ unitsLeft }
|
||||
)
|
||||
: intl.formatMessage({
|
||||
defaultMessage: "Unlimited",
|
||||
id: "unlimitedUnitsLeft",
|
||||
description: "section header"
|
||||
})}
|
||||
</Typography>
|
||||
)}
|
||||
</div>
|
||||
</CardContent>
|
||||
)}
|
||||
|
||||
{productVariantChannelListings?.length > 0 && data.isPreorder && (
|
||||
<Table>
|
||||
<colgroup>
|
||||
<col className={classes.colName} />
|
||||
<col className={classes.colSoldUnits} />
|
||||
<col className={classes.colThreshold} />
|
||||
</colgroup>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell className={classes.colName}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Channels"
|
||||
description="tabel column header"
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className={classes.colSoldUnits}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Sold units"
|
||||
description="table column header, sold units preorder quantity"
|
||||
id="tableColSoldUnits"
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className={classes.colThreshold}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Channel threshold"
|
||||
description="table column header"
|
||||
id="tableColChannelThreshold"
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{renderCollection(productVariantChannelListings, listing => {
|
||||
if (!listing) {
|
||||
return;
|
||||
}
|
||||
|
||||
return (
|
||||
<TableRow key={listing.id}>
|
||||
<TableCell className={classes.colName}>
|
||||
{listing.name}
|
||||
</TableCell>
|
||||
<TableCell className={classes.colQuantity}>
|
||||
{listing?.unitsSold || 0}
|
||||
</TableCell>
|
||||
<TableCell className={classes.colQuantity}>
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
fullWidth
|
||||
inputProps={{
|
||||
className: classes.input,
|
||||
min: 0,
|
||||
type: "number"
|
||||
}}
|
||||
placeholder={intl.formatMessage({
|
||||
defaultMessage: "Unlimited"
|
||||
})}
|
||||
onChange={e => {
|
||||
onVariantChannelListingChange(listing.id, {
|
||||
costPrice: listing.costPrice,
|
||||
price: listing.price,
|
||||
preorderThreshold:
|
||||
e.target.value === ""
|
||||
? undefined
|
||||
: Number(e.target.value)
|
||||
});
|
||||
}}
|
||||
value={listing?.preorderThreshold ?? ""}
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -286,6 +286,7 @@ export const ProductUpdatePage: React.FC<ProductUpdatePageProps> = ({
|
|||
{({
|
||||
change,
|
||||
data,
|
||||
formErrors,
|
||||
disabled: formDisabled,
|
||||
handlers,
|
||||
hasChanged,
|
||||
|
@ -380,14 +381,20 @@ export const ProductUpdatePage: React.FC<ProductUpdatePageProps> = ({
|
|||
/>
|
||||
<CardSpacer />
|
||||
<ProductStocks
|
||||
onVariantChannelListingChange={
|
||||
handlers.changeChannelPreorder
|
||||
}
|
||||
productVariantChannelListings={data.channelListings}
|
||||
data={data}
|
||||
disabled={disabled}
|
||||
hasVariants={false}
|
||||
errors={errors}
|
||||
formErrors={formErrors}
|
||||
stocks={data.stocks}
|
||||
warehouses={warehouses}
|
||||
onChange={handlers.changeStock}
|
||||
onFormDataChange={change}
|
||||
onChangePreorderEndDate={handlers.changePreorderEndDate}
|
||||
onWarehouseStockAdd={handlers.addStock}
|
||||
onWarehouseStockDelete={handlers.deleteStock}
|
||||
onWarehouseConfigure={onWarehouseConfigure}
|
||||
|
|
|
@ -9,18 +9,27 @@ import {
|
|||
createFetchMoreReferencesHandler,
|
||||
createFetchReferencesHandler
|
||||
} from "@saleor/attributes/utils/handlers";
|
||||
import { ChannelData, ChannelPriceArgs } from "@saleor/channels/utils";
|
||||
import {
|
||||
ChannelData,
|
||||
ChannelPreorderArgs,
|
||||
ChannelPriceArgs
|
||||
} from "@saleor/channels/utils";
|
||||
import { AttributeInput } from "@saleor/components/Attributes";
|
||||
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, SubmitPromise } from "@saleor/hooks/useForm";
|
||||
import useForm, {
|
||||
FormChange,
|
||||
FormErrors,
|
||||
SubmitPromise
|
||||
} from "@saleor/hooks/useForm";
|
||||
import useFormset, {
|
||||
FormsetAtomicData,
|
||||
FormsetChange,
|
||||
FormsetData
|
||||
} from "@saleor/hooks/useFormset";
|
||||
import { errorMessages } from "@saleor/intl";
|
||||
import { ProductDetails_product } from "@saleor/products/types/ProductDetails";
|
||||
import {
|
||||
getAttributeInputFromProduct,
|
||||
|
@ -29,7 +38,9 @@ import {
|
|||
} from "@saleor/products/utils/data";
|
||||
import {
|
||||
createChannelsChangeHandler,
|
||||
createChannelsPriceChangeHandler
|
||||
createChannelsPreorderChangeHandler,
|
||||
createChannelsPriceChangeHandler,
|
||||
createPreorderEndDateChangeHandler
|
||||
} from "@saleor/products/utils/handlers";
|
||||
import {
|
||||
validateCostPrice,
|
||||
|
@ -48,6 +59,7 @@ import getMetadata from "@saleor/utils/metadata/getMetadata";
|
|||
import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger";
|
||||
import useRichText from "@saleor/utils/richText/useRichText";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import { ProductStockFormsetData, ProductStockInput } from "../ProductStocks";
|
||||
|
||||
|
@ -68,6 +80,11 @@ export interface ProductUpdateFormData extends MetadataFormData {
|
|||
sku: string;
|
||||
taxCode: string;
|
||||
trackInventory: boolean;
|
||||
isPreorder: boolean;
|
||||
globalThreshold: number;
|
||||
globalSoldUnits: number;
|
||||
hasPreorderEndDate: boolean;
|
||||
preorderEndDateTime?: string;
|
||||
weight: string;
|
||||
}
|
||||
export interface FileAttributeInputData {
|
||||
|
@ -110,6 +127,10 @@ export interface ProductUpdateHandlers
|
|||
FormsetChange<string>
|
||||
>,
|
||||
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<ReorderEvent>>,
|
||||
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<ProductUpdateSubmitData>;
|
||||
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,
|
||||
|
|
|
@ -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<ProductVariantCreatePageProps> = ({
|
||||
channels,
|
||||
disabled,
|
||||
errors,
|
||||
header,
|
||||
|
@ -141,7 +138,6 @@ const ProductVariantCreatePage: React.FC<ProductVariantCreatePageProps> = ({
|
|||
product={product}
|
||||
onSubmit={onSubmit}
|
||||
warehouses={warehouses}
|
||||
currentChannels={channels}
|
||||
referencePages={referencePages}
|
||||
referenceProducts={referenceProducts}
|
||||
fetchReferencePages={fetchReferencePages}
|
||||
|
@ -153,6 +149,7 @@ const ProductVariantCreatePage: React.FC<ProductVariantCreatePageProps> = ({
|
|||
{({
|
||||
change,
|
||||
data,
|
||||
formErrors,
|
||||
disabled: formDisabled,
|
||||
handlers,
|
||||
hasChanged,
|
||||
|
@ -236,10 +233,12 @@ const ProductVariantCreatePage: React.FC<ProductVariantCreatePageProps> = ({
|
|||
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}
|
||||
|
|
|
@ -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<ReorderEvent>>,
|
||||
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<ProductVariantCreateData>;
|
||||
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,
|
||||
|
|
|
@ -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<ProductVariantEndPreorderDialogProps> = ({
|
||||
confirmButtonState,
|
||||
open,
|
||||
onClose,
|
||||
onConfirm,
|
||||
variantGlobalSoldUnits
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
|
||||
return (
|
||||
<ActionDialog
|
||||
confirmButtonLabel={intl.formatMessage(
|
||||
productVariantEndPreorderDialogMessages.dialogConfirmButtonLabel
|
||||
)}
|
||||
confirmButtonState={confirmButtonState}
|
||||
open={open}
|
||||
onClose={onClose}
|
||||
onConfirm={onConfirm}
|
||||
title={intl.formatMessage(
|
||||
productVariantEndPreorderDialogMessages.dialogTitle
|
||||
)}
|
||||
variant="default"
|
||||
>
|
||||
<DialogContentText>
|
||||
{intl.formatMessage(
|
||||
productVariantEndPreorderDialogMessages.dialogMessage,
|
||||
{
|
||||
variantGlobalSoldUnits
|
||||
}
|
||||
)}
|
||||
</DialogContentText>
|
||||
</ActionDialog>
|
||||
);
|
||||
};
|
||||
ProductVariantEndPreorderDialog.displayName = "ProductVariantEndPreorderDialog";
|
||||
export default ProductVariantEndPreorderDialog;
|
|
@ -0,0 +1,2 @@
|
|||
export * from "./ProductVariantEndPreorderDialog";
|
||||
export { default } from "./ProductVariantEndPreorderDialog";
|
|
@ -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"
|
||||
}
|
||||
});
|
|
@ -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<ProductVariantPageProps> = ({
|
|||
onMediaSelect,
|
||||
onSubmit,
|
||||
onVariantClick,
|
||||
onVariantPreorderDeactivate,
|
||||
variantDeactivatePreoderButtonState,
|
||||
onVariantReorder,
|
||||
onSetDefaultVariant,
|
||||
onWarehouseConfigure,
|
||||
|
@ -149,6 +154,11 @@ const ProductVariantPage: React.FC<ProductVariantPageProps> = ({
|
|||
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<ProductVariantPageProps> = ({
|
|||
|
||||
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<ProductVariantPageProps> = ({
|
|||
{({
|
||||
change,
|
||||
data,
|
||||
formErrors,
|
||||
disabled: formDisabled,
|
||||
handlers,
|
||||
hasChanged,
|
||||
|
@ -305,14 +321,28 @@ const ProductVariantPage: React.FC<ProductVariantPageProps> = ({
|
|||
/>
|
||||
<CardSpacer />
|
||||
<ProductStocks
|
||||
productVariantChannelListings={data.channelListings.map(
|
||||
channel => ({
|
||||
...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<ProductVariantPageProps> = ({
|
|||
selectedMedia={maybe(() => variant.media.map(image => image.id))}
|
||||
/>
|
||||
)}
|
||||
{!!variant?.preorder && (
|
||||
<ProductVariantEndPreorderDialog
|
||||
confirmButtonState={variantDeactivatePreoderButtonState}
|
||||
onClose={() => setIsEndPreorderModalOpened(false)}
|
||||
onConfirm={handleDeactivatePreorder}
|
||||
open={isEndPreorderModalOpened}
|
||||
variantGlobalSoldUnits={variant?.preorder?.globalSoldUnits}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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<ChannelPriceData, IChannelPriceArgs>;
|
||||
channelListings: FormsetData<
|
||||
ChannelPriceAndPreorderData,
|
||||
IChannelPriceAndPreorderArgs
|
||||
>;
|
||||
attributes: AttributeInput[];
|
||||
stocks: ProductStockInput[];
|
||||
}
|
||||
|
@ -54,14 +74,17 @@ export interface ProductVariantUpdateSubmitData
|
|||
attributes: AttributeInput[];
|
||||
attributesWithNewFileValue: FormsetData<null, File>;
|
||||
addStocks: ProductStockInput[];
|
||||
channelListings: FormsetData<ChannelPriceData, IChannelPriceArgs>;
|
||||
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<File>>,
|
||||
Record<"reorderAttributeValue", FormsetChange<ReorderEvent>>,
|
||||
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<ProductVariantUpdateData>;
|
||||
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,
|
||||
|
|
|
@ -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<ProductVariantPriceProps> = 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<ProductVariantPriceProps> = props => {
|
|||
onChange={e =>
|
||||
onChange(listing.id, {
|
||||
costPrice: e.target.value,
|
||||
price: listing.price
|
||||
price: listing.price,
|
||||
preorderThreshold: listing.preorderThreshold
|
||||
})
|
||||
}
|
||||
disabled={loading}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
43
src/products/types/ProductVariantPreorderDeactivate.ts
Normal file
43
src/products/types/ProductVariantPreorderDeactivate.ts
Normal file
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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") : "";
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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
|
||||
}));
|
||||
|
|
|
@ -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<ProductUpdateProps> = ({
|
|||
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<ProductUpdateProps> = ({
|
|||
return <NotFoundPage onBack={handleBack} />;
|
||||
}
|
||||
|
||||
const [
|
||||
deactivatePreorder,
|
||||
deactivatePreoderOpts
|
||||
] = useProductVariantPreorderDeactivateMutation({});
|
||||
const handleDeactivateVariantPreorder = async (id: string) =>
|
||||
deactivatePreorder({ variables: { id } });
|
||||
|
||||
const [
|
||||
reorderProductVariants,
|
||||
reorderProductVariantsOpts
|
||||
|
@ -204,6 +227,7 @@ export const ProductVariant: React.FC<ProductUpdateProps> = ({
|
|||
updateVariantOpts.loading ||
|
||||
assignMediaOpts.loading ||
|
||||
unassignMediaOpts.loading ||
|
||||
deactivatePreoderOpts.loading ||
|
||||
reorderProductVariantsOpts.loading ||
|
||||
deleteAttributeValueOpts.loading;
|
||||
|
||||
|
@ -256,6 +280,12 @@ export const ProductVariant: React.FC<ProductUpdateProps> = ({
|
|||
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<ProductUpdateProps> = ({
|
|||
onVariantClick={variantId => {
|
||||
navigate(productVariantEditUrl(productId, variantId));
|
||||
}}
|
||||
onVariantPreorderDeactivate={handleDeactivateVariantPreorder}
|
||||
variantDeactivatePreoderButtonState={deactivatePreoderOpts.status}
|
||||
onVariantReorder={handleVariantReorder}
|
||||
assignReferencesAttributeId={
|
||||
params.action === "assign-attribute-value" && params.id
|
||||
|
|
|
@ -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<ProductVariantCreateProps> = ({
|
|||
|
||||
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<ProductVariantCreateProps> = ({
|
|||
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<ProductVariantCreateProps> = ({
|
|||
})}
|
||||
/>
|
||||
<ProductVariantCreatePage
|
||||
channels={channels}
|
||||
disabled={disableForm}
|
||||
errors={variantCreateResult.data?.productVariantCreate.errors || []}
|
||||
header={intl.formatMessage({
|
||||
|
|
|
@ -36,7 +36,7 @@ export interface SearchProducts_search_edges_node_variants {
|
|||
__typename: "ProductVariant";
|
||||
id: string;
|
||||
name: string;
|
||||
sku: string;
|
||||
sku: string | null;
|
||||
channelListings: SearchProducts_search_edges_node_variants_channelListings[] | null;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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", () => (
|
||||
<ProductVariantCreatePage
|
||||
channels={channels}
|
||||
weightUnit="kg"
|
||||
disabled={false}
|
||||
errors={[]}
|
||||
|
@ -45,7 +37,6 @@ storiesOf("Views / Products / Create product variant", module)
|
|||
))
|
||||
.add("with errors", () => (
|
||||
<ProductVariantCreatePage
|
||||
channels={channels}
|
||||
weightUnit="kg"
|
||||
disabled={false}
|
||||
errors={[
|
||||
|
@ -88,7 +79,6 @@ storiesOf("Views / Products / Create product variant", module)
|
|||
))
|
||||
.add("when loading data", () => (
|
||||
<ProductVariantCreatePage
|
||||
channels={channels}
|
||||
weightUnit="kg"
|
||||
disabled={true}
|
||||
errors={[]}
|
||||
|
@ -112,7 +102,6 @@ storiesOf("Views / Products / Create product variant", module)
|
|||
))
|
||||
.add("add first variant", () => (
|
||||
<ProductVariantCreatePage
|
||||
channels={channels}
|
||||
weightUnit="kg"
|
||||
disabled={false}
|
||||
errors={[]}
|
||||
|
@ -139,7 +128,6 @@ storiesOf("Views / Products / Create product variant", module)
|
|||
))
|
||||
.add("no warehouses", () => (
|
||||
<ProductVariantCreatePage
|
||||
channels={channels}
|
||||
weightUnit="kg"
|
||||
disabled={false}
|
||||
errors={[]}
|
||||
|
|
|
@ -31,6 +31,7 @@ storiesOf("Views / Products / Product variant details", module)
|
|||
onVariantClick={() => 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}
|
||||
/>
|
||||
));
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue