feat(fulfillment): Module service implementation first iteration (#6381)
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/types": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
feat(fulfillment): Module service implementation first iteration
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +0,0 @@
|
|||||||
describe("noop", function () {
|
|
||||||
it("should run", function () {
|
|
||||||
expect(true).toBe(true)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -2,17 +2,12 @@ import { TestDatabaseUtils } from "medusa-test-utils"
|
|||||||
|
|
||||||
import * as Models from "@models"
|
import * as Models from "@models"
|
||||||
|
|
||||||
const pathToMigrations = "../../src/migrations"
|
|
||||||
const mikroOrmEntities = Models as unknown as any[]
|
const mikroOrmEntities = Models as unknown as any[]
|
||||||
|
|
||||||
export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper(
|
export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper(
|
||||||
mikroOrmEntities,
|
mikroOrmEntities,
|
||||||
pathToMigrations
|
null,
|
||||||
)
|
process.env.MEDUSA_FULFILLMENT_DB_SCHEMA
|
||||||
|
|
||||||
export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig(
|
|
||||||
mikroOrmEntities,
|
|
||||||
pathToMigrations
|
|
||||||
)
|
)
|
||||||
|
|
||||||
export const DB_URL = TestDatabaseUtils.getDatabaseURL()
|
export const DB_URL = TestDatabaseUtils.getDatabaseURL()
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
export * from "./database"
|
export * from "./database"
|
||||||
|
export * from "./get-init-module-config"
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,84 @@
|
|||||||
|
import { Migration } from '@mikro-orm/migrations';
|
||||||
|
|
||||||
|
export class Migration20240214103108 extends Migration {
|
||||||
|
|
||||||
|
async up(): Promise<void> {
|
||||||
|
this.addSql('create table if not exists "fulfillment_address" ("id" text not null, "fulfillment_id" text 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_fulfillment_id" ON "fulfillment_address" (fulfillment_id) WHERE deleted_at IS 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_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 INDEX IF NOT EXISTS "IDX_fulfillment_set_deleted_at" ON "fulfillment_set" (deleted_at) WHERE deleted_at IS NOT NULL;');
|
||||||
|
|
||||||
|
this.addSql('create table if not exists "service_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 "service_provider_pkey" primary key ("id"));');
|
||||||
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_service_provider_deleted_at" ON "service_provider" (deleted_at) WHERE deleted_at IS NOT NULL;');
|
||||||
|
|
||||||
|
this.addSql('create table if not exists "service_zone" ("id" text not null, "name" text not null, "metadata" jsonb null, "fulfillment_set_id" text not null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "service_zone_pkey" primary key ("id"));');
|
||||||
|
this.addSql('CREATE UNIQUE INDEX IF NOT EXISTS "IDX_service_zone_name_unique" ON "service_zone" (name) WHERE deleted_at IS NULL;');
|
||||||
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_service_zone_fulfillment_set_id" ON "service_zone" (fulfillment_set_id) WHERE deleted_at IS NULL;');
|
||||||
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_service_zone_deleted_at" ON "service_zone" (deleted_at) WHERE deleted_at IS NOT NULL;');
|
||||||
|
|
||||||
|
this.addSql('create table if not exists "geo_zone" ("id" text not null, "type" text check ("type" in (\'country\', \'province\', \'city\', \'zip\')) not null default \'country\', "country_code" text not null, "province_code" text null, "city" text null, "service_zone_id" text not null, "postal_expression" jsonb null, "metadata" jsonb null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "geo_zone_pkey" primary key ("id"));');
|
||||||
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_geo_zone_country_code" ON "geo_zone" (country_code) WHERE deleted_at IS NULL;');
|
||||||
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_geo_zone_province_code" ON "geo_zone" (province_code) WHERE deleted_at IS NULL AND province_code IS NOT NULL;');
|
||||||
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_geo_zone_city" ON "geo_zone" (city) WHERE deleted_at IS NULL AND city IS NOT NULL;');
|
||||||
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_geo_zone_service_zone_id" ON "geo_zone" (service_zone_id) WHERE deleted_at IS NULL;');
|
||||||
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_geo_zone_deleted_at" ON "geo_zone" (deleted_at) WHERE deleted_at IS NOT NULL;');
|
||||||
|
|
||||||
|
this.addSql('create table if not exists "shipping_option_type" ("id" text not null, "label" text not null, "description" text null, "code" text not null, "shipping_option_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_type_pkey" primary key ("id"));');
|
||||||
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_shipping_option_type_shipping_option_id" ON "shipping_option_type" (shipping_option_id) WHERE deleted_at IS NULL;');
|
||||||
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_shipping_option_type_deleted_at" ON "shipping_option_type" (deleted_at) WHERE deleted_at IS NOT NULL;');
|
||||||
|
|
||||||
|
this.addSql('create table if not exists "shipping_profile" ("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 "shipping_profile_pkey" primary key ("id"));');
|
||||||
|
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 not null, "service_provider_id" text not null, "shipping_option_type_id" text null, "data" jsonb null, "metadata" jsonb 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;');
|
||||||
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_shipping_option_service_provider_id" ON "shipping_option" (service_provider_id) WHERE deleted_at IS NULL;');
|
||||||
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_shipping_option_shipping_option_type_id" ON "shipping_option" (shipping_option_type_id) WHERE deleted_at IS NULL;');
|
||||||
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_shipping_option_deleted_at" ON "shipping_option" (deleted_at) WHERE deleted_at IS NOT NULL;');
|
||||||
|
|
||||||
|
this.addSql('create table if not exists "shipping_option_rule" ("id" text not null, "attribute" text not null, "operator" text not null, "value" jsonb null, "shipping_option_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_rule_pkey" primary key ("id"));');
|
||||||
|
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, "items_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 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_shipping_option_id" ON "fulfillment" (shipping_option_id) WHERE deleted_at IS NULL;');
|
||||||
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_fulfillment_deleted_at" ON "fulfillment" (deleted_at) WHERE deleted_at IS NOT NULL;');
|
||||||
|
|
||||||
|
this.addSql('create table if not exists "fulfillment_label" ("id" text not null, "tracking_number" text not null, "tracking_url" text not null, "label_url" text not null, "fulfillment_id" text not null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "fulfillment_label_pkey" primary key ("id"));');
|
||||||
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_fulfillment_label_fulfillment_id" ON "fulfillment_label" (fulfillment_id) WHERE deleted_at IS NULL;');
|
||||||
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_fulfillment_label_deleted_at" ON "fulfillment_label" (deleted_at) WHERE deleted_at IS NOT NULL;');
|
||||||
|
|
||||||
|
this.addSql('create table if not exists "fulfillment_item" ("id" text not null, "title" text not null, "sku" text not null, "barcode" text not null, "quantity" numeric not null, "line_item_id" text null, "inventory_item_id" text null, "fulfillment_id" text not null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "fulfillment_item_pkey" primary key ("id"));');
|
||||||
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_fulfillment_item_fulfillment_id" ON "fulfillment_item" (line_item_id) WHERE deleted_at IS NULL;');
|
||||||
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_fulfillment_item_fulfillment_id" ON "fulfillment_item" (inventory_item_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('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 "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 "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_shipping_profile_id_foreign" foreign key ("shipping_profile_id") references "shipping_profile" ("id") on update cascade;');
|
||||||
|
this.addSql('alter table if exists "shipping_option" add constraint "shipping_option_service_provider_id_foreign" foreign key ("service_provider_id") references "service_provider" ("id") on update 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;');
|
||||||
|
|
||||||
|
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 "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_provider_id_foreign" foreign key ("provider_id") references "service_provider" ("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;');
|
||||||
|
this.addSql('alter table if exists "fulfillment" add constraint "fulfillment_items_id_foreign" foreign key ("items_id") references "fulfillment_item" ("id") on update 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;');
|
||||||
|
|
||||||
|
this.addSql('alter table if exists "fulfillment_item" add constraint "fulfillment_item_fulfillment_id_foreign" foreign key ("fulfillment_id") references "fulfillment" ("id") on update cascade;');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -6,11 +6,12 @@ import {
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
BeforeCreate,
|
BeforeCreate,
|
||||||
|
Cascade,
|
||||||
Collection,
|
Collection,
|
||||||
Entity,
|
Entity,
|
||||||
Filter,
|
Filter,
|
||||||
Index,
|
Index,
|
||||||
ManyToMany,
|
OneToMany,
|
||||||
OnInit,
|
OnInit,
|
||||||
OptionalProps,
|
OptionalProps,
|
||||||
PrimaryKey,
|
PrimaryKey,
|
||||||
@@ -29,6 +30,15 @@ const deletedAtIndexStatement = createPsqlIndexStatementHelper({
|
|||||||
where: "deleted_at IS NOT NULL",
|
where: "deleted_at IS NOT NULL",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const nameIndexName = "IDX_fulfillment_set_name_unique"
|
||||||
|
const nameIndexStatement = createPsqlIndexStatementHelper({
|
||||||
|
name: nameIndexName,
|
||||||
|
tableName: "fulfillment_set",
|
||||||
|
columns: "name",
|
||||||
|
unique: true,
|
||||||
|
where: "deleted_at IS NULL",
|
||||||
|
})
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
|
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
|
||||||
export default class FulfillmentSet {
|
export default class FulfillmentSet {
|
||||||
@@ -38,6 +48,10 @@ export default class FulfillmentSet {
|
|||||||
id: string
|
id: string
|
||||||
|
|
||||||
@Property({ columnType: "text" })
|
@Property({ columnType: "text" })
|
||||||
|
@Index({
|
||||||
|
name: nameIndexName,
|
||||||
|
expression: nameIndexStatement,
|
||||||
|
})
|
||||||
name: string
|
name: string
|
||||||
|
|
||||||
@Property({ columnType: "text" })
|
@Property({ columnType: "text" })
|
||||||
@@ -46,11 +60,9 @@ export default class FulfillmentSet {
|
|||||||
@Property({ columnType: "jsonb", nullable: true })
|
@Property({ columnType: "jsonb", nullable: true })
|
||||||
metadata: Record<string, unknown> | null = null
|
metadata: Record<string, unknown> | null = null
|
||||||
|
|
||||||
@ManyToMany(() => ServiceZone, "fulfillment_sets", {
|
@OneToMany(() => ServiceZone, "fulfillment_set", {
|
||||||
owner: true,
|
cascade: [Cascade.PERSIST, "soft-remove"] as any,
|
||||||
pivotTable: "fulfillment_set_service_zones",
|
orphanRemoval: true,
|
||||||
joinColumn: "fulfillment_set_id",
|
|
||||||
inverseJoinColumn: "service_zone_id",
|
|
||||||
})
|
})
|
||||||
service_zones = new Collection<ServiceZone>(this)
|
service_zones = new Collection<ServiceZone>(this)
|
||||||
|
|
||||||
|
|||||||
@@ -7,12 +7,11 @@ import {
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
BeforeCreate,
|
BeforeCreate,
|
||||||
Collection,
|
|
||||||
Entity,
|
Entity,
|
||||||
Enum,
|
Enum,
|
||||||
Filter,
|
Filter,
|
||||||
Index,
|
Index,
|
||||||
ManyToMany,
|
ManyToOne,
|
||||||
OnInit,
|
OnInit,
|
||||||
OptionalProps,
|
OptionalProps,
|
||||||
PrimaryKey,
|
PrimaryKey,
|
||||||
@@ -55,6 +54,14 @@ const cityIndexStatement = createPsqlIndexStatementHelper({
|
|||||||
where: "deleted_at IS NULL AND city IS NOT NULL",
|
where: "deleted_at IS NULL AND city IS NOT NULL",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const serviceZoneIdIndexName = "IDX_geo_zone_service_zone_id"
|
||||||
|
const serviceZoneIdStatement = createPsqlIndexStatementHelper({
|
||||||
|
name: serviceZoneIdIndexName,
|
||||||
|
tableName: "geo_zone",
|
||||||
|
columns: "service_zone_id",
|
||||||
|
where: "deleted_at IS NULL",
|
||||||
|
})
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
|
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
|
||||||
export default class GeoZone {
|
export default class GeoZone {
|
||||||
@@ -87,6 +94,13 @@ export default class GeoZone {
|
|||||||
@Property({ columnType: "text", nullable: true })
|
@Property({ columnType: "text", nullable: true })
|
||||||
city: string | null = null
|
city: string | null = null
|
||||||
|
|
||||||
|
@Property({ columnType: "text" })
|
||||||
|
@Index({
|
||||||
|
name: serviceZoneIdIndexName,
|
||||||
|
expression: serviceZoneIdStatement,
|
||||||
|
})
|
||||||
|
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?
|
// 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
|
||||||
@@ -94,8 +108,10 @@ export default class GeoZone {
|
|||||||
@Property({ columnType: "jsonb", nullable: true })
|
@Property({ columnType: "jsonb", nullable: true })
|
||||||
metadata: Record<string, unknown> | null = null
|
metadata: Record<string, unknown> | null = null
|
||||||
|
|
||||||
@ManyToMany(() => ServiceZone, (serviceZone) => serviceZone.geo_zones)
|
@ManyToOne(() => ServiceZone, {
|
||||||
service_zones = new Collection<ServiceZone>(this)
|
persist: false,
|
||||||
|
})
|
||||||
|
service_zone: ServiceZone
|
||||||
|
|
||||||
@Property({
|
@Property({
|
||||||
onCreate: () => new Date(),
|
onCreate: () => new Date(),
|
||||||
@@ -122,10 +138,12 @@ export default class GeoZone {
|
|||||||
@BeforeCreate()
|
@BeforeCreate()
|
||||||
onCreate() {
|
onCreate() {
|
||||||
this.id = generateEntityId(this.id, " fgz")
|
this.id = generateEntityId(this.id, " fgz")
|
||||||
|
this.service_zone_id ??= this.service_zone?.id
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnInit()
|
@OnInit()
|
||||||
onInit() {
|
onInit() {
|
||||||
this.id = generateEntityId(this.id, "fgz")
|
this.id = generateEntityId(this.id, "fgz")
|
||||||
|
this.service_zone_id ??= this.service_zone?.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,12 @@ import {
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
BeforeCreate,
|
BeforeCreate,
|
||||||
|
Cascade,
|
||||||
Collection,
|
Collection,
|
||||||
Entity,
|
Entity,
|
||||||
Filter,
|
Filter,
|
||||||
Index,
|
Index,
|
||||||
ManyToMany,
|
ManyToOne,
|
||||||
OneToMany,
|
OneToMany,
|
||||||
OnInit,
|
OnInit,
|
||||||
OptionalProps,
|
OptionalProps,
|
||||||
@@ -32,6 +33,23 @@ const deletedAtIndexStatement = createPsqlIndexStatementHelper({
|
|||||||
where: "deleted_at IS NOT NULL",
|
where: "deleted_at IS NOT NULL",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const nameIndexName = "IDX_service_zone_name_unique"
|
||||||
|
const nameIndexStatement = createPsqlIndexStatementHelper({
|
||||||
|
name: nameIndexName,
|
||||||
|
tableName: "service_zone",
|
||||||
|
columns: "name",
|
||||||
|
unique: true,
|
||||||
|
where: "deleted_at IS NULL",
|
||||||
|
})
|
||||||
|
|
||||||
|
const fulfillmentSetIdIndexName = "IDX_service_zone_fulfillment_set_id"
|
||||||
|
const fulfillmentSetIdIndexStatement = createPsqlIndexStatementHelper({
|
||||||
|
name: fulfillmentSetIdIndexName,
|
||||||
|
tableName: "service_zone",
|
||||||
|
columns: "fulfillment_set_id",
|
||||||
|
where: "deleted_at IS NULL",
|
||||||
|
})
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
|
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
|
||||||
export default class ServiceZone {
|
export default class ServiceZone {
|
||||||
@@ -41,22 +59,28 @@ export default class ServiceZone {
|
|||||||
id: string
|
id: string
|
||||||
|
|
||||||
@Property({ columnType: "text" })
|
@Property({ columnType: "text" })
|
||||||
|
@Index({
|
||||||
|
name: nameIndexName,
|
||||||
|
expression: nameIndexStatement,
|
||||||
|
})
|
||||||
name: string
|
name: string
|
||||||
|
|
||||||
@Property({ columnType: "jsonb", nullable: true })
|
@Property({ columnType: "jsonb", nullable: true })
|
||||||
metadata: Record<string, unknown> | null = null
|
metadata: Record<string, unknown> | null = null
|
||||||
|
|
||||||
@ManyToMany(
|
@Property({ columnType: "text" })
|
||||||
() => FulfillmentSet,
|
@Index({
|
||||||
(fulfillmentSet) => fulfillmentSet.service_zones
|
name: fulfillmentSetIdIndexName,
|
||||||
)
|
expression: fulfillmentSetIdIndexStatement,
|
||||||
fulfillment_sets = new Collection<FulfillmentSet>(this)
|
})
|
||||||
|
fulfillment_set_id: string
|
||||||
|
|
||||||
@ManyToMany(() => GeoZone, "service_zones", {
|
@ManyToOne(() => FulfillmentSet, { persist: false })
|
||||||
owner: true,
|
fulfillment_set: FulfillmentSet
|
||||||
pivotTable: "service_zone_geo_zones",
|
|
||||||
joinColumn: "service_zone_id",
|
@OneToMany(() => GeoZone, "service_zone", {
|
||||||
inverseJoinColumn: "geo_zone_id",
|
cascade: [Cascade.PERSIST, "soft-remove"] as any,
|
||||||
|
orphanRemoval: true,
|
||||||
})
|
})
|
||||||
geo_zones = new Collection<GeoZone>(this)
|
geo_zones = new Collection<GeoZone>(this)
|
||||||
|
|
||||||
@@ -91,10 +115,12 @@ export default class ServiceZone {
|
|||||||
@BeforeCreate()
|
@BeforeCreate()
|
||||||
onCreate() {
|
onCreate() {
|
||||||
this.id = generateEntityId(this.id, "serzo")
|
this.id = generateEntityId(this.id, "serzo")
|
||||||
|
this.fulfillment_set_id ??= this.fulfillment_set?.id
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnInit()
|
@OnInit()
|
||||||
onInit() {
|
onInit() {
|
||||||
this.id = generateEntityId(this.id, "serzo")
|
this.id = generateEntityId(this.id, "serzo")
|
||||||
|
this.fulfillment_set_id ??= this.fulfillment_set?.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
import { Context, FulfillmentTypes } from "@medusajs/types"
|
||||||
|
import { DALUtils, promiseAll } from "@medusajs/utils"
|
||||||
|
import { FulfillmentSet, ServiceZone } from "@models"
|
||||||
|
import { SqlEntityManager } from "@mikro-orm/postgresql"
|
||||||
|
|
||||||
|
interface CreateFulfillmentSetDTO
|
||||||
|
extends FulfillmentTypes.CreateFulfillmentSetDTO {
|
||||||
|
service_zones: { id: string; name: string }[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export class FulfillmentSetRepository extends DALUtils.mikroOrmBaseRepositoryFactory<FulfillmentSet>(
|
||||||
|
FulfillmentSet
|
||||||
|
) {
|
||||||
|
async update(
|
||||||
|
data: {
|
||||||
|
entity: FulfillmentSet
|
||||||
|
update: FulfillmentTypes.FulfillmentSetDTO
|
||||||
|
}[],
|
||||||
|
context?: Context
|
||||||
|
): Promise<FulfillmentSet[]> {
|
||||||
|
const manager = this.getActiveManager<SqlEntityManager>(context)
|
||||||
|
|
||||||
|
// init all service zones collections
|
||||||
|
await promiseAll(
|
||||||
|
data.map(async ({ entity }) => {
|
||||||
|
return await entity.service_zones.init()
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
const flfillmentSetsToUpdate = data.map(({ entity, update }) => {
|
||||||
|
const { service_zones, ...restToUpdate } = update
|
||||||
|
|
||||||
|
const currentServiceZones = entity.service_zones.getItems()
|
||||||
|
const serviceZonesToDetach = currentServiceZones.filter(
|
||||||
|
(serviceZone) =>
|
||||||
|
!update.service_zones.find(
|
||||||
|
(newServiceZone) => newServiceZone.id === serviceZone.id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
const serviceZonesToAttach = update.service_zones.filter(
|
||||||
|
(newServiceZone) =>
|
||||||
|
!currentServiceZones.find(
|
||||||
|
(serviceZone) => serviceZone.id === newServiceZone.id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
entity.service_zones.remove(serviceZonesToDetach)
|
||||||
|
entity.service_zones.add(serviceZonesToAttach as unknown as ServiceZone[])
|
||||||
|
|
||||||
|
return manager.assign(entity, restToUpdate)
|
||||||
|
})
|
||||||
|
|
||||||
|
manager.persist(flfillmentSetsToUpdate)
|
||||||
|
|
||||||
|
return flfillmentSetsToUpdate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
@@ -8,20 +8,32 @@ import {
|
|||||||
ModulesSdkTypes,
|
ModulesSdkTypes,
|
||||||
UpdateFulfillmentSetDTO,
|
UpdateFulfillmentSetDTO,
|
||||||
} from "@medusajs/types"
|
} from "@medusajs/types"
|
||||||
import { InjectTransactionManager, ModulesSdkUtils } from "@medusajs/utils"
|
import {
|
||||||
|
InjectManager,
|
||||||
|
InjectTransactionManager,
|
||||||
|
MedusaContext,
|
||||||
|
MedusaError,
|
||||||
|
ModulesSdkUtils,
|
||||||
|
promiseAll,
|
||||||
|
getSetDifference
|
||||||
|
} from "@medusajs/utils"
|
||||||
|
|
||||||
import { entityNameToLinkableKeysMap, joinerConfig } from "../joiner-config"
|
import { entityNameToLinkableKeysMap, joinerConfig } from "../joiner-config"
|
||||||
import { FulfillmentSet, ServiceZone, ShippingOption } from "@models"
|
import { FulfillmentSet, GeoZone, ServiceZone, ShippingOption } from "@models"
|
||||||
|
|
||||||
const generateMethodForModels = [ServiceZone, ShippingOption]
|
const generateMethodForModels = [ServiceZone, ShippingOption, GeoZone]
|
||||||
|
|
||||||
type InjectedDependencies = {
|
type InjectedDependencies = {
|
||||||
baseRepository: DAL.RepositoryService
|
baseRepository: DAL.RepositoryService
|
||||||
fulfillmentService: ModulesSdkTypes.InternalModuleService<any>
|
fulfillmentSetService: ModulesSdkTypes.InternalModuleService<any>
|
||||||
|
serviceZoneService: ModulesSdkTypes.InternalModuleService<any>
|
||||||
|
geoZoneService: ModulesSdkTypes.InternalModuleService<any>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class FulfillmentModuleService<
|
export default class FulfillmentModuleService<
|
||||||
TEntity extends FulfillmentSet = FulfillmentSet
|
TEntity extends FulfillmentSet = FulfillmentSet,
|
||||||
|
TServiceZoneEntity extends ServiceZone = ServiceZone,
|
||||||
|
TGeoZoneEntity extends GeoZone = GeoZone
|
||||||
>
|
>
|
||||||
extends ModulesSdkUtils.abstractModuleServiceFactory<
|
extends ModulesSdkUtils.abstractModuleServiceFactory<
|
||||||
InjectedDependencies,
|
InjectedDependencies,
|
||||||
@@ -30,21 +42,31 @@ export default class FulfillmentModuleService<
|
|||||||
FulfillmentSet: { dto: FulfillmentTypes.FulfillmentSetDTO }
|
FulfillmentSet: { dto: FulfillmentTypes.FulfillmentSetDTO }
|
||||||
ServiceZone: { dto: FulfillmentTypes.ServiceZoneDTO }
|
ServiceZone: { dto: FulfillmentTypes.ServiceZoneDTO }
|
||||||
ShippingOption: { dto: FulfillmentTypes.ShippingOptionDTO }
|
ShippingOption: { dto: FulfillmentTypes.ShippingOptionDTO }
|
||||||
|
GeoZone: { dto: FulfillmentTypes.GeoZoneDTO }
|
||||||
}
|
}
|
||||||
>(FulfillmentSet, generateMethodForModels, entityNameToLinkableKeysMap)
|
>(FulfillmentSet, generateMethodForModels, entityNameToLinkableKeysMap)
|
||||||
implements IFulfillmentModuleService
|
implements IFulfillmentModuleService
|
||||||
{
|
{
|
||||||
protected baseRepository_: DAL.RepositoryService
|
protected baseRepository_: DAL.RepositoryService
|
||||||
protected readonly fulfillmentService_: ModulesSdkTypes.InternalModuleService<TEntity>
|
protected readonly fulfillmentSetService_: ModulesSdkTypes.InternalModuleService<TEntity>
|
||||||
|
protected readonly serviceZoneService_: ModulesSdkTypes.InternalModuleService<TServiceZoneEntity>
|
||||||
|
protected readonly geoZoneService_: ModulesSdkTypes.InternalModuleService<TGeoZoneEntity>
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
{ baseRepository, fulfillmentService }: InjectedDependencies,
|
{
|
||||||
|
baseRepository,
|
||||||
|
fulfillmentSetService,
|
||||||
|
serviceZoneService,
|
||||||
|
geoZoneService,
|
||||||
|
}: InjectedDependencies,
|
||||||
protected readonly moduleDeclaration: InternalModuleDeclaration
|
protected readonly moduleDeclaration: InternalModuleDeclaration
|
||||||
) {
|
) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
super(...arguments)
|
super(...arguments)
|
||||||
this.baseRepository_ = baseRepository
|
this.baseRepository_ = baseRepository
|
||||||
this.fulfillmentService_ = fulfillmentService
|
this.fulfillmentSetService_ = fulfillmentSetService
|
||||||
|
this.serviceZoneService_ = serviceZoneService
|
||||||
|
this.geoZoneService_ = geoZoneService
|
||||||
}
|
}
|
||||||
|
|
||||||
__joinerConfig(): ModuleJoinerConfig {
|
__joinerConfig(): ModuleJoinerConfig {
|
||||||
@@ -60,16 +82,41 @@ export default class FulfillmentModuleService<
|
|||||||
sharedContext?: Context
|
sharedContext?: Context
|
||||||
): Promise<FulfillmentTypes.FulfillmentSetDTO>
|
): Promise<FulfillmentTypes.FulfillmentSetDTO>
|
||||||
|
|
||||||
@InjectTransactionManager("baseRepository_")
|
@InjectManager("baseRepository_")
|
||||||
async create(
|
async create(
|
||||||
data:
|
data:
|
||||||
| FulfillmentTypes.CreateFulfillmentSetDTO
|
| FulfillmentTypes.CreateFulfillmentSetDTO
|
||||||
| FulfillmentTypes.CreateFulfillmentSetDTO[],
|
| FulfillmentTypes.CreateFulfillmentSetDTO[],
|
||||||
sharedContext?: Context
|
@MedusaContext() sharedContext: Context = {}
|
||||||
): Promise<
|
): Promise<
|
||||||
FulfillmentTypes.FulfillmentSetDTO | FulfillmentTypes.FulfillmentSetDTO[]
|
FulfillmentTypes.FulfillmentSetDTO | FulfillmentTypes.FulfillmentSetDTO[]
|
||||||
> {
|
> {
|
||||||
return []
|
const createdFulfillmentSets = await this.create_(data, sharedContext)
|
||||||
|
|
||||||
|
return await this.baseRepository_.serialize<
|
||||||
|
FulfillmentTypes.FulfillmentSetDTO | FulfillmentTypes.FulfillmentSetDTO[]
|
||||||
|
>(createdFulfillmentSets, {
|
||||||
|
populate: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
@InjectTransactionManager("baseRepository_")
|
||||||
|
protected async create_(
|
||||||
|
data:
|
||||||
|
| FulfillmentTypes.CreateFulfillmentSetDTO
|
||||||
|
| FulfillmentTypes.CreateFulfillmentSetDTO[],
|
||||||
|
@MedusaContext() sharedContext: Context = {}
|
||||||
|
): Promise<TEntity | TEntity[]> {
|
||||||
|
const data_ = Array.isArray(data) ? data : [data]
|
||||||
|
|
||||||
|
const createdFulfillmentSets = await this.fulfillmentSetService_.create(
|
||||||
|
data_,
|
||||||
|
sharedContext
|
||||||
|
)
|
||||||
|
|
||||||
|
return Array.isArray(data)
|
||||||
|
? createdFulfillmentSets
|
||||||
|
: createdFulfillmentSets[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
createServiceZones(
|
createServiceZones(
|
||||||
@@ -81,16 +128,46 @@ export default class FulfillmentModuleService<
|
|||||||
sharedContext?: Context
|
sharedContext?: Context
|
||||||
): Promise<FulfillmentTypes.ServiceZoneDTO>
|
): Promise<FulfillmentTypes.ServiceZoneDTO>
|
||||||
|
|
||||||
@InjectTransactionManager("baseRepository_")
|
@InjectManager("baseRepository_")
|
||||||
async createServiceZones(
|
async createServiceZones(
|
||||||
data:
|
data:
|
||||||
| FulfillmentTypes.CreateServiceZoneDTO[]
|
| FulfillmentTypes.CreateServiceZoneDTO[]
|
||||||
| FulfillmentTypes.CreateServiceZoneDTO,
|
| FulfillmentTypes.CreateServiceZoneDTO,
|
||||||
sharedContext?: Context
|
@MedusaContext() sharedContext: Context = {}
|
||||||
): Promise<
|
): Promise<
|
||||||
FulfillmentTypes.ServiceZoneDTO | FulfillmentTypes.ServiceZoneDTO[]
|
FulfillmentTypes.ServiceZoneDTO | FulfillmentTypes.ServiceZoneDTO[]
|
||||||
> {
|
> {
|
||||||
return []
|
const createdServiceZones = await this.createServiceZones_(
|
||||||
|
data,
|
||||||
|
sharedContext
|
||||||
|
)
|
||||||
|
|
||||||
|
return await this.baseRepository_.serialize<
|
||||||
|
FulfillmentTypes.ServiceZoneDTO | FulfillmentTypes.ServiceZoneDTO[]
|
||||||
|
>(createdServiceZones, {
|
||||||
|
populate: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
@InjectTransactionManager("baseRepository_")
|
||||||
|
protected async createServiceZones_(
|
||||||
|
data:
|
||||||
|
| FulfillmentTypes.CreateServiceZoneDTO[]
|
||||||
|
| FulfillmentTypes.CreateServiceZoneDTO,
|
||||||
|
@MedusaContext() sharedContext: Context = {}
|
||||||
|
): Promise<TServiceZoneEntity | TServiceZoneEntity[]> {
|
||||||
|
let data_ = Array.isArray(data) ? data : [data]
|
||||||
|
|
||||||
|
if (!data_.length) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
const createdServiceZones = await this.serviceZoneService_.create(
|
||||||
|
data_,
|
||||||
|
sharedContext
|
||||||
|
)
|
||||||
|
|
||||||
|
return Array.isArray(data) ? createdServiceZones : createdServiceZones[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
createShippingOptions(
|
createShippingOptions(
|
||||||
@@ -107,13 +184,42 @@ export default class FulfillmentModuleService<
|
|||||||
data:
|
data:
|
||||||
| FulfillmentTypes.CreateShippingOptionDTO[]
|
| FulfillmentTypes.CreateShippingOptionDTO[]
|
||||||
| FulfillmentTypes.CreateShippingOptionDTO,
|
| FulfillmentTypes.CreateShippingOptionDTO,
|
||||||
sharedContext?: Context
|
@MedusaContext() sharedContext: Context = {}
|
||||||
): Promise<
|
): Promise<
|
||||||
FulfillmentTypes.ShippingOptionDTO | FulfillmentTypes.ShippingOptionDTO[]
|
FulfillmentTypes.ShippingOptionDTO | FulfillmentTypes.ShippingOptionDTO[]
|
||||||
> {
|
> {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createGeoZones(
|
||||||
|
data: FulfillmentTypes.CreateGeoZoneDTO[],
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<FulfillmentTypes.GeoZoneDTO[]>
|
||||||
|
createGeoZones(
|
||||||
|
data: FulfillmentTypes.CreateGeoZoneDTO,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<FulfillmentTypes.GeoZoneDTO>
|
||||||
|
|
||||||
|
@InjectManager("baseRepository_")
|
||||||
|
async createGeoZones(
|
||||||
|
data:
|
||||||
|
| FulfillmentTypes.CreateGeoZoneDTO
|
||||||
|
| FulfillmentTypes.CreateGeoZoneDTO[],
|
||||||
|
@MedusaContext() sharedContext: Context = {}
|
||||||
|
): Promise<FulfillmentTypes.GeoZoneDTO | FulfillmentTypes.GeoZoneDTO[]> {
|
||||||
|
const createdGeoZones = await this.geoZoneService_.create(
|
||||||
|
data,
|
||||||
|
sharedContext
|
||||||
|
)
|
||||||
|
|
||||||
|
return await this.baseRepository_.serialize<FulfillmentTypes.GeoZoneDTO[]>(
|
||||||
|
createdGeoZones,
|
||||||
|
{
|
||||||
|
populate: true,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
update(
|
update(
|
||||||
data: FulfillmentTypes.UpdateFulfillmentSetDTO[],
|
data: FulfillmentTypes.UpdateFulfillmentSetDTO[],
|
||||||
sharedContext?: Context
|
sharedContext?: Context
|
||||||
@@ -123,14 +229,170 @@ export default class FulfillmentModuleService<
|
|||||||
sharedContext?: Context
|
sharedContext?: Context
|
||||||
): Promise<FulfillmentTypes.FulfillmentSetDTO>
|
): Promise<FulfillmentTypes.FulfillmentSetDTO>
|
||||||
|
|
||||||
@InjectTransactionManager("baseRepository_")
|
@InjectManager("baseRepository_")
|
||||||
async update(
|
async update(
|
||||||
data: UpdateFulfillmentSetDTO[] | UpdateFulfillmentSetDTO,
|
data: UpdateFulfillmentSetDTO[] | UpdateFulfillmentSetDTO,
|
||||||
sharedContext?: Context
|
@MedusaContext() sharedContext: Context = {}
|
||||||
): Promise<
|
): Promise<
|
||||||
FulfillmentTypes.FulfillmentSetDTO[] | FulfillmentTypes.FulfillmentSetDTO
|
FulfillmentTypes.FulfillmentSetDTO[] | FulfillmentTypes.FulfillmentSetDTO
|
||||||
> {
|
> {
|
||||||
return []
|
const updatedFulfillmentSets = await this.update_(data, sharedContext)
|
||||||
|
|
||||||
|
return await this.baseRepository_.serialize<
|
||||||
|
FulfillmentTypes.FulfillmentSetDTO | FulfillmentTypes.FulfillmentSetDTO[]
|
||||||
|
>(updatedFulfillmentSets, {
|
||||||
|
populate: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
@InjectTransactionManager("baseRepository_")
|
||||||
|
protected async update_(
|
||||||
|
data: UpdateFulfillmentSetDTO[] | UpdateFulfillmentSetDTO,
|
||||||
|
@MedusaContext() sharedContext: Context = {}
|
||||||
|
): Promise<TEntity[] | TEntity> {
|
||||||
|
const data_ = Array.isArray(data) ? data : [data]
|
||||||
|
|
||||||
|
if (!data_.length) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
const fulfillmentSetIds = data_.map((f) => f.id)
|
||||||
|
if (!fulfillmentSetIds.length) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
const fulfillmentSets = await this.fulfillmentSetService_.list(
|
||||||
|
{
|
||||||
|
id: fulfillmentSetIds,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
relations: ["service_zones", "service_zones.geo_zones"],
|
||||||
|
},
|
||||||
|
sharedContext
|
||||||
|
)
|
||||||
|
|
||||||
|
const fulfillmentSetSet = new Set(fulfillmentSets.map((f) => f.id))
|
||||||
|
const expectedFulfillmentSetSet = new Set(data_.map((f) => f.id))
|
||||||
|
const missingFulfillmentSetIds = getSetDifference(
|
||||||
|
expectedFulfillmentSetSet,
|
||||||
|
fulfillmentSetSet
|
||||||
|
)
|
||||||
|
|
||||||
|
if (missingFulfillmentSetIds.size) {
|
||||||
|
throw new MedusaError(
|
||||||
|
MedusaError.Types.NOT_FOUND,
|
||||||
|
`The following fulfillment sets does not exists: ${Array.from(
|
||||||
|
missingFulfillmentSetIds
|
||||||
|
).join(", ")}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const fulfillmentSetMap = new Map<string, TEntity>(
|
||||||
|
fulfillmentSets.map((f) => [f.id, f])
|
||||||
|
)
|
||||||
|
|
||||||
|
// find service zones to delete
|
||||||
|
const serviceZoneIdsToDelete: string[] = []
|
||||||
|
const geoZoneIdsToDelete: string[] = []
|
||||||
|
data_.forEach((fulfillmentSet) => {
|
||||||
|
if (fulfillmentSet.service_zones) {
|
||||||
|
/**
|
||||||
|
* Detect and delete service zones that are not in the updated
|
||||||
|
*/
|
||||||
|
|
||||||
|
const existingFulfillmentSet = fulfillmentSetMap.get(fulfillmentSet.id)!
|
||||||
|
const existingServiceZones = existingFulfillmentSet.service_zones
|
||||||
|
const updatedServiceZones = fulfillmentSet.service_zones
|
||||||
|
const toDeleteServiceZoneIds = getSetDifference(
|
||||||
|
new Set(existingServiceZones.map((s) => s.id)),
|
||||||
|
new Set(
|
||||||
|
updatedServiceZones
|
||||||
|
.map((s) => "id" in s && s.id)
|
||||||
|
.filter((id): id is string => !!id)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if (toDeleteServiceZoneIds.size) {
|
||||||
|
serviceZoneIdsToDelete.push(...Array.from(toDeleteServiceZoneIds))
|
||||||
|
geoZoneIdsToDelete.push(
|
||||||
|
...existingServiceZones
|
||||||
|
.filter((s) => toDeleteServiceZoneIds.has(s.id))
|
||||||
|
.flatMap((s) => s.geo_zones.map((g) => g.id))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect and re assign service zones to the fulfillment set that are still present
|
||||||
|
*/
|
||||||
|
|
||||||
|
const serviceZonesMap = new Map(
|
||||||
|
existingFulfillmentSet.service_zones.map((serviceZone) => [
|
||||||
|
serviceZone.id,
|
||||||
|
serviceZone,
|
||||||
|
])
|
||||||
|
)
|
||||||
|
const serviceZonesSet = new Set(
|
||||||
|
existingServiceZones
|
||||||
|
.map((s) => "id" in s && s.id)
|
||||||
|
.filter((id): id is string => !!id)
|
||||||
|
)
|
||||||
|
const expectedServiceZoneSet = new Set(
|
||||||
|
fulfillmentSet.service_zones
|
||||||
|
.map((s) => "id" in s && s.id)
|
||||||
|
.filter((id): id is string => !!id)
|
||||||
|
)
|
||||||
|
const missingServiceZoneIds = getSetDifference(
|
||||||
|
expectedServiceZoneSet,
|
||||||
|
serviceZonesSet
|
||||||
|
)
|
||||||
|
|
||||||
|
if (missingServiceZoneIds.size) {
|
||||||
|
throw new MedusaError(
|
||||||
|
MedusaError.Types.NOT_FOUND,
|
||||||
|
`The following service zones does not exists: ${Array.from(
|
||||||
|
missingServiceZoneIds
|
||||||
|
).join(", ")}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// re assign service zones to the fulfillment set
|
||||||
|
if (fulfillmentSet.service_zones) {
|
||||||
|
fulfillmentSet.service_zones = fulfillmentSet.service_zones.map(
|
||||||
|
(serviceZone) => {
|
||||||
|
if (!("id" in serviceZone)) {
|
||||||
|
return serviceZone
|
||||||
|
}
|
||||||
|
return serviceZonesMap.get(serviceZone.id)!
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (serviceZoneIdsToDelete.length) {
|
||||||
|
await promiseAll([
|
||||||
|
this.geoZoneService_.delete(
|
||||||
|
{
|
||||||
|
id: geoZoneIdsToDelete,
|
||||||
|
},
|
||||||
|
sharedContext
|
||||||
|
),
|
||||||
|
this.serviceZoneService_.delete(
|
||||||
|
{
|
||||||
|
id: serviceZoneIdsToDelete,
|
||||||
|
},
|
||||||
|
sharedContext
|
||||||
|
),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatedFulfillmentSets = await this.fulfillmentSetService_.update(
|
||||||
|
data_,
|
||||||
|
sharedContext
|
||||||
|
)
|
||||||
|
|
||||||
|
return Array.isArray(data)
|
||||||
|
? updatedFulfillmentSets
|
||||||
|
: updatedFulfillmentSets[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
updateServiceZones(
|
updateServiceZones(
|
||||||
@@ -142,16 +404,146 @@ export default class FulfillmentModuleService<
|
|||||||
sharedContext?: Context
|
sharedContext?: Context
|
||||||
): Promise<FulfillmentTypes.ServiceZoneDTO>
|
): Promise<FulfillmentTypes.ServiceZoneDTO>
|
||||||
|
|
||||||
@InjectTransactionManager("baseRepository_")
|
@InjectManager("baseRepository_")
|
||||||
async updateServiceZones(
|
async updateServiceZones(
|
||||||
data:
|
data:
|
||||||
| FulfillmentTypes.UpdateServiceZoneDTO[]
|
| FulfillmentTypes.UpdateServiceZoneDTO[]
|
||||||
| FulfillmentTypes.UpdateServiceZoneDTO,
|
| FulfillmentTypes.UpdateServiceZoneDTO,
|
||||||
sharedContext?: Context
|
@MedusaContext() sharedContext: Context = {}
|
||||||
): Promise<
|
): Promise<
|
||||||
FulfillmentTypes.ServiceZoneDTO[] | FulfillmentTypes.ServiceZoneDTO
|
FulfillmentTypes.ServiceZoneDTO[] | FulfillmentTypes.ServiceZoneDTO
|
||||||
> {
|
> {
|
||||||
return []
|
const updatedServiceZones = await this.updateServiceZones_(
|
||||||
|
data,
|
||||||
|
sharedContext
|
||||||
|
)
|
||||||
|
|
||||||
|
return await this.baseRepository_.serialize<
|
||||||
|
FulfillmentTypes.ServiceZoneDTO | FulfillmentTypes.ServiceZoneDTO[]
|
||||||
|
>(updatedServiceZones, {
|
||||||
|
populate: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
@InjectTransactionManager("baseRepository_")
|
||||||
|
protected async updateServiceZones_(
|
||||||
|
data:
|
||||||
|
| FulfillmentTypes.UpdateServiceZoneDTO[]
|
||||||
|
| FulfillmentTypes.UpdateServiceZoneDTO,
|
||||||
|
@MedusaContext() sharedContext: Context = {}
|
||||||
|
): Promise<TServiceZoneEntity | TServiceZoneEntity[]> {
|
||||||
|
const data_ = Array.isArray(data) ? data : [data]
|
||||||
|
|
||||||
|
if (!data_.length) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
const serviceZoneIds = data_.map((s) => s.id)
|
||||||
|
if (!serviceZoneIds.length) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
const serviceZones = await this.serviceZoneService_.list(
|
||||||
|
{
|
||||||
|
id: serviceZoneIds,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
relations: ["geo_zones"],
|
||||||
|
},
|
||||||
|
sharedContext
|
||||||
|
)
|
||||||
|
|
||||||
|
const serviceZoneSet = new Set(serviceZones.map((s) => s.id))
|
||||||
|
const expectedServiceZoneSet = new Set(data_.map((s) => s.id))
|
||||||
|
const missingServiceZoneIds = getSetDifference(
|
||||||
|
expectedServiceZoneSet,
|
||||||
|
serviceZoneSet
|
||||||
|
)
|
||||||
|
|
||||||
|
if (missingServiceZoneIds.size) {
|
||||||
|
throw new MedusaError(
|
||||||
|
MedusaError.Types.NOT_FOUND,
|
||||||
|
`The following service zones does not exists: ${Array.from(
|
||||||
|
missingServiceZoneIds
|
||||||
|
).join(", ")}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const serviceZoneMap = new Map<string, TServiceZoneEntity>(
|
||||||
|
serviceZones.map((s) => [s.id, s])
|
||||||
|
)
|
||||||
|
|
||||||
|
const serviceZoneIdsToDelete: string[] = []
|
||||||
|
const geoZoneIdsToDelete: string[] = []
|
||||||
|
|
||||||
|
data_.forEach((serviceZone) => {
|
||||||
|
if (serviceZone.geo_zones) {
|
||||||
|
const existingServiceZone = serviceZoneMap.get(serviceZone.id)!
|
||||||
|
const existingGeoZones = existingServiceZone.geo_zones
|
||||||
|
const updatedGeoZones = serviceZone.geo_zones
|
||||||
|
const toDeleteGeoZoneIds = getSetDifference(
|
||||||
|
new Set(existingGeoZones.map((g) => g.id)),
|
||||||
|
new Set(
|
||||||
|
updatedGeoZones
|
||||||
|
.map((g) => "id" in g && g.id)
|
||||||
|
.filter((id): id is string => !!id)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if (toDeleteGeoZoneIds.size) {
|
||||||
|
geoZoneIdsToDelete.push(...Array.from(toDeleteGeoZoneIds))
|
||||||
|
}
|
||||||
|
|
||||||
|
const geoZonesMap = new Map(
|
||||||
|
existingServiceZone.geo_zones.map((geoZone) => [geoZone.id, geoZone])
|
||||||
|
)
|
||||||
|
const geoZonesSet = new Set(
|
||||||
|
existingGeoZones
|
||||||
|
.map((g) => "id" in g && g.id)
|
||||||
|
.filter((id): id is string => !!id)
|
||||||
|
)
|
||||||
|
const expectedGeoZoneSet = new Set(
|
||||||
|
serviceZone.geo_zones
|
||||||
|
.map((g) => "id" in g && g.id)
|
||||||
|
.filter((id): id is string => !!id)
|
||||||
|
)
|
||||||
|
const missingGeoZoneIds = getSetDifference(
|
||||||
|
expectedGeoZoneSet,
|
||||||
|
geoZonesSet
|
||||||
|
)
|
||||||
|
|
||||||
|
if (missingGeoZoneIds.size) {
|
||||||
|
throw new MedusaError(
|
||||||
|
MedusaError.Types.NOT_FOUND,
|
||||||
|
`The following geo zones does not exists: ${Array.from(
|
||||||
|
missingGeoZoneIds
|
||||||
|
).join(", ")}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
serviceZone.geo_zones = serviceZone.geo_zones.map((geoZone) => {
|
||||||
|
if (!("id" in geoZone)) {
|
||||||
|
return geoZone
|
||||||
|
}
|
||||||
|
return geoZonesMap.get(geoZone.id)!
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (geoZoneIdsToDelete.length) {
|
||||||
|
await this.geoZoneService_.delete(
|
||||||
|
{
|
||||||
|
id: geoZoneIdsToDelete,
|
||||||
|
},
|
||||||
|
sharedContext
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatedServiceZones = await this.serviceZoneService_.update(
|
||||||
|
data_,
|
||||||
|
sharedContext
|
||||||
|
)
|
||||||
|
|
||||||
|
return Array.isArray(data) ? updatedServiceZones : updatedServiceZones[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
updateShippingOptions(
|
updateShippingOptions(
|
||||||
@@ -168,10 +560,40 @@ export default class FulfillmentModuleService<
|
|||||||
data:
|
data:
|
||||||
| FulfillmentTypes.UpdateShippingOptionDTO[]
|
| FulfillmentTypes.UpdateShippingOptionDTO[]
|
||||||
| FulfillmentTypes.UpdateShippingOptionDTO,
|
| FulfillmentTypes.UpdateShippingOptionDTO,
|
||||||
sharedContext?: Context
|
@MedusaContext() sharedContext: Context = {}
|
||||||
): Promise<
|
): Promise<
|
||||||
FulfillmentTypes.ShippingOptionDTO[] | FulfillmentTypes.ShippingOptionDTO
|
FulfillmentTypes.ShippingOptionDTO[] | FulfillmentTypes.ShippingOptionDTO
|
||||||
> {
|
> {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateGeoZones(
|
||||||
|
data: FulfillmentTypes.UpdateGeoZoneDTO[],
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<FulfillmentTypes.GeoZoneDTO[]>
|
||||||
|
updateGeoZones(
|
||||||
|
data: FulfillmentTypes.UpdateGeoZoneDTO,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<FulfillmentTypes.GeoZoneDTO>
|
||||||
|
|
||||||
|
@InjectManager("baseRepository_")
|
||||||
|
async updateGeoZones(
|
||||||
|
data:
|
||||||
|
| FulfillmentTypes.UpdateGeoZoneDTO
|
||||||
|
| FulfillmentTypes.UpdateGeoZoneDTO[],
|
||||||
|
@MedusaContext() sharedContext: Context = {}
|
||||||
|
): Promise<FulfillmentTypes.GeoZoneDTO | FulfillmentTypes.GeoZoneDTO[]> {
|
||||||
|
const updatedGeoZones = await this.geoZoneService_.update(
|
||||||
|
data,
|
||||||
|
sharedContext
|
||||||
|
)
|
||||||
|
|
||||||
|
const serialized = await this.baseRepository_.serialize<
|
||||||
|
FulfillmentTypes.GeoZoneDTO[]
|
||||||
|
>(updatedGeoZones, {
|
||||||
|
populate: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
return Array.isArray(data) ? serialized : serialized[0]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,12 @@ import { CreateServiceZoneDTO } from "./service-zone"
|
|||||||
export interface CreateFulfillmentSetDTO {
|
export interface CreateFulfillmentSetDTO {
|
||||||
name: string
|
name: string
|
||||||
type: string
|
type: string
|
||||||
service_zones: Omit<CreateServiceZoneDTO, "fulfillment_set_id">[]
|
service_zones?: Omit<CreateServiceZoneDTO, 'fulfillment_set_id'>[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UpdateFulfillmentSetDTO
|
export interface UpdateFulfillmentSetDTO {
|
||||||
extends Partial<CreateFulfillmentSetDTO> {
|
|
||||||
id: string
|
id: string
|
||||||
|
name?: string
|
||||||
|
type?: string
|
||||||
|
service_zones?: (Omit<CreateServiceZoneDTO, 'fulfillment_set_id'> | { id: string })[]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,24 +9,20 @@ interface CreateGeoZoneBaseDTO {
|
|||||||
|
|
||||||
interface CreateCountryGeoZoneDTO extends CreateGeoZoneBaseDTO {
|
interface CreateCountryGeoZoneDTO extends CreateGeoZoneBaseDTO {
|
||||||
type: "country"
|
type: "country"
|
||||||
country_code: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CreateProvinceGeoZoneDTO extends CreateGeoZoneBaseDTO {
|
interface CreateProvinceGeoZoneDTO extends CreateGeoZoneBaseDTO {
|
||||||
type: "province"
|
type: "province"
|
||||||
country_code: string
|
|
||||||
province_code: string
|
province_code: string
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CreateCityGeoZoneDTO extends CreateGeoZoneBaseDTO {
|
interface CreateCityGeoZoneDTO extends CreateGeoZoneBaseDTO {
|
||||||
type: "city"
|
type: "city"
|
||||||
country_code: string
|
|
||||||
city: string
|
city: string
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CreateZipGeoZoneDTO extends CreateGeoZoneBaseDTO {
|
interface CreateZipGeoZoneDTO extends CreateGeoZoneBaseDTO {
|
||||||
type: "zip"
|
type: "zip"
|
||||||
country_code: string
|
|
||||||
postal_expression: Record<string, any>
|
postal_expression: Record<string, any>
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,24 +38,20 @@ interface UpdateGeoZoneBaseDTO extends Partial<CreateGeoZoneBaseDTO> {
|
|||||||
|
|
||||||
interface UpdateCountryGeoZoneDTO extends UpdateGeoZoneBaseDTO {
|
interface UpdateCountryGeoZoneDTO extends UpdateGeoZoneBaseDTO {
|
||||||
type: "country"
|
type: "country"
|
||||||
country_code: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UpdateProvinceGeoZoneDTO extends UpdateGeoZoneBaseDTO {
|
interface UpdateProvinceGeoZoneDTO extends UpdateGeoZoneBaseDTO {
|
||||||
type: "province"
|
type: "province"
|
||||||
country_code: string
|
|
||||||
province_code: string
|
province_code: string
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UpdateCityGeoZoneDTO extends UpdateGeoZoneBaseDTO {
|
interface UpdateCityGeoZoneDTO extends UpdateGeoZoneBaseDTO {
|
||||||
type: "city"
|
type: "city"
|
||||||
country_code: string
|
|
||||||
city: string
|
city: string
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UpdateZipGeoZoneDTO extends UpdateGeoZoneBaseDTO {
|
interface UpdateZipGeoZoneDTO extends UpdateGeoZoneBaseDTO {
|
||||||
type: "zip"
|
type: "zip"
|
||||||
country_code: string
|
|
||||||
postal_expression: Record<string, any>
|
postal_expression: Record<string, any>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
import { CreateGeoZoneDTO, UpdateGeoZoneDTO } from "./geo-zone"
|
import { CreateGeoZoneDTO } from "./geo-zone"
|
||||||
|
|
||||||
export interface CreateServiceZoneDTO {
|
export interface CreateServiceZoneDTO {
|
||||||
fulfillment_set_id: string
|
|
||||||
name: string
|
name: string
|
||||||
geo_zones: (
|
fulfillment_set_id: string
|
||||||
| Omit<CreateGeoZoneDTO, "service_zone_id">
|
geo_zones?: Omit<CreateGeoZoneDTO, "service_zone_id">[]
|
||||||
| Omit<UpdateGeoZoneDTO, "service_zone_id">
|
|
||||||
)[]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UpdateServiceZoneDTO extends Partial<CreateServiceZoneDTO> {
|
export interface UpdateServiceZoneDTO {
|
||||||
id: string
|
id: string
|
||||||
|
name?: string
|
||||||
|
geo_zones?: (Omit<CreateGeoZoneDTO, "service_zone_id"> | { id: string })[]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import { IModuleService } from "../modules-sdk"
|
import { IModuleService } from "../modules-sdk"
|
||||||
import {
|
import {
|
||||||
FilterableFulfillmentSetProps,
|
FilterableFulfillmentSetProps,
|
||||||
|
FilterableGeoZoneProps,
|
||||||
FilterableServiceZoneProps,
|
FilterableServiceZoneProps,
|
||||||
FilterableShippingOptionProps,
|
FilterableShippingOptionProps,
|
||||||
FulfillmentSetDTO,
|
FulfillmentSetDTO,
|
||||||
|
GeoZoneDTO,
|
||||||
ServiceZoneDTO,
|
ServiceZoneDTO,
|
||||||
ShippingOptionDTO,
|
ShippingOptionDTO,
|
||||||
} from "./common"
|
} from "./common"
|
||||||
@@ -12,9 +14,11 @@ import { Context } from "../shared-context"
|
|||||||
import { RestoreReturn, SoftDeleteReturn } from "../dal"
|
import { RestoreReturn, SoftDeleteReturn } from "../dal"
|
||||||
import {
|
import {
|
||||||
CreateFulfillmentSetDTO,
|
CreateFulfillmentSetDTO,
|
||||||
|
CreateGeoZoneDTO,
|
||||||
CreateServiceZoneDTO,
|
CreateServiceZoneDTO,
|
||||||
CreateShippingOptionDTO,
|
CreateShippingOptionDTO,
|
||||||
UpdateFulfillmentSetDTO,
|
UpdateFulfillmentSetDTO,
|
||||||
|
UpdateGeoZoneDTO,
|
||||||
UpdateServiceZoneDTO,
|
UpdateServiceZoneDTO,
|
||||||
UpdateShippingOptionDTO,
|
UpdateShippingOptionDTO,
|
||||||
} from "./mutations"
|
} from "./mutations"
|
||||||
@@ -62,6 +66,20 @@ export interface IFulfillmentModuleService extends IModuleService {
|
|||||||
sharedContext?: Context
|
sharedContext?: Context
|
||||||
): Promise<ShippingOptionDTO>
|
): Promise<ShippingOptionDTO>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new geo zone
|
||||||
|
* @param data
|
||||||
|
* @param sharedContext
|
||||||
|
*/
|
||||||
|
createGeoZones(
|
||||||
|
data: CreateGeoZoneDTO[],
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<GeoZoneDTO[]>
|
||||||
|
createGeoZones(
|
||||||
|
data: CreateGeoZoneDTO,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<GeoZoneDTO>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update a fulfillment set
|
* Update a fulfillment set
|
||||||
* @param data
|
* @param data
|
||||||
@@ -104,6 +122,20 @@ export interface IFulfillmentModuleService extends IModuleService {
|
|||||||
sharedContext?: Context
|
sharedContext?: Context
|
||||||
): Promise<ShippingOptionDTO>
|
): Promise<ShippingOptionDTO>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a geo zone
|
||||||
|
* @param data
|
||||||
|
* @param sharedContext
|
||||||
|
*/
|
||||||
|
updateGeoZones(
|
||||||
|
data: UpdateGeoZoneDTO[],
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<GeoZoneDTO[]>
|
||||||
|
updateGeoZones(
|
||||||
|
data: UpdateGeoZoneDTO,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<GeoZoneDTO>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a fulfillment set
|
* Delete a fulfillment set
|
||||||
* @param ids
|
* @param ids
|
||||||
@@ -128,6 +160,14 @@ export interface IFulfillmentModuleService extends IModuleService {
|
|||||||
deleteShippingOptions(ids: string[], sharedContext?: Context): Promise<void>
|
deleteShippingOptions(ids: string[], sharedContext?: Context): Promise<void>
|
||||||
deleteShippingOptions(id: string, sharedContext?: Context): Promise<void>
|
deleteShippingOptions(id: string, sharedContext?: Context): Promise<void>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a geo zone
|
||||||
|
* @param ids
|
||||||
|
* @param sharedContext
|
||||||
|
*/
|
||||||
|
deleteGeoZones(ids: string[], sharedContext?: Context): Promise<void>
|
||||||
|
deleteGeoZones(id: string, sharedContext?: Context): Promise<void>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a fulfillment set
|
* Retrieve a fulfillment set
|
||||||
* @param id
|
* @param id
|
||||||
@@ -164,6 +204,18 @@ export interface IFulfillmentModuleService extends IModuleService {
|
|||||||
sharedContext?: Context
|
sharedContext?: Context
|
||||||
): Promise<ShippingOptionDTO>
|
): Promise<ShippingOptionDTO>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a geo zone
|
||||||
|
* @param id
|
||||||
|
* @param config
|
||||||
|
* @param sharedContext
|
||||||
|
*/
|
||||||
|
retrieveGeoZone(
|
||||||
|
id: string,
|
||||||
|
config?: FindConfig<GeoZoneDTO>,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<GeoZoneDTO>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List fulfillment sets
|
* List fulfillment sets
|
||||||
* @param filters
|
* @param filters
|
||||||
@@ -200,6 +252,18 @@ export interface IFulfillmentModuleService extends IModuleService {
|
|||||||
sharedContext?: Context
|
sharedContext?: Context
|
||||||
): Promise<ShippingOptionDTO[]>
|
): Promise<ShippingOptionDTO[]>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List geo zones
|
||||||
|
* @param filters
|
||||||
|
* @param config
|
||||||
|
* @param sharedContext
|
||||||
|
*/
|
||||||
|
listGeoZones(
|
||||||
|
filters?: FilterableGeoZoneProps,
|
||||||
|
config?: FindConfig<GeoZoneDTO>,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<GeoZoneDTO[]>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List and count fulfillment sets
|
* List and count fulfillment sets
|
||||||
* @param filters
|
* @param filters
|
||||||
@@ -236,6 +300,18 @@ export interface IFulfillmentModuleService extends IModuleService {
|
|||||||
sharedContext?: Context
|
sharedContext?: Context
|
||||||
): Promise<[ShippingOptionDTO[], number]>
|
): Promise<[ShippingOptionDTO[], number]>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List and count geo zones
|
||||||
|
* @param filters
|
||||||
|
* @param config
|
||||||
|
* @param sharedContext
|
||||||
|
*/
|
||||||
|
listAndCountGeoZones(
|
||||||
|
filters?: FilterableGeoZoneProps,
|
||||||
|
config?: FindConfig<GeoZoneDTO>,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<[GeoZoneDTO[], number]>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Soft delete fulfillment sets
|
* Soft delete fulfillment sets
|
||||||
* @param fulfillmentIds
|
* @param fulfillmentIds
|
||||||
@@ -272,6 +348,18 @@ export interface IFulfillmentModuleService extends IModuleService {
|
|||||||
sharedContext?: Context
|
sharedContext?: Context
|
||||||
): Promise<Record<string, string[]> | void>
|
): Promise<Record<string, string[]> | void>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Soft delete geo zones
|
||||||
|
* @param geoZoneIds
|
||||||
|
* @param config
|
||||||
|
* @param sharedContext
|
||||||
|
*/
|
||||||
|
softDeleteGeoZones<TReturnableLinkableKeys extends string = string>(
|
||||||
|
geoZoneIds: string[],
|
||||||
|
config?: SoftDeleteReturn<TReturnableLinkableKeys>,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<Record<string, string[]> | void>
|
||||||
|
|
||||||
restore<TReturnableLinkableKeys extends string = string>(
|
restore<TReturnableLinkableKeys extends string = string>(
|
||||||
fulfillmentIds: string[],
|
fulfillmentIds: string[],
|
||||||
config?: RestoreReturn<TReturnableLinkableKeys>,
|
config?: RestoreReturn<TReturnableLinkableKeys>,
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* Get the difference between two sets. The difference is the elements that are in the original set but not in the compare set.
|
||||||
|
* @param orignalSet
|
||||||
|
* @param compareSet
|
||||||
|
*/
|
||||||
|
export function getSetDifference<T>(
|
||||||
|
orignalSet: Set<T>,
|
||||||
|
compareSet: Set<T>
|
||||||
|
): Set<T> {
|
||||||
|
const difference = new Set<T>()
|
||||||
|
|
||||||
|
orignalSet.forEach((element) => {
|
||||||
|
if (!compareSet.has(element)) {
|
||||||
|
difference.add(element)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return difference
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
export * from "./alter-columns-helper"
|
export * from "./alter-columns-helper"
|
||||||
export * from "./array-difference"
|
export * from "./array-difference"
|
||||||
|
export * from "./get-set-difference"
|
||||||
export * from "./build-query"
|
export * from "./build-query"
|
||||||
export * from "./camel-to-snake-case"
|
export * from "./camel-to-snake-case"
|
||||||
export * from "./container"
|
export * from "./container"
|
||||||
@@ -46,4 +47,3 @@ export * from "./to-pascal-case"
|
|||||||
export * from "./transaction"
|
export * from "./transaction"
|
||||||
export * from "./upper-case-first"
|
export * from "./upper-case-first"
|
||||||
export * from "./wrap-handler"
|
export * from "./wrap-handler"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user