Add ability to create stock in multiple warehouses

This commit is contained in:
dominik-zeglen 2020-04-09 12:13:42 +02:00
parent b776321e0a
commit 715303e025
6 changed files with 133 additions and 99 deletions

View file

@ -24,16 +24,15 @@ export interface ProductVariantCreatorContentProps {
warehouses: WarehouseFragment[];
}
const ProductVariantCreatorContent: React.FC<ProductVariantCreatorContentProps> = props => {
const {
attributes,
currencySymbol,
data,
dispatchFormDataAction,
errors,
step,
warehouses
} = props;
const ProductVariantCreatorContent: React.FC<ProductVariantCreatorContentProps> = ({
attributes,
currencySymbol,
data,
dispatchFormDataAction,
errors,
step,
warehouses
}) => {
const selectedAttributes = attributes.filter(attribute =>
isSelected(
attribute.id,
@ -104,17 +103,26 @@ const ProductVariantCreatorContent: React.FC<ProductVariantCreatorContentProps>
: ProductVariantCreateReducerActionType.changeApplyStockToAttributeId
})
}
onAttributeValueChange={(valueId, price, type) =>
dispatchFormDataAction(
type === "price" && {
changeAttributeValuePrice: {
price,
valueId
},
type:
ProductVariantCreateReducerActionType.changeAttributeValuePrice
}
)
onAttributePriceChange={(valueId, price) =>
dispatchFormDataAction({
changeAttributeValuePrice: {
price,
valueId
},
type:
ProductVariantCreateReducerActionType.changeAttributeValuePrice
})
}
onAttributeStockChange={(valueId, quantity, warehouseIndex) =>
dispatchFormDataAction({
changeAttributeValueStock: {
quantity,
valueId,
warehouseIndex
},
type:
ProductVariantCreateReducerActionType.changeAttributeValueStock
})
}
onWarehouseToggle={warehouseId =>
dispatchFormDataAction({

View file

@ -50,11 +50,9 @@ function canHitNext(
) {
return false;
}
} else {
return true;
}
if (data.stock.mode === "attribute" || data.stock.attribute) {
if (data.stock.mode === "attribute" && data.stock.attribute === "") {
return false;
}

View file

@ -23,10 +23,11 @@ export interface ProductVariantCreatorPriceAndSkuProps {
onApplyToAllPriceChange: (value: string) => void;
onApplyToAllStockChange: (warehouseIndex: number, value: string) => void;
onAttributeSelect: (id: string, type: PriceOrStock) => void;
onAttributeValueChange: (
onAttributePriceChange: (id: string, value: string) => void;
onAttributeStockChange: (
id: string,
value: string,
type: PriceOrStock
quantity: number,
warehouseIndex: number
) => void;
onWarehouseToggle: (id: string) => void;
}
@ -40,7 +41,8 @@ const ProductVariantCreatorPriceAndSku: React.FC<ProductVariantCreatorPriceAndSk
onApplyToAllPriceChange,
onApplyToAllStockChange,
onAttributeSelect,
onAttributeValueChange,
onAttributePriceChange,
onAttributeStockChange,
onWarehouseToggle
}) => (
<>
@ -51,9 +53,7 @@ const ProductVariantCreatorPriceAndSku: React.FC<ProductVariantCreatorPriceAndSk
onApplyToAllChange={value => onApplyToAllChange(value, "price")}
onApplyToAllPriceChange={onApplyToAllPriceChange}
onAttributeSelect={id => onAttributeSelect(id, "price")}
onAttributeValueChange={(id, value) =>
onAttributeValueChange(id, value, "price")
}
onAttributeValueChange={onAttributePriceChange}
/>
<CardSpacer />
<ProductVariantCreatorStock
@ -63,9 +63,7 @@ const ProductVariantCreatorPriceAndSku: React.FC<ProductVariantCreatorPriceAndSk
onApplyToAllChange={value => onApplyToAllChange(value, "stock")}
onApplyToAllStockChange={onApplyToAllStockChange}
onAttributeSelect={id => onAttributeSelect(id, "stock")}
onAttributeValueChange={(id, value) =>
onAttributeValueChange(id, value, "stock")
}
onAttributeValueChange={onAttributeStockChange}
onWarehouseToggle={onWarehouseToggle}
/>
</>

View file

@ -27,6 +27,17 @@ import { getStockAttributeValues } from "./utils";
const useStyles = makeStyles(
theme => ({
attributeStockContainer: {
columnGap: theme.spacing(3) + "px",
display: "grid",
gridTemplateColumns: ({ data }: ProductVariantCreatorStockProps) =>
`150px repeat(${data.warehouses.length}, 288px)`,
rowGap: theme.spacing(2) + "px"
},
attributeStockScroll: {
overflowX: "scroll",
width: "100%"
},
hr: {
marginBottom: theme.spacing(),
marginTop: theme.spacing(0.5)
@ -75,7 +86,11 @@ export interface ProductVariantCreatorStockProps {
onApplyToAllChange: (mode: VariantCreatorPricesAndSkuMode) => void;
onApplyToAllStockChange: (warehouseIndex: number, value: string) => void;
onAttributeSelect: (id: string) => void;
onAttributeValueChange: (id: string, value: string) => void;
onAttributeValueChange: (
id: string,
quantity: number,
warehouseIndex: number
) => void;
onWarehouseToggle: (id: string) => void;
}
@ -168,11 +183,8 @@ const ProductVariantCreatorStock: React.FC<ProductVariantCreatorStockProps> = pr
{data.stock.mode === "all" && (
<div className={classes.stockContainer}>
{data.warehouses.map((warehouseId, warehouseIndex) => (
<div>
<Typography
className={classes.warehouseName}
key={warehouseId}
>
<div key={warehouseId}>
<Typography className={classes.warehouseName}>
{
warehouses.find(warehouse => warehouse.id === warehouseId)
.name
@ -212,60 +224,74 @@ const ProductVariantCreatorStock: React.FC<ProductVariantCreatorStockProps> = pr
{data.stock.mode === "attribute" && (
<>
<FormSpacer />
<Grid variant="uniform">
<div className={classes.label}>
<Typography>
<FormattedMessage
defaultMessage="Choose attribute"
description="variant attribute"
/>
</Typography>
</div>
<div>
<SingleSelectField
choices={attributeChoices}
label={intl.formatMessage({
defaultMessage: "Attribute",
description: "variant attribute"
})}
value={data.stock.attribute}
onChange={onAttributeSelect}
/>
</div>
</Grid>
{stockAttributeValues &&
stockAttributeValues.map(attributeValue => (
<React.Fragment key={attributeValue.id}>
<Hr className={classes.hrAttribute} />
<FormSpacer />
<Grid variant="uniform">
<div className={classes.label}>
<Typography>{attributeValue.name}</Typography>
</div>
<div>
<TextField
label={intl.formatMessage({
defaultMessage: "Stock",
description: "variant stock",
id: "productVariantCreatePricesSetStockPlaceholder"
})}
fullWidth
value={
data.stock.values.find(
value => value.slug === attributeValue.slug
).value
}
onChange={event =>
onAttributeValueChange(
attributeValue.slug,
event.target.value
<SingleSelectField
className={classes.shortInput}
choices={attributeChoices}
label={intl.formatMessage({
defaultMessage: "Select Attribute",
description: "variant attribute"
})}
value={data.stock.attribute}
onChange={event => onAttributeSelect(event.target.value)}
/>
{stockAttributeValues && (
<>
<Hr className={classes.hrAttribute} />
<FormSpacer />
<div className={classes.attributeStockScroll}>
<div className={classes.attributeStockContainer}>
<div />
{data.stock.attribute &&
data.warehouses.map(warehouseId => (
<Typography
className={classes.warehouseName}
key={warehouseId}
>
{
warehouses.find(
warehouse => warehouse.id === warehouseId
).name
}
</Typography>
))}
{stockAttributeValues.map(attributeValue => (
<React.Fragment key={attributeValue.id}>
<Typography>{attributeValue.name}</Typography>
{data.warehouses.map(
(warehouseId, warehouseIndex) => (
<TextField
fullWidth
inputProps={{
min: 0,
type: "number"
}}
label={intl.formatMessage({
defaultMessage: "Stock",
id:
"productVariantCreatePricesStockInputLabel"
})}
value={
data.stock.values.find(
value => value.slug === attributeValue.slug
).value[warehouseIndex]
}
onChange={event =>
onAttributeValueChange(
attributeValue.slug,
parseInt(event.target.value, 10),
warehouseIndex
)
}
key={warehouseId}
/>
)
}
/>
</div>
</Grid>
</React.Fragment>
))}
)}
</React.Fragment>
))}
</div>
</div>
</>
)}
</>
)}
<FormSpacer />

View file

@ -92,7 +92,7 @@ const useStyles = makeStyles<
marginTop: theme.spacing(0.5)
},
hr: {
gridColumn: props => `span ${4 + props.data.stock.value.length}`
gridColumn: props => `span ${4 + props.data.variants[0].stocks.length}`
},
input: {
"& input": {
@ -103,7 +103,7 @@ const useStyles = makeStyles<
columnGap: theme.spacing(3),
display: "grid",
gridTemplateColumns: props =>
`minmax(240px, auto) 170px repeat(${props.data.stock.value.length}, 140px) 140px 64px`,
`minmax(240px, auto) 170px repeat(${props.data.variants[0].stocks.length}, 140px) 140px 64px`,
overflowX: "scroll",
rowGap: theme.spacing() + "px"
}

View file

@ -186,8 +186,8 @@ function changeAttributeValuePrice(
function changeAttributeValueStock(
state: ProductVariantCreateFormData,
attributeValueSlug: string,
warehouseIndex: number,
quantity: number
quantity: number,
warehouseIndex: number
): ProductVariantCreateFormData {
const index = state.stock.values.findIndex(
value => value.slug === attributeValueSlug
@ -199,8 +199,12 @@ function changeAttributeValueStock(
const values = updateAtIndex(
{
slug: attributeValueSlug,
value: updateAtIndex(quantity, state.stock.value, warehouseIndex)
...state.stock.values[index],
value: updateAtIndex(
quantity,
state.stock.values[index].value,
warehouseIndex
)
},
state.stock.values,
index