feat(fulfillment): Initialize models work (#6328)
**What** Initialize work on the fulfillment module entities. This pr finally also include the indexes as i was working on some utilities i though it would make sense to test them directly. Also this pr add a new utility to generate proper index for our entity properties. It also include a new monkey patch for the migration generator to handle most of if exists/not exists cases. The monkey patch is a workaround the fact that the transpilation does work well with the ECMA used by mikro orm and therefore we end up with some constructor issue when mikro orm try to instanciate the custom generator class extension. **Comment** - The rule part will likely evolved when we reach the point of rule filtering based data, so no need for details review I believe FIXES CORE-1714 FIXES CORE-1715 FIXES CORE-1718 FIXES CORE-1722 FIXES CORE-1723 Current schema diagram 
This commit is contained in:
committed by
GitHub
parent
512ac1e6ed
commit
3fd68d1979
6
.changeset/spicy-pillows-drum.md
Normal file
6
.changeset/spicy-pillows-drum.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@medusajs/types": patch
|
||||
"@medusajs/utils": patch
|
||||
---
|
||||
|
||||
feat(fulfillment): Initialize models work
|
||||
@@ -1,8 +1,12 @@
|
||||
import * as entities from "./src/models"
|
||||
import { TSMigrationGenerator } from "@medusajs/utils"
|
||||
|
||||
module.exports = {
|
||||
entities: Object.values(entities),
|
||||
schema: "public",
|
||||
clientUrl: "postgres://postgres@localhost/medusa-fulfillment",
|
||||
type: "postgresql",
|
||||
migrations: {
|
||||
generator: TSMigrationGenerator,
|
||||
},
|
||||
}
|
||||
|
||||
112
packages/fulfillment/src/models/address.ts
Normal file
112
packages/fulfillment/src/models/address.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
import { DAL } from "@medusajs/types"
|
||||
import {
|
||||
createPsqlIndexStatementHelper,
|
||||
generateEntityId,
|
||||
} from "@medusajs/utils"
|
||||
import {
|
||||
BeforeCreate,
|
||||
Entity,
|
||||
Index,
|
||||
OnInit,
|
||||
OptionalProps,
|
||||
PrimaryKey,
|
||||
Property,
|
||||
} from "@mikro-orm/core"
|
||||
|
||||
type OptionalAddressProps = DAL.SoftDeletableEntityDateColumns
|
||||
|
||||
const fulfillmentIdIndexName = "IDX_fulfillment_address_fulfillment_id"
|
||||
const fulfillmentIdIndexStatement = createPsqlIndexStatementHelper({
|
||||
name: fulfillmentIdIndexName,
|
||||
tableName: "fulfillment_address",
|
||||
columns: "fulfillment_id",
|
||||
where: "deleted_at IS NULL",
|
||||
})
|
||||
|
||||
const fulfillmentDeletedAtIndexName = "IDX_fulfillment_address_deleted_at"
|
||||
const fulfillmentDeletedAtIndexStatement = createPsqlIndexStatementHelper({
|
||||
name: fulfillmentDeletedAtIndexName,
|
||||
tableName: "fulfillment_address",
|
||||
columns: "deleted_at",
|
||||
where: "deleted_at IS NOT NULL",
|
||||
})
|
||||
|
||||
@Entity({ tableName: "fulfillment_address" })
|
||||
export default class Address {
|
||||
[OptionalProps]: OptionalAddressProps
|
||||
|
||||
@PrimaryKey({ columnType: "text" })
|
||||
id!: string
|
||||
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
@Index({
|
||||
name: fulfillmentIdIndexName,
|
||||
expression: fulfillmentIdIndexStatement,
|
||||
})
|
||||
fulfillment_id: string | null = null
|
||||
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
company: string | null = null
|
||||
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
first_name: string | null = null
|
||||
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
last_name: string | null = null
|
||||
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
address_1: string | null = null
|
||||
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
address_2: string | null = null
|
||||
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
city: string | null = null
|
||||
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
country_code: string | null = null
|
||||
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
province: string | null = null
|
||||
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
postal_code: string | null = null
|
||||
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
phone: string | null = null
|
||||
|
||||
@Property({ columnType: "jsonb", nullable: true })
|
||||
metadata: Record<string, unknown> | null = null
|
||||
|
||||
@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
|
||||
|
||||
@Property({ columnType: "timestamptz", nullable: true })
|
||||
@Index({
|
||||
name: fulfillmentDeletedAtIndexName,
|
||||
expression: fulfillmentDeletedAtIndexStatement,
|
||||
})
|
||||
deleted_at: Date | null = null
|
||||
|
||||
@BeforeCreate()
|
||||
onCreate() {
|
||||
this.id = generateEntityId(this.id, "fuladdr")
|
||||
}
|
||||
|
||||
@OnInit()
|
||||
onInit() {
|
||||
this.id = generateEntityId(this.id, "fuladdr")
|
||||
}
|
||||
}
|
||||
130
packages/fulfillment/src/models/fulfillment-item.ts
Normal file
130
packages/fulfillment/src/models/fulfillment-item.ts
Normal file
@@ -0,0 +1,130 @@
|
||||
import {
|
||||
createPsqlIndexStatementHelper,
|
||||
DALUtils,
|
||||
generateEntityId,
|
||||
} from "@medusajs/utils"
|
||||
|
||||
import {
|
||||
BeforeCreate,
|
||||
Entity,
|
||||
Filter,
|
||||
Index,
|
||||
ManyToOne,
|
||||
OnInit,
|
||||
OptionalProps,
|
||||
PrimaryKey,
|
||||
Property,
|
||||
} from "@mikro-orm/core"
|
||||
import { DAL } from "@medusajs/types"
|
||||
import Fulfillment from "./fulfillment"
|
||||
|
||||
type FulfillmentItemOptionalProps = DAL.SoftDeletableEntityDateColumns
|
||||
|
||||
const fulfillmentIdIndexName = "IDX_fulfillment_item_fulfillment_id"
|
||||
const fulfillmentIdIndexStatement = createPsqlIndexStatementHelper({
|
||||
name: fulfillmentIdIndexName,
|
||||
tableName: "fulfillment_item",
|
||||
columns: "fulfillment_id",
|
||||
where: "deleted_at IS NULL",
|
||||
})
|
||||
|
||||
const lineItemIndexName = "IDX_fulfillment_item_line_item_id"
|
||||
const lineItemIdIndexStatement = createPsqlIndexStatementHelper({
|
||||
name: fulfillmentIdIndexName,
|
||||
tableName: "fulfillment_item",
|
||||
columns: "line_item_id",
|
||||
where: "deleted_at IS NULL",
|
||||
})
|
||||
|
||||
const inventoryItemIndexName = "IDX_fulfillment_item_inventory_item_id"
|
||||
const inventoryItemIdIndexStatement = createPsqlIndexStatementHelper({
|
||||
name: fulfillmentIdIndexName,
|
||||
tableName: "fulfillment_item",
|
||||
columns: "inventory_item_id",
|
||||
where: "deleted_at IS NULL",
|
||||
})
|
||||
|
||||
const fulfillmentItemDeletedAtIndexName = "IDX_fulfillment_item_deleted_at"
|
||||
const fulfillmentItemDeletedAtIndexStatement = createPsqlIndexStatementHelper({
|
||||
name: fulfillmentItemDeletedAtIndexName,
|
||||
tableName: "fulfillment_item",
|
||||
columns: "deleted_at",
|
||||
where: "deleted_at IS NOT NULL",
|
||||
})
|
||||
|
||||
@Entity()
|
||||
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
|
||||
export default class FulfillmentItem {
|
||||
[OptionalProps]?: FulfillmentItemOptionalProps
|
||||
|
||||
@PrimaryKey({ columnType: "text" })
|
||||
id: string
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
title: string
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
sku: string
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
barcode: string
|
||||
|
||||
@Property({ columnType: "numeric", serializer: Number })
|
||||
quantity: number // TODO: probably allow big numbers here
|
||||
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
@Index({
|
||||
name: lineItemIndexName,
|
||||
expression: lineItemIdIndexStatement,
|
||||
})
|
||||
line_item_id: string | null = null
|
||||
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
@Index({
|
||||
name: inventoryItemIndexName,
|
||||
expression: inventoryItemIdIndexStatement,
|
||||
})
|
||||
inventory_item_id: string | null = null
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
@Index({
|
||||
name: fulfillmentIdIndexName,
|
||||
expression: fulfillmentIdIndexStatement,
|
||||
})
|
||||
fulfillment_id: string
|
||||
|
||||
@ManyToOne(() => Fulfillment)
|
||||
fulfillment: Fulfillment
|
||||
|
||||
@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
|
||||
|
||||
@Index({
|
||||
name: fulfillmentItemDeletedAtIndexName,
|
||||
expression: fulfillmentItemDeletedAtIndexStatement,
|
||||
})
|
||||
@Property({ columnType: "timestamptz", nullable: true })
|
||||
deleted_at: Date | null = null
|
||||
|
||||
@BeforeCreate()
|
||||
onCreate() {
|
||||
this.id = generateEntityId(this.id, "fulit")
|
||||
}
|
||||
|
||||
@OnInit()
|
||||
onInit() {
|
||||
this.id = generateEntityId(this.id, "fulit")
|
||||
}
|
||||
}
|
||||
112
packages/fulfillment/src/models/fulfillment-label.ts
Normal file
112
packages/fulfillment/src/models/fulfillment-label.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
import {
|
||||
createPsqlIndexStatementHelper,
|
||||
DALUtils,
|
||||
generateEntityId,
|
||||
} from "@medusajs/utils"
|
||||
|
||||
import {
|
||||
BeforeCreate,
|
||||
Entity,
|
||||
Filter,
|
||||
Index,
|
||||
ManyToOne,
|
||||
OnInit,
|
||||
OptionalProps,
|
||||
PrimaryKey,
|
||||
Property,
|
||||
} from "@mikro-orm/core"
|
||||
import { DAL } from "@medusajs/types"
|
||||
import Fulfillment from "./fulfillment"
|
||||
|
||||
type FulfillmentLabelOptionalProps = DAL.SoftDeletableEntityDateColumns
|
||||
|
||||
const fulfillmentIdIndexName = "IDX_fulfillment_label_fulfillment_id"
|
||||
const fulfillmentIdIndexStatement = createPsqlIndexStatementHelper({
|
||||
name: fulfillmentIdIndexName,
|
||||
tableName: "fulfillment_label",
|
||||
columns: "fulfillment_id",
|
||||
where: "deleted_at IS NULL",
|
||||
})
|
||||
|
||||
const providerIdIndexName = "IDX_fulfillment_label_provider_id"
|
||||
const providerIdIndexStatement = createPsqlIndexStatementHelper({
|
||||
name: providerIdIndexName,
|
||||
tableName: "fulfillment_label",
|
||||
columns: "provider_id",
|
||||
where: "deleted_at IS NULL",
|
||||
})
|
||||
|
||||
const deletedAtIndexName = "IDX_fulfillment_label_deleted_at"
|
||||
const deletedAtIndexStatement = createPsqlIndexStatementHelper({
|
||||
name: deletedAtIndexName,
|
||||
tableName: "fulfillment_label",
|
||||
columns: "deleted_at",
|
||||
where: "deleted_at IS NOT NULL",
|
||||
})
|
||||
|
||||
@Entity()
|
||||
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
|
||||
export default class FulfillmentLabel {
|
||||
[OptionalProps]?: FulfillmentLabelOptionalProps
|
||||
|
||||
@PrimaryKey({ columnType: "text" })
|
||||
id: string
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
tracking_number: string
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
tracking_url: string
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
label_url: string
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
@Index({
|
||||
name: fulfillmentIdIndexName,
|
||||
expression: fulfillmentIdIndexStatement,
|
||||
})
|
||||
provider_id: string
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
@Index({
|
||||
name: providerIdIndexName,
|
||||
expression: providerIdIndexStatement,
|
||||
})
|
||||
fulfillment_id: string
|
||||
|
||||
@ManyToOne(() => Fulfillment)
|
||||
fulfillment: Fulfillment
|
||||
|
||||
@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
|
||||
|
||||
@Property({ columnType: "timestamptz", nullable: true })
|
||||
@Index({
|
||||
name: deletedAtIndexName,
|
||||
expression: deletedAtIndexStatement,
|
||||
})
|
||||
deleted_at: Date | null = null
|
||||
|
||||
@BeforeCreate()
|
||||
onCreate() {
|
||||
this.id = generateEntityId(this.id, "fulla")
|
||||
}
|
||||
|
||||
@OnInit()
|
||||
onInit() {
|
||||
this.id = generateEntityId(this.id, "fulla")
|
||||
}
|
||||
}
|
||||
168
packages/fulfillment/src/models/fulfillment.ts
Normal file
168
packages/fulfillment/src/models/fulfillment.ts
Normal file
@@ -0,0 +1,168 @@
|
||||
import {
|
||||
createPsqlIndexStatementHelper,
|
||||
DALUtils,
|
||||
generateEntityId,
|
||||
} from "@medusajs/utils"
|
||||
|
||||
import {
|
||||
BeforeCreate,
|
||||
Collection,
|
||||
Entity,
|
||||
Filter,
|
||||
Index,
|
||||
ManyToOne,
|
||||
OneToMany,
|
||||
OnInit,
|
||||
OptionalProps,
|
||||
PrimaryKey,
|
||||
Property,
|
||||
} from "@mikro-orm/core"
|
||||
import { DAL } from "@medusajs/types"
|
||||
import ShippingOption from "./shipping-option"
|
||||
import ServiceProvider from "./service-provider"
|
||||
import Address from "./address"
|
||||
import FulfillmentItem from "./fulfillment-item"
|
||||
import FulfillmentLabel from "./fulfillment-label"
|
||||
|
||||
type FulfillmentOptionalProps = DAL.SoftDeletableEntityDateColumns
|
||||
|
||||
const fulfillmentDeletedAtIndexName = "IDX_fulfillment_deleted_at"
|
||||
const fulfillmentDeletedAtIndexStatement = createPsqlIndexStatementHelper({
|
||||
name: fulfillmentDeletedAtIndexName,
|
||||
tableName: "fulfillment",
|
||||
columns: "deleted_at",
|
||||
where: "deleted_at IS NOT NULL",
|
||||
})
|
||||
|
||||
const fulfillmentProviderIdIndexName = "IDX_fulfillment_provider_id"
|
||||
const fulfillmentProviderIdIndexStatement = createPsqlIndexStatementHelper({
|
||||
name: fulfillmentProviderIdIndexName,
|
||||
tableName: "fulfillment",
|
||||
columns: "provider_id",
|
||||
where: "deleted_at IS NULL",
|
||||
})
|
||||
|
||||
const fulfillmentLocationIdIndexName = "IDX_fulfillment_location_id"
|
||||
const fulfillmentLocationIdIndexStatement = createPsqlIndexStatementHelper({
|
||||
name: fulfillmentLocationIdIndexName,
|
||||
tableName: "fulfillment",
|
||||
columns: "location_id",
|
||||
where: "deleted_at IS NULL",
|
||||
})
|
||||
|
||||
const fulfillmentShippingOptionIdIndexName =
|
||||
"IDX_fulfillment_shipping_option_id"
|
||||
const fulfillmentShippingOptionIdIndexStatement =
|
||||
createPsqlIndexStatementHelper({
|
||||
name: fulfillmentShippingOptionIdIndexName,
|
||||
tableName: "fulfillment",
|
||||
columns: "shipping_option_id",
|
||||
where: "deleted_at IS NULL",
|
||||
})
|
||||
|
||||
@Entity()
|
||||
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
|
||||
export default class Fulfillment {
|
||||
[OptionalProps]?: FulfillmentOptionalProps
|
||||
|
||||
@PrimaryKey({ columnType: "text" })
|
||||
id: string
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
@Index({
|
||||
name: fulfillmentLocationIdIndexName,
|
||||
expression: fulfillmentLocationIdIndexStatement,
|
||||
})
|
||||
location_id: string
|
||||
|
||||
@Property({
|
||||
columnType: "timestamptz",
|
||||
nullable: true,
|
||||
})
|
||||
packed_at: Date | null = null
|
||||
|
||||
@Property({
|
||||
columnType: "timestamptz",
|
||||
nullable: true,
|
||||
})
|
||||
shipped_at: Date | null = null
|
||||
|
||||
@Property({
|
||||
columnType: "timestamptz",
|
||||
nullable: true,
|
||||
})
|
||||
delivered_at: Date | null = null
|
||||
|
||||
@Property({
|
||||
columnType: "timestamptz",
|
||||
nullable: true,
|
||||
})
|
||||
canceled_at: Date | null = null
|
||||
|
||||
@Property({ columnType: "jsonb", nullable: true })
|
||||
data: Record<string, unknown> | null = null
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
@Index({
|
||||
name: fulfillmentProviderIdIndexName,
|
||||
expression: fulfillmentProviderIdIndexStatement,
|
||||
})
|
||||
provider_id: string
|
||||
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
@Index({
|
||||
name: fulfillmentShippingOptionIdIndexName,
|
||||
expression: fulfillmentShippingOptionIdIndexStatement,
|
||||
})
|
||||
shipping_option_id: string | null = null
|
||||
|
||||
@Property({ columnType: "jsonb", nullable: true })
|
||||
metadata: Record<string, unknown> | null = null
|
||||
|
||||
@ManyToOne(() => ShippingOption, { nullable: true })
|
||||
shipping_option: ShippingOption | null
|
||||
|
||||
@ManyToOne(() => ServiceProvider)
|
||||
provider: ServiceProvider
|
||||
|
||||
@ManyToOne(() => Address)
|
||||
delivery_address: Address
|
||||
|
||||
@ManyToOne(() => FulfillmentItem)
|
||||
items: FulfillmentItem
|
||||
|
||||
@OneToMany(() => FulfillmentLabel, (label) => label.fulfillment)
|
||||
labels = new Collection<FulfillmentLabel>(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
|
||||
|
||||
@Index({
|
||||
name: fulfillmentDeletedAtIndexName,
|
||||
expression: fulfillmentDeletedAtIndexStatement,
|
||||
})
|
||||
@Property({ columnType: "timestamptz", nullable: true })
|
||||
deleted_at: Date | null = null
|
||||
|
||||
@BeforeCreate()
|
||||
onCreate() {
|
||||
this.id = generateEntityId(this.id, "ful")
|
||||
}
|
||||
|
||||
@OnInit()
|
||||
onInit() {
|
||||
this.id = generateEntityId(this.id, "ful")
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,34 @@
|
||||
import { DALUtils, generateEntityId } from "@medusajs/utils"
|
||||
import {
|
||||
createPsqlIndexStatementHelper,
|
||||
DALUtils,
|
||||
generateEntityId,
|
||||
} from "@medusajs/utils"
|
||||
|
||||
import {
|
||||
BeforeCreate,
|
||||
Collection,
|
||||
Entity,
|
||||
Filter,
|
||||
Index,
|
||||
ManyToMany,
|
||||
OnInit,
|
||||
OptionalProps,
|
||||
PrimaryKey,
|
||||
Property,
|
||||
} from "@mikro-orm/core"
|
||||
import { DAL } from "@medusajs/types"
|
||||
import ServiceZone from "./service-zone"
|
||||
|
||||
type FulfillmentSetOptionalProps = DAL.SoftDeletableEntityDateColumns
|
||||
|
||||
const deletedAtIndexName = "IDX_fulfillment_set_deleted_at"
|
||||
const deletedAtIndexStatement = createPsqlIndexStatementHelper({
|
||||
name: deletedAtIndexName,
|
||||
tableName: "fulfillment_set",
|
||||
columns: "deleted_at",
|
||||
where: "deleted_at IS NOT NULL",
|
||||
})
|
||||
|
||||
@Entity()
|
||||
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
|
||||
export default class FulfillmentSet {
|
||||
@@ -25,6 +40,20 @@ export default class FulfillmentSet {
|
||||
@Property({ columnType: "text" })
|
||||
name: string
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
type: string
|
||||
|
||||
@Property({ columnType: "jsonb", nullable: true })
|
||||
metadata: Record<string, unknown> | null = null
|
||||
|
||||
@ManyToMany(() => ServiceZone, "fulfillment_sets", {
|
||||
owner: true,
|
||||
pivotTable: "fulfillment_set_service_zones",
|
||||
joinColumn: "fulfillment_set_id",
|
||||
inverseJoinColumn: "service_zone_id",
|
||||
})
|
||||
service_zones = new Collection<ServiceZone>(this)
|
||||
|
||||
@Property({
|
||||
onCreate: () => new Date(),
|
||||
columnType: "timestamptz",
|
||||
@@ -40,8 +69,11 @@ export default class FulfillmentSet {
|
||||
})
|
||||
updated_at: Date
|
||||
|
||||
@Index({ name: "IDX_fulfillment_set_deleted_at" })
|
||||
@Property({ columnType: "timestamptz", nullable: true })
|
||||
@Index({
|
||||
name: deletedAtIndexName,
|
||||
expression: deletedAtIndexStatement,
|
||||
})
|
||||
deleted_at: Date | null = null
|
||||
|
||||
@BeforeCreate()
|
||||
|
||||
131
packages/fulfillment/src/models/geo-zone.ts
Normal file
131
packages/fulfillment/src/models/geo-zone.ts
Normal file
@@ -0,0 +1,131 @@
|
||||
import {
|
||||
createPsqlIndexStatementHelper,
|
||||
DALUtils,
|
||||
generateEntityId,
|
||||
GeoZoneType,
|
||||
} from "@medusajs/utils"
|
||||
|
||||
import {
|
||||
BeforeCreate,
|
||||
Collection,
|
||||
Entity,
|
||||
Enum,
|
||||
Filter,
|
||||
Index,
|
||||
ManyToMany,
|
||||
OnInit,
|
||||
OptionalProps,
|
||||
PrimaryKey,
|
||||
Property,
|
||||
} from "@mikro-orm/core"
|
||||
import { DAL } from "@medusajs/types"
|
||||
import ServiceZone from "./service-zone"
|
||||
|
||||
type GeoZoneOptionalProps = DAL.SoftDeletableEntityDateColumns
|
||||
|
||||
const deletedAtIndexName = "IDX_geo_zone_deleted_at"
|
||||
const deletedAtIndexStatement = createPsqlIndexStatementHelper({
|
||||
name: deletedAtIndexName,
|
||||
tableName: "geo_zone",
|
||||
columns: "deleted_at",
|
||||
where: "deleted_at IS NOT NULL",
|
||||
})
|
||||
|
||||
const countryCodeIndexName = "IDX_geo_zone_country_code"
|
||||
const countryCodeIndexStatement = createPsqlIndexStatementHelper({
|
||||
name: countryCodeIndexName,
|
||||
tableName: "geo_zone",
|
||||
columns: "country_code",
|
||||
where: "deleted_at IS NULL",
|
||||
})
|
||||
|
||||
const provinceCodeIndexName = "IDX_geo_zone_province_code"
|
||||
const provinceCodeIndexStatement = createPsqlIndexStatementHelper({
|
||||
name: provinceCodeIndexName,
|
||||
tableName: "geo_zone",
|
||||
columns: "province_code",
|
||||
where: "deleted_at IS NULL AND province_code IS NOT NULL",
|
||||
})
|
||||
|
||||
const cityIndexName = "IDX_geo_zone_city"
|
||||
const cityIndexStatement = createPsqlIndexStatementHelper({
|
||||
name: cityIndexName,
|
||||
tableName: "geo_zone",
|
||||
columns: "city",
|
||||
where: "deleted_at IS NULL AND city IS NOT NULL",
|
||||
})
|
||||
|
||||
@Entity()
|
||||
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
|
||||
export default class GeoZone {
|
||||
[OptionalProps]?: GeoZoneOptionalProps
|
||||
|
||||
@PrimaryKey({ columnType: "text" })
|
||||
id: string
|
||||
|
||||
@Enum({ items: () => GeoZoneType, default: GeoZoneType.COUNTRY })
|
||||
type: GeoZoneType
|
||||
|
||||
@Index({
|
||||
name: countryCodeIndexName,
|
||||
expression: countryCodeIndexStatement,
|
||||
})
|
||||
@Property({ columnType: "text" })
|
||||
country_code: string
|
||||
|
||||
@Index({
|
||||
name: provinceCodeIndexName,
|
||||
expression: provinceCodeIndexStatement,
|
||||
})
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
province_code: string | null = null
|
||||
|
||||
@Index({
|
||||
name: cityIndexName,
|
||||
expression: cityIndexStatement,
|
||||
})
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
city: string | null = null
|
||||
|
||||
// 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<string, unknown> | null = null
|
||||
|
||||
@Property({ columnType: "jsonb", nullable: true })
|
||||
metadata: Record<string, unknown> | null = null
|
||||
|
||||
@ManyToMany(() => ServiceZone, (serviceZone) => serviceZone.geo_zones)
|
||||
service_zones = new Collection<ServiceZone>(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
|
||||
|
||||
@Index({
|
||||
name: deletedAtIndexName,
|
||||
expression: deletedAtIndexStatement,
|
||||
})
|
||||
@Property({ columnType: "timestamptz", nullable: true })
|
||||
deleted_at: Date | null = null
|
||||
|
||||
@BeforeCreate()
|
||||
onCreate() {
|
||||
this.id = generateEntityId(this.id, " fgz")
|
||||
}
|
||||
|
||||
@OnInit()
|
||||
onInit() {
|
||||
this.id = generateEntityId(this.id, "fgz")
|
||||
}
|
||||
}
|
||||
@@ -1 +1,12 @@
|
||||
export { default as FulfillmentSet } from "./fullfilment-set"
|
||||
export { default as Fulfillment } from "./fulfillment"
|
||||
export { default as Address } from "./address"
|
||||
export { default as GeoZone } from "./geo-zone"
|
||||
export { default as ServiceZone } from "./service-zone"
|
||||
export { default as FulfillmentItem } from "./fulfillment-item"
|
||||
export { default as FulfillmentLabel } from "./fulfillment-label"
|
||||
export { default as ServiceProvider } from "./service-provider"
|
||||
export { default as ShippingOption } from "./shipping-option"
|
||||
export { default as ShippingOptionType } from "./shipping-option-type"
|
||||
export { default as ShippingOptionRule } from "./shipping-option-rule"
|
||||
export { default as ShippingProfile } from "./shipping-profile"
|
||||
|
||||
80
packages/fulfillment/src/models/service-provider.ts
Normal file
80
packages/fulfillment/src/models/service-provider.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import {
|
||||
createPsqlIndexStatementHelper,
|
||||
DALUtils,
|
||||
generateEntityId,
|
||||
} from "@medusajs/utils"
|
||||
|
||||
import {
|
||||
BeforeCreate,
|
||||
Collection,
|
||||
Entity,
|
||||
Filter,
|
||||
Index,
|
||||
OneToMany,
|
||||
OnInit,
|
||||
OptionalProps,
|
||||
PrimaryKey,
|
||||
Property,
|
||||
} from "@mikro-orm/core"
|
||||
import { DAL } from "@medusajs/types"
|
||||
import ShippingOption from "./shipping-option"
|
||||
|
||||
type ServiceProviderOptionalProps = DAL.SoftDeletableEntityDateColumns
|
||||
|
||||
const deletedAtIndexName = "IDX_service_provider_deleted_at"
|
||||
const deletedAtIndexStatement = createPsqlIndexStatementHelper({
|
||||
name: deletedAtIndexName,
|
||||
tableName: "service_provider",
|
||||
columns: "deleted_at",
|
||||
where: "deleted_at IS NOT NULL",
|
||||
})
|
||||
|
||||
@Entity()
|
||||
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
|
||||
export default class ServiceProvider {
|
||||
[OptionalProps]?: ServiceProviderOptionalProps
|
||||
|
||||
@PrimaryKey({ columnType: "text" })
|
||||
id: string
|
||||
|
||||
@Property({ columnType: "jsonb", nullable: true })
|
||||
metadata: Record<string, unknown> | null = null
|
||||
|
||||
@OneToMany(
|
||||
() => ShippingOption,
|
||||
(shippingOption) => shippingOption.service_provider
|
||||
)
|
||||
shipping_options = new Collection<ShippingOption>(this)
|
||||
|
||||
@Property({
|
||||
onCreate: () => new Date(),
|
||||
columnType: "timestamptz",
|
||||
defaultRaw: "now()",
|
||||
})
|
||||
created_at: Date
|
||||
|
||||
@Property({
|
||||
onCreate: () => new Date(),
|
||||
onUpdate: () => new Date(),
|
||||
columnType: "timestamptz",
|
||||
defaultRaw: "now()",
|
||||
})
|
||||
updated_at: Date
|
||||
|
||||
@Index({
|
||||
name: deletedAtIndexName,
|
||||
expression: deletedAtIndexStatement,
|
||||
})
|
||||
@Property({ columnType: "timestamptz", nullable: true })
|
||||
deleted_at: Date | null = null
|
||||
|
||||
@BeforeCreate()
|
||||
onCreate() {
|
||||
this.id = generateEntityId(this.id, "serpro")
|
||||
}
|
||||
|
||||
@OnInit()
|
||||
onInit() {
|
||||
this.id = generateEntityId(this.id, "serpro")
|
||||
}
|
||||
}
|
||||
100
packages/fulfillment/src/models/service-zone.ts
Normal file
100
packages/fulfillment/src/models/service-zone.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
import {
|
||||
createPsqlIndexStatementHelper,
|
||||
DALUtils,
|
||||
generateEntityId,
|
||||
} from "@medusajs/utils"
|
||||
|
||||
import {
|
||||
BeforeCreate,
|
||||
Collection,
|
||||
Entity,
|
||||
Filter,
|
||||
Index,
|
||||
ManyToMany,
|
||||
OneToMany,
|
||||
OnInit,
|
||||
OptionalProps,
|
||||
PrimaryKey,
|
||||
Property,
|
||||
} from "@mikro-orm/core"
|
||||
import { DAL } from "@medusajs/types"
|
||||
import FulfillmentSet from "./fullfilment-set"
|
||||
import GeoZone from "./geo-zone"
|
||||
import ShippingOption from "./shipping-option"
|
||||
|
||||
type ServiceZoneOptionalProps = DAL.SoftDeletableEntityDateColumns
|
||||
|
||||
const deletedAtIndexName = "IDX_service_zone_deleted_at"
|
||||
const deletedAtIndexStatement = createPsqlIndexStatementHelper({
|
||||
name: deletedAtIndexName,
|
||||
tableName: "service_zone",
|
||||
columns: "deleted_at",
|
||||
where: "deleted_at IS NOT NULL",
|
||||
})
|
||||
|
||||
@Entity()
|
||||
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
|
||||
export default class ServiceZone {
|
||||
[OptionalProps]?: ServiceZoneOptionalProps
|
||||
|
||||
@PrimaryKey({ columnType: "text" })
|
||||
id: string
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
name: string
|
||||
|
||||
@Property({ columnType: "jsonb", nullable: true })
|
||||
metadata: Record<string, unknown> | null = null
|
||||
|
||||
@ManyToMany(
|
||||
() => FulfillmentSet,
|
||||
(fulfillmentSet) => fulfillmentSet.service_zones
|
||||
)
|
||||
fulfillment_sets = new Collection<FulfillmentSet>(this)
|
||||
|
||||
@ManyToMany(() => GeoZone, "service_zones", {
|
||||
owner: true,
|
||||
pivotTable: "service_zone_geo_zones",
|
||||
joinColumn: "service_zone_id",
|
||||
inverseJoinColumn: "geo_zone_id",
|
||||
})
|
||||
geo_zones = new Collection<GeoZone>(this)
|
||||
|
||||
@OneToMany(
|
||||
() => ShippingOption,
|
||||
(shippingOption) => shippingOption.service_zone
|
||||
)
|
||||
shipping_options = new Collection<ShippingOption>(this)
|
||||
|
||||
@Property({
|
||||
onCreate: () => new Date(),
|
||||
columnType: "timestamptz",
|
||||
defaultRaw: "now()",
|
||||
})
|
||||
created_at: Date
|
||||
|
||||
@Property({
|
||||
onCreate: () => new Date(),
|
||||
onUpdate: () => new Date(),
|
||||
columnType: "timestamptz",
|
||||
defaultRaw: "now()",
|
||||
})
|
||||
updated_at: Date
|
||||
|
||||
@Index({
|
||||
name: deletedAtIndexName,
|
||||
expression: deletedAtIndexStatement,
|
||||
})
|
||||
@Property({ columnType: "timestamptz", nullable: true })
|
||||
deleted_at: Date | null = null
|
||||
|
||||
@BeforeCreate()
|
||||
onCreate() {
|
||||
this.id = generateEntityId(this.id, "serzo")
|
||||
}
|
||||
|
||||
@OnInit()
|
||||
onInit() {
|
||||
this.id = generateEntityId(this.id, "serzo")
|
||||
}
|
||||
}
|
||||
88
packages/fulfillment/src/models/shipping-option-rule.ts
Normal file
88
packages/fulfillment/src/models/shipping-option-rule.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import {
|
||||
createPsqlIndexStatementHelper,
|
||||
DALUtils,
|
||||
generateEntityId,
|
||||
} from "@medusajs/utils"
|
||||
|
||||
import {
|
||||
BeforeCreate,
|
||||
Entity,
|
||||
Filter,
|
||||
Index,
|
||||
ManyToOne,
|
||||
OnInit,
|
||||
OptionalProps,
|
||||
PrimaryKey,
|
||||
Property,
|
||||
} from "@mikro-orm/core"
|
||||
import { DAL } from "@medusajs/types"
|
||||
import ShippingOption from "./shipping-option"
|
||||
|
||||
type ShippingOptionRuleOptionalProps = DAL.SoftDeletableEntityDateColumns
|
||||
|
||||
// TODO: need some test to see if we continue with this kind of structure or we change it
|
||||
// More adjustments can appear as I move forward
|
||||
|
||||
const deletedAtIndexName = "IDX_shipping_option_rule_deleted_at"
|
||||
const deletedAtIndexStatement = createPsqlIndexStatementHelper({
|
||||
name: deletedAtIndexName,
|
||||
tableName: "shipping_option_rule",
|
||||
columns: "deleted_at",
|
||||
where: "deleted_at IS NOT NULL",
|
||||
})
|
||||
|
||||
@Entity()
|
||||
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
|
||||
export default class ShippingOptionRule {
|
||||
[OptionalProps]?: ShippingOptionRuleOptionalProps
|
||||
|
||||
@PrimaryKey({ columnType: "text" })
|
||||
id: string
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
attribute: string
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
operator: string
|
||||
|
||||
@Property({ columnType: "jsonb", nullable: true })
|
||||
value: { value: string | string[] } | null = null
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
shipping_option_id: string
|
||||
|
||||
@ManyToOne(() => ShippingOption)
|
||||
shipping_option: ShippingOption
|
||||
|
||||
@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
|
||||
|
||||
@Index({
|
||||
name: deletedAtIndexName,
|
||||
expression: deletedAtIndexStatement,
|
||||
})
|
||||
@Property({ columnType: "timestamptz", nullable: true })
|
||||
deleted_at: Date | null = null
|
||||
|
||||
@BeforeCreate()
|
||||
onCreate() {
|
||||
this.id = generateEntityId(this.id, "sorul")
|
||||
}
|
||||
|
||||
@OnInit()
|
||||
onInit() {
|
||||
this.id = generateEntityId(this.id, "sorul")
|
||||
}
|
||||
}
|
||||
79
packages/fulfillment/src/models/shipping-option-type.ts
Normal file
79
packages/fulfillment/src/models/shipping-option-type.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import {
|
||||
createPsqlIndexStatementHelper,
|
||||
DALUtils,
|
||||
generateEntityId,
|
||||
} from "@medusajs/utils"
|
||||
|
||||
import {
|
||||
BeforeCreate,
|
||||
Entity,
|
||||
Filter,
|
||||
Index,
|
||||
OneToOne,
|
||||
OnInit,
|
||||
OptionalProps,
|
||||
PrimaryKey,
|
||||
Property,
|
||||
} from "@mikro-orm/core"
|
||||
import { DAL } from "@medusajs/types"
|
||||
import ShippingOption from "./shipping-option"
|
||||
|
||||
type ShippingOptionTypeOptionalProps = DAL.SoftDeletableEntityDateColumns
|
||||
|
||||
const deletedAtIndexName = "IDX_shipping_option_type_deleted_at"
|
||||
const deletedAtIndexStatement = createPsqlIndexStatementHelper({
|
||||
name: deletedAtIndexName,
|
||||
tableName: "shipping_option_type",
|
||||
columns: "deleted_at",
|
||||
where: "deleted_at IS NOT NULL",
|
||||
})
|
||||
|
||||
@Entity()
|
||||
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
|
||||
export default class ShippingOptionType {
|
||||
[OptionalProps]?: ShippingOptionTypeOptionalProps
|
||||
|
||||
@PrimaryKey({ columnType: "text" })
|
||||
id: string
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
label: string
|
||||
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
description: string | null = null
|
||||
|
||||
@OneToOne(() => ShippingOption, (so) => so.shipping_option_type)
|
||||
shipping_option: ShippingOption
|
||||
|
||||
@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
|
||||
|
||||
@Index({
|
||||
name: deletedAtIndexName,
|
||||
expression: deletedAtIndexStatement,
|
||||
})
|
||||
@Property({ columnType: "timestamptz", nullable: true })
|
||||
deleted_at: Date | null = null
|
||||
|
||||
@BeforeCreate()
|
||||
onCreate() {
|
||||
this.id = generateEntityId(this.id, "sotype")
|
||||
}
|
||||
|
||||
@OnInit()
|
||||
onInit() {
|
||||
this.id = generateEntityId(this.id, "sotype")
|
||||
}
|
||||
}
|
||||
176
packages/fulfillment/src/models/shipping-option.ts
Normal file
176
packages/fulfillment/src/models/shipping-option.ts
Normal file
@@ -0,0 +1,176 @@
|
||||
import {
|
||||
createPsqlIndexStatementHelper,
|
||||
DALUtils,
|
||||
generateEntityId,
|
||||
ShippingOptionPriceType,
|
||||
} from "@medusajs/utils"
|
||||
|
||||
import {
|
||||
BeforeCreate,
|
||||
Collection,
|
||||
Entity,
|
||||
Enum,
|
||||
Filter,
|
||||
Index,
|
||||
ManyToOne,
|
||||
OneToMany,
|
||||
OneToOne,
|
||||
OnInit,
|
||||
OptionalProps,
|
||||
PrimaryKey,
|
||||
Property,
|
||||
} from "@mikro-orm/core"
|
||||
import { DAL } from "@medusajs/types"
|
||||
import ServiceZone from "./service-zone"
|
||||
import ShippingProfile from "./shipping-profile"
|
||||
import ServiceProvider from "./service-provider"
|
||||
import ShippingOptionType from "./shipping-option-type"
|
||||
import ShippingOptionRule from "./shipping-option-rule"
|
||||
import Fulfillment from "./fulfillment"
|
||||
|
||||
type ShippingOptionOptionalProps = DAL.SoftDeletableEntityDateColumns
|
||||
|
||||
const deletedAtIndexName = "IDX_shipping_option_deleted_at"
|
||||
const deletedAtIndexStatement = createPsqlIndexStatementHelper({
|
||||
name: deletedAtIndexName,
|
||||
tableName: "shipping_option",
|
||||
columns: "deleted_at",
|
||||
where: "deleted_at IS NOT NULL",
|
||||
})
|
||||
|
||||
const serviceZoneIdIndexName = "IDX_shipping_option_service_zone_id"
|
||||
const serviceZoneIdIndexStatement = createPsqlIndexStatementHelper({
|
||||
name: serviceZoneIdIndexName,
|
||||
tableName: "shipping_option",
|
||||
columns: "service_zone_id",
|
||||
where: "deleted_at IS NULL",
|
||||
})
|
||||
|
||||
const shippingProfileIdIndexName = "IDX_shipping_option_shipping_profile_id"
|
||||
const shippingProfileIdIndexStatement = createPsqlIndexStatementHelper({
|
||||
name: shippingProfileIdIndexName,
|
||||
tableName: "shipping_option",
|
||||
columns: "shipping_profile_id",
|
||||
where: "deleted_at IS NULL",
|
||||
})
|
||||
|
||||
const serviceProviderIdIndexName = "IDX_shipping_option_service_provider_id"
|
||||
const serviceProviderIdIndexStatement = createPsqlIndexStatementHelper({
|
||||
name: serviceProviderIdIndexName,
|
||||
tableName: "shipping_option",
|
||||
columns: "service_provider_id",
|
||||
where: "deleted_at IS NULL",
|
||||
})
|
||||
|
||||
const shippingOptionTypeIdIndexName =
|
||||
"IDX_shipping_option_shipping_option_type_id"
|
||||
const shippingOptionTypeIdIndexStatement = createPsqlIndexStatementHelper({
|
||||
name: shippingOptionTypeIdIndexName,
|
||||
tableName: "shipping_option",
|
||||
columns: "shipping_option_type_id",
|
||||
where: "deleted_at IS NULL",
|
||||
})
|
||||
|
||||
@Entity()
|
||||
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
|
||||
export default class ShippingOption {
|
||||
[OptionalProps]?: ShippingOptionOptionalProps
|
||||
|
||||
@PrimaryKey({ columnType: "text" })
|
||||
id: string
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
name: string
|
||||
|
||||
@Enum({
|
||||
items: () => ShippingOptionPriceType,
|
||||
default: ShippingOptionPriceType.CALCULATED,
|
||||
})
|
||||
price_type: ShippingOptionPriceType
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
@Index({
|
||||
name: serviceZoneIdIndexName,
|
||||
expression: serviceZoneIdIndexStatement,
|
||||
})
|
||||
service_zone_id: string
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
@Index({
|
||||
name: shippingProfileIdIndexName,
|
||||
expression: shippingProfileIdIndexStatement,
|
||||
})
|
||||
shipping_profile_id: string
|
||||
|
||||
@Property({ columnType: "text" })
|
||||
@Index({
|
||||
name: serviceProviderIdIndexName,
|
||||
expression: serviceProviderIdIndexStatement,
|
||||
})
|
||||
service_provider_id: string
|
||||
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
@Index({
|
||||
name: shippingOptionTypeIdIndexName,
|
||||
expression: shippingOptionTypeIdIndexStatement,
|
||||
})
|
||||
shipping_option_type_id: string | null = null
|
||||
|
||||
@Property({ columnType: "jsonb", nullable: true })
|
||||
data: Record<string, unknown> | null = null
|
||||
|
||||
@Property({ columnType: "jsonb", nullable: true })
|
||||
metadata: Record<string, unknown> | null = null
|
||||
|
||||
@ManyToOne(() => ServiceZone)
|
||||
service_zone: ServiceZone
|
||||
|
||||
@ManyToOne(() => ShippingProfile)
|
||||
shipping_profile: ShippingProfile
|
||||
|
||||
@ManyToOne(() => ServiceProvider)
|
||||
service_provider: ServiceProvider
|
||||
|
||||
@OneToOne(() => ShippingOptionType, (so) => so.shipping_option, {
|
||||
owner: true,
|
||||
})
|
||||
shipping_option_type: ShippingOptionType
|
||||
|
||||
@OneToMany(() => ShippingOptionRule, (sor) => sor.shipping_option)
|
||||
rules = new Collection<ShippingOptionRule>(this)
|
||||
|
||||
@OneToMany(() => Fulfillment, (fulfillment) => fulfillment.shipping_option)
|
||||
fulfillments = new Collection<Fulfillment>(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
|
||||
|
||||
@Index({
|
||||
name: deletedAtIndexName,
|
||||
expression: deletedAtIndexStatement,
|
||||
})
|
||||
@Property({ columnType: "timestamptz", nullable: true })
|
||||
deleted_at: Date | null = null
|
||||
|
||||
@BeforeCreate()
|
||||
onCreate() {
|
||||
this.id = generateEntityId(this.id, "so")
|
||||
}
|
||||
|
||||
@OnInit()
|
||||
onInit() {
|
||||
this.id = generateEntityId(this.id, "so")
|
||||
}
|
||||
}
|
||||
80
packages/fulfillment/src/models/shipping-profile.ts
Normal file
80
packages/fulfillment/src/models/shipping-profile.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import {
|
||||
createPsqlIndexStatementHelper,
|
||||
DALUtils,
|
||||
generateEntityId,
|
||||
} from "@medusajs/utils"
|
||||
|
||||
import {
|
||||
BeforeCreate,
|
||||
Collection,
|
||||
Entity,
|
||||
Filter,
|
||||
Index,
|
||||
OneToMany,
|
||||
OnInit,
|
||||
OptionalProps,
|
||||
PrimaryKey,
|
||||
Property,
|
||||
} from "@mikro-orm/core"
|
||||
import { DAL } from "@medusajs/types"
|
||||
import ShippingOption from "./shipping-option"
|
||||
|
||||
type ShippingProfileOptionalProps = DAL.SoftDeletableEntityDateColumns
|
||||
|
||||
const deletedAtIndexName = "IDX_shipping_profile_deleted_at"
|
||||
const deletedAtIndexStatement = createPsqlIndexStatementHelper({
|
||||
name: deletedAtIndexName,
|
||||
tableName: "shipping_profile",
|
||||
columns: "deleted_at",
|
||||
where: "deleted_at IS NOT NULL",
|
||||
})
|
||||
|
||||
@Entity()
|
||||
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
|
||||
export default class ShippingProfile {
|
||||
[OptionalProps]?: ShippingProfileOptionalProps
|
||||
|
||||
@PrimaryKey({ columnType: "text" })
|
||||
id: string
|
||||
|
||||
@OneToMany(
|
||||
() => ShippingOption,
|
||||
(shippingOption) => shippingOption.shipping_profile
|
||||
)
|
||||
shipping_options = new Collection<ShippingOption>(this)
|
||||
|
||||
@Property({ columnType: "jsonb", nullable: true })
|
||||
metadata: Record<string, unknown> | null = null
|
||||
|
||||
@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
|
||||
|
||||
@Index({
|
||||
name: deletedAtIndexName,
|
||||
expression: deletedAtIndexStatement,
|
||||
})
|
||||
@Property({ columnType: "timestamptz", nullable: true })
|
||||
deleted_at: Date | null = null
|
||||
|
||||
@BeforeCreate()
|
||||
onCreate() {
|
||||
this.id = generateEntityId(this.id, "sp")
|
||||
}
|
||||
|
||||
@OnInit()
|
||||
onInit() {
|
||||
this.id = generateEntityId(this.id, "sp")
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
export type GeoZoneType = "country" | "province" | "city" | "zip"
|
||||
|
||||
export interface FulfillmentDTO {
|
||||
id: string
|
||||
name: string
|
||||
|
||||
@@ -3,10 +3,10 @@ export * as DecoratorUtils from "./decorators"
|
||||
export * as DefaultsUtils from "./defaults"
|
||||
export * as EventBusUtils from "./event-bus"
|
||||
export * as FeatureFlagUtils from "./feature-flags"
|
||||
export * as FulfillmentUtils from "./fulfillment"
|
||||
export * as ModulesSdkUtils from "./modules-sdk"
|
||||
export * as OrchestrationUtils from "./orchestration"
|
||||
export * as ProductUtils from "./product"
|
||||
export * as PromotionUtils from "./promotion"
|
||||
export * as SearchUtils from "./search"
|
||||
export * as ShippingProfileUtils from "./shipping"
|
||||
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
import { createPsqlIndexStatementHelper } from "../create-psql-index-helper"
|
||||
|
||||
describe("createPsqlIndexStatementHelper", function () {
|
||||
it("should generate a simple index", function () {
|
||||
const options = {
|
||||
name: "index_name",
|
||||
tableName: "table_name",
|
||||
columns: "column_name",
|
||||
}
|
||||
|
||||
const indexStatement = createPsqlIndexStatementHelper(options)
|
||||
expect(indexStatement).toEqual(
|
||||
`CREATE INDEX IF NOT EXISTS ${options.name} ON ${options.tableName} (${options.columns})`
|
||||
)
|
||||
})
|
||||
|
||||
it("should generate a composite index", function () {
|
||||
const options = {
|
||||
name: "index_name",
|
||||
tableName: "table_name",
|
||||
columns: ["column_name_1", "column_name_2"],
|
||||
}
|
||||
|
||||
const indexStatement = createPsqlIndexStatementHelper(options)
|
||||
expect(indexStatement).toEqual(
|
||||
`CREATE INDEX IF NOT EXISTS ${options.name} ON ${
|
||||
options.tableName
|
||||
} (${options.columns.join(", ")})`
|
||||
)
|
||||
})
|
||||
|
||||
it("should generate an index with where clauses", function () {
|
||||
const options = {
|
||||
name: "index_name",
|
||||
tableName: "table_name",
|
||||
columns: ["column_name_1", "column_name_2"],
|
||||
where: "column_name_1 IS NOT NULL",
|
||||
}
|
||||
|
||||
const indexStatement = createPsqlIndexStatementHelper(options)
|
||||
expect(indexStatement).toEqual(
|
||||
`CREATE INDEX IF NOT EXISTS ${options.name} ON ${
|
||||
options.tableName
|
||||
} (${options.columns.join(", ")}) WHERE ${options.where}`
|
||||
)
|
||||
})
|
||||
|
||||
it("should generate an index with where clauses and index type", function () {
|
||||
const options = {
|
||||
name: "index_name",
|
||||
tableName: "table_name",
|
||||
columns: ["column_name_1", "column_name_2"],
|
||||
type: "GIN",
|
||||
where: "column_name_1 IS NOT NULL",
|
||||
}
|
||||
|
||||
const indexStatement = createPsqlIndexStatementHelper(options)
|
||||
expect(indexStatement).toEqual(
|
||||
`CREATE INDEX IF NOT EXISTS ${options.name} ON ${
|
||||
options.tableName
|
||||
} USING GIN (${options.columns.join(", ")}) WHERE ${options.where}`
|
||||
)
|
||||
})
|
||||
})
|
||||
47
packages/utils/src/common/create-psql-index-helper.ts
Normal file
47
packages/utils/src/common/create-psql-index-helper.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Create a PSQL index statement
|
||||
* @param name The name of the index
|
||||
* @param tableName The name of the table
|
||||
* @param columns The columns to index
|
||||
* @param type The type of index (e.g GIN, GIST, BTREE, etc)
|
||||
* @param where The where clause
|
||||
*
|
||||
* @example
|
||||
* createPsqlIndexStatementHelper({
|
||||
* name: "idx_user_email",
|
||||
* tableName: "user",
|
||||
* columns: "email",
|
||||
* type: "btree",
|
||||
* where: "email IS NOT NULL"
|
||||
* });
|
||||
*
|
||||
* // CREATE INDEX IF NOT EXISTS idx_user_email ON user USING btree (email) WHERE email IS NOT NULL;
|
||||
*
|
||||
* createPsqlIndexStatementHelper({
|
||||
* name: "idx_user_email",
|
||||
* tableName: "user",
|
||||
* columns: "email"
|
||||
* });
|
||||
*
|
||||
* // CREATE INDEX IF NOT EXISTS idx_user_email ON user (email);
|
||||
*
|
||||
*/
|
||||
export function createPsqlIndexStatementHelper({
|
||||
name,
|
||||
tableName,
|
||||
columns,
|
||||
type,
|
||||
where,
|
||||
}: {
|
||||
name: string
|
||||
tableName: string
|
||||
columns: string | string[]
|
||||
type?: string
|
||||
where?: string
|
||||
}) {
|
||||
columns = Array.isArray(columns) ? columns.join(", ") : columns
|
||||
const typeStr = type ? ` USING ${type}` : ""
|
||||
const optionsStr = where ? ` WHERE ${where}` : ""
|
||||
|
||||
return `CREATE INDEX IF NOT EXISTS ${name} ON ${tableName}${typeStr} (${columns})${optionsStr}`
|
||||
}
|
||||
@@ -3,6 +3,7 @@ export * from "./build-query"
|
||||
export * from "./camel-to-snake-case"
|
||||
export * from "./container"
|
||||
export * from "./create-container-like"
|
||||
export * from "./create-psql-index-helper"
|
||||
export * from "./deduplicate"
|
||||
export * from "./deep-equal-obj"
|
||||
export * from "./errors"
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
import { TSMigrationGenerator } from "../mikro-orm-create-connection"
|
||||
|
||||
function unwrapSql(sql: string) {
|
||||
return sql.match(/this.addSql\('(.*?)'\)/)?.[1]
|
||||
}
|
||||
|
||||
describe("TSMigrationGenerator", () => {
|
||||
it('should add "if not exists" to "create table" statements', () => {
|
||||
const sql = "create table my_table (id int)"
|
||||
const result = unwrapSql(
|
||||
TSMigrationGenerator.prototype.createStatement(sql, 0)
|
||||
)
|
||||
expect(result).toBe("create table if not exists my_table (id int)")
|
||||
})
|
||||
|
||||
it('should add "if exists" to "alter table" statements as well as to the add column', () => {
|
||||
const sql = "alter table my_table add column name varchar(100)"
|
||||
const result = unwrapSql(
|
||||
TSMigrationGenerator.prototype.createStatement(sql, 0)
|
||||
)
|
||||
expect(result).toBe(
|
||||
"alter table if exists my_table add column if not exists name varchar(100)"
|
||||
)
|
||||
})
|
||||
|
||||
it('should add "if exists" to "alter table" statements as well as to the drop column', () => {
|
||||
const sql = "alter table my_table drop column name"
|
||||
const result = unwrapSql(
|
||||
TSMigrationGenerator.prototype.createStatement(sql, 0)
|
||||
)
|
||||
expect(result).toBe(
|
||||
"alter table if exists my_table drop column if exists name"
|
||||
)
|
||||
})
|
||||
|
||||
it('should add "if exists" to "alter table" statements as well as to the alter column', () => {
|
||||
const sql = "alter table my_table alter column name"
|
||||
const result = unwrapSql(
|
||||
TSMigrationGenerator.prototype.createStatement(sql, 0)
|
||||
)
|
||||
expect(result).toBe(
|
||||
"alter table if exists my_table alter column if exists name"
|
||||
)
|
||||
})
|
||||
|
||||
it('should add "if not exists" to "create index" statements', () => {
|
||||
const sql = "create index idx_name on my_table(name)"
|
||||
const result = unwrapSql(
|
||||
TSMigrationGenerator.prototype.createStatement(sql, 0)
|
||||
)
|
||||
expect(result).toBe("create index if not exists idx_name on my_table(name)")
|
||||
})
|
||||
|
||||
it('should add "if exists" to "drop index" statements', () => {
|
||||
const sql = "drop index idx_name"
|
||||
const result = unwrapSql(
|
||||
TSMigrationGenerator.prototype.createStatement(sql, 0)
|
||||
)
|
||||
expect(result).toBe("drop index if exists idx_name")
|
||||
})
|
||||
|
||||
it('should add "if not exists" to "create unique index" statements', () => {
|
||||
const sql = "create unique index idx_unique_name on my_table(name)"
|
||||
const result = unwrapSql(
|
||||
TSMigrationGenerator.prototype.createStatement(sql, 0)
|
||||
)
|
||||
expect(result).toBe(
|
||||
"create unique index if not exists idx_unique_name on my_table(name)"
|
||||
)
|
||||
})
|
||||
|
||||
it('should add "if exists" to "drop unique index" statements', () => {
|
||||
const sql = "drop unique index idx_unique_name"
|
||||
const result = unwrapSql(
|
||||
TSMigrationGenerator.prototype.createStatement(sql, 0)
|
||||
)
|
||||
expect(result).toBe("drop unique index if exists idx_unique_name")
|
||||
})
|
||||
|
||||
it('should add "if not exists" to "add column" statements', () => {
|
||||
const sql = "add column name varchar(100)"
|
||||
const result = unwrapSql(
|
||||
TSMigrationGenerator.prototype.createStatement(sql, 0)
|
||||
)
|
||||
expect(result).toBe("add column if not exists name varchar(100)")
|
||||
})
|
||||
|
||||
it('should add "if exists" to "drop column" statements', () => {
|
||||
const sql = "drop column name"
|
||||
const result = unwrapSql(
|
||||
TSMigrationGenerator.prototype.createStatement(sql, 0)
|
||||
)
|
||||
expect(result).toBe("drop column if exists name")
|
||||
})
|
||||
|
||||
it('should add "if exists" to "alter column" statements', () => {
|
||||
const sql = "alter column name"
|
||||
const result = unwrapSql(
|
||||
TSMigrationGenerator.prototype.createStatement(sql, 0)
|
||||
)
|
||||
expect(result).toBe("alter column if exists name")
|
||||
})
|
||||
|
||||
it('should add "if exists" to "drop constraint" statements', () => {
|
||||
const sql = "drop constraint fk_name"
|
||||
const result = unwrapSql(
|
||||
TSMigrationGenerator.prototype.createStatement(sql, 0)
|
||||
)
|
||||
expect(result).toBe("drop constraint if exists fk_name")
|
||||
})
|
||||
})
|
||||
@@ -1,4 +1,71 @@
|
||||
import { ModuleServiceInitializeOptions } from "@medusajs/types"
|
||||
import { TSMigrationGenerator } from "@mikro-orm/migrations"
|
||||
import { isString } from "../../common"
|
||||
|
||||
// Monkey patch due to the compilation version issue which prevents us from creating a proper class that extends the TSMigrationGenerator
|
||||
const originalCreateStatement = TSMigrationGenerator.prototype.createStatement
|
||||
|
||||
/**
|
||||
* Safe migration generation for MikroORM
|
||||
*
|
||||
* @param sql The sql statement
|
||||
* @param padLeft The padding
|
||||
*
|
||||
* @example see test file
|
||||
*/
|
||||
TSMigrationGenerator.prototype.createStatement = function (
|
||||
sql: string,
|
||||
padLeft: number
|
||||
) {
|
||||
if (isString(sql)) {
|
||||
if (!sql.includes("create table if not exists")) {
|
||||
sql = sql.replace("create table", "create table if not exists")
|
||||
}
|
||||
|
||||
if (!sql.includes("alter table if exists")) {
|
||||
sql = sql.replace("alter table", "alter table if exists")
|
||||
}
|
||||
|
||||
if (!sql.includes("create index if not exists")) {
|
||||
sql = sql.replace("create index", "create index if not exists")
|
||||
}
|
||||
|
||||
if (!sql.includes("drop index if exists")) {
|
||||
sql = sql.replace("drop index", "drop index if exists")
|
||||
}
|
||||
|
||||
if (!sql.includes("create unique index if not exists")) {
|
||||
sql = sql.replace(
|
||||
"create unique index",
|
||||
"create unique index if not exists"
|
||||
)
|
||||
}
|
||||
|
||||
if (!sql.includes("drop unique index if exists")) {
|
||||
sql = sql.replace("drop unique index", "drop unique index if exists")
|
||||
}
|
||||
|
||||
if (!sql.includes("add column if not exists")) {
|
||||
sql = sql.replace("add column", "add column if not exists")
|
||||
}
|
||||
|
||||
if (!sql.includes("alter column if exists exists")) {
|
||||
sql = sql.replace("alter column", "alter column if exists")
|
||||
}
|
||||
|
||||
if (!sql.includes("drop column if exists")) {
|
||||
sql = sql.replace("drop column", "drop column if exists")
|
||||
}
|
||||
|
||||
if (!sql.includes("drop constraint if exists")) {
|
||||
sql = sql.replace("drop constraint", "drop constraint if exists")
|
||||
}
|
||||
}
|
||||
|
||||
return originalCreateStatement(sql, padLeft)
|
||||
}
|
||||
|
||||
export { TSMigrationGenerator }
|
||||
|
||||
export async function mikroOrmCreateConnection(
|
||||
database: ModuleServiceInitializeOptions["database"] & { connection?: any },
|
||||
@@ -35,6 +102,7 @@ export async function mikroOrmCreateConnection(
|
||||
type: "postgresql",
|
||||
migrations: {
|
||||
path: pathToMigrations,
|
||||
generator: TSMigrationGenerator,
|
||||
},
|
||||
pool: database.pool as any,
|
||||
})
|
||||
|
||||
6
packages/utils/src/fulfillment/geo-zone.ts
Normal file
6
packages/utils/src/fulfillment/geo-zone.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export enum GeoZoneType {
|
||||
COUNTRY = "country",
|
||||
PROVINCE = "province",
|
||||
CITY = "city",
|
||||
ZIP = "zip",
|
||||
}
|
||||
2
packages/utils/src/fulfillment/index.ts
Normal file
2
packages/utils/src/fulfillment/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from "./geo-zone"
|
||||
export * from "./shipping-options"
|
||||
4
packages/utils/src/fulfillment/shipping-options.ts
Normal file
4
packages/utils/src/fulfillment/shipping-options.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export enum ShippingOptionPriceType {
|
||||
CALCULATED = "calculated",
|
||||
FLAT = "flat",
|
||||
}
|
||||
@@ -7,6 +7,7 @@ export * from "./defaults"
|
||||
export * from "./event-bus"
|
||||
export * from "./exceptions"
|
||||
export * from "./feature-flags"
|
||||
export * from "./fulfillment"
|
||||
export * from "./modules-sdk"
|
||||
export * from "./orchestration"
|
||||
export * from "./payment"
|
||||
|
||||
Reference in New Issue
Block a user