fix product availability date (#696)

* VisibilityCard - fix product availability date

* revert changes in VisibilityCard, refetch data on successfully updated availability

* fix availability in ProductCreate and ProductUpdate

* ProductUpdate - remove unneeded refetch

* create  getProductAvailabilityVariables handler
This commit is contained in:
AlicjaSzu 2020-09-18 15:01:00 +02:00 committed by GitHub
parent 2f84747dec
commit cd88102af7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 95 additions and 19 deletions

View file

@ -241,7 +241,10 @@ export const VisibilityCard: React.FC<VisibilityCardProps> = props => {
const { value } = e.target; const { value } = e.target;
if (!value) { if (!value) {
onChange({ onChange({
target: { name: "availableForPurchase", value: null } target: {
name: "availableForPurchase",
value: null
}
}); });
} }
return onChange(e); return onChange(e);

View file

@ -611,6 +611,11 @@ const productSetAvailabilityForPurchase = gql`
productId: $productId productId: $productId
startDate: $startDate startDate: $startDate
) { ) {
product {
id
availableForPurchase
isAvailableForPurchase
}
errors: productErrors { errors: productErrors {
...ProductErrorFragment ...ProductErrorFragment
message message

View file

@ -8,6 +8,13 @@ import { ProductErrorCode } from "./../../types/globalTypes";
// GraphQL mutation operation: ProductSetAvailabilityForPurchase // GraphQL mutation operation: ProductSetAvailabilityForPurchase
// ==================================================== // ====================================================
export interface ProductSetAvailabilityForPurchase_productSetAvailabilityForPurchase_product {
__typename: "Product";
id: string;
availableForPurchase: any | null;
isAvailableForPurchase: boolean | null;
}
export interface ProductSetAvailabilityForPurchase_productSetAvailabilityForPurchase_errors { export interface ProductSetAvailabilityForPurchase_productSetAvailabilityForPurchase_errors {
__typename: "ProductError"; __typename: "ProductError";
code: ProductErrorCode; code: ProductErrorCode;
@ -17,6 +24,7 @@ export interface ProductSetAvailabilityForPurchase_productSetAvailabilityForPurc
export interface ProductSetAvailabilityForPurchase_productSetAvailabilityForPurchase { export interface ProductSetAvailabilityForPurchase_productSetAvailabilityForPurchase {
__typename: "ProductSetAvailabilityForPurchase"; __typename: "ProductSetAvailabilityForPurchase";
product: ProductSetAvailabilityForPurchase_productSetAvailabilityForPurchase_product | null;
errors: ProductSetAvailabilityForPurchase_productSetAvailabilityForPurchase_errors[]; errors: ProductSetAvailabilityForPurchase_productSetAvailabilityForPurchase_errors[];
} }

View file

@ -116,3 +116,30 @@ export function createProductTypeSelectHandler(
); );
}; };
} }
interface ProductAvailabilityArgs {
availableForPurchase: string | null;
isAvailableForPurchase: boolean;
productId: string;
}
export function getProductAvailabilityVariables({
isAvailableForPurchase,
availableForPurchase,
productId
}: ProductAvailabilityArgs) {
const isAvailable =
availableForPurchase && !isAvailableForPurchase
? true
: isAvailableForPurchase;
return {
isAvailable,
productId,
startDate: isAvailableForPurchase
? null
: availableForPurchase !== ""
? availableForPurchase
: null
};
}

View file

@ -3,6 +3,7 @@ import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config";
import useNavigator from "@saleor/hooks/useNavigator"; import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import { getProductAvailabilityVariables } from "@saleor/products/utils/handlers";
import useCategorySearch from "@saleor/searches/useCategorySearch"; import useCategorySearch from "@saleor/searches/useCategorySearch";
import useCollectionSearch from "@saleor/searches/useCollectionSearch"; import useCollectionSearch from "@saleor/searches/useCollectionSearch";
import useProductTypeSearch from "@saleor/searches/useProductTypeSearch"; import useProductTypeSearch from "@saleor/searches/useProductTypeSearch";
@ -19,7 +20,10 @@ import { decimal, weight } from "../../misc";
import ProductCreatePage, { import ProductCreatePage, {
ProductCreatePageSubmitData ProductCreatePageSubmitData
} from "../components/ProductCreatePage"; } from "../components/ProductCreatePage";
import { useProductCreateMutation } from "../mutations"; import {
useProductCreateMutation,
useProductSetAvailabilityForPurchase
} from "../mutations";
import { productListUrl, productUrl } from "../urls"; import { productListUrl, productUrl } from "../urls";
export const ProductCreateView: React.FC = () => { export const ProductCreateView: React.FC = () => {
@ -59,6 +63,18 @@ export const ProductCreateView: React.FC = () => {
const handleBack = () => navigate(productListUrl()); const handleBack = () => navigate(productListUrl());
const [
setProductAvailability,
productAvailabilityOpts
] = useProductSetAvailabilityForPurchase({
onCompleted: data => {
const errors = data?.productSetAvailabilityForPurchase?.errors;
if (errors?.length === 0) {
navigate(productUrl(data.productSetAvailabilityForPurchase.product.id));
}
}
});
const [productCreate, productCreateOpts] = useProductCreateMutation({ const [productCreate, productCreateOpts] = useProductCreateMutation({
onCompleted: data => { onCompleted: data => {
if (data.productCreate.errors.length === 0) { if (data.productCreate.errors.length === 0) {
@ -68,7 +84,6 @@ export const ProductCreateView: React.FC = () => {
defaultMessage: "Product created" defaultMessage: "Product created"
}) })
}); });
navigate(productUrl(data.productCreate.product.id));
} }
} }
}); });
@ -100,11 +115,28 @@ export const ProductCreateView: React.FC = () => {
warehouse: stock.id warehouse: stock.id
})), })),
trackInventory: formData.trackInventory, trackInventory: formData.trackInventory,
visibleInListings: formData.visibleInListings,
weight: weight(formData.weight) weight: weight(formData.weight)
} }
}); });
return result.data.productCreate?.product?.id || null; const productId = result.data.productCreate?.product?.id;
if (productId) {
const { isAvailableForPurchase, availableForPurchase } = formData;
const variables = getProductAvailabilityVariables({
availableForPurchase,
isAvailableForPurchase,
productId
});
setProductAvailability({
variables
});
}
return productId || null;
}; };
const handleSubmit = createMetadataCreateHandler( const handleSubmit = createMetadataCreateHandler(
handleCreate, handleCreate,
@ -128,7 +160,7 @@ export const ProductCreateView: React.FC = () => {
collections={(searchCollectionOpts.data?.search.edges || []).map( collections={(searchCollectionOpts.data?.search.edges || []).map(
edge => edge.node edge => edge.node
)} )}
disabled={productCreateOpts.loading} disabled={productCreateOpts.loading || productAvailabilityOpts.loading}
errors={productCreateOpts.data?.productCreate.errors || []} errors={productCreateOpts.data?.productCreate.errors || []}
fetchCategories={searchCategory} fetchCategories={searchCategory}
fetchCollections={searchCollection} fetchCollections={searchCollection}

View file

@ -10,6 +10,7 @@ import useBulkActions from "@saleor/hooks/useBulkActions";
import useNavigator from "@saleor/hooks/useNavigator"; import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import useStateFromProps from "@saleor/hooks/useStateFromProps";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { import {
useProductDeleteMutation, useProductDeleteMutation,
@ -177,6 +178,12 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
onCompleted: data => { onCompleted: data => {
const errors = data?.productSetAvailabilityForPurchase?.errors; const errors = data?.productSetAvailabilityForPurchase?.errors;
if (errors?.length === 0) { if (errors?.length === 0) {
const updatedProduct = data?.productSetAvailabilityForPurchase?.product;
setProduct(product => ({
...product,
availableForPurchase: updatedProduct.availableForPurchase,
isAvailableForPurchase: updatedProduct.isAvailableForPurchase
}));
notify({ notify({
status: "success", status: "success",
text: intl.formatMessage({ text: intl.formatMessage({
@ -195,7 +202,7 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
const handleBack = () => navigate(productListUrl()); const handleBack = () => navigate(productListUrl());
const product = data?.product; const [product, setProduct] = useStateFromProps(data?.product);
if (product === null) { if (product === null) {
return <NotFoundPage onBack={handleBack} />; return <NotFoundPage onBack={handleBack} />;

View file

@ -19,6 +19,7 @@ import {
SimpleProductUpdateVariables SimpleProductUpdateVariables
} from "@saleor/products/types/SimpleProductUpdate"; } from "@saleor/products/types/SimpleProductUpdate";
import { mapFormsetStockToStockInput } from "@saleor/products/utils/data"; import { mapFormsetStockToStockInput } from "@saleor/products/utils/data";
import { getProductAvailabilityVariables } from "@saleor/products/utils/handlers";
import { ReorderEvent } from "@saleor/types"; import { ReorderEvent } from "@saleor/types";
import { MutationFetchResult } from "react-apollo"; import { MutationFetchResult } from "react-apollo";
import { arrayMove } from "react-sortable-hoc"; import { arrayMove } from "react-sortable-hoc";
@ -91,20 +92,13 @@ export function createUpdateHandler(
isAvailableForPurchase !== product.isAvailableForPurchase || isAvailableForPurchase !== product.isAvailableForPurchase ||
availableForPurchase !== product.availableForPurchase availableForPurchase !== product.availableForPurchase
) { ) {
const isAvailable = const variables = getProductAvailabilityVariables({
availableForPurchase && !isAvailableForPurchase availableForPurchase,
? true isAvailableForPurchase,
: isAvailableForPurchase; productId: product.id
const availabilityResult = await setProductAvailability({
isAvailable,
productId: product.id,
startDate: isAvailableForPurchase
? null
: availableForPurchase !== ""
? availableForPurchase
: null
}); });
const availabilityResult = await setProductAvailability(variables);
errors = [ errors = [
...errors, ...errors,
...availabilityResult.data.productSetAvailabilityForPurchase.errors ...availabilityResult.data.productSetAvailabilityForPurchase.errors