feat: Add currency module and remove currency models from region and pricing modules (#6536)
What: - Creates a new currency module - Removes currency model from the pricing module - Removes currency model from region module
This commit is contained in:
1 parent
06f706a51a
commit
dc025302a1
102 files changed
+1502
-2128
No files matched your search
@@ -26,12 +26,9 @@ describe("Region Module Service", () => {
|
||||
await shutdownFunc()
|
||||
})
|
||||
|
||||
it("should create countries and currencies on application start", async () => {
|
||||
it("should create countries on application start", async () => {
|
||||
const countries = await service.listCountries()
|
||||
const currencies = await service.listCurrencies()
|
||||
|
||||
expect(countries.length).toBeGreaterThan(0)
|
||||
expect(currencies.length).toBeGreaterThan(0)
|
||||
})
|
||||
|
||||
it("should create countries added to default ones", async () => {
|
||||
@@ -47,7 +44,7 @@ describe("Region Module Service", () => {
|
||||
numeric: "420",
|
||||
})
|
||||
|
||||
await service.createDefaultCountriesAndCurrencies()
|
||||
await service.createDefaultCountries()
|
||||
|
||||
const [, newCount] = await service.listAndCountCountries()
|
||||
expect(newCount).toEqual(initialCountries + 1)
|
||||
@@ -69,7 +66,7 @@ describe("Region Module Service", () => {
|
||||
)
|
||||
|
||||
const region = await service.retrieve(createdRegion.id, {
|
||||
relations: ["currency", "countries"],
|
||||
relations: ["countries"],
|
||||
})
|
||||
|
||||
expect(region).toEqual(
|
||||
@@ -77,10 +74,6 @@ describe("Region Module Service", () => {
|
||||
id: region.id,
|
||||
name: "Europe",
|
||||
currency_code: "eur",
|
||||
currency: expect.objectContaining({
|
||||
code: "eur",
|
||||
name: "Euro",
|
||||
}),
|
||||
countries: [],
|
||||
})
|
||||
)
|
||||
@@ -94,7 +87,7 @@ describe("Region Module Service", () => {
|
||||
})
|
||||
|
||||
const region = await service.retrieve(createdRegion.id, {
|
||||
relations: ["countries", "currency"],
|
||||
relations: ["countries"],
|
||||
})
|
||||
|
||||
expect(region).toEqual(
|
||||
@@ -102,10 +95,6 @@ describe("Region Module Service", () => {
|
||||
id: region.id,
|
||||
name: "North America",
|
||||
currency_code: "usd",
|
||||
currency: expect.objectContaining({
|
||||
code: "usd",
|
||||
name: "US Dollar",
|
||||
}),
|
||||
countries: [
|
||||
expect.objectContaining({
|
||||
display_name: "Canada",
|
||||
@@ -182,7 +171,7 @@ describe("Region Module Service", () => {
|
||||
})
|
||||
|
||||
const latestRegion = await service.retrieve(createdRegion.id, {
|
||||
relations: ["currency", "countries"],
|
||||
relations: ["countries"],
|
||||
})
|
||||
|
||||
expect(latestRegion).toMatchObject({
|
||||
@@ -243,7 +232,7 @@ describe("Region Module Service", () => {
|
||||
})
|
||||
|
||||
const latestRegion = await service.retrieve(createdRegion.id, {
|
||||
relations: ["currency", "countries"],
|
||||
relations: ["countries"],
|
||||
})
|
||||
|
||||
expect(latestRegion).toMatchObject({
|
||||
@@ -268,7 +257,7 @@ describe("Region Module Service", () => {
|
||||
})
|
||||
|
||||
const updatedRegion = await service.retrieve(createdRegion.id, {
|
||||
relations: ["currency", "countries"],
|
||||
relations: ["countries"],
|
||||
})
|
||||
|
||||
expect(updatedRegion).toMatchObject({
|
||||
@@ -294,7 +283,7 @@ describe("Region Module Service", () => {
|
||||
})
|
||||
|
||||
const updatedRegion = await service.retrieve(createdRegion.id, {
|
||||
relations: ["currency", "countries"],
|
||||
relations: ["countries"],
|
||||
})
|
||||
|
||||
expect(updatedRegion).toMatchObject({
|
||||
@@ -306,23 +295,6 @@ describe("Region Module Service", () => {
|
||||
expect(updatedRegion.countries).toHaveLength(0)
|
||||
})
|
||||
|
||||
it("should fail updating the region currency to a non-existent one", async () => {
|
||||
const createdRegion = await service.create({
|
||||
name: "North America",
|
||||
currency_code: "USD",
|
||||
countries: ["us", "ca"],
|
||||
})
|
||||
|
||||
await expect(
|
||||
service.update(
|
||||
{ id: createdRegion.id },
|
||||
{
|
||||
currency_code: "DOGECOIN",
|
||||
}
|
||||
)
|
||||
).rejects.toThrowError('Currencies with codes: "dogecoin" were not found')
|
||||
})
|
||||
|
||||
it("should fail updating the region countries to non-existent ones", async () => {
|
||||
const createdRegion = await service.create({
|
||||
name: "North America",
|
||||
@@ -384,13 +356,4 @@ describe("Region Module Service", () => {
|
||||
'Countries with codes: "mx" are already assigned to a region'
|
||||
)
|
||||
})
|
||||
|
||||
it("should fail when currency does not exist", async () => {
|
||||
await expect(
|
||||
service.create({
|
||||
name: "Europe",
|
||||
currency_code: "DOGECOIN",
|
||||
})
|
||||
).rejects.toThrowError('Currencies with codes: "dogecoin" were not found')
|
||||
})
|
||||
})
|
||||
@@ -1,11 +1,10 @@
|
||||
import { Modules } from "@medusajs/modules-sdk"
|
||||
import { ModuleJoinerConfig } from "@medusajs/types"
|
||||
import { MapToConfig } from "@medusajs/utils"
|
||||
import { Country, Currency, Region } from "@models"
|
||||
import { Country, Region } from "@models"
|
||||
|
||||
export const LinkableKeys = {
|
||||
region_id: Region.name,
|
||||
currency_code: Country.name,
|
||||
country_id: Region.name,
|
||||
}
|
||||
|
||||
@@ -29,10 +28,6 @@ export const joinerConfig: ModuleJoinerConfig = {
|
||||
name: ["region", "regions"],
|
||||
args: { entity: Region.name },
|
||||
},
|
||||
{
|
||||
name: ["currency", "currencies"],
|
||||
args: { entity: Currency.name },
|
||||
},
|
||||
{
|
||||
name: ["country", "countries"],
|
||||
args: { entity: Country.name },
|
||||
|
||||
@@ -8,6 +8,6 @@ export default async ({ container }: LoaderOptions): Promise<void> => {
|
||||
|
||||
// TODO: Remove when legacy modules have been migrated
|
||||
if (!!process.env.MEDUSA_FF_MEDUSA_V2) {
|
||||
await service.createDefaultCountriesAndCurrencies()
|
||||
await service.createDefaultCountries()
|
||||
}
|
||||
}
|
||||
@@ -1,64 +1,7 @@
|
||||
{
|
||||
"namespaces": [
|
||||
"public"
|
||||
],
|
||||
"namespaces": ["public"],
|
||||
"name": "public",
|
||||
"tables": [
|
||||
{
|
||||
"columns": {
|
||||
"code": {
|
||||
"name": "code",
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
"autoincrement": false,
|
||||
"primary": false,
|
||||
"nullable": false,
|
||||
"mappedType": "text"
|
||||
},
|
||||
"symbol": {
|
||||
"name": "symbol",
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
"autoincrement": false,
|
||||
"primary": false,
|
||||
"nullable": false,
|
||||
"mappedType": "text"
|
||||
},
|
||||
"symbol_native": {
|
||||
"name": "symbol_native",
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
"autoincrement": false,
|
||||
"primary": false,
|
||||
"nullable": false,
|
||||
"mappedType": "text"
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
"autoincrement": false,
|
||||
"primary": false,
|
||||
"nullable": false,
|
||||
"mappedType": "text"
|
||||
}
|
||||
},
|
||||
"name": "region_currency",
|
||||
"schema": "public",
|
||||
"indexes": [
|
||||
{
|
||||
"keyName": "region_currency_pkey",
|
||||
"columnNames": [
|
||||
"code"
|
||||
],
|
||||
"composite": false,
|
||||
"primary": true,
|
||||
"unique": true
|
||||
}
|
||||
],
|
||||
"checks": [],
|
||||
"foreignKeys": {}
|
||||
},
|
||||
{
|
||||
"columns": {
|
||||
"id": {
|
||||
@@ -134,18 +77,7 @@
|
||||
"schema": "public",
|
||||
"indexes": [
|
||||
{
|
||||
"columnNames": [
|
||||
"currency_code"
|
||||
],
|
||||
"composite": false,
|
||||
"keyName": "IDX_region_currency_code",
|
||||
"primary": false,
|
||||
"unique": false
|
||||
},
|
||||
{
|
||||
"columnNames": [
|
||||
"deleted_at"
|
||||
],
|
||||
"columnNames": ["deleted_at"],
|
||||
"composite": false,
|
||||
"keyName": "IDX_region_deleted_at",
|
||||
"primary": false,
|
||||
@@ -153,30 +85,14 @@
|
||||
},
|
||||
{
|
||||
"keyName": "region_pkey",
|
||||
"columnNames": [
|
||||
"id"
|
||||
],
|
||||
"columnNames": ["id"],
|
||||
"composite": false,
|
||||
"primary": true,
|
||||
"unique": true
|
||||
}
|
||||
],
|
||||
"checks": [],
|
||||
"foreignKeys": {
|
||||
"region_currency_code_foreign": {
|
||||
"constraintName": "region_currency_code_foreign",
|
||||
"columnNames": [
|
||||
"currency_code"
|
||||
],
|
||||
"localTableName": "public.region",
|
||||
"referencedColumnNames": [
|
||||
"code"
|
||||
],
|
||||
"referencedTableName": "public.region_currency",
|
||||
"deleteRule": "set null",
|
||||
"updateRule": "cascade"
|
||||
}
|
||||
}
|
||||
"foreignKeys": {}
|
||||
},
|
||||
{
|
||||
"columns": {
|
||||
@@ -249,9 +165,7 @@
|
||||
"indexes": [
|
||||
{
|
||||
"keyName": "region_country_pkey",
|
||||
"columnNames": [
|
||||
"id"
|
||||
],
|
||||
"columnNames": ["id"],
|
||||
"composite": false,
|
||||
"primary": true,
|
||||
"unique": true
|
||||
@@ -261,13 +175,9 @@
|
||||
"foreignKeys": {
|
||||
"region_country_region_id_foreign": {
|
||||
"constraintName": "region_country_region_id_foreign",
|
||||
"columnNames": [
|
||||
"region_id"
|
||||
],
|
||||
"columnNames": ["region_id"],
|
||||
"localTableName": "public.region_country",
|
||||
"referencedColumnNames": [
|
||||
"id"
|
||||
],
|
||||
"referencedColumnNames": ["id"],
|
||||
"referencedTableName": "public.region",
|
||||
"deleteRule": "set null",
|
||||
"updateRule": "cascade"
|
||||
|
||||
@@ -16,15 +16,6 @@ CREATE TABLE IF NOT EXISTS "region" (
|
||||
CONSTRAINT "region_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- Create or update "region_currency" table
|
||||
CREATE TABLE IF NOT EXISTS "region_currency" (
|
||||
"code" text NOT NULL,
|
||||
"symbol" text NOT NULL,
|
||||
"symbol_native" text NOT NULL,
|
||||
"name" text NOT NULL,
|
||||
CONSTRAINT "region_currency_pkey" PRIMARY KEY ("code")
|
||||
);
|
||||
|
||||
-- Adjust "region" table
|
||||
ALTER TABLE "region" DROP CONSTRAINT IF EXISTS "FK_3bdd5896ec93be2f1c62a3309a5";
|
||||
ALTER TABLE "region" DROP CONSTRAINT IF EXISTS "FK_91f88052197680f9790272aaf5b";
|
||||
@@ -35,9 +26,6 @@ ${generatePostgresAlterColummnIfExistStatement(
|
||||
"DROP NOT NULL"
|
||||
)}
|
||||
|
||||
ALTER TABLE "region" ADD CONSTRAINT "region_currency_code_foreign" FOREIGN KEY ("currency_code") REFERENCES "region_currency" ("code") ON UPDATE CASCADE;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS "IDX_region_currency_code" ON "region" ("currency_code");
|
||||
CREATE INDEX IF NOT EXISTS "IDX_region_deleted_at" ON "region" ("deleted_at") WHERE "deleted_at" IS NOT NULL;
|
||||
|
||||
-- Create or update "region_country" table
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
import { Entity, PrimaryKey, Property } from "@mikro-orm/core"
|
||||
|
||||
@Entity({ tableName: "region_currency" })
|
||||
export default class Currency {
|
||||
@PrimaryKey({ columnType: "text" })
|
||||
code: string
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
symbol: string
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
symbol_native: string
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
name: string
|
||||
}
|
||||
@@ -1,4 +1,2 @@
|
||||
export { default as Country } from "./country"
|
||||
export { default as Currency } from "./currency"
|
||||
export { default as Region } from "./region"
|
||||
|
||||
@@ -14,12 +14,8 @@ import {
|
||||
Property,
|
||||
} from "@mikro-orm/core"
|
||||
import Country from "./country"
|
||||
import Currency from "./currency"
|
||||
|
||||
type RegionOptionalProps =
|
||||
| "currency"
|
||||
| "countries"
|
||||
| DAL.SoftDeletableEntityDateColumns
|
||||
type RegionOptionalProps = "countries" | DAL.SoftDeletableEntityDateColumns
|
||||
|
||||
@Entity({ tableName: "region" })
|
||||
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
|
||||
@@ -35,13 +31,6 @@ export default class Region {
|
||||
@Property({ columnType: "text" })
|
||||
currency_code: string
|
||||
|
||||
@ManyToOne({
|
||||
entity: () => Currency,
|
||||
index: "IDX_region_currency_code",
|
||||
nullable: true,
|
||||
})
|
||||
currency?: Currency
|
||||
|
||||
@OneToMany(() => Country, (country) => country.region)
|
||||
countries = new Collection<Country>(this)
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ import {
|
||||
ModuleJoinerConfig,
|
||||
ModulesSdkTypes,
|
||||
RegionCountryDTO,
|
||||
RegionCurrencyDTO,
|
||||
RegionDTO,
|
||||
UpdateRegionDTO,
|
||||
UpsertRegionDTO,
|
||||
@@ -27,9 +26,9 @@ import {
|
||||
getDuplicates,
|
||||
} from "@medusajs/utils"
|
||||
|
||||
import { Country, Currency, Region } from "@models"
|
||||
import { Country, Region } from "@models"
|
||||
|
||||
import { CreateCountryDTO, CreateCurrencyDTO, UpdateRegionInput } from "@types"
|
||||
import { CreateCountryDTO, UpdateRegionInput } from "@types"
|
||||
import { entityNameToLinkableKeysMap, joinerConfig } from "../joiner-config"
|
||||
|
||||
const COUNTRIES_LIMIT = 1000
|
||||
@@ -38,15 +37,13 @@ type InjectedDependencies = {
|
||||
baseRepository: DAL.RepositoryService
|
||||
regionService: ModulesSdkTypes.InternalModuleService<any>
|
||||
countryService: ModulesSdkTypes.InternalModuleService<any>
|
||||
currencyService: ModulesSdkTypes.InternalModuleService<any>
|
||||
}
|
||||
|
||||
const generateMethodForModels = [Country, Currency]
|
||||
const generateMethodForModels = [Country]
|
||||
|
||||
export default class RegionModuleService<
|
||||
TRegion extends Region = Region,
|
||||
TCountry extends Country = Country,
|
||||
TCurrency extends Currency = Currency
|
||||
TCountry extends Country = Country
|
||||
>
|
||||
extends ModulesSdkUtils.abstractModuleServiceFactory<
|
||||
InjectedDependencies,
|
||||
@@ -55,9 +52,6 @@ export default class RegionModuleService<
|
||||
Country: {
|
||||
dto: RegionCountryDTO
|
||||
}
|
||||
Currency: {
|
||||
dto: RegionCurrencyDTO
|
||||
}
|
||||
}
|
||||
>(Region, generateMethodForModels, entityNameToLinkableKeysMap)
|
||||
implements IRegionModuleService
|
||||
@@ -65,15 +59,9 @@ export default class RegionModuleService<
|
||||
protected baseRepository_: DAL.RepositoryService
|
||||
protected readonly regionService_: ModulesSdkTypes.InternalModuleService<TRegion>
|
||||
protected readonly countryService_: ModulesSdkTypes.InternalModuleService<TCountry>
|
||||
protected readonly currencyService_: ModulesSdkTypes.InternalModuleService<TCurrency>
|
||||
|
||||
constructor(
|
||||
{
|
||||
baseRepository,
|
||||
regionService,
|
||||
countryService,
|
||||
currencyService,
|
||||
}: InjectedDependencies,
|
||||
{ baseRepository, regionService, countryService }: InjectedDependencies,
|
||||
protected readonly moduleDeclaration: InternalModuleDeclaration
|
||||
) {
|
||||
// @ts-ignore
|
||||
@@ -81,7 +69,6 @@ export default class RegionModuleService<
|
||||
this.baseRepository_ = baseRepository
|
||||
this.regionService_ = regionService
|
||||
this.countryService_ = countryService
|
||||
this.currencyService_ = currencyService
|
||||
}
|
||||
|
||||
__joinerConfig(): ModuleJoinerConfig {
|
||||
@@ -118,10 +105,6 @@ export default class RegionModuleService<
|
||||
let normalizedInput = RegionModuleService.normalizeInput(data)
|
||||
|
||||
const validations = [
|
||||
this.validateCurrencies(
|
||||
normalizedInput.map((r) => r.currency_code),
|
||||
sharedContext
|
||||
),
|
||||
this.validateCountries(
|
||||
normalizedInput.map((r) => r.countries ?? []).flat(),
|
||||
sharedContext
|
||||
@@ -129,7 +112,7 @@ export default class RegionModuleService<
|
||||
] as const
|
||||
|
||||
// Assign the full country object so the ORM updates the relationship
|
||||
const [, dbCountries] = await promiseAll(validations)
|
||||
const [dbCountries] = await promiseAll(validations)
|
||||
const dbCountriesMap = new Map(dbCountries.map((d) => [d.iso_2, d]))
|
||||
let normalizedDbRegions = normalizedInput.map((region) =>
|
||||
removeUndefined({
|
||||
@@ -246,10 +229,6 @@ export default class RegionModuleService<
|
||||
}
|
||||
|
||||
const validations = [
|
||||
this.validateCurrencies(
|
||||
normalizedInput.map((d) => d.currency_code),
|
||||
sharedContext
|
||||
),
|
||||
this.validateCountries(
|
||||
normalizedInput.map((d) => d.countries ?? []).flat(),
|
||||
sharedContext
|
||||
@@ -257,7 +236,7 @@ export default class RegionModuleService<
|
||||
] as const
|
||||
|
||||
// Assign the full country object so the ORM updates the relationship
|
||||
const [, dbCountries] = await promiseAll(validations)
|
||||
const [dbCountries] = await promiseAll(validations)
|
||||
const dbCountriesMap = new Map(dbCountries.map((d) => [d.iso_2, d]))
|
||||
let normalizedDbRegions = normalizedInput.map((region) =>
|
||||
removeUndefined({
|
||||
@@ -280,41 +259,6 @@ export default class RegionModuleService<
|
||||
)
|
||||
}
|
||||
|
||||
private async validateCurrencies(
|
||||
currencyCodes: (string | undefined)[] | undefined,
|
||||
sharedContext: Context
|
||||
): Promise<void> {
|
||||
const normalizedCurrencyCodes = currencyCodes
|
||||
?.filter((c) => c !== undefined)
|
||||
.map((c) => c!.toLowerCase())
|
||||
|
||||
if (!normalizedCurrencyCodes?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const uniqueCurrencyCodes = Array.from(new Set(normalizedCurrencyCodes))
|
||||
const dbCurrencies = await this.currencyService_.list(
|
||||
{ code: uniqueCurrencyCodes },
|
||||
{},
|
||||
sharedContext
|
||||
)
|
||||
const dbCurrencyCodes = dbCurrencies.map((c) => c.code.toLowerCase())
|
||||
|
||||
if (uniqueCurrencyCodes.length !== dbCurrencyCodes.length) {
|
||||
const missingCurrencies = arrayDifference(
|
||||
uniqueCurrencyCodes,
|
||||
dbCurrencyCodes
|
||||
)
|
||||
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Currencies with codes: "${missingCurrencies.join(
|
||||
", "
|
||||
)}" were not found`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private async validateCountries(
|
||||
countries: string[] | undefined,
|
||||
sharedContext: Context
|
||||
@@ -369,13 +313,10 @@ export default class RegionModuleService<
|
||||
}
|
||||
|
||||
@InjectManager("baseRepository_")
|
||||
public async createDefaultCountriesAndCurrencies(
|
||||
public async createDefaultCountries(
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<void> {
|
||||
await promiseAll([
|
||||
await this.maybeCreateCountries(sharedContext),
|
||||
await this.maybeCreateCurrencies(sharedContext),
|
||||
])
|
||||
await this.maybeCreateCountries(sharedContext)
|
||||
}
|
||||
|
||||
@InjectTransactionManager("baseRepository_")
|
||||
@@ -409,31 +350,4 @@ export default class RegionModuleService<
|
||||
await this.countryService_.create(countsToCreate, sharedContext)
|
||||
}
|
||||
}
|
||||
|
||||
@InjectTransactionManager("baseRepository_")
|
||||
private async maybeCreateCurrencies(
|
||||
@MedusaContext() sharedContext: Context
|
||||
): Promise<void> {
|
||||
const [currency] = await this.currencyService_.list(
|
||||
{},
|
||||
{ select: ["code"], take: 1 },
|
||||
sharedContext
|
||||
)
|
||||
|
||||
let currsToCreate: CreateCurrencyDTO[] = []
|
||||
if (!currency) {
|
||||
currsToCreate = Object.entries(DefaultsUtils.defaultCurrencies).map(
|
||||
([code, currency]) => ({
|
||||
code: code.toLowerCase(),
|
||||
symbol: currency.symbol,
|
||||
symbol_native: currency.symbol_native,
|
||||
name: currency.name,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
if (currsToCreate.length) {
|
||||
await this.currencyService_.create(currsToCreate, sharedContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,13 +10,6 @@ export type UpdateCountryRegion = {
|
||||
region_id: string
|
||||
}
|
||||
|
||||
export type CreateCurrencyDTO = {
|
||||
code: string
|
||||
symbol: string
|
||||
name: string
|
||||
symbol_native: string
|
||||
}
|
||||
|
||||
export type CreateCountryDTO = {
|
||||
iso_2: string
|
||||
iso_3: string
|
||||
|
||||
Reference in new issue
Block a user