Add variant stock filtering by warehouse
This commit is contained in:
parent
ccc51b1243
commit
ee36d6046c
10 changed files with 160 additions and 16 deletions
|
@ -53,13 +53,15 @@ const useStyles = makeStyles(
|
|||
);
|
||||
|
||||
export interface LinkChoiceProps {
|
||||
className?: string;
|
||||
choices: SingleAutocompleteChoiceType[];
|
||||
name: "country";
|
||||
name?: string;
|
||||
value: string;
|
||||
onChange: FormChange;
|
||||
}
|
||||
|
||||
const LinkChoice: React.FC<LinkChoiceProps> = ({
|
||||
className,
|
||||
choices,
|
||||
name,
|
||||
value,
|
||||
|
@ -107,7 +109,7 @@ const LinkChoice: React.FC<LinkChoiceProps> = ({
|
|||
|
||||
return (
|
||||
<span
|
||||
className={classes.root}
|
||||
className={classNames(classes.root, className)}
|
||||
ref={anchor}
|
||||
onKeyDown={handleKeyPress}
|
||||
tabIndex={0}
|
||||
|
|
|
@ -8,7 +8,7 @@ import TableCell from "@material-ui/core/TableCell";
|
|||
import TableRow from "@material-ui/core/TableRow";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import React from "react";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
import { FormattedMessage, useIntl, IntlShape } from "react-intl";
|
||||
|
||||
import CardTitle from "@saleor/components/CardTitle";
|
||||
import Checkbox from "@saleor/components/Checkbox";
|
||||
|
@ -16,11 +16,51 @@ import Money from "@saleor/components/Money";
|
|||
import ResponsiveTable from "@saleor/components/ResponsiveTable";
|
||||
import Skeleton from "@saleor/components/Skeleton";
|
||||
import TableHead from "@saleor/components/TableHead";
|
||||
import { SingleAutocompleteChoiceType } from "@saleor/components/SingleAutocompleteSelectField";
|
||||
import LinkChoice from "@saleor/components/LinkChoice";
|
||||
import { maybe, renderCollection } from "../../../misc";
|
||||
import { ListActions } from "../../../types";
|
||||
import { ProductDetails_product_variants } from "../../types/ProductDetails";
|
||||
import {
|
||||
ProductDetails_product_variants,
|
||||
ProductDetails_product_variants_stock_warehouse
|
||||
} from "../../types/ProductDetails";
|
||||
import { ProductVariant_costPrice } from "../../types/ProductVariant";
|
||||
|
||||
function getWarehouseChoices(
|
||||
variants: ProductDetails_product_variants[],
|
||||
intl: IntlShape
|
||||
): SingleAutocompleteChoiceType[] {
|
||||
return [
|
||||
{
|
||||
label: intl.formatMessage({
|
||||
defaultMessage: "All Warehouses",
|
||||
description: "filtering option"
|
||||
}),
|
||||
value: null
|
||||
},
|
||||
...variants
|
||||
.reduce<ProductDetails_product_variants_stock_warehouse[]>(
|
||||
(warehouses, variant) => [
|
||||
...warehouses,
|
||||
...variant.stock.reduce<
|
||||
ProductDetails_product_variants_stock_warehouse[]
|
||||
>((variantStocks, stock) => {
|
||||
if (!!warehouses.find(w => w.id === stock.warehouse.id)) {
|
||||
return variantStocks;
|
||||
}
|
||||
|
||||
return [...variantStocks, stock.warehouse];
|
||||
}, [])
|
||||
],
|
||||
[]
|
||||
)
|
||||
.map(w => ({
|
||||
label: w.name,
|
||||
value: w.id
|
||||
}))
|
||||
];
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(
|
||||
theme => ({
|
||||
[theme.breakpoints.up("lg")]: {
|
||||
|
@ -57,6 +97,13 @@ const useStyles = makeStyles(
|
|||
},
|
||||
textRight: {
|
||||
textAlign: "right" as "right"
|
||||
},
|
||||
warehouseLabel: {
|
||||
display: "inline-block",
|
||||
marginRight: theme.spacing()
|
||||
},
|
||||
warehouseSelectContainer: {
|
||||
paddingTop: theme.spacing(2)
|
||||
}
|
||||
}),
|
||||
{ name: "ProductVariants" }
|
||||
|
@ -90,6 +137,7 @@ export const ProductVariants: React.FC<ProductVariantsProps> = props => {
|
|||
const classes = useStyles(props);
|
||||
|
||||
const intl = useIntl();
|
||||
const [warehouse, setWarehouse] = React.useState(null);
|
||||
const hasVariants = maybe(() => variants.length > 0, true);
|
||||
|
||||
return (
|
||||
|
@ -127,7 +175,23 @@ export const ProductVariants: React.FC<ProductVariantsProps> = props => {
|
|||
)
|
||||
}
|
||||
/>
|
||||
{!variants.length && (
|
||||
|
||||
{variants.length > 0 ? (
|
||||
<CardContent className={classes.warehouseSelectContainer}>
|
||||
<Typography className={classes.warehouseLabel}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Available inventoty at:"
|
||||
description="variant stock status"
|
||||
/>
|
||||
</Typography>
|
||||
<LinkChoice
|
||||
choices={getWarehouseChoices(variants, intl)}
|
||||
name="warehouse"
|
||||
value={warehouse}
|
||||
onChange={event => setWarehouse(event.target.value)}
|
||||
/>
|
||||
</CardContent>
|
||||
) : (
|
||||
<CardContent>
|
||||
<Typography color={hasVariants ? "textPrimary" : "textSecondary"}>
|
||||
<FormattedMessage defaultMessage="Use variants for products that come in a variety of versions for example different sizes or colors" />
|
||||
|
@ -146,7 +210,7 @@ export const ProductVariants: React.FC<ProductVariantsProps> = props => {
|
|||
>
|
||||
<TableCell className={classes.colName}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Name"
|
||||
defaultMessage="Variant"
|
||||
description="product variant name"
|
||||
/>
|
||||
</TableCell>
|
||||
|
@ -175,6 +239,9 @@ export const ProductVariants: React.FC<ProductVariantsProps> = props => {
|
|||
variant && variant.stock
|
||||
? variant.stock.reduce((acc, s) => acc + s.quantity, 0)
|
||||
: null;
|
||||
const variantStock = variant.stock.find(
|
||||
s => s.warehouse.id === warehouse
|
||||
);
|
||||
|
||||
return (
|
||||
<TableRow
|
||||
|
@ -219,7 +286,8 @@ export const ProductVariants: React.FC<ProductVariantsProps> = props => {
|
|||
>
|
||||
{numAvailable === null ? (
|
||||
<Skeleton />
|
||||
) : numAvailable === 0 ? (
|
||||
) : warehouse === null ? (
|
||||
numAvailable === 0 ? (
|
||||
<FormattedMessage
|
||||
defaultMessage="Unavailable in all locations"
|
||||
description="product variant inventory"
|
||||
|
@ -233,6 +301,27 @@ export const ProductVariants: React.FC<ProductVariantsProps> = props => {
|
|||
numLocations: variant.stock.length
|
||||
}}
|
||||
/>
|
||||
)
|
||||
) : !!variantStock ? (
|
||||
variantStock.quantity > 0 ? (
|
||||
<FormattedMessage
|
||||
defaultMessage="{stockQuantity} available"
|
||||
description="product variant inventory"
|
||||
values={{
|
||||
stockQuantity: variantStock.quantity
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<FormattedMessage
|
||||
defaultMessage="Unavailable"
|
||||
description="product variant inventory"
|
||||
/>
|
||||
)
|
||||
) : (
|
||||
<FormattedMessage
|
||||
defaultMessage="Not stocked"
|
||||
description="product variant inventory"
|
||||
/>
|
||||
)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
|
|
@ -149,6 +149,10 @@ export const productFragmentDetails = gql`
|
|||
stock {
|
||||
id
|
||||
quantity
|
||||
warehouse {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
productType {
|
||||
|
|
|
@ -127,10 +127,17 @@ export interface Product_variants_priceOverride {
|
|||
currency: string;
|
||||
}
|
||||
|
||||
export interface Product_variants_stock_warehouse {
|
||||
__typename: "Warehouse";
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface Product_variants_stock {
|
||||
__typename: "Stock";
|
||||
id: string;
|
||||
quantity: number;
|
||||
warehouse: Product_variants_stock_warehouse;
|
||||
}
|
||||
|
||||
export interface Product_variants {
|
||||
|
|
|
@ -133,10 +133,17 @@ export interface ProductCreate_productCreate_product_variants_priceOverride {
|
|||
currency: string;
|
||||
}
|
||||
|
||||
export interface ProductCreate_productCreate_product_variants_stock_warehouse {
|
||||
__typename: "Warehouse";
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface ProductCreate_productCreate_product_variants_stock {
|
||||
__typename: "Stock";
|
||||
id: string;
|
||||
quantity: number;
|
||||
warehouse: ProductCreate_productCreate_product_variants_stock_warehouse;
|
||||
}
|
||||
|
||||
export interface ProductCreate_productCreate_product_variants {
|
||||
|
|
|
@ -127,10 +127,17 @@ export interface ProductDetails_product_variants_priceOverride {
|
|||
currency: string;
|
||||
}
|
||||
|
||||
export interface ProductDetails_product_variants_stock_warehouse {
|
||||
__typename: "Warehouse";
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface ProductDetails_product_variants_stock {
|
||||
__typename: "Stock";
|
||||
id: string;
|
||||
quantity: number;
|
||||
warehouse: ProductDetails_product_variants_stock_warehouse;
|
||||
}
|
||||
|
||||
export interface ProductDetails_product_variants {
|
||||
|
|
|
@ -133,10 +133,17 @@ export interface ProductImageCreate_productImageCreate_product_variants_priceOve
|
|||
currency: string;
|
||||
}
|
||||
|
||||
export interface ProductImageCreate_productImageCreate_product_variants_stock_warehouse {
|
||||
__typename: "Warehouse";
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface ProductImageCreate_productImageCreate_product_variants_stock {
|
||||
__typename: "Stock";
|
||||
id: string;
|
||||
quantity: number;
|
||||
warehouse: ProductImageCreate_productImageCreate_product_variants_stock_warehouse;
|
||||
}
|
||||
|
||||
export interface ProductImageCreate_productImageCreate_product_variants {
|
||||
|
|
|
@ -133,10 +133,17 @@ export interface ProductImageUpdate_productImageUpdate_product_variants_priceOve
|
|||
currency: string;
|
||||
}
|
||||
|
||||
export interface ProductImageUpdate_productImageUpdate_product_variants_stock_warehouse {
|
||||
__typename: "Warehouse";
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface ProductImageUpdate_productImageUpdate_product_variants_stock {
|
||||
__typename: "Stock";
|
||||
id: string;
|
||||
quantity: number;
|
||||
warehouse: ProductImageUpdate_productImageUpdate_product_variants_stock_warehouse;
|
||||
}
|
||||
|
||||
export interface ProductImageUpdate_productImageUpdate_product_variants {
|
||||
|
|
|
@ -133,10 +133,17 @@ export interface ProductUpdate_productUpdate_product_variants_priceOverride {
|
|||
currency: string;
|
||||
}
|
||||
|
||||
export interface ProductUpdate_productUpdate_product_variants_stock_warehouse {
|
||||
__typename: "Warehouse";
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface ProductUpdate_productUpdate_product_variants_stock {
|
||||
__typename: "Stock";
|
||||
id: string;
|
||||
quantity: number;
|
||||
warehouse: ProductUpdate_productUpdate_product_variants_stock_warehouse;
|
||||
}
|
||||
|
||||
export interface ProductUpdate_productUpdate_product_variants {
|
||||
|
|
|
@ -133,10 +133,17 @@ export interface SimpleProductUpdate_productUpdate_product_variants_priceOverrid
|
|||
currency: string;
|
||||
}
|
||||
|
||||
export interface SimpleProductUpdate_productUpdate_product_variants_stock_warehouse {
|
||||
__typename: "Warehouse";
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface SimpleProductUpdate_productUpdate_product_variants_stock {
|
||||
__typename: "Stock";
|
||||
id: string;
|
||||
quantity: number;
|
||||
warehouse: SimpleProductUpdate_productUpdate_product_variants_stock_warehouse;
|
||||
}
|
||||
|
||||
export interface SimpleProductUpdate_productUpdate_product_variants {
|
||||
|
|
Loading…
Reference in a new issue