From d9d5afc3cfc29221d0e65bff7b78474a8fb8f31f Mon Sep 17 00:00:00 2001 From: Adrien de Peretti Date: Mon, 11 Mar 2024 16:56:08 +0100 Subject: [PATCH] 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 --- .changeset/mean-ways-study.md | 5 + .../__fixtures__/fulfillment.ts | 30 +- .../integration-tests/__fixtures__/index.ts | 50 + .../__fixtures__/shipping-options.ts | 8 +- .../fulfillment.spec.ts | 73 +- .../fulfillment-module-service/index.spec.ts | 264 +++++ packages/fulfillment/src/joiner-config.ts | 60 +- packages/fulfillment/src/loaders/providers.ts | 49 +- .../.snapshot-medusa-fulfillment.json | 63 +- ...on20240311145700_InitialSetupMigration.ts} | 21 +- .../src/models/fulfillment-provider.ts | 53 +- .../fulfillment/src/models/fulfillment.ts | 22 +- packages/fulfillment/src/models/geo-zone.ts | 2 +- .../fulfillment/src/models/service-zone.ts | 7 +- .../src/models/shipping-option-rule.ts | 1 + .../src/models/shipping-option-type.ts | 1 + .../fulfillment/src/models/shipping-option.ts | 5 +- ...ce-provider.ts => fulfillment-provider.ts} | 2 +- .../src/fulfillment/common/fulfillment.ts | 4 +- .../types/src/fulfillment/common/index.ts | 2 +- .../src/fulfillment/common/shipping-option.ts | 10 +- .../fulfillment/mutations/shipping-option.ts | 4 +- packages/types/src/fulfillment/service.ts | 945 +++++++++--------- 23 files changed, 985 insertions(+), 696 deletions(-) create mode 100644 .changeset/mean-ways-study.md create mode 100644 packages/fulfillment/integration-tests/__tests__/fulfillment-module-service/index.spec.ts rename packages/fulfillment/src/migrations/{Migration20240305095931_InitialSetupMigration.ts => Migration20240311145700_InitialSetupMigration.ts} (91%) rename packages/types/src/fulfillment/common/{service-provider.ts => fulfillment-provider.ts} (84%) diff --git a/.changeset/mean-ways-study.md b/.changeset/mean-ways-study.md new file mode 100644 index 0000000000..64e688a411 --- /dev/null +++ b/.changeset/mean-ways-study.md @@ -0,0 +1,5 @@ +--- +"@medusajs/types": patch +--- + +Feat/fulfillment module soft delete and providers enabled diff --git a/packages/fulfillment/integration-tests/__fixtures__/fulfillment.ts b/packages/fulfillment/integration-tests/__fixtures__/fulfillment.ts index cf60b6bd52..20ed8760d2 100644 --- a/packages/fulfillment/integration-tests/__fixtures__/fulfillment.ts +++ b/packages/fulfillment/integration-tests/__fixtures__/fulfillment.ts @@ -6,6 +6,8 @@ export function generateCreateFulfillmentData( shipping_option_id: string } ) { + const randomString = Math.random().toString(36).substring(7) + return { location_id: "test-location", packed_at: null, @@ -17,28 +19,28 @@ export function generateCreateFulfillmentData( shipping_option_id: data.shipping_option_id, metadata: data.metadata ?? null, delivery_address: data.delivery_address ?? { - address_1: "test-address", - address_2: "test-address", - city: "test-city", - postal_code: "test-postal-code", - country_code: "test-country-code", - province: "test-province", - phone: "test-phone", - full_name: "test-full-name", + address_1: "test-address_" + randomString, + address_2: "test-address_" + randomString, + city: "test-city_" + randomString, + postal_code: "test-postal-code_" + randomString, + country_code: "test-country-code_" + randomString, + province: "test-province_" + randomString, + phone: "test-phone_" + randomString, + full_name: "test-full-name_" + randomString, }, items: data.items ?? [ { - title: "test-title", - sku: "test-sku", + title: "test-title_" + randomString, + sku: "test-sku_" + randomString, quantity: 1, - barcode: "test-barcode", + barcode: "test-barcode_" + randomString, }, ], labels: data.labels ?? [ { - tracking_number: "test-tracking-number", - tracking_url: "test-tracking-url", - label_url: "test-label-url", + tracking_number: "test-tracking-number_" + randomString, + tracking_url: "test-tracking-url_" + randomString, + label_url: "test-label-url_" + randomString, }, ], order: data.order ?? {}, diff --git a/packages/fulfillment/integration-tests/__fixtures__/index.ts b/packages/fulfillment/integration-tests/__fixtures__/index.ts index 6ff6616db4..26751493ac 100644 --- a/packages/fulfillment/integration-tests/__fixtures__/index.ts +++ b/packages/fulfillment/integration-tests/__fixtures__/index.ts @@ -1,2 +1,52 @@ +import { generateCreateShippingOptionsData } from "./shipping-options" +import { generateCreateFulfillmentData } from "./fulfillment" +import { IFulfillmentModuleService } from "@medusajs/types" + export * from "./shipping-options" 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, + }) + ) +} diff --git a/packages/fulfillment/integration-tests/__fixtures__/shipping-options.ts b/packages/fulfillment/integration-tests/__fixtures__/shipping-options.ts index 9a77d6032e..45044638a8 100644 --- a/packages/fulfillment/integration-tests/__fixtures__/shipping-options.ts +++ b/packages/fulfillment/integration-tests/__fixtures__/shipping-options.ts @@ -14,14 +14,16 @@ export function generateCreateShippingOptionsData({ name?: string type?: CreateShippingOptionDTO["type"] }): Required { + const randomString = Math.random().toString(36).substring(7) + return { service_zone_id: service_zone_id, shipping_profile_id: shipping_profile_id, fulfillment_provider_id: fulfillment_provider_id, type: type ?? { - code: "test-type", - description: "test-description", - label: "test-label", + code: "test-type_" + randomString, + description: "test-description_" + randomString, + label: "test-label_" + randomString, }, data: data ?? { amount: 1000, diff --git a/packages/fulfillment/integration-tests/__tests__/fulfillment-module-service/fulfillment.spec.ts b/packages/fulfillment/integration-tests/__tests__/fulfillment-module-service/fulfillment.spec.ts index 8f1927e4e0..6129d5a82b 100644 --- a/packages/fulfillment/integration-tests/__tests__/fulfillment-module-service/fulfillment.spec.ts +++ b/packages/fulfillment/integration-tests/__tests__/fulfillment-module-service/fulfillment.spec.ts @@ -1,14 +1,11 @@ import { resolve } from "path" -import { Modules, ModulesDefinition } from "@medusajs/modules-sdk" +import { Modules } from "@medusajs/modules-sdk" import { IFulfillmentModuleService } from "@medusajs/types" import { moduleIntegrationTestRunner, SuiteOptions } from "medusa-test-utils" import { generateCreateFulfillmentData, generateCreateShippingOptionsData, } from "../../__fixtures__" -import { initModules } from "medusa-test-utils/dist" -import { FulfillmentProviderService } from "@services" -import { FulfillmentProviderServiceFixtures } from "../../__fixtures__/providers" jest.setTimeout(100000) @@ -33,73 +30,7 @@ const providerId = "fixtures-fulfillment-provider_test-provider" moduleIntegrationTestRunner({ moduleName: Modules.FULFILLMENT, moduleOptions: moduleOptions, - testSuite: ({ - MikroOrmWrapper, - service, - }: SuiteOptions) => { - 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() - }) - }) - + testSuite: ({ service }: SuiteOptions) => { describe("Fulfillment Module Service", () => { describe("read", () => { it("should list fulfillment", async () => { diff --git a/packages/fulfillment/integration-tests/__tests__/fulfillment-module-service/index.spec.ts b/packages/fulfillment/integration-tests/__tests__/fulfillment-module-service/index.spec.ts new file mode 100644 index 0000000000..1a6f4bed48 --- /dev/null +++ b/packages/fulfillment/integration-tests/__tests__/fulfillment-module-service/index.spec.ts @@ -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 +) { + 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) => + 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) + }) + }), +}) diff --git a/packages/fulfillment/src/joiner-config.ts b/packages/fulfillment/src/joiner-config.ts index cfddbd51a9..58ba9c05bd 100644 --- a/packages/fulfillment/src/joiner-config.ts +++ b/packages/fulfillment/src/joiner-config.ts @@ -1,10 +1,20 @@ import { Modules } from "@medusajs/modules-sdk" import { ModuleJoinerConfig } from "@medusajs/types" import { MapToConfig } from "@medusajs/utils" +import { + Fulfillment, + FulfillmentSet, + GeoZone, + ServiceZone, + ShippingOption, + ShippingProfile, +} from "@models" -// TODO manage the config - -export const LinkableKeys: Record = {} +export const LinkableKeys: Record = { + fulfillment_id: Fulfillment.name, + fulfillment_set_id: FulfillmentSet.name, + shipping_option_id: ShippingOption.name, +} const entityLinkableKeysMap: MapToConfig = {} Object.entries(LinkableKeys).forEach(([key, value]) => { @@ -21,5 +31,47 @@ export const joinerConfig: ModuleJoinerConfig = { serviceName: Modules.FULFILLMENT, primaryKeys: ["id"], 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 diff --git a/packages/fulfillment/src/loaders/providers.ts b/packages/fulfillment/src/loaders/providers.ts index d15746d129..1822fe7169 100644 --- a/packages/fulfillment/src/loaders/providers.ts +++ b/packages/fulfillment/src/loaders/providers.ts @@ -2,7 +2,7 @@ import { moduleProviderLoader } from "@medusajs/modules-sdk" import { LoaderOptions, ModuleProvider, ModulesSdkTypes } from "@medusajs/types" import { asFunction, asValue, Lifetime } from "awilix" import { FulfillmentIdentifiersRegistrationName } from "@types" -import { lowerCaseFirst } from "@medusajs/utils" +import { lowerCaseFirst, promiseAll } from "@medusajs/utils" import { FulfillmentProviderService } from "@services" import { ContainerRegistrationKeys } from "@medusajs/utils/src" @@ -56,7 +56,8 @@ async function syncDatabaseProviders({ container }) { FulfillmentProviderService.name ) - const logger = container.resolve(ContainerRegistrationKeys.LOGGER) + const logger = container.resolve(ContainerRegistrationKeys.LOGGER) ?? console + try { const providerIdentifiers: string[] = ( container.resolve(FulfillmentIdentifiersRegistrationName) ?? [] @@ -65,22 +66,44 @@ async function syncDatabaseProviders({ container }) { const providerService: ModulesSdkTypes.InternalModuleService = container.resolve(providerServiceRegistrationKey) - const providers = await providerService.list({ - id: providerIdentifiers, - }) - + const providers = await providerService.list({}) const loadedProvidersMap = new Map(providers.map((p) => [p.id, p])) - const providersToCreate: any[] = [] - for (const identifier of providerIdentifiers) { - if (loadedProvidersMap.has(identifier)) { - continue - } + const providersToCreate = providerIdentifiers.filter( + (id) => !loadedProvidersMap.has(id) + ) + const providersToEnabled = providerIdentifiers.filter((id) => + loadedProvidersMap.has(id) + ) + const providersToDisable = providers.filter( + (p) => !providerIdentifiers.includes(p.id) + ) - providersToCreate.push({ id: identifier }) + const promises: Promise[] = [] + + 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) { logger.error(`Error syncing providers: ${error.message}`) } diff --git a/packages/fulfillment/src/migrations/.snapshot-medusa-fulfillment.json b/packages/fulfillment/src/migrations/.snapshot-medusa-fulfillment.json index dc71772361..b530721865 100644 --- a/packages/fulfillment/src/migrations/.snapshot-medusa-fulfillment.json +++ b/packages/fulfillment/src/migrations/.snapshot-medusa-fulfillment.json @@ -184,61 +184,20 @@ "nullable": false, "mappedType": "text" }, - "metadata": { - "name": "metadata", - "type": "jsonb", - "unsigned": false, - "autoincrement": false, - "primary": false, - "nullable": true, - "mappedType": "json" - }, - "created_at": { - "name": "created_at", - "type": "timestamptz", + "is_enabled": { + "name": "is_enabled", + "type": "boolean", "unsigned": false, "autoincrement": false, "primary": false, "nullable": false, - "length": 6, - "default": "now()", - "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" + "default": "true", + "mappedType": "boolean" } }, "name": "fulfillment_provider", "schema": "public", "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", "columnNames": [ @@ -485,6 +444,7 @@ "id" ], "referencedTableName": "public.fulfillment_set", + "deleteRule": "cascade", "updateRule": "cascade" } } @@ -678,6 +638,7 @@ "id" ], "referencedTableName": "public.service_zone", + "deleteRule": "cascade", "updateRule": "cascade" } } @@ -971,7 +932,7 @@ "unsigned": false, "autoincrement": false, "primary": false, - "nullable": true, + "nullable": false, "mappedType": "text" }, "created_at": { @@ -1091,6 +1052,7 @@ "id" ], "referencedTableName": "public.service_zone", + "deleteRule": "cascade", "updateRule": "cascade" }, "shipping_option_shipping_profile_id_foreign": { @@ -1269,6 +1231,7 @@ "id" ], "referencedTableName": "public.shipping_option", + "deleteRule": "cascade", "updateRule": "cascade" } } @@ -1348,7 +1311,7 @@ "unsigned": false, "autoincrement": false, "primary": false, - "nullable": false, + "nullable": true, "mappedType": "text" }, "shipping_option_id": { @@ -1375,7 +1338,7 @@ "unsigned": false, "autoincrement": false, "primary": false, - "nullable": false, + "nullable": true, "mappedType": "text" }, "created_at": { @@ -1485,6 +1448,7 @@ "id" ], "referencedTableName": "public.fulfillment_provider", + "deleteRule": "set null", "updateRule": "cascade" }, "fulfillment_shipping_option_id_foreign": { @@ -1510,6 +1474,7 @@ "id" ], "referencedTableName": "public.fulfillment_address", + "deleteRule": "cascade", "updateRule": "cascade" } } diff --git a/packages/fulfillment/src/migrations/Migration20240305095931_InitialSetupMigration.ts b/packages/fulfillment/src/migrations/Migration20240311145700_InitialSetupMigration.ts similarity index 91% rename from packages/fulfillment/src/migrations/Migration20240305095931_InitialSetupMigration.ts rename to packages/fulfillment/src/migrations/Migration20240311145700_InitialSetupMigration.ts index 2889ff6be0..8f44b8812e 100644 --- a/packages/fulfillment/src/migrations/Migration20240305095931_InitialSetupMigration.ts +++ b/packages/fulfillment/src/migrations/Migration20240311145700_InitialSetupMigration.ts @@ -1,13 +1,12 @@ import { Migration } from '@mikro-orm/migrations'; -export class Migration20240305095931_InitialSetupMigration extends Migration { +export class Migration20240311145700_InitialSetupMigration extends Migration { async up(): Promise { 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 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 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_provider" ("id" text not null, "is_enabled" boolean not null default true, constraint "fulfillment_provider_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;'); @@ -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 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('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;'); @@ -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_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('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;'); @@ -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_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_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_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_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;'); diff --git a/packages/fulfillment/src/models/fulfillment-provider.ts b/packages/fulfillment/src/models/fulfillment-provider.ts index 380d349cf5..2cc586c264 100644 --- a/packages/fulfillment/src/models/fulfillment-provider.ts +++ b/packages/fulfillment/src/models/fulfillment-provider.ts @@ -1,66 +1,19 @@ -import { - createPsqlIndexStatementHelper, - DALUtils, - generateEntityId, -} from "@medusajs/utils" - -import { DAL } from "@medusajs/types" +import { generateEntityId } from "@medusajs/utils" import { BeforeCreate, - Collection, Entity, - Filter, - OneToMany, OnInit, - OptionalProps, PrimaryKey, Property, } 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() -@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions) export default class FulfillmentProvider { - [OptionalProps]?: FulfillmentProviderOptionalProps - @PrimaryKey({ columnType: "text" }) id: string - @Property({ columnType: "jsonb", nullable: true }) - metadata: Record | null = null - - @OneToMany( - () => ShippingOption, - (shippingOption) => shippingOption.fulfillment_provider - ) - shipping_options = new Collection(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 + @Property({ columnType: "boolean", defaultRaw: "true" }) + is_enabled: boolean = true @BeforeCreate() onCreate() { diff --git a/packages/fulfillment/src/models/fulfillment.ts b/packages/fulfillment/src/models/fulfillment.ts index 3416853bd8..eed4cdb8fe 100644 --- a/packages/fulfillment/src/models/fulfillment.ts +++ b/packages/fulfillment/src/models/fulfillment.ts @@ -7,6 +7,7 @@ import { import { DAL } from "@medusajs/types" import { BeforeCreate, + Cascade, Collection, Entity, Filter, @@ -93,6 +94,8 @@ export default class Fulfillment { columnType: "text", fieldName: "provider_id", mapToPk: true, + nullable: true, + onDelete: "set null", }) @FulfillmentProviderIdIndex.MikroORMIndex() provider_id: string @@ -102,6 +105,7 @@ export default class Fulfillment { fieldName: "shipping_option_id", nullable: true, mapToPk: true, + onDelete: "set null", }) @FulfillmentShippingOptionIdIndex.MikroORMIndex() shipping_option_id: string | null = null @@ -115,13 +119,25 @@ export default class Fulfillment { @ManyToOne(() => FulfillmentProvider, { persist: false }) provider: FulfillmentProvider - @OneToOne() + @OneToOne({ + entity: () => Address, + owner: true, + cascade: [Cascade.PERSIST, "soft-remove"] as any, + nullable: true, + onDelete: "cascade", + }) 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(this) - @OneToMany(() => FulfillmentLabel, (label) => label.fulfillment) + @OneToMany(() => FulfillmentLabel, (label) => label.fulfillment, { + cascade: [Cascade.PERSIST, "soft-remove"] as any, + orphanRemoval: true, + }) labels = new Collection(this) @Property({ diff --git a/packages/fulfillment/src/models/geo-zone.ts b/packages/fulfillment/src/models/geo-zone.ts index 61f6a187d5..1483fb363d 100644 --- a/packages/fulfillment/src/models/geo-zone.ts +++ b/packages/fulfillment/src/models/geo-zone.ts @@ -78,11 +78,11 @@ export default class GeoZone { type: "text", mapToPk: true, fieldName: "service_zone_id", + onDelete: "cascade", }) @ServiceZoneIdIndex.MikroORMIndex() 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 }) postal_expression: Record | null = null diff --git a/packages/fulfillment/src/models/service-zone.ts b/packages/fulfillment/src/models/service-zone.ts index de6ad100dc..046d1e2280 100644 --- a/packages/fulfillment/src/models/service-zone.ts +++ b/packages/fulfillment/src/models/service-zone.ts @@ -65,6 +65,7 @@ export default class ServiceZone { type: "text", mapToPk: true, fieldName: "fulfillment_set_id", + onDelete: "cascade", }) @FulfillmentSetIdIndex.MikroORMIndex() fulfillment_set_id: string @@ -80,7 +81,11 @@ export default class ServiceZone { @OneToMany( () => ShippingOption, - (shippingOption) => shippingOption.service_zone + (shippingOption) => shippingOption.service_zone, + { + cascade: [Cascade.PERSIST, "soft-remove"] as any, + orphanRemoval: true, + } ) shipping_options = new Collection(this) diff --git a/packages/fulfillment/src/models/shipping-option-rule.ts b/packages/fulfillment/src/models/shipping-option-rule.ts index 4457708bf7..d77db4cef4 100644 --- a/packages/fulfillment/src/models/shipping-option-rule.ts +++ b/packages/fulfillment/src/models/shipping-option-rule.ts @@ -57,6 +57,7 @@ export default class ShippingOptionRule { type: "text", mapToPk: true, fieldName: "shipping_option_id", + onDelete: "cascade", }) @ShippingOptionIdIndex.MikroORMIndex() shipping_option_id: string diff --git a/packages/fulfillment/src/models/shipping-option-type.ts b/packages/fulfillment/src/models/shipping-option-type.ts index 7fce83ee68..3d3ef7c899 100644 --- a/packages/fulfillment/src/models/shipping-option-type.ts +++ b/packages/fulfillment/src/models/shipping-option-type.ts @@ -50,6 +50,7 @@ export default class ShippingOptionType { @OneToOne(() => ShippingOption, (so) => so.type, { type: "text", + onDelete: "cascade", }) shipping_option: ShippingOption diff --git a/packages/fulfillment/src/models/shipping-option.ts b/packages/fulfillment/src/models/shipping-option.ts index f1687d1e12..549c692626 100644 --- a/packages/fulfillment/src/models/shipping-option.ts +++ b/packages/fulfillment/src/models/shipping-option.ts @@ -81,6 +81,7 @@ export default class ShippingOption { type: "text", fieldName: "service_zone_id", mapToPk: true, + onDelete: "cascade", }) @ServiceZoneIdIndex.MikroORMIndex() service_zone_id: string @@ -90,6 +91,7 @@ export default class ShippingOption { fieldName: "shipping_profile_id", mapToPk: true, nullable: true, + onDelete: "set null", }) @ShippingProfileIdIndex.MikroORMIndex() shipping_profile_id: string | null @@ -128,9 +130,10 @@ export default class ShippingOption { @OneToOne(() => ShippingOptionType, (so) => so.shipping_option, { owner: true, - cascade: [Cascade.PERSIST, Cascade.REMOVE, "soft-remove"] as any, + cascade: [Cascade.PERSIST, "soft-remove"] as any, orphanRemoval: true, fieldName: "shipping_option_type_id", + onDelete: "cascade", }) type: ShippingOptionType diff --git a/packages/types/src/fulfillment/common/service-provider.ts b/packages/types/src/fulfillment/common/fulfillment-provider.ts similarity index 84% rename from packages/types/src/fulfillment/common/service-provider.ts rename to packages/types/src/fulfillment/common/fulfillment-provider.ts index 2a9e7522a8..e62b2f10bc 100644 --- a/packages/types/src/fulfillment/common/service-provider.ts +++ b/packages/types/src/fulfillment/common/fulfillment-provider.ts @@ -1,6 +1,6 @@ import { ShippingOptionDTO } from "./shipping-option" -export interface ServiceProviderDTO { +export interface FulfillmentProviderDTO { id: string name: string metadata: Record | null diff --git a/packages/types/src/fulfillment/common/fulfillment.ts b/packages/types/src/fulfillment/common/fulfillment.ts index cd1bfd95e9..abab0af6ad 100644 --- a/packages/types/src/fulfillment/common/fulfillment.ts +++ b/packages/types/src/fulfillment/common/fulfillment.ts @@ -1,5 +1,5 @@ import { ShippingOptionDTO } from "./shipping-option" -import { ServiceProviderDTO } from "./service-provider" +import { FulfillmentProviderDTO } from "./fulfillment-provider" import { FulfillmentAddressDTO } from "./address" import { FulfillmentItemDTO } from "./fulfillment-item" import { FulfillmentLabelDTO } from "./fulfillment-label" @@ -17,7 +17,7 @@ export interface FulfillmentDTO { shipping_option_id: string | null metadata: Record | null shipping_option: ShippingOptionDTO | null - provider: ServiceProviderDTO + provider: FulfillmentProviderDTO delivery_address: FulfillmentAddressDTO items: FulfillmentItemDTO[] labels: FulfillmentLabelDTO[] diff --git a/packages/types/src/fulfillment/common/index.ts b/packages/types/src/fulfillment/common/index.ts index dff878e31f..e6d058d998 100644 --- a/packages/types/src/fulfillment/common/index.ts +++ b/packages/types/src/fulfillment/common/index.ts @@ -6,7 +6,7 @@ export * from "./shipping-option" export * from "./shipping-option-type" export * from "./service-zone" export * from "./geo-zone" -export * from "./service-provider" +export * from "./fulfillment-provider" export * from "./fulfillment" export * from "./fulfillment-item" export * from "./fulfillment-label" diff --git a/packages/types/src/fulfillment/common/shipping-option.ts b/packages/types/src/fulfillment/common/shipping-option.ts index a88989aabd..07b2b166cf 100644 --- a/packages/types/src/fulfillment/common/shipping-option.ts +++ b/packages/types/src/fulfillment/common/shipping-option.ts @@ -1,6 +1,6 @@ import { FilterableServiceZoneProps, ServiceZoneDTO } from "./service-zone" import { ShippingProfileDTO } from "./shipping-profile" -import { ServiceProviderDTO } from "./service-provider" +import { FulfillmentProviderDTO } from "./fulfillment-provider" import { FilterableShippingOptionTypeProps, ShippingOptionTypeDTO, @@ -10,6 +10,7 @@ import { ShippingOptionRuleDTO, } from "./shipping-option-rule" import { BaseFilterable, OperatorMap } from "../../dal" +import { FulfillmentDTO } from "./fulfillment" export type ShippingOptionPriceType = "calculated" | "flat" @@ -19,15 +20,16 @@ export interface ShippingOptionDTO { price_type: ShippingOptionPriceType service_zone_id: string shipping_profile_id: string - service_provider_id: string + fulfillment_provider_id: string shipping_option_type_id: string | null data: Record | null metadata: Record | null service_zone: ServiceZoneDTO shipping_profile: ShippingProfileDTO - service_provider: ServiceProviderDTO - shipping_option_type: ShippingOptionTypeDTO + fulfillment_provider: FulfillmentProviderDTO + type: ShippingOptionTypeDTO rules: ShippingOptionRuleDTO[] + fulfillments: FulfillmentDTO[] created_at: Date updated_at: Date deleted_at: Date | null diff --git a/packages/types/src/fulfillment/mutations/shipping-option.ts b/packages/types/src/fulfillment/mutations/shipping-option.ts index 3070870b07..0793143273 100644 --- a/packages/types/src/fulfillment/mutations/shipping-option.ts +++ b/packages/types/src/fulfillment/mutations/shipping-option.ts @@ -7,7 +7,7 @@ export interface CreateShippingOptionDTO { price_type: ShippingOptionPriceType service_zone_id: string shipping_profile_id: string - service_provider_id: string + fulfillment_provider_id: string type: Omit data?: Record | null rules?: Omit[] @@ -19,7 +19,7 @@ export interface UpdateShippingOptionDTO { price_type?: ShippingOptionPriceType service_zone_id?: string shipping_profile_id?: string - service_provider_id?: string + fulfillment_provider_id?: string type: Omit | { id: string } data?: Record | null rules?: ( diff --git a/packages/types/src/fulfillment/service.ts b/packages/types/src/fulfillment/service.ts index 7f511c1113..788c708d42 100644 --- a/packages/types/src/fulfillment/service.ts +++ b/packages/types/src/fulfillment/service.ts @@ -36,6 +36,39 @@ import { CreateShippingProfileDTO } from "./mutations/shipping-profile" import { CreateFulfillmentDTO } from "./mutations/fulfillment" export interface IFulfillmentModuleService extends IModuleService { + /** + * Retrieve a fulfillment set + * @param id + * @param config + * @param sharedContext + */ + retrieve( + id: string, + config?: FindConfig, + sharedContext?: Context + ): Promise + /** + * List fulfillment sets + * @param filters + * @param config + * @param sharedContext + */ + list( + filters?: FilterableFulfillmentSetProps, + config?: FindConfig, + sharedContext?: Context + ): Promise + /** + * List and count fulfillment sets + * @param filters + * @param config + * @param sharedContext + */ + listAndCount( + filters?: FilterableFulfillmentSetProps, + config?: FindConfig, + sharedContext?: Context + ): Promise<[FulfillmentSetDTO[], number]> /** * Create a new fulfillment set * @param data @@ -49,78 +82,6 @@ export interface IFulfillmentModuleService extends IModuleService { data: CreateFulfillmentSetDTO, sharedContext?: Context ): Promise - - /** - * Create a new service zone - * @param data - * @param sharedContext - */ - createServiceZones( - data: CreateServiceZoneDTO[], - sharedContext?: Context - ): Promise - createServiceZones( - data: CreateServiceZoneDTO, - sharedContext?: Context - ): Promise - - /** - * Create a new shipping option - * @param data - * @param sharedContext - */ - createShippingOptions( - data: CreateShippingOptionDTO[], - sharedContext?: Context - ): Promise - createShippingOptions( - data: CreateShippingOptionDTO, - sharedContext?: Context - ): Promise - - /** - * Create a new shipping profile - * @param data - * @param sharedContext - */ - createShippingProfiles( - data: CreateShippingProfileDTO[], - sharedContext?: Context - ): Promise - - createShippingProfiles( - data: CreateShippingProfileDTO, - sharedContext?: Context - ): Promise - - /** - * Create a new geo zone - * @param data - * @param sharedContext - */ - createGeoZones( - data: CreateGeoZoneDTO[], - sharedContext?: Context - ): Promise - createGeoZones( - data: CreateGeoZoneDTO, - sharedContext?: Context - ): Promise - - /** - * Create a new shipping option rules - * @param data - * @param sharedContext - */ - createShippingOptionRules( - data: CreateShippingOptionRuleDTO[], - sharedContext?: Context - ): Promise - createShippingOptionRules( - data: CreateShippingOptionRuleDTO, - sharedContext?: Context - ): Promise - /** * Update a fulfillment set * @param data @@ -134,7 +95,82 @@ export interface IFulfillmentModuleService extends IModuleService { data: UpdateFulfillmentSetDTO, sharedContext?: Context ): Promise + /** + * Delete a fulfillment set + * @param ids + * @param sharedContext + */ + delete(ids: string[], sharedContext?: Context): Promise + delete(id: string, sharedContext?: Context): Promise + /** + * Soft delete fulfillment sets + * @param fulfillmentIds + * @param config + * @param sharedContext + */ + softDelete( + fulfillmentIds: string[], + config?: SoftDeleteReturn, + sharedContext?: Context + ): Promise | void> + /** + * Restore fulfillment sets + * @param fulfillmentIds + * @param config + * @param sharedContext + */ + restore( + fulfillmentIds: string[], + config?: RestoreReturn, + sharedContext?: Context + ): Promise | void> + /** + * Retrieve a service zone + * @param id + * @param config + * @param sharedContext + */ + retrieveServiceZone( + id: string, + config?: FindConfig, + sharedContext?: Context + ): Promise + /** + * List service zones + * @param filters + * @param config + * @param sharedContext + */ + listServiceZones( + filters?: FilterableServiceZoneProps, + config?: FindConfig, + sharedContext?: Context + ): Promise + /** + * List and count service zones + * @param filters + * @param config + * @param sharedContext + */ + listAndCountServiceZones( + filters?: FilterableServiceZoneProps, + config?: FindConfig, + sharedContext?: Context + ): Promise<[ServiceZoneDTO[], number]> + /** + * Create a new service zone + * @param data + * @param sharedContext + */ + createServiceZones( + data: CreateServiceZoneDTO[], + sharedContext?: Context + ): Promise + createServiceZones( + data: CreateServiceZoneDTO, + sharedContext?: Context + ): Promise /** * Update a service zone * @param data @@ -148,35 +184,82 @@ export interface IFulfillmentModuleService extends IModuleService { data: UpdateServiceZoneDTO, sharedContext?: Context ): Promise + /** + * Delete a service zone + * @param ids + * @param sharedContext + */ + deleteServiceZones(ids: string[], sharedContext?: Context): Promise + deleteServiceZones(id: string, sharedContext?: Context): Promise + /** + * Soft delete service zones + * @param serviceZoneIds + * @param config + * @param sharedContext + */ + softDeleteServiceZones( + serviceZoneIds: string[], + config?: SoftDeleteReturn, + sharedContext?: Context + ): Promise | void> + /** + * Restore service zones + * @param serviceZoneIds + * @param config + * @param sharedContext + */ + restoreServiceZones( + serviceZoneIds: string[], + config?: RestoreReturn, + sharedContext?: Context + ): Promise | void> /** - * Update a shipping option + * Retrieve a geo zone + * @param id + * @param config + * @param sharedContext + */ + retrieveGeoZone( + id: string, + config?: FindConfig, + sharedContext?: Context + ): Promise + /** + * List geo zones + * @param filters + * @param config + * @param sharedContext + */ + listGeoZones( + filters?: FilterableGeoZoneProps, + config?: FindConfig, + sharedContext?: Context + ): Promise + /** + * List and count geo zones + * @param filters + * @param config + * @param sharedContext + */ + listAndCountGeoZones( + filters?: FilterableGeoZoneProps, + config?: FindConfig, + sharedContext?: Context + ): Promise<[GeoZoneDTO[], number]> + /** + * Create a new geo zone * @param data * @param sharedContext */ - updateShippingOptions( - data: UpdateShippingOptionDTO[], + createGeoZones( + data: CreateGeoZoneDTO[], sharedContext?: Context - ): Promise - updateShippingOptions( - data: UpdateShippingOptionDTO, + ): Promise + createGeoZones( + data: CreateGeoZoneDTO, sharedContext?: Context - ): Promise - - /** - * Update a shipping profile - * @param data - * @param sharedContext - */ - updateShippingProfiles( - data: CreateShippingProfileDTO[], - sharedContext?: Context - ): Promise - updateShippingProfiles( - data: CreateShippingProfileDTO, - sharedContext?: Context - ): Promise - + ): Promise /** * Update a geo zone * @param data @@ -190,7 +273,260 @@ export interface IFulfillmentModuleService extends IModuleService { data: UpdateGeoZoneDTO, sharedContext?: Context ): Promise + /** + * Delete a geo zone + * @param ids + * @param sharedContext + */ + deleteGeoZones(ids: string[], sharedContext?: Context): Promise + deleteGeoZones(id: string, sharedContext?: Context): Promise + /** + * Soft delete geo zones + * @param geoZoneIds + * @param config + * @param sharedContext + */ + softDeleteGeoZones( + geoZoneIds: string[], + config?: SoftDeleteReturn, + sharedContext?: Context + ): Promise | void> + /** + * Restore geo zones + * @param geoZoneIds + * @param config + * @param sharedContext + */ + restoreGeoZones( + geoZoneIds: string[], + config?: RestoreReturn, + sharedContext?: Context + ): Promise | void> + /** + * Retrieve a shipping option + * @param id + * @param config + * @param sharedContext + */ + retrieveShippingOption( + id: string, + config?: FindConfig, + sharedContext?: Context + ): Promise + /** + * List shipping options + * @param filters + * @param config + * @param sharedContext + */ + listShippingOptions( + filters?: FilterableShippingOptionProps, + config?: FindConfig, + sharedContext?: Context + ): Promise + /** + * List and count shipping options + * @param filters + * @param config + * @param sharedContext + */ + listAndCountShippingOptions( + filters?: FilterableShippingOptionProps, + config?: FindConfig, + sharedContext?: Context + ): Promise<[ShippingOptionDTO[], number]> + /** + * Create a new shipping option + * @param data + * @param sharedContext + */ + createShippingOptions( + data: CreateShippingOptionDTO[], + sharedContext?: Context + ): Promise + createShippingOptions( + data: CreateShippingOptionDTO, + sharedContext?: Context + ): Promise + /** + * Update a shipping option + * @param data + * @param sharedContext + */ + updateShippingOptions( + data: UpdateShippingOptionDTO[], + sharedContext?: Context + ): Promise + updateShippingOptions( + data: UpdateShippingOptionDTO, + sharedContext?: Context + ): Promise + /** + * Delete a shippingOption + * @param ids + * @param sharedContext + */ + deleteShippingOptions(ids: string[], sharedContext?: Context): Promise + deleteShippingOptions(id: string, sharedContext?: Context): Promise + /** + * Soft delete shipping options + * @param shippingOptionIds + * @param config + * @param sharedContext + */ + softDeleteShippingOptions( + shippingOptionIds: string[], + config?: SoftDeleteReturn, + sharedContext?: Context + ): Promise | void> + /** + * Restore shipping options + * @param shippingOptionIds + * @param config + * @param sharedContext + */ + restoreShippingOptions( + shippingOptionIds: string[], + config?: RestoreReturn, + sharedContext?: Context + ): Promise | void> + + /** + * Retrieve a shipping profile + * @param id + * @param config + * @param sharedContext + */ + retrieveShippingProfile( + id: string, + config?: FindConfig, + sharedContext?: Context + ): Promise + /** + * List shipping profiles + * @param filters + * @param config + * @param sharedContext + */ + listShippingProfiles( + filters?: FilterableShippingProfileProps, + config?: FindConfig, + sharedContext?: Context + ): Promise + /** + * List and count shipping profiles + * @param filters + * @param config + * @param sharedContext + */ + listAndCountShippingProfiles( + filters?: FilterableShippingProfileProps, + config?: FindConfig, + sharedContext?: Context + ): Promise<[ShippingProfileDTO[], number]> + /** + * Create a new shipping profile + * @param data + * @param sharedContext + */ + createShippingProfiles( + data: CreateShippingProfileDTO[], + sharedContext?: Context + ): Promise + createShippingProfiles( + data: CreateShippingProfileDTO, + sharedContext?: Context + ): Promise + /** + * Update a shipping profile + * @param data + * @param sharedContext + */ + updateShippingProfiles( + data: CreateShippingProfileDTO[], + sharedContext?: Context + ): Promise + updateShippingProfiles( + data: CreateShippingProfileDTO, + sharedContext?: Context + ): Promise + /** + * Delete a shipping profile + * @param ids + * @param sharedContext + */ + deleteShippingProfiles(ids: string[], sharedContext?: Context): Promise + deleteShippingProfiles(id: string, sharedContext?: Context): Promise + /** + * Soft delete shipping profiles + * @param shippingProfileIds + * @param config + * @param sharedContext + */ + softDeleteShippingProfiles( + shippingProfileIds: string[], + config?: SoftDeleteReturn, + sharedContext?: Context + ): Promise | void> + /** + * Restore shipping profiles + * @param shippingProfileIds + * @param config + * @param sharedContext + */ + restoreShippingProfiles( + shippingProfileIds: string[], + config?: RestoreReturn, + sharedContext?: Context + ): Promise | void> + + /** + * Retrieve a shipping option rule + * @param id + * @param config + * @param sharedContext + */ + retrieveShippingOptionRule( + id: string, + config?: FindConfig, + sharedContext?: Context + ): Promise + /** + * List shipping option rules + * @param filters + * @param config + * @param sharedContext + */ + listShippingOptionRules( + filters?: FilterableShippingOptionRuleProps, + config?: FindConfig, + sharedContext?: Context + ): Promise + /** + * List and count shipping option rules + * @param filters + * @param config + * @param sharedContext + */ + listAndCountShippingOptionRules( + filters?: FilterableShippingOptionRuleProps, + config?: FindConfig, + sharedContext?: Context + ): Promise<[ShippingOptionRuleDTO[], number]> + /** + * Create a new shipping option rules + * @param data + * @param sharedContext + */ + createShippingOptionRules( + data: CreateShippingOptionRuleDTO[], + sharedContext?: Context + ): Promise + createShippingOptionRules( + data: CreateShippingOptionRuleDTO, + sharedContext?: Context + ): Promise /** * Update a shipping option rule * @param data @@ -204,58 +540,6 @@ export interface IFulfillmentModuleService extends IModuleService { data: UpdateShippingOptionRuleDTO, sharedContext?: Context ): Promise - - /** - * Update a fulfillment - * @param data - * @param sharedContext - */ - updateFulfillment( - id: string, - data: UpdateFulfillmentDTO, - sharedContext?: Context - ): Promise - - /** - * Delete a fulfillment set - * @param ids - * @param sharedContext - */ - delete(ids: string[], sharedContext?: Context): Promise - delete(id: string, sharedContext?: Context): Promise - - /** - * Delete a service zone - * @param ids - * @param sharedContext - */ - deleteServiceZones(ids: string[], sharedContext?: Context): Promise - deleteServiceZones(id: string, sharedContext?: Context): Promise - - /** - * Delete a shippingOption - * @param ids - * @param sharedContext - */ - deleteShippingOptions(ids: string[], sharedContext?: Context): Promise - deleteShippingOptions(id: string, sharedContext?: Context): Promise - - /** - * Delete a shipping profile - * @param ids - * @param sharedContext - */ - deleteShippingProfiles(ids: string[], sharedContext?: Context): Promise - deleteShippingProfiles(id: string, sharedContext?: Context): Promise - - /** - * Delete a geo zone - * @param ids - * @param sharedContext - */ - deleteGeoZones(ids: string[], sharedContext?: Context): Promise - deleteGeoZones(id: string, sharedContext?: Context): Promise - /** * Delete a shipping option rule * @param ids @@ -267,78 +551,6 @@ export interface IFulfillmentModuleService extends IModuleService { ): Promise deleteShippingOptionRules(id: string, sharedContext?: Context): Promise - /** - * Retrieve a fulfillment set - * @param id - * @param config - * @param sharedContext - */ - retrieve( - id: string, - config?: FindConfig, - sharedContext?: Context - ): Promise - - /** - * Retrieve a service zone - * @param id - * @param config - * @param sharedContext - */ - retrieveServiceZone( - id: string, - config?: FindConfig, - sharedContext?: Context - ): Promise - - /** - * Retrieve a shipping option - * @param id - * @param config - * @param sharedContext - */ - retrieveShippingOption( - id: string, - config?: FindConfig, - sharedContext?: Context - ): Promise - - /** - * Retrieve a shipping profile - * @param id - * @param config - * @param sharedContext - */ - retrieveShippingProfile( - id: string, - config?: FindConfig, - sharedContext?: Context - ): Promise - - /** - * Retrieve a geo zone - * @param id - * @param config - * @param sharedContext - */ - retrieveGeoZone( - id: string, - config?: FindConfig, - sharedContext?: Context - ): Promise - - /** - * Retrieve a shipping option rule - * @param id - * @param config - * @param sharedContext - */ - retrieveShippingOptionRule( - id: string, - config?: FindConfig, - sharedContext?: Context - ): Promise - /** * Retrieve a shipping option type * @param id @@ -350,91 +562,6 @@ export interface IFulfillmentModuleService extends IModuleService { config?: FindConfig, sharedContext?: Context ): Promise - - /** - * Retrieve a fulfillment - * @param id - * @param config - * @param sharedContext - */ - retrieveFulfillment( - id: string, - config?: FindConfig, - sharedContext?: Context - ): Promise - - /** - * List fulfillment sets - * @param filters - * @param config - * @param sharedContext - */ - list( - filters?: FilterableFulfillmentSetProps, - config?: FindConfig, - sharedContext?: Context - ): Promise - - /** - * List service zones - * @param filters - * @param config - * @param sharedContext - */ - listServiceZones( - filters?: FilterableServiceZoneProps, - config?: FindConfig, - sharedContext?: Context - ): Promise - - /** - * List shipping options - * @param filters - * @param config - * @param sharedContext - */ - listShippingOptions( - filters?: FilterableShippingOptionProps, - config?: FindConfig, - sharedContext?: Context - ): Promise - - /** - * List shipping profiles - * @param filters - * @param config - * @param sharedContext - */ - listShippingProfiles( - filters?: FilterableShippingProfileProps, - config?: FindConfig, - sharedContext?: Context - ): Promise - - /** - * List geo zones - * @param filters - * @param config - * @param sharedContext - */ - listGeoZones( - filters?: FilterableGeoZoneProps, - config?: FindConfig, - sharedContext?: Context - ): Promise - - /** - * List shipping option rules - * @param filters - * @param config - * @param sharedContext - */ - listShippingOptionRules( - filters?: FilterableShippingOptionRuleProps, - config?: FindConfig, - sharedContext?: Context - ): Promise - /** * List shipping option types * @param filters @@ -446,91 +573,6 @@ export interface IFulfillmentModuleService extends IModuleService { config?: FindConfig, sharedContext?: Context ): Promise - - /** - * List fulfillments - * @param filters - * @param config - * @param sharedContext - */ - listFulfillments( - filters?: FilterableFulfillmentSetProps, - config?: FindConfig, - sharedContext?: Context - ): Promise - - /** - * List and count fulfillment sets - * @param filters - * @param config - * @param sharedContext - */ - listAndCount( - filters?: FilterableFulfillmentSetProps, - config?: FindConfig, - sharedContext?: Context - ): Promise<[FulfillmentSetDTO[], number]> - - /** - * List and count service zones - * @param filters - * @param config - * @param sharedContext - */ - listAndCountServiceZones( - filters?: FilterableServiceZoneProps, - config?: FindConfig, - sharedContext?: Context - ): Promise<[ServiceZoneDTO[], number]> - - /** - * List and count shipping options - * @param filters - * @param config - * @param sharedContext - */ - listAndCountShippingOptions( - filters?: FilterableShippingOptionProps, - config?: FindConfig, - sharedContext?: Context - ): Promise<[ShippingOptionDTO[], number]> - - /** - * List and count shipping profiles - * @param filters - * @param config - * @param sharedContext - */ - listAndCountShippingProfiles( - filters?: FilterableShippingProfileProps, - config?: FindConfig, - sharedContext?: Context - ): Promise<[ShippingProfileDTO[], number]> - - /** - * List and count geo zones - * @param filters - * @param config - * @param sharedContext - */ - listAndCountGeoZones( - filters?: FilterableGeoZoneProps, - config?: FindConfig, - sharedContext?: Context - ): Promise<[GeoZoneDTO[], number]> - - /** - * List and count shipping option rules - * @param filters - * @param config - * @param sharedContext - */ - listAndCountShippingOptionRules( - filters?: FilterableShippingOptionRuleProps, - config?: FindConfig, - sharedContext?: Context - ): Promise<[ShippingOptionRuleDTO[], number]> - /** * List and count shipping options types * @param filters @@ -543,6 +585,39 @@ export interface IFulfillmentModuleService extends IModuleService { sharedContext?: Context ): Promise<[ShippingOptionTypeDTO[], number]> + /** + * delete a shipping option type + * @param ids + * @param sharedContext + */ + deleteShippingOptionTypes( + ids: string[], + sharedContext?: Context + ): Promise + deleteShippingOptionTypes(id: string, sharedContext?: Context): Promise + + /** + * Retrieve a fulfillment + * @param id + * @param config + * @param sharedContext + */ + retrieveFulfillment( + id: string, + config?: FindConfig, + sharedContext?: Context + ): Promise + /** + * List fulfillments + * @param filters + * @param config + * @param sharedContext + */ + listFulfillments( + filters?: FilterableFulfillmentSetProps, + config?: FindConfig, + sharedContext?: Context + ): Promise /** * List and count fulfillments * @param filters @@ -554,82 +629,6 @@ export interface IFulfillmentModuleService extends IModuleService { config?: FindConfig, sharedContext?: Context ): Promise<[FulfillmentDTO[], number]> - - /** - * Soft delete fulfillment sets - * @param fulfillmentIds - * @param config - * @param sharedContext - */ - softDelete( - fulfillmentIds: string[], - config?: SoftDeleteReturn, - sharedContext?: Context - ): Promise | void> - - /** - * Soft delete service zones - * @param serviceZoneIds - * @param config - * @param sharedContext - */ - softDeleteServiceZones( - serviceZoneIds: string[], - config?: SoftDeleteReturn, - sharedContext?: Context - ): Promise | void> - - /** - * Soft delete shipping options - * @param shippingOptionsIds - * @param config - * @param sharedContext - */ - softDeleteShippingOptions( - shippingOptionsIds: string[], - config?: SoftDeleteReturn, - sharedContext?: Context - ): Promise | void> - - /** - * Soft delete shipping profiles - * @param shippingProfileIds - * @param config - * @param sharedContext - */ - softDeleteShippingProfiles( - shippingProfileIds: string[], - config?: SoftDeleteReturn, - sharedContext?: Context - ): Promise | void> - - /** - * Soft delete geo zones - * @param geoZoneIds - * @param config - * @param sharedContext - */ - softDeleteGeoZones( - geoZoneIds: string[], - config?: SoftDeleteReturn, - sharedContext?: Context - ): Promise | void> - - restore( - fulfillmentIds: string[], - config?: RestoreReturn, - sharedContext?: Context - ): Promise | void> - - // TODO define needed soft delete/delete/restore methods - - /** - * Retrieve the available fulfillment options for the given data. - */ - retrieveFulfillmentOptions( - providerId: string - ): Promise[]> - /** * Create a new fulfillment including into the third party provider * @param data @@ -639,7 +638,16 @@ export interface IFulfillmentModuleService extends IModuleService { data: CreateFulfillmentDTO, sharedContext?: Context ): Promise - + /** + * Update a fulfillment + * @param data + * @param sharedContext + */ + updateFulfillment( + id: string, + data: UpdateFulfillmentDTO, + sharedContext?: Context + ): Promise /** * Cancel the given fulfillment including into the third party provider * @param id @@ -649,4 +657,11 @@ export interface IFulfillmentModuleService extends IModuleService { id: string, sharedContext?: Context ): Promise + + /** + * Retrieve the available fulfillment options for the given data. + */ + retrieveFulfillmentOptions( + providerId: string + ): Promise[]> }