From 9b38b750def5c5cb7a83850c95435bffaae48b2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frane=20Poli=C4=87?= <16856471+fPolic@users.noreply.github.com> Date: Thu, 21 Aug 2025 12:06:36 +0200 Subject: [PATCH] feat(dashboard): shipping option tax rate overrides UI (#13260) * feat(dashboard): shipping option tax rate overrides UI * feat: add location filter * feat: show service zone in SO table * feat: display location in the SO table --- .changeset/long-needles-reflect.md | 5 + .../use-shipping-option-table-columns.tsx | 89 ++++++++++ .../use-shipping-option-table-filters.tsx | 29 ++-- .../query/use-shipping-option-table-query.tsx | 20 ++- .../src/i18n/translations/$schema.json | 30 +++- .../dashboard/src/i18n/translations/en.json | 12 +- .../dashboard/src/lib/shipping-options.ts | 43 +++++ .../components/target-form/target-form.tsx | 163 +++++++++++++++++- .../tax-override-card/tax-override-card.tsx | 25 +++ .../routes/tax-regions/common/constants.ts | 1 + .../tax-region-tax-override-create.tsx | 24 +++ .../tax-region-tax-override-edit-form.tsx | 24 +++ .../tax-region-tax-override-edit.tsx | 84 +++++---- .../tax-region-tax-override-edit/types.ts | 7 +- 14 files changed, 480 insertions(+), 76 deletions(-) create mode 100644 .changeset/long-needles-reflect.md create mode 100644 packages/admin/dashboard/src/hooks/table/columns/use-shipping-option-table-columns.tsx diff --git a/.changeset/long-needles-reflect.md b/.changeset/long-needles-reflect.md new file mode 100644 index 0000000000..2e71f85fe3 --- /dev/null +++ b/.changeset/long-needles-reflect.md @@ -0,0 +1,5 @@ +--- +"@medusajs/dashboard": patch +--- + +feat(dashboard): shipping option tax rate overrides UI diff --git a/packages/admin/dashboard/src/hooks/table/columns/use-shipping-option-table-columns.tsx b/packages/admin/dashboard/src/hooks/table/columns/use-shipping-option-table-columns.tsx new file mode 100644 index 0000000000..39a8670843 --- /dev/null +++ b/packages/admin/dashboard/src/hooks/table/columns/use-shipping-option-table-columns.tsx @@ -0,0 +1,89 @@ +import { HttpTypes } from "@medusajs/types" +import { createColumnHelper } from "@tanstack/react-table" +import { useMemo } from "react" +import { useTranslation } from "react-i18next" + +import { DateCell } from "../../../components/table/table-cells/common/date-cell" +import { TextCell } from "../../../components/table/table-cells/common/text-cell" +import { getFormattedShippingOptionLocationName } from "../../../lib/shipping-options" + +const columnHelper = createColumnHelper() + +export const useShippingOptionTableColumns = () => { + const { t } = useTranslation() + + return useMemo( + () => [ + columnHelper.accessor("name", { + header: () => t("fields.name"), + cell: ({ getValue }) => , + }), + columnHelper.accessor("shipping_profile", { + header: () => t("fields.shippingProfile"), + cell: ({ row }) => ( + + ), + }), + columnHelper.display({ + id: "location", + header: () => t("fields.location"), + cell: ({ row }) => { + const locationName = getFormattedShippingOptionLocationName( + row.original + ) + + return + }, + }), + columnHelper.display({ + id: "service_zone", + header: () => t("fields.serviceZone"), + cell: ({ row }) => { + const serviceZoneName = row.original.service_zone?.name + + return + }, + }), + columnHelper.display({ + id: "enabled_in_store", + header: () => t("fields.enabledInStore"), + cell: ({ row }) => { + let text = "N/A" + const val = row.original.rules?.find( + (r) => r.attribute === "enabled_in_store" + ) + + if (val) { + text = val.value === "true" ? "Yes" : "No" + } + + return + }, + }), + columnHelper.display({ + id: "is_return", + header: () => t("fields.isReturn"), + cell: ({ row }) => { + let text = "N/A" + const val = row.original.rules?.find( + (r) => r.attribute === "is_return" + ) + + if (val) { + text = val.value === "true" ? "Yes" : "No" + } + + return + }, + }), + columnHelper.accessor("created_at", { + header: () => t("fields.createdAt"), + + cell: ({ getValue }) => { + return + }, + }), + ], + [t] + ) +} diff --git a/packages/admin/dashboard/src/hooks/table/filters/use-shipping-option-table-filters.tsx b/packages/admin/dashboard/src/hooks/table/filters/use-shipping-option-table-filters.tsx index aed7c43d98..c2f3d9b30e 100644 --- a/packages/admin/dashboard/src/hooks/table/filters/use-shipping-option-table-filters.tsx +++ b/packages/admin/dashboard/src/hooks/table/filters/use-shipping-option-table-filters.tsx @@ -1,27 +1,18 @@ import { useTranslation } from "react-i18next" +import { HttpTypes } from "@medusajs/types" + import { Filter } from "../../../components/table/data-table" -export const useShippingOptionTableFilters = () => { +export const useShippingOptionTableFilters = ( + locations: HttpTypes.AdminStockLocation[] +) => { const { t } = useTranslation() - const isReturnFilter: Filter = { - key: "is_return", - label: t("fields.type"), + const locationFilter: Filter = { + key: "stock_location_id", + label: t("fields.location"), type: "select", - options: [ - { label: t("regions.return"), value: "true" }, - { label: t("regions.outbound"), value: "false" }, - ], - } - - const isAdminFilter: Filter = { - key: "admin_only", - label: t("fields.availability"), - type: "select", - options: [ - { label: t("general.admin"), value: "true" }, - { label: t("general.store"), value: "false" }, - ], + options: locations.map((l) => ({ label: l.name, value: l.id })), } const dateFilters: Filter[] = [ @@ -33,7 +24,7 @@ export const useShippingOptionTableFilters = () => { type: "date", })) - const filters = [isReturnFilter, isAdminFilter, ...dateFilters] + const filters = [locationFilter, ...dateFilters] return filters } diff --git a/packages/admin/dashboard/src/hooks/table/query/use-shipping-option-table-query.tsx b/packages/admin/dashboard/src/hooks/table/query/use-shipping-option-table-query.tsx index 3be4d0baab..ca0ce37d19 100644 --- a/packages/admin/dashboard/src/hooks/table/query/use-shipping-option-table-query.tsx +++ b/packages/admin/dashboard/src/hooks/table/query/use-shipping-option-table-query.tsx @@ -22,22 +22,34 @@ export const useShippingOptionTableQuery = ({ "is_return", "created_at", "updated_at", + "stock_location_id", ], prefix ) - const { offset, order, q, admin_only, is_return, created_at, updated_at } = - queryObject + const { + offset, + order, + q, + admin_only, + is_return, + created_at, + updated_at, + stock_location_id, + } = queryObject const searchParams: HttpTypes.AdminShippingOptionListParams = { limit: pageSize, offset: offset ? Number(offset) : 0, // TODO: We don't allow region_id in the API yet // region_id: regionId, - is_return: is_return ? is_return === "true" : undefined, - admin_only: admin_only ? admin_only === "true" : undefined, + + // TODO: not supported + // is_return: is_return ? is_return === "true" : undefined, + // admin_only: admin_only ? admin_only === "true" : undefined, q, order, + stock_location_id, created_at: created_at ? JSON.parse(created_at) : undefined, updated_at: updated_at ? JSON.parse(updated_at) : undefined, } diff --git a/packages/admin/dashboard/src/i18n/translations/$schema.json b/packages/admin/dashboard/src/i18n/translations/$schema.json index 3a1258bc7e..6161fd2789 100644 --- a/packages/admin/dashboard/src/i18n/translations/$schema.json +++ b/packages/admin/dashboard/src/i18n/translations/$schema.json @@ -7075,6 +7075,9 @@ }, "customerGroup": { "type": "string" + }, + "shippingOption": { + "type": "string" } }, "required": [ @@ -7082,7 +7085,8 @@ "productCollection", "productTag", "productType", - "customerGroup" + "customerGroup", + "shippingOption" ], "additionalProperties": false }, @@ -7119,6 +7123,9 @@ }, "customerGroup": { "type": "string" + }, + "shippingOption": { + "type": "string" } }, "required": [ @@ -7126,7 +7133,8 @@ "productCollection", "productTag", "productType", - "customerGroup" + "customerGroup", + "shippingOption" ], "additionalProperties": false }, @@ -7147,6 +7155,9 @@ }, "customerGroup": { "type": "string" + }, + "shippingOption": { + "type": "string" } }, "required": [ @@ -7154,7 +7165,8 @@ "productCollection", "productTag", "productType", - "customerGroup" + "customerGroup", + "shippingOption" ], "additionalProperties": false }, @@ -10854,6 +10866,12 @@ "configurations": { "type": "string" }, + "enabledInStore": { + "type": "string" + }, + "isReturn": { + "type": "string" + }, "conditions": { "type": "string" }, @@ -10959,6 +10977,9 @@ "countries": { "type": "string" }, + "serviceZone": { + "type": "string" + }, "paymentProviders": { "type": "string" }, @@ -11283,6 +11304,8 @@ "categories", "shippingMethod", "configurations", + "enabledInStore", + "isReturn", "conditions", "category", "collection", @@ -11318,6 +11341,7 @@ "minutes", "totalRedemptions", "countries", + "serviceZone", "paymentProviders", "refundReason", "fulfillmentProviders", diff --git a/packages/admin/dashboard/src/i18n/translations/en.json b/packages/admin/dashboard/src/i18n/translations/en.json index 50a449b433..0a3bed0cc1 100644 --- a/packages/admin/dashboard/src/i18n/translations/en.json +++ b/packages/admin/dashboard/src/i18n/translations/en.json @@ -1900,7 +1900,8 @@ "productCollection": "Product collections", "productTag": "Product tags", "productType": "Product types", - "customerGroup": "Customer groups" + "customerGroup": "Customer groups", + "shippingOption": "Shipping options" }, "operators": { "in": "in", @@ -1912,14 +1913,16 @@ "productCollection": "Search for product collections", "productTag": "Search for product tags", "productType": "Search for product types", - "customerGroup": "Search for customer groups" + "customerGroup": "Search for customer groups", + "shippingOption": "Search for shipping options" }, "tags": { "product": "Product", "productCollection": "Product collection", "productTag": "Product tag", "productType": "Product type", - "customerGroup": "Customer group" + "customerGroup": "Customer group", + "shippingOption": "Shipping option" }, "modal": { "header": "Add targets" @@ -2924,6 +2927,8 @@ "categories": "Categories", "shippingMethod": "Shipping method", "configurations": "Configurations", + "enabledInStore": "Enabled in store", + "isReturn": "Is return", "conditions": "Conditions", "category": "Category", "collection": "Collection", @@ -2959,6 +2964,7 @@ "minutes": "Minutes", "totalRedemptions": "Total Redemptions", "countries": "Countries", + "serviceZone": "Service Zone", "paymentProviders": "Payment Providers", "refundReason": "Refund Reason", "fulfillmentProviders": "Fulfillment Providers", diff --git a/packages/admin/dashboard/src/lib/shipping-options.ts b/packages/admin/dashboard/src/lib/shipping-options.ts index c623a2a694..4a23b61669 100644 --- a/packages/admin/dashboard/src/lib/shipping-options.ts +++ b/packages/admin/dashboard/src/lib/shipping-options.ts @@ -17,3 +17,46 @@ export function isOptionEnabledInStore( r.operator === "eq" ) } + +/** + * Return a name for the shipping option location or generate one based on the locations address + */ +export function getFormattedShippingOptionLocationName( + shippingOption: HttpTypes.AdminShippingOption +) { + const location = shippingOption.service_zone.fulfillment_set.location + + if (!location) { + return "N/A" + } + + if (location.name) { + return `${location.name}` + } + + let name = "" + + if (location.address) { + if (location.address.address_1) { + name += `${location.address.address_1}` + } + + if (location.address.address_2) { + name += `${location.address.address_2}` + } + + if (location.address.city) { + name += `${location.address.city}` + } + + if (location.address.postal_code) { + name += `${location.address.postal_code}` + } + + if (location.address.country_code) { + name += `, ${location.address.country_code}` + } + } + + return name || "N/A" +} diff --git a/packages/admin/dashboard/src/routes/tax-regions/common/components/target-form/target-form.tsx b/packages/admin/dashboard/src/routes/tax-regions/common/components/target-form/target-form.tsx index 0a5df53e6f..fcb4aea1e0 100644 --- a/packages/admin/dashboard/src/routes/tax-regions/common/components/target-form/target-form.tsx +++ b/packages/admin/dashboard/src/routes/tax-regions/common/components/target-form/target-form.tsx @@ -21,6 +21,8 @@ import { useProductTags, useProductTypes, useProducts, + useShippingOptions, + useStockLocations, } from "../../../../../hooks/api" import { useCollectionTableColumns, @@ -35,6 +37,7 @@ import { useProductTableFilters, useProductTagTableFilters, useProductTypeTableFilters, + useShippingOptionTableFilters, } from "../../../../../hooks/table/filters" import { useCollectionTableQuery, @@ -42,10 +45,12 @@ import { useProductTableQuery, useProductTagTableQuery, useProductTypeTableQuery, + useShippingOptionTableQuery, } from "../../../../../hooks/table/query" import { useDataTable } from "../../../../../hooks/use-data-table" import { TaxRateRuleReferenceType } from "../../constants" import { TaxRateRuleReference } from "../../schemas" +import { useShippingOptionTableColumns } from "../../../../../hooks/table/columns/use-shipping-option-table-columns" type TargetFormProps = { referenceType: TaxRateRuleReferenceType @@ -110,16 +115,18 @@ type TableProps = { const Table = ({ referenceType, ...props }: TableProps) => { switch (referenceType) { - case TaxRateRuleReferenceType.CUSTOMER_GROUP: - return + // case TaxRateRuleReferenceType.CUSTOMER_GROUP: + // return case TaxRateRuleReferenceType.PRODUCT: return - case TaxRateRuleReferenceType.PRODUCT_COLLECTION: - return + // case TaxRateRuleReferenceType.PRODUCT_COLLECTION: + // return case TaxRateRuleReferenceType.PRODUCT_TYPE: return - case TaxRateRuleReferenceType.PRODUCT_TAG: - return + // case TaxRateRuleReferenceType.PRODUCT_TAG: + // return + case TaxRateRuleReferenceType.SHIPPING_OPTION: + return default: return null } @@ -671,6 +678,150 @@ const useProductTypeColumns = () => { ) } +const PREFIX_SHIPPING_OPTION = "so" + +const ShippingOptionTable = ({ + initialRowState, + intermediate, + setIntermediate, +}: TableImplementationProps) => { + const { t } = useTranslation() + + const [rowSelection, setRowSelection] = + useState(initialRowState) + + useCleanupSearchParams() + + const { searchParams, raw } = useShippingOptionTableQuery({ + pageSize: PAGE_SIZE, + prefix: PREFIX_SHIPPING_OPTION, + }) + + const { shipping_options, count, isLoading, isError, error } = + useShippingOptions( + { + ...searchParams, + fields: "+service_zone.fulfillment_set.location.*", + }, + { + placeholderData: keepPreviousData, + } + ) + + const updater: OnChangeFn = (value) => { + const state = typeof value === "function" ? value(rowSelection) : value + const currentIds = Object.keys(rowSelection) + + const ids = Object.keys(state) + + const newIds = ids.filter((id) => !currentIds.includes(id)) + const removedIds = currentIds.filter((id) => !ids.includes(id)) + + const newShippingOptions = + shipping_options + ?.filter((p) => newIds.includes(p.id)) + .map((p) => ({ + value: p.id, + label: p.name, + })) || [] + + const filteredIntermediate = intermediate.filter( + (p) => !removedIds.includes(p.value) + ) + + setIntermediate([...filteredIntermediate, ...newShippingOptions]) + setRowSelection(state) + } + + const { stock_locations } = useStockLocations({ + limit: 1000, + }) + + const filters = useShippingOptionTableFilters(stock_locations || []) + const columns = useShippingOptionColumns() + + const { table } = useDataTable({ + data: shipping_options || [], + columns, + count, + enablePagination: true, + enableRowSelection: true, + getRowId: (row) => row.id, + rowSelection: { + state: rowSelection, + updater, + }, + pageSize: PAGE_SIZE, + prefix: PREFIX_SHIPPING_OPTION, + }) + + if (isError) { + throw error + } + + return ( + <_DataTable + table={table} + columns={columns} + pageSize={PAGE_SIZE} + count={count} + isLoading={isLoading} + filters={filters} + orderBy={[ + { key: "name", label: t("fields.name") }, + { key: "created_at", label: t("fields.createdAt") }, + { key: "updated_at", label: t("fields.updatedAt") }, + ]} + layout="fill" + pagination + search + prefix={PREFIX_SHIPPING_OPTION} + queryObject={raw} + /> + ) +} + +const soColumnHelper = createColumnHelper() + +const useShippingOptionColumns = () => { + const base = useShippingOptionTableColumns() + + return useMemo( + () => [ + soColumnHelper.display({ + id: "select", + header: ({ table }) => { + return ( + + table.toggleAllPageRowsSelected(!!value) + } + /> + ) + }, + cell: ({ row }) => { + return ( + row.toggleSelected(!!value)} + onClick={(e) => { + e.stopPropagation() + }} + /> + ) + }, + }), + ...base, + ], + [base] + ) +} + const PREFIX_PRODUCT_TAG = "ptag" const ProductTagTable = ({ diff --git a/packages/admin/dashboard/src/routes/tax-regions/common/components/tax-override-card/tax-override-card.tsx b/packages/admin/dashboard/src/routes/tax-regions/common/components/tax-override-card/tax-override-card.tsx index 951b084b31..b309b86ab0 100644 --- a/packages/admin/dashboard/src/routes/tax-regions/common/components/tax-override-card/tax-override-card.tsx +++ b/packages/admin/dashboard/src/routes/tax-regions/common/components/tax-override-card/tax-override-card.tsx @@ -24,6 +24,7 @@ import { useProducts } from "../../../../../hooks/api/products" import { formatPercentage } from "../../../../../lib/percentage-helpers" import { TaxRateRuleReferenceType } from "../../constants" import { useDeleteTaxRateAction } from "../../hooks" +import { useShippingOptions } from "../../../../../hooks/api" interface TaxOverrideCardProps extends ComponentPropsWithoutRef<"div"> { taxRate: HttpTypes.AdminTaxRate @@ -201,6 +202,9 @@ const ReferenceBadge = ({ case TaxRateRuleReferenceType.PRODUCT_TYPE: label = t("taxRegions.fields.targets.tags.productType") break + case TaxRateRuleReferenceType.SHIPPING_OPTION: + label = t("taxRegions.fields.targets.tags.shippingOption") + break // case TaxRateRuleReferenceType.CUSTOMER_GROUP: // label = t("taxRegions.fields.targets.tags.customerGroup") // break @@ -303,6 +307,16 @@ const useReferenceValues = ( } ) + const shippingOptions = useShippingOptions( + { + id: ids, + limit: 10, + }, + { + enabled: + !!ids.length && type === TaxRateRuleReferenceType.SHIPPING_OPTION, + } + ) // const collections = useCollections( // { // id: ids, @@ -358,6 +372,17 @@ const useReferenceValues = ( isError: productTypes.isError, error: productTypes.error, } + case TaxRateRuleReferenceType.SHIPPING_OPTION: + return { + labels: shippingOptions.shipping_options?.map((option) => option.name), + isPending: shippingOptions.isPending, + additional: shippingOptions.count + ? shippingOptions.count - + (shippingOptions.shipping_options?.length || 0) + : 0, + isError: shippingOptions.isError, + error: shippingOptions.error, + } // case TaxRateRuleReferenceType.PRODUCT_COLLECTION: // return { // labels: collections.collections?.map((collection) => collection.title!), diff --git a/packages/admin/dashboard/src/routes/tax-regions/common/constants.ts b/packages/admin/dashboard/src/routes/tax-regions/common/constants.ts index 5775902bb3..ead981b742 100644 --- a/packages/admin/dashboard/src/routes/tax-regions/common/constants.ts +++ b/packages/admin/dashboard/src/routes/tax-regions/common/constants.ts @@ -1,6 +1,7 @@ export enum TaxRateRuleReferenceType { PRODUCT = "product", PRODUCT_TYPE = "product_type", + SHIPPING_OPTION = "shipping_option", // PRODUCT_COLLECTION = "product_collection", // PRODUCT_TAG = "product_tag", // CUSTOMER_GROUP = "customer_group", diff --git a/packages/admin/dashboard/src/routes/tax-regions/tax-region-tax-override-create/components/tax-region-override-create-form/tax-region-tax-override-create.tsx b/packages/admin/dashboard/src/routes/tax-regions/tax-region-tax-override-create/components/tax-region-override-create-form/tax-region-tax-override-create.tsx index c46ddce0f7..7d9a043ca7 100644 --- a/packages/admin/dashboard/src/routes/tax-regions/tax-region-tax-override-create/components/tax-region-override-create-form/tax-region-tax-override-create.tsx +++ b/packages/admin/dashboard/src/routes/tax-regions/tax-region-tax-override-create/components/tax-region-override-create-form/tax-region-tax-override-create.tsx @@ -50,12 +50,14 @@ const TaxRegionCreateTaxOverrideSchema = z.object({ enabled_rules: z.object({ product: z.boolean(), product_type: z.boolean(), + shipping_option: z.boolean(), // product_collection: z.boolean(), // product_tag: z.boolean(), // customer_group: z.boolean(), }), product: z.array(TaxRateRuleReferenceSchema).optional(), product_type: z.array(TaxRateRuleReferenceSchema).optional(), + shipping_option: z.array(TaxRateRuleReferenceSchema).optional(), // product_collection: z.array(TaxRateRuleReferenceSchema).optional(), // product_tag: z.array(TaxRateRuleReferenceSchema).optional(), // customer_group: z.array(TaxRateRuleReferenceSchema).optional(), @@ -87,12 +89,14 @@ export const TaxRegionCreateTaxOverrideForm = ({ enabled_rules: { product: true, product_type: false, + shipping_option: false, // product_collection: false, // product_tag: false, // customer_group: false, }, product: [], product_type: [], + shipping_option: [], // product_collection: [], // product_tag: [], // customer_group: [], @@ -109,6 +113,7 @@ export const TaxRegionCreateTaxOverrideForm = ({ // customer_group, // product_collection, // product_tag, + shipping_option, } = values const productRules = createTaxRulePayload({ @@ -119,6 +124,10 @@ export const TaxRegionCreateTaxOverrideForm = ({ reference_type: TaxRateRuleReferenceType.PRODUCT_TYPE, references: product_type || [], }) + const shippingOptionRules = createTaxRulePayload({ + reference_type: TaxRateRuleReferenceType.SHIPPING_OPTION, + references: shipping_option || [], + }) // const customerGroupRules = createTaxRulePayload({ // reference_type: TaxRateRuleReferenceType.CUSTOMER_GROUP, // references: customer_group || [], @@ -135,6 +144,7 @@ export const TaxRegionCreateTaxOverrideForm = ({ const rules = [ productRules, productTypeRules, + shippingOptionRules, // customerGroupRules, // productCollectionRules, // productTagRules, @@ -173,6 +183,11 @@ export const TaxRegionCreateTaxOverrideForm = ({ name: TaxRateRuleReferenceType.PRODUCT_TYPE, }) + const shippingOptions = useFieldArray({ + control: form.control, + name: TaxRateRuleReferenceType.SHIPPING_OPTION, + }) + // const productCollections = useFieldArray({ // control: form.control, // name: TaxRateRuleReferenceType.PRODUCT_COLLECTION, @@ -195,6 +210,8 @@ export const TaxRegionCreateTaxOverrideForm = ({ return products case TaxRateRuleReferenceType.PRODUCT_TYPE: return productTypes + case TaxRateRuleReferenceType.SHIPPING_OPTION: + return shippingOptions // case TaxRateRuleReferenceType.PRODUCT_COLLECTION: // return productCollections // case TaxRateRuleReferenceType.PRODUCT_TAG: @@ -213,6 +230,10 @@ export const TaxRegionCreateTaxOverrideForm = ({ value: TaxRateRuleReferenceType.PRODUCT_TYPE, label: t("taxRegions.fields.targets.options.productType"), }, + { + value: TaxRateRuleReferenceType.SHIPPING_OPTION, + label: t("taxRegions.fields.targets.options.shippingOption"), + }, // { // value: TaxRateRuleReferenceType.PRODUCT_COLLECTION, // label: t("taxRegions.fields.targets.options.productCollection"), @@ -234,6 +255,9 @@ export const TaxRegionCreateTaxOverrideForm = ({ [TaxRateRuleReferenceType.PRODUCT_TYPE]: t( "taxRegions.fields.targets.placeholders.productType" ), + [TaxRateRuleReferenceType.SHIPPING_OPTION]: t( + "taxRegions.fields.targets.placeholders.shippingOption" + ), // [TaxRateRuleReferenceType.PRODUCT_COLLECTION]: t( // "taxRegions.fields.targets.placeholders.productCollection" // ), diff --git a/packages/admin/dashboard/src/routes/tax-regions/tax-region-tax-override-edit/components/tax-region-tax-override-edit-form/tax-region-tax-override-edit-form.tsx b/packages/admin/dashboard/src/routes/tax-regions/tax-region-tax-override-edit/components/tax-region-tax-override-edit-form/tax-region-tax-override-edit-form.tsx index f96942bf89..2643158234 100644 --- a/packages/admin/dashboard/src/routes/tax-regions/tax-region-tax-override-edit/components/tax-region-tax-override-edit-form/tax-region-tax-override-edit-form.tsx +++ b/packages/admin/dashboard/src/routes/tax-regions/tax-region-tax-override-edit/components/tax-region-tax-override-edit-form/tax-region-tax-override-edit-form.tsx @@ -58,12 +58,14 @@ const TaxRegionTaxRateEditSchema = z.object({ enabled_rules: z.object({ product: z.boolean(), product_type: z.boolean(), + shipping_option: z.boolean(), // product_collection: z.boolean(), // product_tag: z.boolean(), // customer_group: z.boolean(), }), product: z.array(TaxRateRuleReferenceSchema).optional(), product_type: z.array(TaxRateRuleReferenceSchema).optional(), + shipping_option: z.array(TaxRateRuleReferenceSchema).optional(), // product_collection: z.array(TaxRateRuleReferenceSchema).optional(), // product_tag: z.array(TaxRateRuleReferenceSchema).optional(), // customer_group: z.array(TaxRateRuleReferenceSchema).optional(), @@ -89,6 +91,7 @@ export const TaxRegionTaxOverrideEditForm = ({ enabled_rules: { product: initialValues.product.length > 0, product_type: initialValues.product_type.length > 0, + shipping_option: initialValues.shipping_option.length > 0, // customer_groups: initialValues.customer_group.length > 0, // product_collections: // initialValues.product_collections.length > 0, @@ -96,6 +99,7 @@ export const TaxRegionTaxOverrideEditForm = ({ }, product: initialValues.product, product_type: initialValues.product_type, + shipping_option: initialValues.shipping_option, // product_collections: initialValues.product_collection, // product_tags: initialValues.product_tag, // customer_groups: initialValues.customer_group, @@ -109,6 +113,7 @@ export const TaxRegionTaxOverrideEditForm = ({ const { product, product_type, + shipping_option, // customer_groups, // product_collections, // product_tags, @@ -122,6 +127,10 @@ export const TaxRegionTaxOverrideEditForm = ({ reference_type: TaxRateRuleReferenceType.PRODUCT_TYPE, references: product_type || [], }) + const shippingOptionRules = createTaxRulePayload({ + reference_type: TaxRateRuleReferenceType.SHIPPING_OPTION, + references: shipping_option || [], + }) // const customerGroupRules = createTaxRulePayload({ // reference_type: TaxRateRuleReferenceType.CUSTOMER_GROUP, // references: customer_groups || [], @@ -138,6 +147,7 @@ export const TaxRegionTaxOverrideEditForm = ({ const rules = [ productRules, productTypeRules, + shippingOptionRules, // customerGroupRules, // productCollectionRules, // productTagRules, @@ -175,6 +185,11 @@ export const TaxRegionTaxOverrideEditForm = ({ name: "product_type", }) + const shippingOptions = useFieldArray({ + control: form.control, + name: "shipping_option", + }) + // const productCollections = useFieldArray({ // control: form.control, // name: "product_collection", @@ -197,6 +212,8 @@ export const TaxRegionTaxOverrideEditForm = ({ return products case TaxRateRuleReferenceType.PRODUCT_TYPE: return productTypes + case TaxRateRuleReferenceType.SHIPPING_OPTION: + return shippingOptions // case TaxRateRuleReferenceType.PRODUCT_COLLECTION: // return productCollections // case TaxRateRuleReferenceType.PRODUCT_TAG: @@ -215,6 +232,10 @@ export const TaxRegionTaxOverrideEditForm = ({ value: TaxRateRuleReferenceType.PRODUCT_TYPE, label: t("taxRegions.fields.targets.options.productType"), }, + { + value: TaxRateRuleReferenceType.SHIPPING_OPTION, + label: t("taxRegions.fields.targets.options.shippingOption"), + }, // { // value: TaxRateRuleReferenceType.PRODUCT_COLLECTION, // label: t("taxRegions.fields.targets.options.productCollection"), @@ -236,6 +257,9 @@ export const TaxRegionTaxOverrideEditForm = ({ [TaxRateRuleReferenceType.PRODUCT_TYPE]: t( "taxRegions.fields.targets.placeholders.productType" ), + [TaxRateRuleReferenceType.SHIPPING_OPTION]: t( + "taxRegions.fields.targets.placeholders.shippingOption" + ), // [TaxRateRuleReferenceType.PRODUCT_COLLECTION]: t( // "taxRegions.fields.targets.placeholders.productCollection" // ), diff --git a/packages/admin/dashboard/src/routes/tax-regions/tax-region-tax-override-edit/tax-region-tax-override-edit.tsx b/packages/admin/dashboard/src/routes/tax-regions/tax-region-tax-override-edit/tax-region-tax-override-edit.tsx index 3bfcf73a81..ba7b8e3746 100644 --- a/packages/admin/dashboard/src/routes/tax-regions/tax-region-tax-override-edit/tax-region-tax-override-edit.tsx +++ b/packages/admin/dashboard/src/routes/tax-regions/tax-region-tax-override-edit/tax-region-tax-override-edit.tsx @@ -4,15 +4,12 @@ import { useTranslation } from "react-i18next" import { useParams } from "react-router-dom" import { RouteDrawer } from "../../../components/modals" -import { useCollections } from "../../../hooks/api/collections" -import { useCustomerGroups } from "../../../hooks/api/customer-groups" import { useProductTypes } from "../../../hooks/api/product-types" import { useProducts } from "../../../hooks/api/products" -import { useProductTags } from "../../../hooks/api/tags" -import { useTaxRate } from "../../../hooks/api/tax-rates" import { TaxRateRuleReferenceType } from "../common/constants" import { TaxRegionTaxOverrideEditForm } from "./components/tax-region-tax-override-edit-form" import { InitialRuleValues } from "./types" +import { useShippingOptions, useTaxRate } from "../../../hooks/api" export const TaxRegionTaxOverrideEdit = () => { const { t } = useTranslation() @@ -59,10 +56,11 @@ const useDefaultRulesValues = ( [key in TaxRateRuleReferenceType]: string[] } = { [TaxRateRuleReferenceType.PRODUCT]: [], - [TaxRateRuleReferenceType.PRODUCT_COLLECTION]: [], - [TaxRateRuleReferenceType.PRODUCT_TAG]: [], + // [TaxRateRuleReferenceType.PRODUCT_COLLECTION]: [], + // [TaxRateRuleReferenceType.PRODUCT_TAG]: [], [TaxRateRuleReferenceType.PRODUCT_TYPE]: [], - [TaxRateRuleReferenceType.CUSTOMER_GROUP]: [], + [TaxRateRuleReferenceType.SHIPPING_OPTION]: [], + // [TaxRateRuleReferenceType.CUSTOMER_GROUP]: [], } rules.forEach((rule) => { @@ -81,26 +79,26 @@ const useDefaultRulesValues = ( value: product.id, })), }, - { - ids: idsByReferenceType[TaxRateRuleReferenceType.PRODUCT_COLLECTION], - hook: useCollections, - key: TaxRateRuleReferenceType.PRODUCT_COLLECTION, - getResult: (result: HttpTypes.AdminCollectionListResponse) => - result.collections.map((collection) => ({ - label: collection.title!, - value: collection.id!, - })), - }, - { - ids: idsByReferenceType[TaxRateRuleReferenceType.PRODUCT_TAG], - hook: useProductTags, - key: TaxRateRuleReferenceType.PRODUCT_TAG, - getResult: (result: any) => - result.tags.map((tag: any) => ({ - label: tag.value, - value: tag.id, - })), - }, + // { + // ids: idsByReferenceType[TaxRateRuleReferenceType.PRODUCT_COLLECTION], + // hook: useCollections, + // key: TaxRateRuleReferenceType.PRODUCT_COLLECTION, + // getResult: (result: HttpTypes.AdminCollectionListResponse) => + // result.collections.map((collection) => ({ + // label: collection.title!, + // value: collection.id!, + // })), + // }, + // { + // ids: idsByReferenceType[TaxRateRuleReferenceType.PRODUCT_TAG], + // hook: useProductTags, + // key: TaxRateRuleReferenceType.PRODUCT_TAG, + // getResult: (result: any) => + // result.tags.map((tag: any) => ({ + // label: tag.value, + // value: tag.id, + // })), + // }, { ids: idsByReferenceType[TaxRateRuleReferenceType.PRODUCT_TYPE], hook: useProductTypes, @@ -112,19 +110,29 @@ const useDefaultRulesValues = ( })), }, { - ids: idsByReferenceType[TaxRateRuleReferenceType.CUSTOMER_GROUP], - hook: useCustomerGroups, - key: TaxRateRuleReferenceType.CUSTOMER_GROUP, - getResult: ( - result: HttpTypes.PaginatedResponse<{ - customer_groups: HttpTypes.AdminCustomerGroup[] - }> - ) => - result.customer_groups.map((customerGroup) => ({ - label: customerGroup.name!, - value: customerGroup.id, + ids: idsByReferenceType[TaxRateRuleReferenceType.SHIPPING_OPTION], + hook: useShippingOptions, + key: TaxRateRuleReferenceType.SHIPPING_OPTION, + getResult: (result: HttpTypes.AdminShippingOptionListResponse) => + result.shipping_options.map((shippingOption) => ({ + label: shippingOption.name, + value: shippingOption.id, })), }, + // { + // ids: idsByReferenceType[TaxRateRuleReferenceType.CUSTOMER_GROUP], + // hook: useCustomerGroups, + // key: TaxRateRuleReferenceType.CUSTOMER_GROUP, + // getResult: ( + // result: HttpTypes.PaginatedResponse<{ + // customer_groups: HttpTypes.AdminCustomerGroup[] + // }> + // ) => + // result.customer_groups.map((customerGroup) => ({ + // label: customerGroup.name!, + // value: customerGroup.id, + // })), + // }, ] const queryResults = queries.map(({ ids, hook }) => { diff --git a/packages/admin/dashboard/src/routes/tax-regions/tax-region-tax-override-edit/types.ts b/packages/admin/dashboard/src/routes/tax-regions/tax-region-tax-override-edit/types.ts index 43b8c7c573..5fbb55af01 100644 --- a/packages/admin/dashboard/src/routes/tax-regions/tax-region-tax-override-edit/types.ts +++ b/packages/admin/dashboard/src/routes/tax-regions/tax-region-tax-override-edit/types.ts @@ -3,8 +3,9 @@ import { TaxRateRuleReference } from "../common/schemas" export type InitialRuleValues = { [TaxRateRuleReferenceType.PRODUCT]: TaxRateRuleReference[] - [TaxRateRuleReferenceType.PRODUCT_COLLECTION]: TaxRateRuleReference[] - [TaxRateRuleReferenceType.PRODUCT_TAG]: TaxRateRuleReference[] + // [TaxRateRuleReferenceType.PRODUCT_COLLECTION]: TaxRateRuleReference[] + // [TaxRateRuleReferenceType.PRODUCT_TAG]: TaxRateRuleReference[] + [TaxRateRuleReferenceType.SHIPPING_OPTION]: TaxRateRuleReference[] [TaxRateRuleReferenceType.PRODUCT_TYPE]: TaxRateRuleReference[] - [TaxRateRuleReferenceType.CUSTOMER_GROUP]: TaxRateRuleReference[] + // [TaxRateRuleReferenceType.CUSTOMER_GROUP]: TaxRateRuleReference[] }