feat(fulfillment): Soft deletes (#6630)
**What** - Ensure soft delete works properly according to the soft delete configuration and validate all relation of the entire data model - Add is_enabled to the providers in order to manage new providers to enabled or disabled - include joiner config update FIXES CORE-1853 FIXES CORE-1830 FIXES CORE-1719
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/types": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Feat/fulfillment module soft delete and providers enabled
|
||||||
@@ -6,6 +6,8 @@ export function generateCreateFulfillmentData(
|
|||||||
shipping_option_id: string
|
shipping_option_id: string
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
|
const randomString = Math.random().toString(36).substring(7)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
location_id: "test-location",
|
location_id: "test-location",
|
||||||
packed_at: null,
|
packed_at: null,
|
||||||
@@ -17,28 +19,28 @@ export function generateCreateFulfillmentData(
|
|||||||
shipping_option_id: data.shipping_option_id,
|
shipping_option_id: data.shipping_option_id,
|
||||||
metadata: data.metadata ?? null,
|
metadata: data.metadata ?? null,
|
||||||
delivery_address: data.delivery_address ?? {
|
delivery_address: data.delivery_address ?? {
|
||||||
address_1: "test-address",
|
address_1: "test-address_" + randomString,
|
||||||
address_2: "test-address",
|
address_2: "test-address_" + randomString,
|
||||||
city: "test-city",
|
city: "test-city_" + randomString,
|
||||||
postal_code: "test-postal-code",
|
postal_code: "test-postal-code_" + randomString,
|
||||||
country_code: "test-country-code",
|
country_code: "test-country-code_" + randomString,
|
||||||
province: "test-province",
|
province: "test-province_" + randomString,
|
||||||
phone: "test-phone",
|
phone: "test-phone_" + randomString,
|
||||||
full_name: "test-full-name",
|
full_name: "test-full-name_" + randomString,
|
||||||
},
|
},
|
||||||
items: data.items ?? [
|
items: data.items ?? [
|
||||||
{
|
{
|
||||||
title: "test-title",
|
title: "test-title_" + randomString,
|
||||||
sku: "test-sku",
|
sku: "test-sku_" + randomString,
|
||||||
quantity: 1,
|
quantity: 1,
|
||||||
barcode: "test-barcode",
|
barcode: "test-barcode_" + randomString,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
labels: data.labels ?? [
|
labels: data.labels ?? [
|
||||||
{
|
{
|
||||||
tracking_number: "test-tracking-number",
|
tracking_number: "test-tracking-number_" + randomString,
|
||||||
tracking_url: "test-tracking-url",
|
tracking_url: "test-tracking-url_" + randomString,
|
||||||
label_url: "test-label-url",
|
label_url: "test-label-url_" + randomString,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
order: data.order ?? {},
|
order: data.order ?? {},
|
||||||
|
|||||||
@@ -1,2 +1,52 @@
|
|||||||
|
import { generateCreateShippingOptionsData } from "./shipping-options"
|
||||||
|
import { generateCreateFulfillmentData } from "./fulfillment"
|
||||||
|
import { IFulfillmentModuleService } from "@medusajs/types"
|
||||||
|
|
||||||
export * from "./shipping-options"
|
export * from "./shipping-options"
|
||||||
export * from "./fulfillment"
|
export * from "./fulfillment"
|
||||||
|
|
||||||
|
export async function createFullDataStructure(
|
||||||
|
service: IFulfillmentModuleService,
|
||||||
|
{
|
||||||
|
providerId,
|
||||||
|
}: {
|
||||||
|
providerId: string
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
const randomString = Math.random().toString(36).substring(7)
|
||||||
|
|
||||||
|
const shippingProfile = await service.createShippingProfiles({
|
||||||
|
// generate random string
|
||||||
|
name: "test_" + randomString,
|
||||||
|
type: "default",
|
||||||
|
})
|
||||||
|
const fulfillmentSet = await service.create({
|
||||||
|
name: "test_" + randomString,
|
||||||
|
type: "test-type",
|
||||||
|
})
|
||||||
|
const serviceZone = await service.createServiceZones({
|
||||||
|
name: "test_" + randomString,
|
||||||
|
fulfillment_set_id: fulfillmentSet.id,
|
||||||
|
geo_zones: [
|
||||||
|
{
|
||||||
|
type: "country",
|
||||||
|
country_code: "US_" + randomString,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
|
||||||
|
const shippingOption = await service.createShippingOptions(
|
||||||
|
generateCreateShippingOptionsData({
|
||||||
|
fulfillment_provider_id: providerId,
|
||||||
|
service_zone_id: serviceZone.id,
|
||||||
|
shipping_profile_id: shippingProfile.id,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
await service.createFulfillment(
|
||||||
|
generateCreateFulfillmentData({
|
||||||
|
provider_id: providerId,
|
||||||
|
shipping_option_id: shippingOption.id,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,14 +14,16 @@ export function generateCreateShippingOptionsData({
|
|||||||
name?: string
|
name?: string
|
||||||
type?: CreateShippingOptionDTO["type"]
|
type?: CreateShippingOptionDTO["type"]
|
||||||
}): Required<CreateShippingOptionDTO> {
|
}): Required<CreateShippingOptionDTO> {
|
||||||
|
const randomString = Math.random().toString(36).substring(7)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
service_zone_id: service_zone_id,
|
service_zone_id: service_zone_id,
|
||||||
shipping_profile_id: shipping_profile_id,
|
shipping_profile_id: shipping_profile_id,
|
||||||
fulfillment_provider_id: fulfillment_provider_id,
|
fulfillment_provider_id: fulfillment_provider_id,
|
||||||
type: type ?? {
|
type: type ?? {
|
||||||
code: "test-type",
|
code: "test-type_" + randomString,
|
||||||
description: "test-description",
|
description: "test-description_" + randomString,
|
||||||
label: "test-label",
|
label: "test-label_" + randomString,
|
||||||
},
|
},
|
||||||
data: data ?? {
|
data: data ?? {
|
||||||
amount: 1000,
|
amount: 1000,
|
||||||
|
|||||||
+2
-71
@@ -1,14 +1,11 @@
|
|||||||
import { resolve } from "path"
|
import { resolve } from "path"
|
||||||
import { Modules, ModulesDefinition } from "@medusajs/modules-sdk"
|
import { Modules } from "@medusajs/modules-sdk"
|
||||||
import { IFulfillmentModuleService } from "@medusajs/types"
|
import { IFulfillmentModuleService } from "@medusajs/types"
|
||||||
import { moduleIntegrationTestRunner, SuiteOptions } from "medusa-test-utils"
|
import { moduleIntegrationTestRunner, SuiteOptions } from "medusa-test-utils"
|
||||||
import {
|
import {
|
||||||
generateCreateFulfillmentData,
|
generateCreateFulfillmentData,
|
||||||
generateCreateShippingOptionsData,
|
generateCreateShippingOptionsData,
|
||||||
} from "../../__fixtures__"
|
} from "../../__fixtures__"
|
||||||
import { initModules } from "medusa-test-utils/dist"
|
|
||||||
import { FulfillmentProviderService } from "@services"
|
|
||||||
import { FulfillmentProviderServiceFixtures } from "../../__fixtures__/providers"
|
|
||||||
|
|
||||||
jest.setTimeout(100000)
|
jest.setTimeout(100000)
|
||||||
|
|
||||||
@@ -33,73 +30,7 @@ const providerId = "fixtures-fulfillment-provider_test-provider"
|
|||||||
moduleIntegrationTestRunner({
|
moduleIntegrationTestRunner({
|
||||||
moduleName: Modules.FULFILLMENT,
|
moduleName: Modules.FULFILLMENT,
|
||||||
moduleOptions: moduleOptions,
|
moduleOptions: moduleOptions,
|
||||||
testSuite: ({
|
testSuite: ({ service }: SuiteOptions<IFulfillmentModuleService>) => {
|
||||||
MikroOrmWrapper,
|
|
||||||
service,
|
|
||||||
}: SuiteOptions<IFulfillmentModuleService>) => {
|
|
||||||
describe("Fulfillment Module Service", () => {
|
|
||||||
it("should load and save all the providers on bootstrap", async () => {
|
|
||||||
const databaseConfig = {
|
|
||||||
schema: "public",
|
|
||||||
clientUrl: MikroOrmWrapper.clientUrl,
|
|
||||||
}
|
|
||||||
|
|
||||||
const providersConfig = {}
|
|
||||||
for (let i = 0; i < 10; i++) {
|
|
||||||
providersConfig[`provider-${i}`] = {}
|
|
||||||
}
|
|
||||||
|
|
||||||
const moduleOptions = {
|
|
||||||
databaseConfig,
|
|
||||||
modulesConfig: {
|
|
||||||
[Modules.FULFILLMENT]: {
|
|
||||||
definition: ModulesDefinition[Modules.FULFILLMENT],
|
|
||||||
options: {
|
|
||||||
databaseConfig,
|
|
||||||
providers: [
|
|
||||||
{
|
|
||||||
resolve: resolve(
|
|
||||||
process.cwd() +
|
|
||||||
"/integration-tests/__fixtures__/providers/default-provider"
|
|
||||||
),
|
|
||||||
options: {
|
|
||||||
config: providersConfig,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
const { shutdown } = await initModules(moduleOptions)
|
|
||||||
|
|
||||||
const fulfillmentProviderrs =
|
|
||||||
await MikroOrmWrapper.forkManager().execute(
|
|
||||||
`SELECT * FROM fulfillment_provider`
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(fulfillmentProviderrs).toHaveLength(
|
|
||||||
Object.keys(providersConfig).length + 1 // +1 for the default provider
|
|
||||||
)
|
|
||||||
|
|
||||||
for (const [name] of Object.entries(providersConfig)) {
|
|
||||||
const provider = fulfillmentProviderrs.find((p) => {
|
|
||||||
return (
|
|
||||||
p.id ===
|
|
||||||
FulfillmentProviderService.getRegistrationIdentifier(
|
|
||||||
FulfillmentProviderServiceFixtures,
|
|
||||||
name
|
|
||||||
)
|
|
||||||
)
|
|
||||||
})
|
|
||||||
expect(provider).toBeDefined()
|
|
||||||
}
|
|
||||||
|
|
||||||
await shutdown()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe("Fulfillment Module Service", () => {
|
describe("Fulfillment Module Service", () => {
|
||||||
describe("read", () => {
|
describe("read", () => {
|
||||||
it("should list fulfillment", async () => {
|
it("should list fulfillment", async () => {
|
||||||
|
|||||||
+264
@@ -0,0 +1,264 @@
|
|||||||
|
import { Modules, ModulesDefinition } from "@medusajs/modules-sdk"
|
||||||
|
import { FulfillmentSetDTO, IFulfillmentModuleService } from "@medusajs/types"
|
||||||
|
import {
|
||||||
|
initModules,
|
||||||
|
moduleIntegrationTestRunner,
|
||||||
|
SuiteOptions,
|
||||||
|
} from "medusa-test-utils/dist"
|
||||||
|
import { resolve } from "path"
|
||||||
|
import { createFullDataStructure } from "../../__fixtures__"
|
||||||
|
import { FulfillmentProviderService } from "@services"
|
||||||
|
import { FulfillmentProviderServiceFixtures } from "../../__fixtures__/providers"
|
||||||
|
|
||||||
|
let moduleOptions = {
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
resolve: resolve(
|
||||||
|
process.cwd() +
|
||||||
|
"/integration-tests/__fixtures__/providers/default-provider"
|
||||||
|
),
|
||||||
|
options: {
|
||||||
|
config: {
|
||||||
|
"test-provider": {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
let providerId = "fixtures-fulfillment-provider_test-provider"
|
||||||
|
|
||||||
|
async function list(
|
||||||
|
service: IFulfillmentModuleService,
|
||||||
|
...args: Parameters<IFulfillmentModuleService["list"]>
|
||||||
|
) {
|
||||||
|
const [filters = {}, config = {}] = args
|
||||||
|
|
||||||
|
const finalConfig = {
|
||||||
|
relations: [
|
||||||
|
"service_zones.geo_zones",
|
||||||
|
"service_zones.shipping_options.shipping_profile",
|
||||||
|
"service_zones.shipping_options.fulfillment_provider",
|
||||||
|
"service_zones.shipping_options.type",
|
||||||
|
"service_zones.shipping_options.rules",
|
||||||
|
"service_zones.shipping_options.fulfillments.labels",
|
||||||
|
"service_zones.shipping_options.fulfillments.items",
|
||||||
|
"service_zones.shipping_options.fulfillments.delivery_address",
|
||||||
|
],
|
||||||
|
...config,
|
||||||
|
}
|
||||||
|
|
||||||
|
return await service.list(filters, finalConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
function expectSoftDeleted(
|
||||||
|
fulfillmentSets: FulfillmentSetDTO[],
|
||||||
|
{ softDeleted = false } = {}
|
||||||
|
) {
|
||||||
|
expect(fulfillmentSets).toHaveLength(1)
|
||||||
|
|
||||||
|
let fulfillmentSet = fulfillmentSets[0]
|
||||||
|
expect(!!fulfillmentSet.deleted_at).toEqual(softDeleted)
|
||||||
|
expect(fulfillmentSet.service_zones).toHaveLength(1)
|
||||||
|
|
||||||
|
let serviceZone = fulfillmentSet.service_zones[0]
|
||||||
|
expect(!!serviceZone.deleted_at).toEqual(softDeleted)
|
||||||
|
expect(serviceZone.geo_zones).toHaveLength(1)
|
||||||
|
expect(serviceZone.shipping_options).toHaveLength(1)
|
||||||
|
|
||||||
|
let geoZone = serviceZone.geo_zones[0]
|
||||||
|
expect(!!geoZone.deleted_at).toEqual(softDeleted)
|
||||||
|
|
||||||
|
let shippingOption = serviceZone.shipping_options[0]
|
||||||
|
expect(!!shippingOption.deleted_at).toEqual(softDeleted)
|
||||||
|
expect(!!shippingOption.shipping_profile.deleted_at).toEqual(false)
|
||||||
|
expect(!!shippingOption.type.deleted_at).toEqual(softDeleted)
|
||||||
|
expect(shippingOption.fulfillments).toHaveLength(1)
|
||||||
|
expect(shippingOption.rules).toHaveLength(1)
|
||||||
|
|
||||||
|
let rule = shippingOption.rules[0]
|
||||||
|
expect(!!rule.deleted_at).toEqual(softDeleted)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We do not expect the fulfillment to be soft deleted when soft deleting parents entities
|
||||||
|
*/
|
||||||
|
|
||||||
|
let fulfillment = shippingOption.fulfillments[0]
|
||||||
|
expect(!!fulfillment.deleted_at).toEqual(false)
|
||||||
|
expect(fulfillment.labels).toHaveLength(1)
|
||||||
|
expect(fulfillment.items).toHaveLength(1)
|
||||||
|
|
||||||
|
let label = fulfillment.labels[0]
|
||||||
|
expect(!!label.deleted_at).toEqual(false)
|
||||||
|
|
||||||
|
let item = fulfillment.items[0]
|
||||||
|
expect(!!item.deleted_at).toEqual(false)
|
||||||
|
|
||||||
|
let deliveryAddress = fulfillment.delivery_address
|
||||||
|
expect(!!deliveryAddress.deleted_at).toEqual(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
moduleIntegrationTestRunner({
|
||||||
|
moduleName: Modules.FULFILLMENT,
|
||||||
|
moduleOptions,
|
||||||
|
testSuite: ({
|
||||||
|
MikroOrmWrapper,
|
||||||
|
service,
|
||||||
|
}: SuiteOptions<IFulfillmentModuleService>) =>
|
||||||
|
describe("Fulfillment Module Service", () => {
|
||||||
|
it("should load and save all the providers on bootstrap with the correct is_enabled value", async () => {
|
||||||
|
const databaseConfig = {
|
||||||
|
schema: "public",
|
||||||
|
clientUrl: MikroOrmWrapper.clientUrl,
|
||||||
|
}
|
||||||
|
|
||||||
|
const providersConfig = {}
|
||||||
|
for (let i = 0; i < 10; i++) {
|
||||||
|
providersConfig[`provider-${i}`] = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
let moduleOptions = {
|
||||||
|
databaseConfig,
|
||||||
|
modulesConfig: {
|
||||||
|
[Modules.FULFILLMENT]: {
|
||||||
|
definition: ModulesDefinition[Modules.FULFILLMENT],
|
||||||
|
options: {
|
||||||
|
databaseConfig,
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
resolve: resolve(
|
||||||
|
process.cwd() +
|
||||||
|
"/integration-tests/__fixtures__/providers/default-provider"
|
||||||
|
),
|
||||||
|
options: {
|
||||||
|
config: providersConfig,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
let { shutdown } = await initModules(moduleOptions)
|
||||||
|
|
||||||
|
let fulfillmentProviders = await MikroOrmWrapper.forkManager().execute(
|
||||||
|
`SELECT * FROM fulfillment_provider`
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(fulfillmentProviders).toHaveLength(
|
||||||
|
Object.keys(providersConfig).length + 1 // +1 for the default provider
|
||||||
|
)
|
||||||
|
|
||||||
|
for (const [name] of Object.entries(providersConfig)) {
|
||||||
|
const provider = fulfillmentProviders.find((p) => {
|
||||||
|
return (
|
||||||
|
p.id ===
|
||||||
|
FulfillmentProviderService.getRegistrationIdentifier(
|
||||||
|
FulfillmentProviderServiceFixtures,
|
||||||
|
name
|
||||||
|
)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
expect(provider).toBeDefined()
|
||||||
|
expect(provider.is_enabled).toBeTruthy()
|
||||||
|
}
|
||||||
|
|
||||||
|
await shutdown()
|
||||||
|
|
||||||
|
const providersConfig2 = {}
|
||||||
|
for (let i = 10; i < 20; i++) {
|
||||||
|
providersConfig2[`provider-${i}`] = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
moduleOptions = {
|
||||||
|
databaseConfig,
|
||||||
|
modulesConfig: {
|
||||||
|
[Modules.FULFILLMENT]: {
|
||||||
|
definition: ModulesDefinition[Modules.FULFILLMENT],
|
||||||
|
options: {
|
||||||
|
databaseConfig,
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
resolve: resolve(
|
||||||
|
process.cwd() +
|
||||||
|
"/integration-tests/__fixtures__/providers/default-provider"
|
||||||
|
),
|
||||||
|
options: {
|
||||||
|
config: providersConfig2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const medusaApp = await initModules(moduleOptions)
|
||||||
|
shutdown = medusaApp.shutdown
|
||||||
|
|
||||||
|
fulfillmentProviders = await MikroOrmWrapper.forkManager().execute(
|
||||||
|
`SELECT * FROM fulfillment_provider`
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(fulfillmentProviders).toHaveLength(
|
||||||
|
Object.keys(providersConfig2).length +
|
||||||
|
Object.keys(providersConfig).length +
|
||||||
|
1 // +1 for the default provider
|
||||||
|
)
|
||||||
|
|
||||||
|
const allProviders = Object.assign(
|
||||||
|
{},
|
||||||
|
providersConfig,
|
||||||
|
providersConfig2
|
||||||
|
)
|
||||||
|
|
||||||
|
for (const [name] of Object.entries(allProviders)) {
|
||||||
|
const provider = fulfillmentProviders.find((p) => {
|
||||||
|
return (
|
||||||
|
p.id ===
|
||||||
|
FulfillmentProviderService.getRegistrationIdentifier(
|
||||||
|
FulfillmentProviderServiceFixtures,
|
||||||
|
name
|
||||||
|
)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
expect(provider).toBeDefined()
|
||||||
|
|
||||||
|
const isEnabled = !!providersConfig2[name]
|
||||||
|
expect(provider.is_enabled).toEqual(isEnabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
await shutdown().catch(() => void 0)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should soft delete and restore the data respecting the configured cascade", async () => {
|
||||||
|
await createFullDataStructure(service, { providerId })
|
||||||
|
|
||||||
|
let fulfillmentSets = await list(service)
|
||||||
|
expectSoftDeleted(fulfillmentSets)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Soft delete the fulfillment set
|
||||||
|
*/
|
||||||
|
|
||||||
|
await service.softDelete(fulfillmentSets[0].id)
|
||||||
|
const deletedFulfillmentSets = await list(
|
||||||
|
service,
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
withDeleted: true,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
expectSoftDeleted(deletedFulfillmentSets, { softDeleted: true })
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore the fulfillment set
|
||||||
|
*/
|
||||||
|
|
||||||
|
await service.restore(fulfillmentSets[0].id)
|
||||||
|
const restoredFulfillmentSets = await list(service)
|
||||||
|
expectSoftDeleted(restoredFulfillmentSets)
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
})
|
||||||
@@ -1,10 +1,20 @@
|
|||||||
import { Modules } from "@medusajs/modules-sdk"
|
import { Modules } from "@medusajs/modules-sdk"
|
||||||
import { ModuleJoinerConfig } from "@medusajs/types"
|
import { ModuleJoinerConfig } from "@medusajs/types"
|
||||||
import { MapToConfig } from "@medusajs/utils"
|
import { MapToConfig } from "@medusajs/utils"
|
||||||
|
import {
|
||||||
|
Fulfillment,
|
||||||
|
FulfillmentSet,
|
||||||
|
GeoZone,
|
||||||
|
ServiceZone,
|
||||||
|
ShippingOption,
|
||||||
|
ShippingProfile,
|
||||||
|
} from "@models"
|
||||||
|
|
||||||
// TODO manage the config
|
export const LinkableKeys: Record<string, string> = {
|
||||||
|
fulfillment_id: Fulfillment.name,
|
||||||
export const LinkableKeys: Record<string, string> = {}
|
fulfillment_set_id: FulfillmentSet.name,
|
||||||
|
shipping_option_id: ShippingOption.name,
|
||||||
|
}
|
||||||
|
|
||||||
const entityLinkableKeysMap: MapToConfig = {}
|
const entityLinkableKeysMap: MapToConfig = {}
|
||||||
Object.entries(LinkableKeys).forEach(([key, value]) => {
|
Object.entries(LinkableKeys).forEach(([key, value]) => {
|
||||||
@@ -21,5 +31,47 @@ export const joinerConfig: ModuleJoinerConfig = {
|
|||||||
serviceName: Modules.FULFILLMENT,
|
serviceName: Modules.FULFILLMENT,
|
||||||
primaryKeys: ["id"],
|
primaryKeys: ["id"],
|
||||||
linkableKeys: LinkableKeys,
|
linkableKeys: LinkableKeys,
|
||||||
alias: [],
|
alias: [
|
||||||
|
{
|
||||||
|
name: ["fulfillment_set", "fulfillment_sets"],
|
||||||
|
args: {
|
||||||
|
entity: FulfillmentSet.name,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: ["shipping_option", "shipping_options"],
|
||||||
|
args: {
|
||||||
|
entity: ShippingOption.name,
|
||||||
|
methodSuffix: "ShippingOptions",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: ["shipping_profile", "shipping_profiles"],
|
||||||
|
args: {
|
||||||
|
entity: ShippingProfile.name,
|
||||||
|
methodSuffix: "ShippingProfiles",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: ["fulfillment", "fulfillments"],
|
||||||
|
args: {
|
||||||
|
entity: Fulfillment.name,
|
||||||
|
methodSuffix: "Fulfillments",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: ["service_zone", "service_zones"],
|
||||||
|
args: {
|
||||||
|
entity: ServiceZone.name,
|
||||||
|
methodSuffix: "ServiceZones",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: ["geo_zone", "geo_zones"],
|
||||||
|
args: {
|
||||||
|
entity: GeoZone.name,
|
||||||
|
methodSuffix: "GeoZones",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
} as ModuleJoinerConfig
|
} as ModuleJoinerConfig
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { moduleProviderLoader } from "@medusajs/modules-sdk"
|
|||||||
import { LoaderOptions, ModuleProvider, ModulesSdkTypes } from "@medusajs/types"
|
import { LoaderOptions, ModuleProvider, ModulesSdkTypes } from "@medusajs/types"
|
||||||
import { asFunction, asValue, Lifetime } from "awilix"
|
import { asFunction, asValue, Lifetime } from "awilix"
|
||||||
import { FulfillmentIdentifiersRegistrationName } from "@types"
|
import { FulfillmentIdentifiersRegistrationName } from "@types"
|
||||||
import { lowerCaseFirst } from "@medusajs/utils"
|
import { lowerCaseFirst, promiseAll } from "@medusajs/utils"
|
||||||
import { FulfillmentProviderService } from "@services"
|
import { FulfillmentProviderService } from "@services"
|
||||||
import { ContainerRegistrationKeys } from "@medusajs/utils/src"
|
import { ContainerRegistrationKeys } from "@medusajs/utils/src"
|
||||||
|
|
||||||
@@ -56,7 +56,8 @@ async function syncDatabaseProviders({ container }) {
|
|||||||
FulfillmentProviderService.name
|
FulfillmentProviderService.name
|
||||||
)
|
)
|
||||||
|
|
||||||
const logger = container.resolve(ContainerRegistrationKeys.LOGGER)
|
const logger = container.resolve(ContainerRegistrationKeys.LOGGER) ?? console
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const providerIdentifiers: string[] = (
|
const providerIdentifiers: string[] = (
|
||||||
container.resolve(FulfillmentIdentifiersRegistrationName) ?? []
|
container.resolve(FulfillmentIdentifiersRegistrationName) ?? []
|
||||||
@@ -65,22 +66,44 @@ async function syncDatabaseProviders({ container }) {
|
|||||||
const providerService: ModulesSdkTypes.InternalModuleService<any> =
|
const providerService: ModulesSdkTypes.InternalModuleService<any> =
|
||||||
container.resolve(providerServiceRegistrationKey)
|
container.resolve(providerServiceRegistrationKey)
|
||||||
|
|
||||||
const providers = await providerService.list({
|
const providers = await providerService.list({})
|
||||||
id: providerIdentifiers,
|
|
||||||
})
|
|
||||||
|
|
||||||
const loadedProvidersMap = new Map(providers.map((p) => [p.id, p]))
|
const loadedProvidersMap = new Map(providers.map((p) => [p.id, p]))
|
||||||
|
|
||||||
const providersToCreate: any[] = []
|
const providersToCreate = providerIdentifiers.filter(
|
||||||
for (const identifier of providerIdentifiers) {
|
(id) => !loadedProvidersMap.has(id)
|
||||||
if (loadedProvidersMap.has(identifier)) {
|
)
|
||||||
continue
|
const providersToEnabled = providerIdentifiers.filter((id) =>
|
||||||
}
|
loadedProvidersMap.has(id)
|
||||||
|
)
|
||||||
|
const providersToDisable = providers.filter(
|
||||||
|
(p) => !providerIdentifiers.includes(p.id)
|
||||||
|
)
|
||||||
|
|
||||||
providersToCreate.push({ id: identifier })
|
const promises: Promise<any>[] = []
|
||||||
|
|
||||||
|
if (providersToCreate.length) {
|
||||||
|
promises.push(
|
||||||
|
providerService.create(providersToCreate.map((id) => ({ id })))
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
await providerService.create(providersToCreate)
|
if (providersToEnabled.length) {
|
||||||
|
promises.push(
|
||||||
|
providerService.update(
|
||||||
|
providersToEnabled.map((id) => ({ id, is_enabled: true }))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (providersToDisable.length) {
|
||||||
|
promises.push(
|
||||||
|
providerService.update(
|
||||||
|
providersToDisable.map((p) => ({ id: p.id, is_enabled: false }))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
await promiseAll(promises)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`Error syncing providers: ${error.message}`)
|
logger.error(`Error syncing providers: ${error.message}`)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -184,61 +184,20 @@
|
|||||||
"nullable": false,
|
"nullable": false,
|
||||||
"mappedType": "text"
|
"mappedType": "text"
|
||||||
},
|
},
|
||||||
"metadata": {
|
"is_enabled": {
|
||||||
"name": "metadata",
|
"name": "is_enabled",
|
||||||
"type": "jsonb",
|
"type": "boolean",
|
||||||
"unsigned": false,
|
|
||||||
"autoincrement": false,
|
|
||||||
"primary": false,
|
|
||||||
"nullable": true,
|
|
||||||
"mappedType": "json"
|
|
||||||
},
|
|
||||||
"created_at": {
|
|
||||||
"name": "created_at",
|
|
||||||
"type": "timestamptz",
|
|
||||||
"unsigned": false,
|
"unsigned": false,
|
||||||
"autoincrement": false,
|
"autoincrement": false,
|
||||||
"primary": false,
|
"primary": false,
|
||||||
"nullable": false,
|
"nullable": false,
|
||||||
"length": 6,
|
"default": "true",
|
||||||
"default": "now()",
|
"mappedType": "boolean"
|
||||||
"mappedType": "datetime"
|
|
||||||
},
|
|
||||||
"updated_at": {
|
|
||||||
"name": "updated_at",
|
|
||||||
"type": "timestamptz",
|
|
||||||
"unsigned": false,
|
|
||||||
"autoincrement": false,
|
|
||||||
"primary": false,
|
|
||||||
"nullable": false,
|
|
||||||
"length": 6,
|
|
||||||
"default": "now()",
|
|
||||||
"mappedType": "datetime"
|
|
||||||
},
|
|
||||||
"deleted_at": {
|
|
||||||
"name": "deleted_at",
|
|
||||||
"type": "timestamptz",
|
|
||||||
"unsigned": false,
|
|
||||||
"autoincrement": false,
|
|
||||||
"primary": false,
|
|
||||||
"nullable": true,
|
|
||||||
"length": 6,
|
|
||||||
"mappedType": "datetime"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"name": "fulfillment_provider",
|
"name": "fulfillment_provider",
|
||||||
"schema": "public",
|
"schema": "public",
|
||||||
"indexes": [
|
"indexes": [
|
||||||
{
|
|
||||||
"keyName": "IDX_fulfillment_provider_deleted_at",
|
|
||||||
"columnNames": [
|
|
||||||
"deleted_at"
|
|
||||||
],
|
|
||||||
"composite": false,
|
|
||||||
"primary": false,
|
|
||||||
"unique": false,
|
|
||||||
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_fulfillment_provider_deleted_at\" ON \"fulfillment_provider\" (deleted_at) WHERE deleted_at IS NOT NULL"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"keyName": "fulfillment_provider_pkey",
|
"keyName": "fulfillment_provider_pkey",
|
||||||
"columnNames": [
|
"columnNames": [
|
||||||
@@ -485,6 +444,7 @@
|
|||||||
"id"
|
"id"
|
||||||
],
|
],
|
||||||
"referencedTableName": "public.fulfillment_set",
|
"referencedTableName": "public.fulfillment_set",
|
||||||
|
"deleteRule": "cascade",
|
||||||
"updateRule": "cascade"
|
"updateRule": "cascade"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -678,6 +638,7 @@
|
|||||||
"id"
|
"id"
|
||||||
],
|
],
|
||||||
"referencedTableName": "public.service_zone",
|
"referencedTableName": "public.service_zone",
|
||||||
|
"deleteRule": "cascade",
|
||||||
"updateRule": "cascade"
|
"updateRule": "cascade"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -971,7 +932,7 @@
|
|||||||
"unsigned": false,
|
"unsigned": false,
|
||||||
"autoincrement": false,
|
"autoincrement": false,
|
||||||
"primary": false,
|
"primary": false,
|
||||||
"nullable": true,
|
"nullable": false,
|
||||||
"mappedType": "text"
|
"mappedType": "text"
|
||||||
},
|
},
|
||||||
"created_at": {
|
"created_at": {
|
||||||
@@ -1091,6 +1052,7 @@
|
|||||||
"id"
|
"id"
|
||||||
],
|
],
|
||||||
"referencedTableName": "public.service_zone",
|
"referencedTableName": "public.service_zone",
|
||||||
|
"deleteRule": "cascade",
|
||||||
"updateRule": "cascade"
|
"updateRule": "cascade"
|
||||||
},
|
},
|
||||||
"shipping_option_shipping_profile_id_foreign": {
|
"shipping_option_shipping_profile_id_foreign": {
|
||||||
@@ -1269,6 +1231,7 @@
|
|||||||
"id"
|
"id"
|
||||||
],
|
],
|
||||||
"referencedTableName": "public.shipping_option",
|
"referencedTableName": "public.shipping_option",
|
||||||
|
"deleteRule": "cascade",
|
||||||
"updateRule": "cascade"
|
"updateRule": "cascade"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1348,7 +1311,7 @@
|
|||||||
"unsigned": false,
|
"unsigned": false,
|
||||||
"autoincrement": false,
|
"autoincrement": false,
|
||||||
"primary": false,
|
"primary": false,
|
||||||
"nullable": false,
|
"nullable": true,
|
||||||
"mappedType": "text"
|
"mappedType": "text"
|
||||||
},
|
},
|
||||||
"shipping_option_id": {
|
"shipping_option_id": {
|
||||||
@@ -1375,7 +1338,7 @@
|
|||||||
"unsigned": false,
|
"unsigned": false,
|
||||||
"autoincrement": false,
|
"autoincrement": false,
|
||||||
"primary": false,
|
"primary": false,
|
||||||
"nullable": false,
|
"nullable": true,
|
||||||
"mappedType": "text"
|
"mappedType": "text"
|
||||||
},
|
},
|
||||||
"created_at": {
|
"created_at": {
|
||||||
@@ -1485,6 +1448,7 @@
|
|||||||
"id"
|
"id"
|
||||||
],
|
],
|
||||||
"referencedTableName": "public.fulfillment_provider",
|
"referencedTableName": "public.fulfillment_provider",
|
||||||
|
"deleteRule": "set null",
|
||||||
"updateRule": "cascade"
|
"updateRule": "cascade"
|
||||||
},
|
},
|
||||||
"fulfillment_shipping_option_id_foreign": {
|
"fulfillment_shipping_option_id_foreign": {
|
||||||
@@ -1510,6 +1474,7 @@
|
|||||||
"id"
|
"id"
|
||||||
],
|
],
|
||||||
"referencedTableName": "public.fulfillment_address",
|
"referencedTableName": "public.fulfillment_address",
|
||||||
|
"deleteRule": "cascade",
|
||||||
"updateRule": "cascade"
|
"updateRule": "cascade"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-11
@@ -1,13 +1,12 @@
|
|||||||
import { Migration } from '@mikro-orm/migrations';
|
import { Migration } from '@mikro-orm/migrations';
|
||||||
|
|
||||||
export class Migration20240305095931_InitialSetupMigration extends Migration {
|
export class Migration20240311145700_InitialSetupMigration extends Migration {
|
||||||
|
|
||||||
async up(): Promise<void> {
|
async up(): Promise<void> {
|
||||||
this.addSql('create table if not exists "fulfillment_address" ("id" text not null, "company" text null, "first_name" text null, "last_name" text null, "address_1" text null, "address_2" text null, "city" text null, "country_code" text null, "province" text null, "postal_code" text null, "phone" text null, "metadata" jsonb null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "fulfillment_address_pkey" primary key ("id"));');
|
this.addSql('create table if not exists "fulfillment_address" ("id" text not null, "company" text null, "first_name" text null, "last_name" text null, "address_1" text null, "address_2" text null, "city" text null, "country_code" text null, "province" text null, "postal_code" text null, "phone" text null, "metadata" jsonb null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "fulfillment_address_pkey" primary key ("id"));');
|
||||||
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_fulfillment_address_deleted_at" ON "fulfillment_address" (deleted_at) WHERE deleted_at IS NOT NULL;');
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_fulfillment_address_deleted_at" ON "fulfillment_address" (deleted_at) WHERE deleted_at IS NOT NULL;');
|
||||||
|
|
||||||
this.addSql('create table if not exists "fulfillment_provider" ("id" text not null, "metadata" jsonb null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "fulfillment_provider_pkey" primary key ("id"));');
|
this.addSql('create table if not exists "fulfillment_provider" ("id" text not null, "is_enabled" boolean not null default true, constraint "fulfillment_provider_pkey" primary key ("id"));');
|
||||||
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_fulfillment_provider_deleted_at" ON "fulfillment_provider" (deleted_at) WHERE deleted_at IS NOT NULL;');
|
|
||||||
|
|
||||||
this.addSql('create table if not exists "fulfillment_set" ("id" text not null, "name" text not null, "type" text not null, "metadata" jsonb null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "fulfillment_set_pkey" primary key ("id"));');
|
this.addSql('create table if not exists "fulfillment_set" ("id" text not null, "name" text not null, "type" text not null, "metadata" jsonb null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "fulfillment_set_pkey" primary key ("id"));');
|
||||||
this.addSql('CREATE UNIQUE INDEX IF NOT EXISTS "IDX_fulfillment_set_name_unique" ON "fulfillment_set" (name) WHERE deleted_at IS NULL;');
|
this.addSql('CREATE UNIQUE INDEX IF NOT EXISTS "IDX_fulfillment_set_name_unique" ON "fulfillment_set" (name) WHERE deleted_at IS NULL;');
|
||||||
@@ -32,7 +31,7 @@ export class Migration20240305095931_InitialSetupMigration extends Migration {
|
|||||||
this.addSql('CREATE UNIQUE INDEX IF NOT EXISTS "IDX_shipping_profile_name_unique" ON "shipping_profile" (name) WHERE deleted_at IS NULL;');
|
this.addSql('CREATE UNIQUE INDEX IF NOT EXISTS "IDX_shipping_profile_name_unique" ON "shipping_profile" (name) WHERE deleted_at IS NULL;');
|
||||||
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_shipping_profile_deleted_at" ON "shipping_profile" (deleted_at) WHERE deleted_at IS NOT NULL;');
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_shipping_profile_deleted_at" ON "shipping_profile" (deleted_at) WHERE deleted_at IS NOT NULL;');
|
||||||
|
|
||||||
this.addSql('create table if not exists "shipping_option" ("id" text not null, "name" text not null, "price_type" text check ("price_type" in (\'calculated\', \'flat\')) not null default \'calculated\', "service_zone_id" text not null, "shipping_profile_id" text null, "fulfillment_provider_id" text null, "data" jsonb null, "metadata" jsonb null, "shipping_option_type_id" text null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "shipping_option_pkey" primary key ("id"));');
|
this.addSql('create table if not exists "shipping_option" ("id" text not null, "name" text not null, "price_type" text check ("price_type" in (\'calculated\', \'flat\')) not null default \'calculated\', "service_zone_id" text not null, "shipping_profile_id" text null, "fulfillment_provider_id" text null, "data" jsonb null, "metadata" jsonb null, "shipping_option_type_id" text not null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "shipping_option_pkey" primary key ("id"));');
|
||||||
this.addSql('alter table if exists "shipping_option" add constraint "shipping_option_shipping_option_type_id_unique" unique ("shipping_option_type_id");');
|
this.addSql('alter table if exists "shipping_option" add constraint "shipping_option_shipping_option_type_id_unique" unique ("shipping_option_type_id");');
|
||||||
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_shipping_option_service_zone_id" ON "shipping_option" (service_zone_id) WHERE deleted_at IS NULL;');
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_shipping_option_service_zone_id" ON "shipping_option" (service_zone_id) WHERE deleted_at IS NULL;');
|
||||||
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_shipping_option_shipping_profile_id" ON "shipping_option" (shipping_profile_id) WHERE deleted_at IS NULL;');
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_shipping_option_shipping_profile_id" ON "shipping_option" (shipping_profile_id) WHERE deleted_at IS NULL;');
|
||||||
@@ -44,7 +43,7 @@ export class Migration20240305095931_InitialSetupMigration extends Migration {
|
|||||||
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_shipping_option_rule_shipping_option_id" ON "shipping_option_rule" (shipping_option_id) WHERE deleted_at IS NULL;');
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_shipping_option_rule_shipping_option_id" ON "shipping_option_rule" (shipping_option_id) WHERE deleted_at IS NULL;');
|
||||||
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_shipping_option_rule_deleted_at" ON "shipping_option_rule" (deleted_at) WHERE deleted_at IS NOT NULL;');
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_shipping_option_rule_deleted_at" ON "shipping_option_rule" (deleted_at) WHERE deleted_at IS NOT NULL;');
|
||||||
|
|
||||||
this.addSql('create table if not exists "fulfillment" ("id" text not null, "location_id" text not null, "packed_at" timestamptz null, "shipped_at" timestamptz null, "delivered_at" timestamptz null, "canceled_at" timestamptz null, "data" jsonb null, "provider_id" text not null, "shipping_option_id" text null, "metadata" jsonb null, "delivery_address_id" text not null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "fulfillment_pkey" primary key ("id"));');
|
this.addSql('create table if not exists "fulfillment" ("id" text not null, "location_id" text not null, "packed_at" timestamptz null, "shipped_at" timestamptz null, "delivered_at" timestamptz null, "canceled_at" timestamptz null, "data" jsonb null, "provider_id" text null, "shipping_option_id" text null, "metadata" jsonb null, "delivery_address_id" text null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "fulfillment_pkey" primary key ("id"));');
|
||||||
this.addSql('alter table if exists "fulfillment" add constraint "fulfillment_delivery_address_id_unique" unique ("delivery_address_id");');
|
this.addSql('alter table if exists "fulfillment" add constraint "fulfillment_delivery_address_id_unique" unique ("delivery_address_id");');
|
||||||
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_fulfillment_location_id" ON "fulfillment" (location_id) WHERE deleted_at IS NULL;');
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_fulfillment_location_id" ON "fulfillment" (location_id) WHERE deleted_at IS NULL;');
|
||||||
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_fulfillment_provider_id" ON "fulfillment" (provider_id) WHERE deleted_at IS NULL;');
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_fulfillment_provider_id" ON "fulfillment" (provider_id) WHERE deleted_at IS NULL;');
|
||||||
@@ -61,20 +60,20 @@ export class Migration20240305095931_InitialSetupMigration extends Migration {
|
|||||||
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_fulfillment_item_fulfillment_id" ON "fulfillment_item" (fulfillment_id) WHERE deleted_at IS NULL;');
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_fulfillment_item_fulfillment_id" ON "fulfillment_item" (fulfillment_id) WHERE deleted_at IS NULL;');
|
||||||
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_fulfillment_item_deleted_at" ON "fulfillment_item" (deleted_at) WHERE deleted_at IS NOT NULL;');
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_fulfillment_item_deleted_at" ON "fulfillment_item" (deleted_at) WHERE deleted_at IS NOT NULL;');
|
||||||
|
|
||||||
this.addSql('alter table if exists "service_zone" add constraint "service_zone_fulfillment_set_id_foreign" foreign key ("fulfillment_set_id") references "fulfillment_set" ("id") on update cascade;');
|
this.addSql('alter table if exists "service_zone" add constraint "service_zone_fulfillment_set_id_foreign" foreign key ("fulfillment_set_id") references "fulfillment_set" ("id") on update cascade on delete cascade;');
|
||||||
|
|
||||||
this.addSql('alter table if exists "geo_zone" add constraint "geo_zone_service_zone_id_foreign" foreign key ("service_zone_id") references "service_zone" ("id") on update cascade;');
|
this.addSql('alter table if exists "geo_zone" add constraint "geo_zone_service_zone_id_foreign" foreign key ("service_zone_id") references "service_zone" ("id") on update cascade on delete cascade;');
|
||||||
|
|
||||||
this.addSql('alter table if exists "shipping_option" add constraint "shipping_option_service_zone_id_foreign" foreign key ("service_zone_id") references "service_zone" ("id") on update cascade;');
|
this.addSql('alter table if exists "shipping_option" add constraint "shipping_option_service_zone_id_foreign" foreign key ("service_zone_id") references "service_zone" ("id") on update cascade on delete cascade;');
|
||||||
this.addSql('alter table if exists "shipping_option" add constraint "shipping_option_shipping_profile_id_foreign" foreign key ("shipping_profile_id") references "shipping_profile" ("id") on update cascade on delete set null;');
|
this.addSql('alter table if exists "shipping_option" add constraint "shipping_option_shipping_profile_id_foreign" foreign key ("shipping_profile_id") references "shipping_profile" ("id") on update cascade on delete set null;');
|
||||||
this.addSql('alter table if exists "shipping_option" add constraint "shipping_option_fulfillment_provider_id_foreign" foreign key ("fulfillment_provider_id") references "fulfillment_provider" ("id") on update cascade on delete set null;');
|
this.addSql('alter table if exists "shipping_option" add constraint "shipping_option_fulfillment_provider_id_foreign" foreign key ("fulfillment_provider_id") references "fulfillment_provider" ("id") on update cascade on delete set null;');
|
||||||
this.addSql('alter table if exists "shipping_option" add constraint "shipping_option_shipping_option_type_id_foreign" foreign key ("shipping_option_type_id") references "shipping_option_type" ("id") on update cascade on delete cascade;');
|
this.addSql('alter table if exists "shipping_option" add constraint "shipping_option_shipping_option_type_id_foreign" foreign key ("shipping_option_type_id") references "shipping_option_type" ("id") on update cascade on delete cascade;');
|
||||||
|
|
||||||
this.addSql('alter table if exists "shipping_option_rule" add constraint "shipping_option_rule_shipping_option_id_foreign" foreign key ("shipping_option_id") references "shipping_option" ("id") on update cascade;');
|
this.addSql('alter table if exists "shipping_option_rule" add constraint "shipping_option_rule_shipping_option_id_foreign" foreign key ("shipping_option_id") references "shipping_option" ("id") on update cascade on delete cascade;');
|
||||||
|
|
||||||
this.addSql('alter table if exists "fulfillment" add constraint "fulfillment_provider_id_foreign" foreign key ("provider_id") references "fulfillment_provider" ("id") on update cascade;');
|
this.addSql('alter table if exists "fulfillment" add constraint "fulfillment_provider_id_foreign" foreign key ("provider_id") references "fulfillment_provider" ("id") on update cascade on delete set null;');
|
||||||
this.addSql('alter table if exists "fulfillment" add constraint "fulfillment_shipping_option_id_foreign" foreign key ("shipping_option_id") references "shipping_option" ("id") on update cascade on delete set null;');
|
this.addSql('alter table if exists "fulfillment" add constraint "fulfillment_shipping_option_id_foreign" foreign key ("shipping_option_id") references "shipping_option" ("id") on update cascade on delete set null;');
|
||||||
this.addSql('alter table if exists "fulfillment" add constraint "fulfillment_delivery_address_id_foreign" foreign key ("delivery_address_id") references "fulfillment_address" ("id") on update cascade;');
|
this.addSql('alter table if exists "fulfillment" add constraint "fulfillment_delivery_address_id_foreign" foreign key ("delivery_address_id") references "fulfillment_address" ("id") on update cascade on delete cascade;');
|
||||||
|
|
||||||
this.addSql('alter table if exists "fulfillment_label" add constraint "fulfillment_label_fulfillment_id_foreign" foreign key ("fulfillment_id") references "fulfillment" ("id") on update cascade on delete cascade;');
|
this.addSql('alter table if exists "fulfillment_label" add constraint "fulfillment_label_fulfillment_id_foreign" foreign key ("fulfillment_id") references "fulfillment" ("id") on update cascade on delete cascade;');
|
||||||
|
|
||||||
@@ -1,66 +1,19 @@
|
|||||||
import {
|
import { generateEntityId } from "@medusajs/utils"
|
||||||
createPsqlIndexStatementHelper,
|
|
||||||
DALUtils,
|
|
||||||
generateEntityId,
|
|
||||||
} from "@medusajs/utils"
|
|
||||||
|
|
||||||
import { DAL } from "@medusajs/types"
|
|
||||||
import {
|
import {
|
||||||
BeforeCreate,
|
BeforeCreate,
|
||||||
Collection,
|
|
||||||
Entity,
|
Entity,
|
||||||
Filter,
|
|
||||||
OneToMany,
|
|
||||||
OnInit,
|
OnInit,
|
||||||
OptionalProps,
|
|
||||||
PrimaryKey,
|
PrimaryKey,
|
||||||
Property,
|
Property,
|
||||||
} from "@mikro-orm/core"
|
} from "@mikro-orm/core"
|
||||||
import ShippingOption from "./shipping-option"
|
|
||||||
|
|
||||||
type FulfillmentProviderOptionalProps = DAL.SoftDeletableEntityDateColumns
|
|
||||||
|
|
||||||
const DeletedAtIndex = createPsqlIndexStatementHelper({
|
|
||||||
tableName: "fulfillment_provider",
|
|
||||||
columns: "deleted_at",
|
|
||||||
where: "deleted_at IS NOT NULL",
|
|
||||||
})
|
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
|
|
||||||
export default class FulfillmentProvider {
|
export default class FulfillmentProvider {
|
||||||
[OptionalProps]?: FulfillmentProviderOptionalProps
|
|
||||||
|
|
||||||
@PrimaryKey({ columnType: "text" })
|
@PrimaryKey({ columnType: "text" })
|
||||||
id: string
|
id: string
|
||||||
|
|
||||||
@Property({ columnType: "jsonb", nullable: true })
|
@Property({ columnType: "boolean", defaultRaw: "true" })
|
||||||
metadata: Record<string, unknown> | null = null
|
is_enabled: boolean = true
|
||||||
|
|
||||||
@OneToMany(
|
|
||||||
() => ShippingOption,
|
|
||||||
(shippingOption) => shippingOption.fulfillment_provider
|
|
||||||
)
|
|
||||||
shipping_options = new Collection<ShippingOption>(this)
|
|
||||||
|
|
||||||
@Property({
|
|
||||||
onCreate: () => new Date(),
|
|
||||||
columnType: "timestamptz",
|
|
||||||
defaultRaw: "now()",
|
|
||||||
})
|
|
||||||
created_at: Date
|
|
||||||
|
|
||||||
@Property({
|
|
||||||
onCreate: () => new Date(),
|
|
||||||
onUpdate: () => new Date(),
|
|
||||||
columnType: "timestamptz",
|
|
||||||
defaultRaw: "now()",
|
|
||||||
})
|
|
||||||
updated_at: Date
|
|
||||||
|
|
||||||
@DeletedAtIndex.MikroORMIndex()
|
|
||||||
@Property({ columnType: "timestamptz", nullable: true })
|
|
||||||
deleted_at: Date | null = null
|
|
||||||
|
|
||||||
@BeforeCreate()
|
@BeforeCreate()
|
||||||
onCreate() {
|
onCreate() {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
import { DAL } from "@medusajs/types"
|
import { DAL } from "@medusajs/types"
|
||||||
import {
|
import {
|
||||||
BeforeCreate,
|
BeforeCreate,
|
||||||
|
Cascade,
|
||||||
Collection,
|
Collection,
|
||||||
Entity,
|
Entity,
|
||||||
Filter,
|
Filter,
|
||||||
@@ -93,6 +94,8 @@ export default class Fulfillment {
|
|||||||
columnType: "text",
|
columnType: "text",
|
||||||
fieldName: "provider_id",
|
fieldName: "provider_id",
|
||||||
mapToPk: true,
|
mapToPk: true,
|
||||||
|
nullable: true,
|
||||||
|
onDelete: "set null",
|
||||||
})
|
})
|
||||||
@FulfillmentProviderIdIndex.MikroORMIndex()
|
@FulfillmentProviderIdIndex.MikroORMIndex()
|
||||||
provider_id: string
|
provider_id: string
|
||||||
@@ -102,6 +105,7 @@ export default class Fulfillment {
|
|||||||
fieldName: "shipping_option_id",
|
fieldName: "shipping_option_id",
|
||||||
nullable: true,
|
nullable: true,
|
||||||
mapToPk: true,
|
mapToPk: true,
|
||||||
|
onDelete: "set null",
|
||||||
})
|
})
|
||||||
@FulfillmentShippingOptionIdIndex.MikroORMIndex()
|
@FulfillmentShippingOptionIdIndex.MikroORMIndex()
|
||||||
shipping_option_id: string | null = null
|
shipping_option_id: string | null = null
|
||||||
@@ -115,13 +119,25 @@ export default class Fulfillment {
|
|||||||
@ManyToOne(() => FulfillmentProvider, { persist: false })
|
@ManyToOne(() => FulfillmentProvider, { persist: false })
|
||||||
provider: FulfillmentProvider
|
provider: FulfillmentProvider
|
||||||
|
|
||||||
@OneToOne()
|
@OneToOne({
|
||||||
|
entity: () => Address,
|
||||||
|
owner: true,
|
||||||
|
cascade: [Cascade.PERSIST, "soft-remove"] as any,
|
||||||
|
nullable: true,
|
||||||
|
onDelete: "cascade",
|
||||||
|
})
|
||||||
delivery_address!: Address
|
delivery_address!: Address
|
||||||
|
|
||||||
@OneToMany(() => FulfillmentItem, (item) => item.fulfillment)
|
@OneToMany(() => FulfillmentItem, (item) => item.fulfillment, {
|
||||||
|
cascade: [Cascade.PERSIST, "soft-remove"] as any,
|
||||||
|
orphanRemoval: true,
|
||||||
|
})
|
||||||
items = new Collection<FulfillmentItem>(this)
|
items = new Collection<FulfillmentItem>(this)
|
||||||
|
|
||||||
@OneToMany(() => FulfillmentLabel, (label) => label.fulfillment)
|
@OneToMany(() => FulfillmentLabel, (label) => label.fulfillment, {
|
||||||
|
cascade: [Cascade.PERSIST, "soft-remove"] as any,
|
||||||
|
orphanRemoval: true,
|
||||||
|
})
|
||||||
labels = new Collection<FulfillmentLabel>(this)
|
labels = new Collection<FulfillmentLabel>(this)
|
||||||
|
|
||||||
@Property({
|
@Property({
|
||||||
|
|||||||
@@ -78,11 +78,11 @@ export default class GeoZone {
|
|||||||
type: "text",
|
type: "text",
|
||||||
mapToPk: true,
|
mapToPk: true,
|
||||||
fieldName: "service_zone_id",
|
fieldName: "service_zone_id",
|
||||||
|
onDelete: "cascade",
|
||||||
})
|
})
|
||||||
@ServiceZoneIdIndex.MikroORMIndex()
|
@ServiceZoneIdIndex.MikroORMIndex()
|
||||||
service_zone_id: string
|
service_zone_id: string
|
||||||
|
|
||||||
// TODO: Do we have an example or idea of what would be stored in this field? like lat/long for example?
|
|
||||||
@Property({ columnType: "jsonb", nullable: true })
|
@Property({ columnType: "jsonb", nullable: true })
|
||||||
postal_expression: Record<string, unknown> | null = null
|
postal_expression: Record<string, unknown> | null = null
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ export default class ServiceZone {
|
|||||||
type: "text",
|
type: "text",
|
||||||
mapToPk: true,
|
mapToPk: true,
|
||||||
fieldName: "fulfillment_set_id",
|
fieldName: "fulfillment_set_id",
|
||||||
|
onDelete: "cascade",
|
||||||
})
|
})
|
||||||
@FulfillmentSetIdIndex.MikroORMIndex()
|
@FulfillmentSetIdIndex.MikroORMIndex()
|
||||||
fulfillment_set_id: string
|
fulfillment_set_id: string
|
||||||
@@ -80,7 +81,11 @@ export default class ServiceZone {
|
|||||||
|
|
||||||
@OneToMany(
|
@OneToMany(
|
||||||
() => ShippingOption,
|
() => ShippingOption,
|
||||||
(shippingOption) => shippingOption.service_zone
|
(shippingOption) => shippingOption.service_zone,
|
||||||
|
{
|
||||||
|
cascade: [Cascade.PERSIST, "soft-remove"] as any,
|
||||||
|
orphanRemoval: true,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
shipping_options = new Collection<ShippingOption>(this)
|
shipping_options = new Collection<ShippingOption>(this)
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ export default class ShippingOptionRule {
|
|||||||
type: "text",
|
type: "text",
|
||||||
mapToPk: true,
|
mapToPk: true,
|
||||||
fieldName: "shipping_option_id",
|
fieldName: "shipping_option_id",
|
||||||
|
onDelete: "cascade",
|
||||||
})
|
})
|
||||||
@ShippingOptionIdIndex.MikroORMIndex()
|
@ShippingOptionIdIndex.MikroORMIndex()
|
||||||
shipping_option_id: string
|
shipping_option_id: string
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ export default class ShippingOptionType {
|
|||||||
|
|
||||||
@OneToOne(() => ShippingOption, (so) => so.type, {
|
@OneToOne(() => ShippingOption, (so) => so.type, {
|
||||||
type: "text",
|
type: "text",
|
||||||
|
onDelete: "cascade",
|
||||||
})
|
})
|
||||||
shipping_option: ShippingOption
|
shipping_option: ShippingOption
|
||||||
|
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ export default class ShippingOption {
|
|||||||
type: "text",
|
type: "text",
|
||||||
fieldName: "service_zone_id",
|
fieldName: "service_zone_id",
|
||||||
mapToPk: true,
|
mapToPk: true,
|
||||||
|
onDelete: "cascade",
|
||||||
})
|
})
|
||||||
@ServiceZoneIdIndex.MikroORMIndex()
|
@ServiceZoneIdIndex.MikroORMIndex()
|
||||||
service_zone_id: string
|
service_zone_id: string
|
||||||
@@ -90,6 +91,7 @@ export default class ShippingOption {
|
|||||||
fieldName: "shipping_profile_id",
|
fieldName: "shipping_profile_id",
|
||||||
mapToPk: true,
|
mapToPk: true,
|
||||||
nullable: true,
|
nullable: true,
|
||||||
|
onDelete: "set null",
|
||||||
})
|
})
|
||||||
@ShippingProfileIdIndex.MikroORMIndex()
|
@ShippingProfileIdIndex.MikroORMIndex()
|
||||||
shipping_profile_id: string | null
|
shipping_profile_id: string | null
|
||||||
@@ -128,9 +130,10 @@ export default class ShippingOption {
|
|||||||
|
|
||||||
@OneToOne(() => ShippingOptionType, (so) => so.shipping_option, {
|
@OneToOne(() => ShippingOptionType, (so) => so.shipping_option, {
|
||||||
owner: true,
|
owner: true,
|
||||||
cascade: [Cascade.PERSIST, Cascade.REMOVE, "soft-remove"] as any,
|
cascade: [Cascade.PERSIST, "soft-remove"] as any,
|
||||||
orphanRemoval: true,
|
orphanRemoval: true,
|
||||||
fieldName: "shipping_option_type_id",
|
fieldName: "shipping_option_type_id",
|
||||||
|
onDelete: "cascade",
|
||||||
})
|
})
|
||||||
type: ShippingOptionType
|
type: ShippingOptionType
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { ShippingOptionDTO } from "./shipping-option"
|
import { ShippingOptionDTO } from "./shipping-option"
|
||||||
|
|
||||||
export interface ServiceProviderDTO {
|
export interface FulfillmentProviderDTO {
|
||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
metadata: Record<string, unknown> | null
|
metadata: Record<string, unknown> | null
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ShippingOptionDTO } from "./shipping-option"
|
import { ShippingOptionDTO } from "./shipping-option"
|
||||||
import { ServiceProviderDTO } from "./service-provider"
|
import { FulfillmentProviderDTO } from "./fulfillment-provider"
|
||||||
import { FulfillmentAddressDTO } from "./address"
|
import { FulfillmentAddressDTO } from "./address"
|
||||||
import { FulfillmentItemDTO } from "./fulfillment-item"
|
import { FulfillmentItemDTO } from "./fulfillment-item"
|
||||||
import { FulfillmentLabelDTO } from "./fulfillment-label"
|
import { FulfillmentLabelDTO } from "./fulfillment-label"
|
||||||
@@ -17,7 +17,7 @@ export interface FulfillmentDTO {
|
|||||||
shipping_option_id: string | null
|
shipping_option_id: string | null
|
||||||
metadata: Record<string, unknown> | null
|
metadata: Record<string, unknown> | null
|
||||||
shipping_option: ShippingOptionDTO | null
|
shipping_option: ShippingOptionDTO | null
|
||||||
provider: ServiceProviderDTO
|
provider: FulfillmentProviderDTO
|
||||||
delivery_address: FulfillmentAddressDTO
|
delivery_address: FulfillmentAddressDTO
|
||||||
items: FulfillmentItemDTO[]
|
items: FulfillmentItemDTO[]
|
||||||
labels: FulfillmentLabelDTO[]
|
labels: FulfillmentLabelDTO[]
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ export * from "./shipping-option"
|
|||||||
export * from "./shipping-option-type"
|
export * from "./shipping-option-type"
|
||||||
export * from "./service-zone"
|
export * from "./service-zone"
|
||||||
export * from "./geo-zone"
|
export * from "./geo-zone"
|
||||||
export * from "./service-provider"
|
export * from "./fulfillment-provider"
|
||||||
export * from "./fulfillment"
|
export * from "./fulfillment"
|
||||||
export * from "./fulfillment-item"
|
export * from "./fulfillment-item"
|
||||||
export * from "./fulfillment-label"
|
export * from "./fulfillment-label"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { FilterableServiceZoneProps, ServiceZoneDTO } from "./service-zone"
|
import { FilterableServiceZoneProps, ServiceZoneDTO } from "./service-zone"
|
||||||
import { ShippingProfileDTO } from "./shipping-profile"
|
import { ShippingProfileDTO } from "./shipping-profile"
|
||||||
import { ServiceProviderDTO } from "./service-provider"
|
import { FulfillmentProviderDTO } from "./fulfillment-provider"
|
||||||
import {
|
import {
|
||||||
FilterableShippingOptionTypeProps,
|
FilterableShippingOptionTypeProps,
|
||||||
ShippingOptionTypeDTO,
|
ShippingOptionTypeDTO,
|
||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
ShippingOptionRuleDTO,
|
ShippingOptionRuleDTO,
|
||||||
} from "./shipping-option-rule"
|
} from "./shipping-option-rule"
|
||||||
import { BaseFilterable, OperatorMap } from "../../dal"
|
import { BaseFilterable, OperatorMap } from "../../dal"
|
||||||
|
import { FulfillmentDTO } from "./fulfillment"
|
||||||
|
|
||||||
export type ShippingOptionPriceType = "calculated" | "flat"
|
export type ShippingOptionPriceType = "calculated" | "flat"
|
||||||
|
|
||||||
@@ -19,15 +20,16 @@ export interface ShippingOptionDTO {
|
|||||||
price_type: ShippingOptionPriceType
|
price_type: ShippingOptionPriceType
|
||||||
service_zone_id: string
|
service_zone_id: string
|
||||||
shipping_profile_id: string
|
shipping_profile_id: string
|
||||||
service_provider_id: string
|
fulfillment_provider_id: string
|
||||||
shipping_option_type_id: string | null
|
shipping_option_type_id: string | null
|
||||||
data: Record<string, unknown> | null
|
data: Record<string, unknown> | null
|
||||||
metadata: Record<string, unknown> | null
|
metadata: Record<string, unknown> | null
|
||||||
service_zone: ServiceZoneDTO
|
service_zone: ServiceZoneDTO
|
||||||
shipping_profile: ShippingProfileDTO
|
shipping_profile: ShippingProfileDTO
|
||||||
service_provider: ServiceProviderDTO
|
fulfillment_provider: FulfillmentProviderDTO
|
||||||
shipping_option_type: ShippingOptionTypeDTO
|
type: ShippingOptionTypeDTO
|
||||||
rules: ShippingOptionRuleDTO[]
|
rules: ShippingOptionRuleDTO[]
|
||||||
|
fulfillments: FulfillmentDTO[]
|
||||||
created_at: Date
|
created_at: Date
|
||||||
updated_at: Date
|
updated_at: Date
|
||||||
deleted_at: Date | null
|
deleted_at: Date | null
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ export interface CreateShippingOptionDTO {
|
|||||||
price_type: ShippingOptionPriceType
|
price_type: ShippingOptionPriceType
|
||||||
service_zone_id: string
|
service_zone_id: string
|
||||||
shipping_profile_id: string
|
shipping_profile_id: string
|
||||||
service_provider_id: string
|
fulfillment_provider_id: string
|
||||||
type: Omit<CreateShippingOptionTypeDTO, "shipping_option_id">
|
type: Omit<CreateShippingOptionTypeDTO, "shipping_option_id">
|
||||||
data?: Record<string, unknown> | null
|
data?: Record<string, unknown> | null
|
||||||
rules?: Omit<CreateShippingOptionRuleDTO, "shipping_option_id">[]
|
rules?: Omit<CreateShippingOptionRuleDTO, "shipping_option_id">[]
|
||||||
@@ -19,7 +19,7 @@ export interface UpdateShippingOptionDTO {
|
|||||||
price_type?: ShippingOptionPriceType
|
price_type?: ShippingOptionPriceType
|
||||||
service_zone_id?: string
|
service_zone_id?: string
|
||||||
shipping_profile_id?: string
|
shipping_profile_id?: string
|
||||||
service_provider_id?: string
|
fulfillment_provider_id?: string
|
||||||
type: Omit<CreateShippingOptionTypeDTO, "shipping_option_id"> | { id: string }
|
type: Omit<CreateShippingOptionTypeDTO, "shipping_option_id"> | { id: string }
|
||||||
data?: Record<string, unknown> | null
|
data?: Record<string, unknown> | null
|
||||||
rules?: (
|
rules?: (
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user