Skip to content

Commit

Permalink
fix: Accept filters in softDelete + fulfillment location clean-up (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
olivermrbl committed May 3, 2024
1 parent 1366e2e commit 2f7b534
Show file tree
Hide file tree
Showing 20 changed files with 231 additions and 113 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,14 @@ medusaIntegrationTestRunner({
object: "stock_location",
deleted: true,
})

const stockLocations = await api.get(
`/admin/stock-locations`,
adminHeaders
)

expect(stockLocations.status).toEqual(200)
expect(stockLocations.data.stock_locations).toEqual([])
})

it("should successfully delete stock location associations", async () => {
Expand Down Expand Up @@ -390,7 +398,7 @@ medusaIntegrationTestRunner({
stockLocationId = createResponse.data.stock_location.id
})

it("should create a fulfillment set for the location", async () => {
it("should create a fulfillment set for the location and then delete it and its associations", async () => {
const response = await api.post(
`/admin/stock-locations/${stockLocationId}/fulfillment-sets?fields=id,*fulfillment_sets`,
{
Expand All @@ -407,6 +415,19 @@ medusaIntegrationTestRunner({
id: expect.any(String),
}),
])

await api.delete(
`/admin/stock-locations/${stockLocationId}`,
adminHeaders
)

const fulfillmentModule = appContainer.resolve(
ModuleRegistrationName.FULFILLMENT
)

const sets = await fulfillmentModule.list()

expect(sets).toHaveLength(0)
})

// This is really just to test the new Zod middleware. We don't need more of these.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1634,12 +1634,12 @@ medusaIntegrationTestRunner({
},
},
{
[Modules.FULFILLMENT]: {
fulfillment_set_id: fulfillmentSet.id,
},
[Modules.STOCK_LOCATION]: {
stock_location_id: location.id,
},
[Modules.FULFILLMENT]: {
fulfillment_set_id: fulfillmentSet.id,
},
},
{
[Modules.FULFILLMENT]: {
Expand Down Expand Up @@ -1745,12 +1745,12 @@ medusaIntegrationTestRunner({

await remoteLink.create([
{
[Modules.FULFILLMENT]: {
fulfillment_set_id: fulfillmentSet.id,
},
[Modules.STOCK_LOCATION]: {
stock_location_id: location.id,
},
[Modules.FULFILLMENT]: {
fulfillment_set_id: fulfillmentSet.id,
},
},
{
[Modules.FULFILLMENT]: {
Expand Down Expand Up @@ -1849,12 +1849,12 @@ medusaIntegrationTestRunner({
},
},
{
[Modules.FULFILLMENT]: {
fulfillment_set_id: fulfillmentSet.id,
},
[Modules.STOCK_LOCATION]: {
stock_location_id: location.id,
},
[Modules.FULFILLMENT]: {
fulfillment_set_id: fulfillmentSet.id,
},
},
])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1485,8 +1485,8 @@ medusaIntegrationTestRunner({

await remoteLinkService.create([
{
[Modules.FULFILLMENT]: { fulfillment_set_id: fulfillmentSet.id },
[Modules.STOCK_LOCATION]: { stock_location_id: stockLocation.id },
[Modules.FULFILLMENT]: { fulfillment_set_id: fulfillmentSet.id },
},
])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,18 @@ medusaIntegrationTestRunner({

await remoteLink.create([
{
[Modules.FULFILLMENT]: {
fulfillment_set_id: fulfillmentSet.id,
},
[Modules.STOCK_LOCATION]: {
stock_location_id: euWarehouse.id,
},
[Modules.FULFILLMENT]: {
fulfillment_set_id: fulfillmentSet.id,
},
},
])

const linkQuery = remoteQueryObjectFromString({
entryPoint: "fulfillment_sets",
fields: ["id", "stock_locations.id"],
entryPoint: "stock_locations",
fields: ["id", "fulfillment_sets.id"],
})

const link = await remoteQuery(linkQuery)
Expand All @@ -72,10 +72,10 @@ medusaIntegrationTestRunner({
expect(link).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: fulfillmentSet.id,
stock_locations: expect.arrayContaining([
id: euWarehouse.id,
fulfillment_sets: expect.arrayContaining([
expect.objectContaining({
id: euWarehouse.id,
id: fulfillmentSet.id,
}),
]),
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,12 @@ medusaIntegrationTestRunner({

await remoteLinkService.create([
{
[Modules.FULFILLMENT]: {
fulfillment_set_id: fulfillmentSet.id,
},
[Modules.STOCK_LOCATION]: {
stock_location_id: stockLocation.id,
},
[Modules.FULFILLMENT]: {
fulfillment_set_id: fulfillmentSet.id,
},
},
])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ export const associateFulfillmentSetsWithLocationStep = createStep(
.map((link) => {
return link.fulfillment_set_ids.map((id) => {
return {
[Modules.FULFILLMENT]: {
fulfillment_set_id: id,
},
[Modules.STOCK_LOCATION]: {
stock_location_id: link.location_id,
},
[Modules.FULFILLMENT]: {
fulfillment_set_id: id,
},
}
})
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
import {
DeleteEntityInput,
ModuleRegistrationName,
Modules,
} from "@medusajs/modules-sdk"
import { StepResponse, createStep } from "@medusajs/workflows-sdk"

import { ModuleRegistrationName } from "@medusajs/modules-sdk"

export const deleteStockLocationsStepId = "delete-stock-locations-step"
export const deleteStockLocationsStep = createStep(
deleteStockLocationsStepId,
async (input: string[], { container }) => {
const service = container.resolve(ModuleRegistrationName.STOCK_LOCATION)

await service.softDelete(input)
const softDeletedEntities = await service.softDelete(input)

return new StepResponse(void 0, input)
return new StepResponse(
{
[Modules.STOCK_LOCATION]: softDeletedEntities,
} as DeleteEntityInput,
input
)
},
async (deletedLocationIds, { container }) => {
if (!deletedLocationIds?.length) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"

import { Modules } from "@medusajs/modules-sdk"
import { deleteStockLocationsStep } from "../steps"
import { removeRemoteLinkStep } from "../../common/steps/remove-remote-links"
import { deleteStockLocationsStep } from "../steps"

interface WorkflowInput {
ids: string[]
Expand All @@ -12,10 +11,8 @@ export const deleteStockLocationsWorkflowId = "delete-stock-locations-workflow"
export const deleteStockLocationsWorkflow = createWorkflow(
deleteStockLocationsWorkflowId,
(input: WorkflowData<WorkflowInput>) => {
deleteStockLocationsStep(input.ids)
const softDeletedEntities = deleteStockLocationsStep(input.ids)

removeRemoteLinkStep({
[Modules.STOCK_LOCATION]: { stock_location_id: input.ids },
})
removeRemoteLinkStep(softDeletedEntities)
}
)
8 changes: 6 additions & 2 deletions packages/core/types/src/dal/repository-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { Context } from "../shared-context"
import {
BaseFilterable,
FilterQuery,
FindOptions,
FilterQuery as InternalFilterQuery,
FindOptions,
UpsertWithReplaceConfig,
} from "./index"

Expand Down Expand Up @@ -61,7 +61,11 @@ export interface RepositoryService<T = any> extends BaseRepositoryService<T> {
* @returns [T[], Record<string, string[]>] the second value being the map of the entity names and ids that were soft deleted
*/
softDelete(
idsOrFilter: string[] | InternalFilterQuery,
idsOrFilter:
| string
| string[]
| InternalFilterQuery
| InternalFilterQuery[],
context?: Context
): Promise<[T[], Record<string, unknown[]>]>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,11 @@ export interface InternalModuleService<
): Promise<void>

softDelete(
idsOrFilter: string[] | InternalFilterQuery,
idsOrFilter:
| string
| string[]
| InternalFilterQuery
| InternalFilterQuery[],
sharedContext?: Context
): Promise<[TEntity[], Record<string, unknown[]>]>

Expand Down
74 changes: 46 additions & 28 deletions packages/core/utils/src/dal/mikro-orm/mikro-orm-repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
LoadStrategy,
ReferenceType,
RequiredEntityData,
wrap,
} from "@mikro-orm/core"
import { FindOptions as MikroOptions } from "@mikro-orm/core/drivers/IDatabaseDriver"
import {
Expand All @@ -25,19 +24,19 @@ import {
} from "@mikro-orm/core/typings"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import {
MedusaError,
arrayDifference,
isString,
MedusaError,
promiseAll,
} from "../../common"
import { buildQuery } from "../../modules-sdk"
import {
getSoftDeletedCascadedEntitiesIdsMappedBy,
transactionWrapper,
} from "../utils"
import { mikroOrmUpdateDeletedAtRecursively } from "./utils"
import { mikroOrmSerializer } from "./mikro-orm-serializer"
import { dbErrorMapper } from "./db-error-mapper"
import { mikroOrmSerializer } from "./mikro-orm-serializer"
import { mikroOrmUpdateDeletedAtRecursively } from "./utils"

export class MikroOrmBase<T = any> {
readonly manager_: any
Expand Down Expand Up @@ -101,6 +100,17 @@ export class MikroOrmBaseRepository<T extends object = object>
super(...arguments)
}

static buildUniqueCompositeKeyValue(keys: string[], data: object) {
return keys.map((k) => data[k]).join("_")
}

static retrievePrimaryKeys(entity: EntityClass<any> | EntitySchema) {
return (
(entity as EntitySchema).meta?.primaryKeys ??
(entity as EntityClass<any>).prototype.__meta.primaryKeys ?? ["id"]
)
}

create(data: unknown[], context?: Context): Promise<T[]> {
throw new Error("Method not implemented.")
}
Expand Down Expand Up @@ -142,21 +152,14 @@ export class MikroOrmBaseRepository<T extends object = object>
}

async softDelete(
idsOrFilter: string[] | InternalFilterQuery,
filters:
| string
| string[]
| (FilterQuery<T> & BaseFilterable<FilterQuery<T>>)
| (FilterQuery<T> & BaseFilterable<FilterQuery<T>>)[],
sharedContext: Context = {}
): Promise<[T[], Record<string, unknown[]>]> {
const isArray = Array.isArray(idsOrFilter)
// TODO handle composite keys
const filter =
isArray || isString(idsOrFilter)
? {
id: {
$in: isArray ? idsOrFilter : [idsOrFilter],
},
}
: idsOrFilter

const entities = await this.find({ where: filter as any }, sharedContext)
const entities = await this.find({ where: filters as any }, sharedContext)
const date = new Date()

const manager = this.getActiveManager<SqlEntityManager>(sharedContext)
Expand Down Expand Up @@ -286,17 +289,6 @@ export function mikroOrmBaseRepositoryFactory<T extends object = object>(
})
}

static buildUniqueCompositeKeyValue(keys: string[], data: object) {
return keys.map((k) => data[k]).join("_")
}

static retrievePrimaryKeys(entity: EntityClass<T> | EntitySchema<T>) {
return (
(entity as EntitySchema<T>).meta?.primaryKeys ??
(entity as EntityClass<T>).prototype.__meta.primaryKeys ?? ["id"]
)
}

async create(data: any[], context?: Context): Promise<T[]> {
const manager = this.getActiveManager<EntityManager>(context)

Expand Down Expand Up @@ -768,6 +760,32 @@ export function mikroOrmBaseRepositoryFactory<T extends object = object>(

return orderedEntities
}

async softDelete(
filters:
| string
| string[]
| (FilterQuery<T> & BaseFilterable<FilterQuery<T>>)
| (FilterQuery<T> & BaseFilterable<FilterQuery<T>>)[],
sharedContext: Context = {}
): Promise<[T[], Record<string, unknown[]>]> {
const primaryKeys =
MikroOrmAbstractBaseRepository_.retrievePrimaryKeys(entity)

const filterArray = Array.isArray(filters) ? filters : [filters]
const normalizedFilters: FilterQuery = {
$or: filterArray.map((filter) => {
// TODO: add support for composite keys
if (isString(filter)) {
return { [primaryKeys[0]]: filter }
}

return filter
}),
}

return await super.softDelete(normalizedFilters, sharedContext)
}
}

return MikroOrmAbstractBaseRepository_ as unknown as {
Expand Down

0 comments on commit 2f7b534

Please sign in to comment.