diff --git a/packages/currency/integration-tests/__tests__/currency-module-service.spec.ts b/packages/currency/integration-tests/__tests__/currency-module-service.spec.ts index 4e15e014fd..f2bf6bc796 100644 --- a/packages/currency/integration-tests/__tests__/currency-module-service.spec.ts +++ b/packages/currency/integration-tests/__tests__/currency-module-service.spec.ts @@ -19,10 +19,12 @@ moduleIntegrationTestRunner({ expect.objectContaining({ code: "cad", name: "Canadian Dollar", + decimal_digits: 2, }), expect.objectContaining({ code: "usd", name: "US Dollar", + decimal_digits: 2, }), ]) ) @@ -116,7 +118,7 @@ moduleIntegrationTestRunner({ {}, { take: 1, - select: ["code"], + select: ["code", "rounding"], } ) @@ -126,6 +128,8 @@ moduleIntegrationTestRunner({ expect(serialized).toEqual([ { code: "aed", + rounding: 0, + raw_rounding: expect.any(Object), }, ]) }) diff --git a/packages/currency/src/migrations/.snapshot-medusa-currency.json b/packages/currency/src/migrations/.snapshot-medusa-currency.json index c34620bb72..cf10d6199f 100644 --- a/packages/currency/src/migrations/.snapshot-medusa-currency.json +++ b/packages/currency/src/migrations/.snapshot-medusa-currency.json @@ -41,6 +41,35 @@ "primary": false, "nullable": false, "mappedType": "text" + }, + "decimal_digits": { + "name": "decimal_digits", + "type": "int", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "default": "0", + "mappedType": "integer" + }, + "rounding": { + "name": "rounding", + "type": "numeric", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "default": "0", + "mappedType": "decimal" + }, + "raw_rounding": { + "name": "raw_rounding", + "type": "jsonb", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "json" } }, "name": "currency", diff --git a/packages/currency/src/migrations/InitialSetup20240228133303.ts b/packages/currency/src/migrations/InitialSetup20240228133303.ts index 095ccd3345..bad3e9af1b 100644 --- a/packages/currency/src/migrations/InitialSetup20240228133303.ts +++ b/packages/currency/src/migrations/InitialSetup20240228133303.ts @@ -2,8 +2,24 @@ import { Migration } from "@mikro-orm/migrations" export class InitialSetup20240228133303 extends Migration { async up(): Promise { + const currencyTables = await this.execute( + "select * from information_schema.tables where table_name = 'currency' and table_schema = 'public'" + ) + + if (currencyTables.length > 0) { + // This is so we can still run the api tests, remove completely once that is not needed + this.addSql( + `alter table "currency" add column "decimal_digits" int not null default 0;` + ) + this.addSql( + `alter table "currency" add column "rounding" numeric not null default 0;` + ) + this.addSql(`alter table "currency" add column "raw_rounding" jsonb;`) + } + this.addSql(`create table if not exists "currency" ("code" text not null, "symbol" text not null, "symbol_native" text not null, "name" text not null, + "decimal_digits" int not null default 0, "rounding" numeric not null default 0, "raw_rounding" jsonb not null, constraint "currency_pkey" primary key ("code"));`) } } diff --git a/packages/currency/src/models/currency.ts b/packages/currency/src/models/currency.ts index 0bbdf3c794..ac8d79a1e3 100644 --- a/packages/currency/src/models/currency.ts +++ b/packages/currency/src/models/currency.ts @@ -1,3 +1,5 @@ +import { BigNumberRawValue } from "@medusajs/types" +import { BigNumber, MikroOrmBigNumberProperty } from "@medusajs/utils" import { Entity, PrimaryKey, Property } from "@mikro-orm/core" @Entity({ tableName: "currency" }) @@ -13,6 +15,15 @@ class Currency { @Property({ columnType: "text" }) name: string + + @Property({ columnType: "int", default: 0 }) + decimal_digits: number + + @MikroOrmBigNumberProperty({ default: 0 }) + rounding: BigNumber | number + + @Property({ columnType: "jsonb" }) + raw_rounding: BigNumberRawValue } export default Currency diff --git a/packages/medusa/src/api-v2/admin/currencies/[code]/route.ts b/packages/medusa/src/api-v2/admin/currencies/[code]/route.ts index b04517b6d8..85516f9345 100644 --- a/packages/medusa/src/api-v2/admin/currencies/[code]/route.ts +++ b/packages/medusa/src/api-v2/admin/currencies/[code]/route.ts @@ -1,6 +1,5 @@ import { remoteQueryObjectFromString } from "@medusajs/utils" import { MedusaRequest, MedusaResponse } from "../../../../types/routing" -import { defaultAdminCurrencyFields } from "../query-config" export const GET = async (req: MedusaRequest, res: MedusaResponse) => { const remoteQuery = req.scope.resolve("remoteQuery") @@ -10,7 +9,7 @@ export const GET = async (req: MedusaRequest, res: MedusaResponse) => { const queryObject = remoteQueryObjectFromString({ entryPoint: "currency", variables, - fields: defaultAdminCurrencyFields, + fields: req.remoteQueryConfig.fields, }) const [currency] = await remoteQuery(queryObject) diff --git a/packages/medusa/src/api-v2/admin/currencies/middlewares.ts b/packages/medusa/src/api-v2/admin/currencies/middlewares.ts index a326582b08..58f82d2f7d 100644 --- a/packages/medusa/src/api-v2/admin/currencies/middlewares.ts +++ b/packages/medusa/src/api-v2/admin/currencies/middlewares.ts @@ -1,11 +1,8 @@ -import { transformQuery } from "../../../api/middlewares" import { MiddlewareRoute } from "../../../loaders/helpers/routing/types" import { authenticate } from "../../../utils/authenticate-middleware" +import { validateAndTransformQuery } from "../../utils/validate-query" import * as QueryConfig from "./query-config" -import { - AdminGetCurrenciesCurrencyParams, - AdminGetCurrenciesParams, -} from "./validators" +import { AdminGetCurrencyParams, AdminGetCurrenciesParams } from "./validators" export const adminCurrencyRoutesMiddlewares: MiddlewareRoute[] = [ { @@ -17,7 +14,7 @@ export const adminCurrencyRoutesMiddlewares: MiddlewareRoute[] = [ method: ["GET"], matcher: "/admin/currencies", middlewares: [ - transformQuery( + validateAndTransformQuery( AdminGetCurrenciesParams, QueryConfig.listTransformQueryConfig ), @@ -27,8 +24,8 @@ export const adminCurrencyRoutesMiddlewares: MiddlewareRoute[] = [ method: ["GET"], matcher: "/admin/currencies/:code", middlewares: [ - transformQuery( - AdminGetCurrenciesCurrencyParams, + validateAndTransformQuery( + AdminGetCurrencyParams, QueryConfig.retrieveTransformQueryConfig ), ], diff --git a/packages/medusa/src/api-v2/admin/currencies/query-config.ts b/packages/medusa/src/api-v2/admin/currencies/query-config.ts index f9d5acc888..7d6056036c 100644 --- a/packages/medusa/src/api-v2/admin/currencies/query-config.ts +++ b/packages/medusa/src/api-v2/admin/currencies/query-config.ts @@ -1,20 +1,19 @@ -export const defaultAdminCurrencyRelations = [] -export const allowedAdminCurrencyRelations = [] export const defaultAdminCurrencyFields = [ "code", "name", "symbol", "symbol_native", + "decimal_digits", + "rounding", ] export const retrieveTransformQueryConfig = { - defaultFields: defaultAdminCurrencyFields, - defaultRelations: defaultAdminCurrencyRelations, - allowedRelations: allowedAdminCurrencyRelations, + defaults: defaultAdminCurrencyFields, isList: false, } export const listTransformQueryConfig = { + ...retrieveTransformQueryConfig, defaultLimit: 50, isList: true, } diff --git a/packages/medusa/src/api-v2/admin/currencies/route.ts b/packages/medusa/src/api-v2/admin/currencies/route.ts index 48be803557..9a12b7c252 100644 --- a/packages/medusa/src/api-v2/admin/currencies/route.ts +++ b/packages/medusa/src/api-v2/admin/currencies/route.ts @@ -1,6 +1,5 @@ import { remoteQueryObjectFromString } from "@medusajs/utils" import { MedusaRequest, MedusaResponse } from "../../../types/routing" -import { defaultAdminCurrencyFields } from "./query-config" export const GET = async (req: MedusaRequest, res: MedusaResponse) => { const remoteQuery = req.scope.resolve("remoteQuery") @@ -9,11 +8,9 @@ export const GET = async (req: MedusaRequest, res: MedusaResponse) => { entryPoint: "currency", variables: { filters: req.filterableFields, - order: req.listConfig.order, - skip: req.listConfig.skip, - take: req.listConfig.take, + ...req.remoteQueryConfig.pagination, }, - fields: defaultAdminCurrencyFields, + fields: req.remoteQueryConfig.fields, }) const { rows: currencies, metadata } = await remoteQuery(queryObject) diff --git a/packages/medusa/src/api-v2/admin/currencies/validators.ts b/packages/medusa/src/api-v2/admin/currencies/validators.ts index eda5833141..28ac593507 100644 --- a/packages/medusa/src/api-v2/admin/currencies/validators.ts +++ b/packages/medusa/src/api-v2/admin/currencies/validators.ts @@ -1,30 +1,18 @@ -import { Type } from "class-transformer" -import { IsOptional, IsString, ValidateNested } from "class-validator" -import { FindParams, extendedFindParamsMixin } from "../../../types/common" +import { createFindParams, createSelectParams } from "../../utils/validators" +import { z } from "zod" -export class AdminGetCurrenciesCurrencyParams extends FindParams {} -/** - * Parameters used to filter and configure the pagination of the retrieved currencies. - */ -export class AdminGetCurrenciesParams extends extendedFindParamsMixin({ - limit: 50, +export const AdminGetCurrencyParams = createSelectParams() + +export type AdminGetCurrenciesParamsType = z.infer< + typeof AdminGetCurrenciesParams +> +export const AdminGetCurrenciesParams = createFindParams({ offset: 0, -}) { - /** - * Search parameter for currencies. - */ - @IsString({ each: true }) - @IsOptional() - code?: string | string[] - - // Additional filters from BaseFilterable - @IsOptional() - @ValidateNested({ each: true }) - @Type(() => AdminGetCurrenciesParams) - $and?: AdminGetCurrenciesParams[] - - @IsOptional() - @ValidateNested({ each: true }) - @Type(() => AdminGetCurrenciesParams) - $or?: AdminGetCurrenciesParams[] -} + limit: 50, +}).merge( + z.object({ + code: z.union([z.string(), z.array(z.string())]).optional(), + $and: z.lazy(() => AdminGetCurrenciesParams.array()).optional(), + $or: z.lazy(() => AdminGetCurrenciesParams.array()).optional(), + }) +)