fix(dashboard): allow to unset currency cell value (#9312)

**What**
- unset datagrid currency cell on delete press instead of setting it to 0
- consolidate pricing editors validations
- fix PL edit pricing schema

---

FIXES CC-529
This commit is contained in:
Frane Polić
2024-10-01 11:03:51 +02:00
committed by GitHub
parent 2e16949979
commit 4587a69f3f
7 changed files with 64 additions and 36 deletions

View File

@@ -12,7 +12,7 @@ type UseDataGridFormHandlersOptions<TData, TFieldValues extends FieldValues> = {
export const useDataGridFormHandlers = < export const useDataGridFormHandlers = <
TData, TData,
TFieldValues extends FieldValues TFieldValues extends FieldValues,
>({ >({
matrix, matrix,
form, form,
@@ -119,7 +119,7 @@ export function convertArrayToPrimitive(
): any[] { ): any[] {
switch (type) { switch (type) {
case "number": case "number":
return values.map(convertToNumber) return values.map((v) => (v === "" ? v : convertToNumber(v)))
case "boolean": case "boolean":
return values.map(convertToBoolean) return values.map(convertToBoolean)
case "text": case "text":

View File

@@ -62,25 +62,29 @@ export function CreateShippingOptionsForm({
const handleSubmit = form.handleSubmit(async (data) => { const handleSubmit = form.handleSubmit(async (data) => {
const currencyPrices = Object.entries(data.currency_prices) const currencyPrices = Object.entries(data.currency_prices)
.map(([code, value]) => { .map(([code, value]) => {
const amount = value ? castNumber(value) : undefined if (value === "" || value === undefined) {
return undefined
}
return { return {
currency_code: code, currency_code: code,
amount: amount, amount: castNumber(value),
} }
}) })
.filter((o) => !!o.amount) as { currency_code: string; amount: number }[] .filter((o) => !!o) as { currency_code: string; amount: number }[]
const regionPrices = Object.entries(data.region_prices) const regionPrices = Object.entries(data.region_prices)
.map(([region_id, value]) => { .map(([region_id, value]) => {
const amount = value ? castNumber(value) : undefined if (value === "" || value === undefined) {
return undefined
}
return { return {
region_id, region_id,
amount: amount, amount: castNumber(value),
} }
}) })
.filter((o) => !!o.amount) as { region_id: string; amount: number }[] .filter((o) => !!o) as { region_id: string; amount: number }[]
await mutateAsync( await mutateAsync(
{ {

View File

@@ -57,7 +57,7 @@ export type PriceListCreateProductsSchema = z.infer<
> >
export const PriceListUpdateCurrencyPriceSchema = z.object({ export const PriceListUpdateCurrencyPriceSchema = z.object({
amount: z.string().nullish(), amount: z.string().or(z.number()).optional(),
id: z.string().nullish(), id: z.string().nullish(),
}) })
@@ -66,7 +66,7 @@ export type PriceListUpdateCurrencyPrice = z.infer<
> >
export const PriceListUpdateRegionPriceSchema = z.object({ export const PriceListUpdateRegionPriceSchema = z.object({
amount: z.string().nullish(), amount: z.string().or(z.number()).optional(),
id: z.string().nullish(), id: z.string().nullish(),
}) })

View File

@@ -185,10 +185,13 @@ function convertToPriceArray(
) { ) {
const prices: PriceObject[] = [] const prices: PriceObject[] = []
const regionCurrencyMap = regions.reduce((map, region) => { const regionCurrencyMap = regions.reduce(
map[region.id] = region.currency_code (map, region) => {
return map map[region.id] = region.currency_code
}, {} as Record<string, string>) return map
},
{} as Record<string, string>
)
for (const [_productId, product] of Object.entries(data || {})) { for (const [_productId, product] of Object.entries(data || {})) {
const { variants } = product || {} const { variants } = product || {}
@@ -200,7 +203,10 @@ function convertToPriceArray(
for (const [currencyCode, currencyPrice] of Object.entries( for (const [currencyCode, currencyPrice] of Object.entries(
currencyPrices || {} currencyPrices || {}
)) { )) {
if (currencyPrice?.amount) { if (
currencyPrice?.amount !== "" &&
typeof currencyPrice?.amount !== "undefined"
) {
prices.push({ prices.push({
variantId, variantId,
currencyCode, currencyCode,
@@ -213,7 +219,10 @@ function convertToPriceArray(
for (const [regionId, regionPrice] of Object.entries( for (const [regionId, regionPrice] of Object.entries(
regionPrices || {} regionPrices || {}
)) { )) {
if (regionPrice?.amount) { if (
regionPrice?.amount !== "" &&
typeof regionPrice?.amount !== "undefined"
) {
prices.push({ prices.push({
variantId, variantId,
regionId, regionId,
@@ -240,15 +249,21 @@ function comparePrices(initialPrices: PriceObject[], newPrices: PriceObject[]) {
const pricesToCreate: HttpTypes.AdminCreatePriceListPrice[] = [] const pricesToCreate: HttpTypes.AdminCreatePriceListPrice[] = []
const pricesToDelete: string[] = [] const pricesToDelete: string[] = []
const initialPriceMap = initialPrices.reduce((map, price) => { const initialPriceMap = initialPrices.reduce(
map[createMapKey(price)] = price (map, price) => {
return map map[createMapKey(price)] = price
}, {} as Record<string, (typeof initialPrices)[0]>) return map
},
{} as Record<string, (typeof initialPrices)[0]>
)
const newPriceMap = newPrices.reduce((map, price) => { const newPriceMap = newPrices.reduce(
map[createMapKey(price)] = price (map, price) => {
return map map[createMapKey(price)] = price
}, {} as Record<string, (typeof newPrices)[0]>) return map
},
{} as Record<string, (typeof newPrices)[0]>
)
const keys = new Set([ const keys = new Set([
...Object.keys(initialPriceMap), ...Object.keys(initialPriceMap),

View File

@@ -74,10 +74,13 @@ export const CreateProductVariantForm = ({
return {} return {}
} }
return regions.reduce((acc, reg) => { return regions.reduce(
acc[reg.id] = reg.currency_code (acc, reg) => {
return acc acc[reg.id] = reg.currency_code
}, {} as Record<string, string>) return acc
},
{} as Record<string, string>
)
}, [regions]) }, [regions])
const isManageInventoryEnabled = useWatch({ const isManageInventoryEnabled = useWatch({
@@ -210,13 +213,13 @@ export const CreateProductVariantForm = ({
options: data.options, options: data.options,
prices: Object.entries(data.prices ?? {}) prices: Object.entries(data.prices ?? {})
.map(([currencyOrRegion, value]) => { .map(([currencyOrRegion, value]) => {
const ret: AdminCreateProductVariantPrice = {} if (value === "" || value === undefined) {
const amount = castNumber(value)
if (isNaN(amount) || value === "") {
return undefined return undefined
} }
const ret: AdminCreateProductVariantPrice = {}
const amount = castNumber(value)
if (currencyOrRegion.startsWith("reg_")) { if (currencyOrRegion.startsWith("reg_")) {
ret.rules = { region_id: currencyOrRegion } ret.rules = { region_id: currencyOrRegion }
ret.currency_code = regionsCurrencyMap[currencyOrRegion] ret.currency_code = regionsCurrencyMap[currencyOrRegion]

View File

@@ -75,6 +75,10 @@ export const normalizeVariants = (
.filter(Boolean), .filter(Boolean),
prices: Object.entries(variant.prices || {}) prices: Object.entries(variant.prices || {})
.map(([key, value]: any) => { .map(([key, value]: any) => {
if (value === "" || value === undefined) {
return undefined
}
if (key.startsWith("reg_")) { if (key.startsWith("reg_")) {
return { return {
currency_code: regionsCurrencyMap[key], currency_code: regionsCurrencyMap[key],

View File

@@ -74,8 +74,11 @@ export const PricingEdit = ({
const handleSubmit = form.handleSubmit(async (values) => { const handleSubmit = form.handleSubmit(async (values) => {
const reqData = values.variants.map((variant, ind) => ({ const reqData = values.variants.map((variant, ind) => ({
id: variants[ind].id, id: variants[ind].id,
prices: Object.entries(variant.prices || {}).map( prices: Object.entries(variant.prices || {})
([currencyCodeOrRegionId, value]: any) => { .filter(
([_, value]) => value !== "" && typeof value !== "undefined" // deleted cells
)
.map(([currencyCodeOrRegionId, value]: any) => {
const regionId = currencyCodeOrRegionId.startsWith("reg_") const regionId = currencyCodeOrRegionId.startsWith("reg_")
? currencyCodeOrRegionId ? currencyCodeOrRegionId
: undefined : undefined
@@ -105,8 +108,7 @@ export const PricingEdit = ({
amount, amount,
...(regionId ? { rules: { region_id: regionId } } : {}), ...(regionId ? { rules: { region_id: regionId } } : {}),
} }
} }),
),
})) }))
await mutateAsync(reqData, { await mutateAsync(reqData, {