chore(inventory): convert to dml (#10569)
Fixes: FRMW-2848 Co-authored-by: Harminder Virk <1706381+thetutlage@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
ae1d875fcf
commit
729eb5da7b
7
.changeset/big-days-train.md
Normal file
7
.changeset/big-days-train.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/inventory": patch
|
||||||
|
"@medusajs/types": patch
|
||||||
|
"@medusajs/utils": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
chore: Inventory DML
|
||||||
@@ -1353,7 +1353,7 @@ medusaIntegrationTestRunner({
|
|||||||
{ title: "variant two", options: { color: "blue" } },
|
{ title: "variant two", options: { color: "blue" } },
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
console.log(product)
|
|
||||||
const [variantOne, variantTwo] = product.variants
|
const [variantOne, variantTwo] = product.variants
|
||||||
|
|
||||||
const [itemOne, itemTwo, itemThree] =
|
const [itemOne, itemTwo, itemThree] =
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ export type PropertyMetadata = {
|
|||||||
fieldName: string
|
fieldName: string
|
||||||
defaultValue?: any
|
defaultValue?: any
|
||||||
nullable: boolean
|
nullable: boolean
|
||||||
|
computed: boolean
|
||||||
dataType: {
|
dataType: {
|
||||||
name: KnownDataTypes
|
name: KnownDataTypes
|
||||||
options?: Record<string, any>
|
options?: Record<string, any>
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ describe("Array property", () => {
|
|||||||
name: "array",
|
name: "array",
|
||||||
},
|
},
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
computed: false,
|
||||||
indexes: [],
|
indexes: [],
|
||||||
relationships: [],
|
relationships: [],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ describe("Autoincrement property", () => {
|
|||||||
options: {},
|
options: {},
|
||||||
},
|
},
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
computed: false,
|
||||||
indexes: [],
|
indexes: [],
|
||||||
relationships: [],
|
relationships: [],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
import { PropertyMetadata } from "@medusajs/types"
|
||||||
import { expectTypeOf } from "expect-type"
|
import { expectTypeOf } from "expect-type"
|
||||||
import { BaseProperty } from "../properties/base"
|
import { BaseProperty } from "../properties/base"
|
||||||
import { PropertyMetadata } from "@medusajs/types"
|
|
||||||
import { TextProperty } from "../properties/text"
|
import { TextProperty } from "../properties/text"
|
||||||
|
|
||||||
describe("Base property", () => {
|
describe("Base property", () => {
|
||||||
@@ -20,6 +20,7 @@ describe("Base property", () => {
|
|||||||
name: "text",
|
name: "text",
|
||||||
},
|
},
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
computed: false,
|
||||||
indexes: [],
|
indexes: [],
|
||||||
relationships: [],
|
relationships: [],
|
||||||
})
|
})
|
||||||
@@ -38,6 +39,7 @@ describe("Base property", () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
computed: false,
|
||||||
indexes: [],
|
indexes: [],
|
||||||
relationships: [],
|
relationships: [],
|
||||||
})
|
})
|
||||||
@@ -59,6 +61,42 @@ describe("Base property", () => {
|
|||||||
name: "text",
|
name: "text",
|
||||||
},
|
},
|
||||||
nullable: true,
|
nullable: true,
|
||||||
|
computed: false,
|
||||||
|
indexes: [],
|
||||||
|
relationships: [],
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test("apply computed property", () => {
|
||||||
|
class StringProperty extends BaseProperty<string> {
|
||||||
|
protected dataType: PropertyMetadata["dataType"] = {
|
||||||
|
name: "text",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const property = new StringProperty().computed()
|
||||||
|
const property2 = new StringProperty().nullable().computed()
|
||||||
|
|
||||||
|
expectTypeOf(property["$dataType"]).toEqualTypeOf<string | null>()
|
||||||
|
expect(property.parse("username")).toEqual({
|
||||||
|
fieldName: "username",
|
||||||
|
dataType: {
|
||||||
|
name: "text",
|
||||||
|
},
|
||||||
|
nullable: false,
|
||||||
|
computed: true,
|
||||||
|
indexes: [],
|
||||||
|
relationships: [],
|
||||||
|
})
|
||||||
|
|
||||||
|
expectTypeOf(property2["$dataType"]).toEqualTypeOf<string | null>()
|
||||||
|
expect(property2.parse("username")).toEqual({
|
||||||
|
fieldName: "username",
|
||||||
|
dataType: {
|
||||||
|
name: "text",
|
||||||
|
},
|
||||||
|
nullable: true,
|
||||||
|
computed: true,
|
||||||
indexes: [],
|
indexes: [],
|
||||||
relationships: [],
|
relationships: [],
|
||||||
})
|
})
|
||||||
@@ -81,6 +119,7 @@ describe("Base property", () => {
|
|||||||
},
|
},
|
||||||
defaultValue: "foo",
|
defaultValue: "foo",
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
computed: false,
|
||||||
indexes: [],
|
indexes: [],
|
||||||
relationships: [],
|
relationships: [],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ describe("Big Number property", () => {
|
|||||||
name: "bigNumber",
|
name: "bigNumber",
|
||||||
},
|
},
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
computed: false,
|
||||||
indexes: [],
|
indexes: [],
|
||||||
relationships: [],
|
relationships: [],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ describe("Boolean property", () => {
|
|||||||
name: "boolean",
|
name: "boolean",
|
||||||
},
|
},
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
computed: false,
|
||||||
indexes: [],
|
indexes: [],
|
||||||
relationships: [],
|
relationships: [],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ describe("DateTime property", () => {
|
|||||||
name: "dateTime",
|
name: "dateTime",
|
||||||
},
|
},
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
computed: false,
|
||||||
indexes: [],
|
indexes: [],
|
||||||
relationships: [],
|
relationships: [],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ describe("Enum property", () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
computed: false,
|
||||||
indexes: [],
|
indexes: [],
|
||||||
relationships: [],
|
relationships: [],
|
||||||
})
|
})
|
||||||
@@ -42,6 +43,7 @@ describe("Enum property", () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
nullable: true,
|
nullable: true,
|
||||||
|
computed: false,
|
||||||
indexes: [],
|
indexes: [],
|
||||||
relationships: [],
|
relationships: [],
|
||||||
})
|
})
|
||||||
@@ -66,6 +68,7 @@ describe("Enum property", () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
computed: false,
|
||||||
indexes: [],
|
indexes: [],
|
||||||
relationships: [],
|
relationships: [],
|
||||||
})
|
})
|
||||||
@@ -90,6 +93,7 @@ describe("Enum property", () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
computed: false,
|
||||||
indexes: [],
|
indexes: [],
|
||||||
relationships: [],
|
relationships: [],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ describe("Float property", () => {
|
|||||||
name: "float",
|
name: "float",
|
||||||
},
|
},
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
computed: false,
|
||||||
indexes: [],
|
indexes: [],
|
||||||
relationships: [],
|
relationships: [],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ describe("Id property", () => {
|
|||||||
options: {},
|
options: {},
|
||||||
},
|
},
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
computed: false,
|
||||||
indexes: [],
|
indexes: [],
|
||||||
relationships: [],
|
relationships: [],
|
||||||
})
|
})
|
||||||
@@ -29,6 +30,7 @@ describe("Id property", () => {
|
|||||||
options: {},
|
options: {},
|
||||||
},
|
},
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
computed: false,
|
||||||
indexes: [],
|
indexes: [],
|
||||||
relationships: [],
|
relationships: [],
|
||||||
primaryKey: true,
|
primaryKey: true,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ describe("JSON property", () => {
|
|||||||
name: "json",
|
name: "json",
|
||||||
},
|
},
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
computed: false,
|
||||||
indexes: [],
|
indexes: [],
|
||||||
relationships: [],
|
relationships: [],
|
||||||
})
|
})
|
||||||
@@ -30,6 +31,7 @@ describe("JSON property", () => {
|
|||||||
a: 1,
|
a: 1,
|
||||||
},
|
},
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
computed: false,
|
||||||
indexes: [],
|
indexes: [],
|
||||||
relationships: [],
|
relationships: [],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ describe("Number property", () => {
|
|||||||
options: {},
|
options: {},
|
||||||
},
|
},
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
computed: false,
|
||||||
indexes: [],
|
indexes: [],
|
||||||
relationships: [],
|
relationships: [],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ describe("Text property", () => {
|
|||||||
options: { searchable: false },
|
options: { searchable: false },
|
||||||
},
|
},
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
computed: false,
|
||||||
indexes: [],
|
indexes: [],
|
||||||
relationships: [],
|
relationships: [],
|
||||||
})
|
})
|
||||||
@@ -29,6 +30,7 @@ describe("Text property", () => {
|
|||||||
options: { searchable: false },
|
options: { searchable: false },
|
||||||
},
|
},
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
computed: false,
|
||||||
indexes: [],
|
indexes: [],
|
||||||
relationships: [],
|
relationships: [],
|
||||||
primaryKey: true,
|
primaryKey: true,
|
||||||
|
|||||||
@@ -41,10 +41,16 @@ export function createBigNumberProperties<Schema extends DMLSchema>(
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
const jsonProperty = parsed.nullable
|
let jsonProperty = parsed.nullable
|
||||||
? new JSONProperty().nullable()
|
? new JSONProperty().nullable()
|
||||||
: new JSONProperty()
|
: new JSONProperty()
|
||||||
|
|
||||||
|
if (parsed.computed) {
|
||||||
|
jsonProperty = jsonProperty.computed() as unknown as
|
||||||
|
| JSONProperty
|
||||||
|
| NullableModifier<Record<string, unknown>, JSONProperty>
|
||||||
|
}
|
||||||
|
|
||||||
schemaWithBigNumber[`raw_${key}`] = jsonProperty
|
schemaWithBigNumber[`raw_${key}`] = jsonProperty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,6 +140,10 @@ export function defineProperty(
|
|||||||
BeforeCreate()(MikroORMEntity.prototype, defaultValueSetterHookName)
|
BeforeCreate()(MikroORMEntity.prototype, defaultValueSetterHookName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (field.computed) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (SPECIAL_PROPERTIES[field.fieldName]) {
|
if (SPECIAL_PROPERTIES[field.fieldName]) {
|
||||||
SPECIAL_PROPERTIES[field.fieldName](MikroORMEntity, field, tableName)
|
SPECIAL_PROPERTIES[field.fieldName](MikroORMEntity, field, tableName)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { PropertyMetadata, PropertyType } from "@medusajs/types"
|
import { PropertyMetadata, PropertyType } from "@medusajs/types"
|
||||||
|
import { ComputedProperty } from "./computed"
|
||||||
import { NullableModifier } from "./nullable"
|
import { NullableModifier } from "./nullable"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -48,6 +49,27 @@ export abstract class BaseProperty<T> implements PropertyType<T> {
|
|||||||
return new NullableModifier<T, this>(this)
|
return new NullableModifier<T, this>(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method indicated that the property is a computed property.
|
||||||
|
* Computed properties are not stored in the database but are
|
||||||
|
* computed on the fly.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* import { model } from "@medusajs/framework/utils"
|
||||||
|
*
|
||||||
|
* const MyCustom = model.define("my_custom", {
|
||||||
|
* calculated_price: model.bigNumber().computed(),
|
||||||
|
* // ...
|
||||||
|
* })
|
||||||
|
*
|
||||||
|
* export default MyCustom
|
||||||
|
*
|
||||||
|
* @customNamespace Property Configuration Methods
|
||||||
|
*/
|
||||||
|
computed() {
|
||||||
|
return new ComputedProperty<T | null, this>(this)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method defines an index on a property.
|
* This method defines an index on a property.
|
||||||
*
|
*
|
||||||
@@ -132,6 +154,7 @@ export abstract class BaseProperty<T> implements PropertyType<T> {
|
|||||||
fieldName,
|
fieldName,
|
||||||
dataType: this.dataType,
|
dataType: this.dataType,
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
computed: false,
|
||||||
defaultValue: this.#defaultValue,
|
defaultValue: this.#defaultValue,
|
||||||
indexes: this.#indexes,
|
indexes: this.#indexes,
|
||||||
relationships: this.#relationships,
|
relationships: this.#relationships,
|
||||||
|
|||||||
39
packages/core/utils/src/dml/properties/computed.ts
Normal file
39
packages/core/utils/src/dml/properties/computed.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import { PropertyType } from "@medusajs/types"
|
||||||
|
|
||||||
|
const IsComputedProperty = Symbol.for("isComputedProperty")
|
||||||
|
/**
|
||||||
|
* Computed property marks a schema node as computed
|
||||||
|
*/
|
||||||
|
export class ComputedProperty<T, Schema extends PropertyType<T>>
|
||||||
|
implements PropertyType<T | null>
|
||||||
|
{
|
||||||
|
[IsComputedProperty]: true = true
|
||||||
|
|
||||||
|
static isComputedProperty(obj: any): obj is ComputedProperty<any, any> {
|
||||||
|
return !!obj?.[IsComputedProperty]
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* A type-only property to infer the JavScript data-type
|
||||||
|
* of the schema property
|
||||||
|
*/
|
||||||
|
declare $dataType: T | null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The parent schema on which the computed property is
|
||||||
|
* applied
|
||||||
|
*/
|
||||||
|
#schema: Schema
|
||||||
|
|
||||||
|
constructor(schema: Schema) {
|
||||||
|
this.#schema = schema
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the serialized metadata
|
||||||
|
*/
|
||||||
|
parse(fieldName: string) {
|
||||||
|
const schema = this.#schema.parse(fieldName)
|
||||||
|
schema.computed = true
|
||||||
|
return schema
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,12 +3,13 @@ export * from "./autoincrement"
|
|||||||
export * from "./base"
|
export * from "./base"
|
||||||
export * from "./big-number"
|
export * from "./big-number"
|
||||||
export * from "./boolean"
|
export * from "./boolean"
|
||||||
|
export * from "./computed"
|
||||||
export * from "./date-time"
|
export * from "./date-time"
|
||||||
export * from "./enum"
|
export * from "./enum"
|
||||||
|
export * from "./float"
|
||||||
export * from "./id"
|
export * from "./id"
|
||||||
export * from "./json"
|
export * from "./json"
|
||||||
export * from "./nullable"
|
export * from "./nullable"
|
||||||
export * from "./number"
|
export * from "./number"
|
||||||
export * from "./float"
|
|
||||||
export * from "./primary-key"
|
export * from "./primary-key"
|
||||||
export * from "./text"
|
export * from "./text"
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { PropertyType } from "@medusajs/types"
|
import { PropertyType } from "@medusajs/types"
|
||||||
|
import { ComputedProperty } from "./computed"
|
||||||
|
|
||||||
const IsNullableModifier = Symbol.for("isNullableModifier")
|
const IsNullableModifier = Symbol.for("isNullableModifier")
|
||||||
/**
|
/**
|
||||||
@@ -28,6 +29,13 @@ export class NullableModifier<T, Schema extends PropertyType<T>>
|
|||||||
this.#schema = schema
|
this.#schema = schema
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method indicated that the property is a computed property.
|
||||||
|
*/
|
||||||
|
computed() {
|
||||||
|
return new ComputedProperty<T | null, this>(this)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the serialized metadata
|
* Returns the serialized metadata
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { dropDatabase } from "pg-god"
|
import { dropDatabase } from "pg-god"
|
||||||
import {
|
import {
|
||||||
createClient,
|
createClient,
|
||||||
parseConnectionString,
|
|
||||||
dbExists,
|
|
||||||
createDb,
|
createDb,
|
||||||
|
dbExists,
|
||||||
|
parseConnectionString,
|
||||||
} from "../../index"
|
} from "../../index"
|
||||||
|
|
||||||
const DB_HOST = process.env.DB_HOST ?? "localhost"
|
const DB_HOST = process.env.DB_HOST ?? "localhost"
|
||||||
|
|||||||
@@ -229,6 +229,29 @@ moduleIntegrationTestRunner<IInventoryService>({
|
|||||||
expect(inventoryLevel).toEqual(
|
expect(inventoryLevel).toEqual(
|
||||||
expect.objectContaining({ id: expect.any(String), ...data })
|
expect.objectContaining({ id: expect.any(String), ...data })
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const getItems = await service.listInventoryItems(
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
select: [
|
||||||
|
"id",
|
||||||
|
"sku",
|
||||||
|
"origin_country",
|
||||||
|
"reserved_quantity",
|
||||||
|
"stocked_quantity",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(getItems).toEqual([
|
||||||
|
{
|
||||||
|
id: inventoryItem.id,
|
||||||
|
sku: "test-sku",
|
||||||
|
origin_country: "test-country",
|
||||||
|
reserved_quantity: 0,
|
||||||
|
stocked_quantity: 2,
|
||||||
|
},
|
||||||
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should create inventoryLevels from array", async () => {
|
it("should create inventoryLevels from array", async () => {
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
{
|
{
|
||||||
"namespaces": ["public"],
|
"namespaces": [
|
||||||
|
"public"
|
||||||
|
],
|
||||||
"name": "public",
|
"name": "public",
|
||||||
"tables": [
|
"tables": [
|
||||||
{
|
{
|
||||||
@@ -13,38 +15,6 @@
|
|||||||
"nullable": false,
|
"nullable": false,
|
||||||
"mappedType": "text"
|
"mappedType": "text"
|
||||||
},
|
},
|
||||||
"created_at": {
|
|
||||||
"name": "created_at",
|
|
||||||
"type": "timestamptz",
|
|
||||||
"unsigned": false,
|
|
||||||
"autoincrement": false,
|
|
||||||
"primary": false,
|
|
||||||
"nullable": false,
|
|
||||||
"length": 6,
|
|
||||||
"default": "now()",
|
|
||||||
"mappedType": "datetime"
|
|
||||||
},
|
|
||||||
"updated_at": {
|
|
||||||
"name": "updated_at",
|
|
||||||
"type": "timestamptz",
|
|
||||||
"unsigned": false,
|
|
||||||
"autoincrement": false,
|
|
||||||
"primary": false,
|
|
||||||
"nullable": false,
|
|
||||||
"length": 6,
|
|
||||||
"default": "now()",
|
|
||||||
"mappedType": "datetime"
|
|
||||||
},
|
|
||||||
"deleted_at": {
|
|
||||||
"name": "deleted_at",
|
|
||||||
"type": "timestamptz",
|
|
||||||
"unsigned": false,
|
|
||||||
"autoincrement": false,
|
|
||||||
"primary": false,
|
|
||||||
"nullable": true,
|
|
||||||
"length": 6,
|
|
||||||
"mappedType": "datetime"
|
|
||||||
},
|
|
||||||
"sku": {
|
"sku": {
|
||||||
"name": "sku",
|
"name": "sku",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
@@ -92,7 +62,7 @@
|
|||||||
},
|
},
|
||||||
"weight": {
|
"weight": {
|
||||||
"name": "weight",
|
"name": "weight",
|
||||||
"type": "int",
|
"type": "integer",
|
||||||
"unsigned": false,
|
"unsigned": false,
|
||||||
"autoincrement": false,
|
"autoincrement": false,
|
||||||
"primary": false,
|
"primary": false,
|
||||||
@@ -101,7 +71,7 @@
|
|||||||
},
|
},
|
||||||
"length": {
|
"length": {
|
||||||
"name": "length",
|
"name": "length",
|
||||||
"type": "int",
|
"type": "integer",
|
||||||
"unsigned": false,
|
"unsigned": false,
|
||||||
"autoincrement": false,
|
"autoincrement": false,
|
||||||
"primary": false,
|
"primary": false,
|
||||||
@@ -110,7 +80,7 @@
|
|||||||
},
|
},
|
||||||
"height": {
|
"height": {
|
||||||
"name": "height",
|
"name": "height",
|
||||||
"type": "int",
|
"type": "integer",
|
||||||
"unsigned": false,
|
"unsigned": false,
|
||||||
"autoincrement": false,
|
"autoincrement": false,
|
||||||
"primary": false,
|
"primary": false,
|
||||||
@@ -119,7 +89,7 @@
|
|||||||
},
|
},
|
||||||
"width": {
|
"width": {
|
||||||
"name": "width",
|
"name": "width",
|
||||||
"type": "int",
|
"type": "integer",
|
||||||
"unsigned": false,
|
"unsigned": false,
|
||||||
"autoincrement": false,
|
"autoincrement": false,
|
||||||
"primary": false,
|
"primary": false,
|
||||||
@@ -171,6 +141,38 @@
|
|||||||
"primary": false,
|
"primary": false,
|
||||||
"nullable": true,
|
"nullable": true,
|
||||||
"mappedType": "json"
|
"mappedType": "json"
|
||||||
|
},
|
||||||
|
"created_at": {
|
||||||
|
"name": "created_at",
|
||||||
|
"type": "timestamptz",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"length": 6,
|
||||||
|
"default": "now()",
|
||||||
|
"mappedType": "datetime"
|
||||||
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"name": "updated_at",
|
||||||
|
"type": "timestamptz",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"length": 6,
|
||||||
|
"default": "now()",
|
||||||
|
"mappedType": "datetime"
|
||||||
|
},
|
||||||
|
"deleted_at": {
|
||||||
|
"name": "deleted_at",
|
||||||
|
"type": "timestamptz",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": true,
|
||||||
|
"length": 6,
|
||||||
|
"mappedType": "datetime"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"name": "inventory_item",
|
"name": "inventory_item",
|
||||||
@@ -178,23 +180,33 @@
|
|||||||
"indexes": [
|
"indexes": [
|
||||||
{
|
{
|
||||||
"keyName": "IDX_inventory_item_deleted_at",
|
"keyName": "IDX_inventory_item_deleted_at",
|
||||||
"columnNames": ["deleted_at"],
|
"columnNames": [],
|
||||||
|
"composite": false,
|
||||||
|
"primary": false,
|
||||||
|
"unique": false,
|
||||||
|
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_inventory_item_deleted_at\" ON \"inventory_item\" (deleted_at) WHERE deleted_at IS NULL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keyName": "IDX_inventory_item_deleted_at",
|
||||||
|
"columnNames": [],
|
||||||
"composite": false,
|
"composite": false,
|
||||||
"primary": false,
|
"primary": false,
|
||||||
"unique": false,
|
"unique": false,
|
||||||
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_inventory_item_deleted_at\" ON \"inventory_item\" (deleted_at) WHERE deleted_at IS NOT NULL"
|
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_inventory_item_deleted_at\" ON \"inventory_item\" (deleted_at) WHERE deleted_at IS NOT NULL"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"keyName": "IDX_inventory_item_sku_unique",
|
"keyName": "IDX_inventory_item_sku",
|
||||||
"columnNames": ["sku"],
|
"columnNames": [],
|
||||||
"composite": false,
|
"composite": false,
|
||||||
"primary": false,
|
"primary": false,
|
||||||
"unique": false,
|
"unique": false,
|
||||||
"expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_inventory_item_sku_unique\" ON \"inventory_item\" (sku)"
|
"expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_inventory_item_sku\" ON \"inventory_item\" (sku) WHERE deleted_at IS NULL"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"keyName": "inventory_item_pkey",
|
"keyName": "inventory_item_pkey",
|
||||||
"columnNames": ["id"],
|
"columnNames": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
"composite": false,
|
"composite": false,
|
||||||
"primary": true,
|
"primary": true,
|
||||||
"unique": true
|
"unique": true
|
||||||
@@ -214,6 +226,90 @@
|
|||||||
"nullable": false,
|
"nullable": false,
|
||||||
"mappedType": "text"
|
"mappedType": "text"
|
||||||
},
|
},
|
||||||
|
"location_id": {
|
||||||
|
"name": "location_id",
|
||||||
|
"type": "text",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"mappedType": "text"
|
||||||
|
},
|
||||||
|
"stocked_quantity": {
|
||||||
|
"name": "stocked_quantity",
|
||||||
|
"type": "numeric",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"default": "0",
|
||||||
|
"mappedType": "decimal"
|
||||||
|
},
|
||||||
|
"reserved_quantity": {
|
||||||
|
"name": "reserved_quantity",
|
||||||
|
"type": "numeric",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"default": "0",
|
||||||
|
"mappedType": "decimal"
|
||||||
|
},
|
||||||
|
"incoming_quantity": {
|
||||||
|
"name": "incoming_quantity",
|
||||||
|
"type": "numeric",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"default": "0",
|
||||||
|
"mappedType": "decimal"
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"name": "metadata",
|
||||||
|
"type": "jsonb",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": true,
|
||||||
|
"mappedType": "json"
|
||||||
|
},
|
||||||
|
"inventory_item_id": {
|
||||||
|
"name": "inventory_item_id",
|
||||||
|
"type": "text",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"mappedType": "text"
|
||||||
|
},
|
||||||
|
"raw_stocked_quantity": {
|
||||||
|
"name": "raw_stocked_quantity",
|
||||||
|
"type": "jsonb",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"mappedType": "json"
|
||||||
|
},
|
||||||
|
"raw_reserved_quantity": {
|
||||||
|
"name": "raw_reserved_quantity",
|
||||||
|
"type": "jsonb",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"mappedType": "json"
|
||||||
|
},
|
||||||
|
"raw_incoming_quantity": {
|
||||||
|
"name": "raw_incoming_quantity",
|
||||||
|
"type": "jsonb",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"mappedType": "json"
|
||||||
|
},
|
||||||
"created_at": {
|
"created_at": {
|
||||||
"name": "created_at",
|
"name": "created_at",
|
||||||
"type": "timestamptz",
|
"type": "timestamptz",
|
||||||
@@ -245,91 +341,26 @@
|
|||||||
"nullable": true,
|
"nullable": true,
|
||||||
"length": 6,
|
"length": 6,
|
||||||
"mappedType": "datetime"
|
"mappedType": "datetime"
|
||||||
},
|
|
||||||
"inventory_item_id": {
|
|
||||||
"name": "inventory_item_id",
|
|
||||||
"type": "text",
|
|
||||||
"unsigned": false,
|
|
||||||
"autoincrement": false,
|
|
||||||
"primary": false,
|
|
||||||
"nullable": false,
|
|
||||||
"mappedType": "text"
|
|
||||||
},
|
|
||||||
"location_id": {
|
|
||||||
"name": "location_id",
|
|
||||||
"type": "text",
|
|
||||||
"unsigned": false,
|
|
||||||
"autoincrement": false,
|
|
||||||
"primary": false,
|
|
||||||
"nullable": false,
|
|
||||||
"mappedType": "text"
|
|
||||||
},
|
|
||||||
"stocked_quantity": {
|
|
||||||
"name": "stocked_quantity",
|
|
||||||
"type": "int",
|
|
||||||
"unsigned": false,
|
|
||||||
"autoincrement": false,
|
|
||||||
"primary": false,
|
|
||||||
"nullable": false,
|
|
||||||
"default": "0",
|
|
||||||
"mappedType": "integer"
|
|
||||||
},
|
|
||||||
"reserved_quantity": {
|
|
||||||
"name": "reserved_quantity",
|
|
||||||
"type": "int",
|
|
||||||
"unsigned": false,
|
|
||||||
"autoincrement": false,
|
|
||||||
"primary": false,
|
|
||||||
"nullable": false,
|
|
||||||
"default": "0",
|
|
||||||
"mappedType": "integer"
|
|
||||||
},
|
|
||||||
"incoming_quantity": {
|
|
||||||
"name": "incoming_quantity",
|
|
||||||
"type": "int",
|
|
||||||
"unsigned": false,
|
|
||||||
"autoincrement": false,
|
|
||||||
"primary": false,
|
|
||||||
"nullable": false,
|
|
||||||
"default": "0",
|
|
||||||
"mappedType": "integer"
|
|
||||||
},
|
|
||||||
"metadata": {
|
|
||||||
"name": "metadata",
|
|
||||||
"type": "jsonb",
|
|
||||||
"unsigned": false,
|
|
||||||
"autoincrement": false,
|
|
||||||
"primary": false,
|
|
||||||
"nullable": true,
|
|
||||||
"mappedType": "json"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"name": "inventory_level",
|
"name": "inventory_level",
|
||||||
"schema": "public",
|
"schema": "public",
|
||||||
"indexes": [
|
"indexes": [
|
||||||
{
|
|
||||||
"keyName": "IDX_inventory_level_deleted_at",
|
|
||||||
"columnNames": ["deleted_at"],
|
|
||||||
"composite": false,
|
|
||||||
"primary": false,
|
|
||||||
"unique": false,
|
|
||||||
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_inventory_level_deleted_at\" ON \"inventory_level\" (deleted_at) WHERE deleted_at IS NOT NULL"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"keyName": "IDX_inventory_level_inventory_item_id",
|
"keyName": "IDX_inventory_level_inventory_item_id",
|
||||||
"columnNames": ["inventory_item_id"],
|
"columnNames": [],
|
||||||
"composite": false,
|
"composite": false,
|
||||||
"primary": false,
|
"primary": false,
|
||||||
"unique": false,
|
"unique": false,
|
||||||
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_inventory_level_inventory_item_id\" ON \"inventory_level\" (inventory_item_id)"
|
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_inventory_level_inventory_item_id\" ON \"inventory_level\" (inventory_item_id) WHERE deleted_at IS NULL"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"keyName": "IDX_inventory_level_location_id",
|
"keyName": "IDX_inventory_level_deleted_at",
|
||||||
"columnNames": ["location_id"],
|
"columnNames": [],
|
||||||
"composite": false,
|
"composite": false,
|
||||||
"primary": false,
|
"primary": false,
|
||||||
"unique": false,
|
"unique": false,
|
||||||
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_inventory_level_location_id\" ON \"inventory_level\" (location_id)"
|
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_inventory_level_deleted_at\" ON \"inventory_level\" (deleted_at) WHERE deleted_at IS NULL"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"keyName": "IDX_inventory_level_location_id",
|
"keyName": "IDX_inventory_level_location_id",
|
||||||
@@ -337,11 +368,21 @@
|
|||||||
"composite": false,
|
"composite": false,
|
||||||
"primary": false,
|
"primary": false,
|
||||||
"unique": false,
|
"unique": false,
|
||||||
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_inventory_level_location_id\" ON \"inventory_level\" (location_id)"
|
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_inventory_level_location_id\" ON \"inventory_level\" (location_id) WHERE deleted_at IS NULL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keyName": "IDX_inventory_level_location_id_inventory_item_id",
|
||||||
|
"columnNames": [],
|
||||||
|
"composite": false,
|
||||||
|
"primary": false,
|
||||||
|
"unique": false,
|
||||||
|
"expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_inventory_level_location_id_inventory_item_id\" ON \"inventory_level\" (inventory_item_id, location_id) WHERE deleted_at IS NULL"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"keyName": "inventory_level_pkey",
|
"keyName": "inventory_level_pkey",
|
||||||
"columnNames": ["id"],
|
"columnNames": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
"composite": false,
|
"composite": false,
|
||||||
"primary": true,
|
"primary": true,
|
||||||
"unique": true
|
"unique": true
|
||||||
@@ -351,9 +392,13 @@
|
|||||||
"foreignKeys": {
|
"foreignKeys": {
|
||||||
"inventory_level_inventory_item_id_foreign": {
|
"inventory_level_inventory_item_id_foreign": {
|
||||||
"constraintName": "inventory_level_inventory_item_id_foreign",
|
"constraintName": "inventory_level_inventory_item_id_foreign",
|
||||||
"columnNames": ["inventory_item_id"],
|
"columnNames": [
|
||||||
|
"inventory_item_id"
|
||||||
|
],
|
||||||
"localTableName": "public.inventory_level",
|
"localTableName": "public.inventory_level",
|
||||||
"referencedColumnNames": ["id"],
|
"referencedColumnNames": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
"referencedTableName": "public.inventory_item",
|
"referencedTableName": "public.inventory_item",
|
||||||
"deleteRule": "cascade",
|
"deleteRule": "cascade",
|
||||||
"updateRule": "cascade"
|
"updateRule": "cascade"
|
||||||
@@ -371,38 +416,6 @@
|
|||||||
"nullable": false,
|
"nullable": false,
|
||||||
"mappedType": "text"
|
"mappedType": "text"
|
||||||
},
|
},
|
||||||
"created_at": {
|
|
||||||
"name": "created_at",
|
|
||||||
"type": "timestamptz",
|
|
||||||
"unsigned": false,
|
|
||||||
"autoincrement": false,
|
|
||||||
"primary": false,
|
|
||||||
"nullable": false,
|
|
||||||
"length": 6,
|
|
||||||
"default": "now()",
|
|
||||||
"mappedType": "datetime"
|
|
||||||
},
|
|
||||||
"updated_at": {
|
|
||||||
"name": "updated_at",
|
|
||||||
"type": "timestamptz",
|
|
||||||
"unsigned": false,
|
|
||||||
"autoincrement": false,
|
|
||||||
"primary": false,
|
|
||||||
"nullable": false,
|
|
||||||
"length": 6,
|
|
||||||
"default": "now()",
|
|
||||||
"mappedType": "datetime"
|
|
||||||
},
|
|
||||||
"deleted_at": {
|
|
||||||
"name": "deleted_at",
|
|
||||||
"type": "timestamptz",
|
|
||||||
"unsigned": false,
|
|
||||||
"autoincrement": false,
|
|
||||||
"primary": false,
|
|
||||||
"nullable": true,
|
|
||||||
"length": 6,
|
|
||||||
"mappedType": "datetime"
|
|
||||||
},
|
|
||||||
"line_item_id": {
|
"line_item_id": {
|
||||||
"name": "line_item_id",
|
"name": "line_item_id",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
@@ -412,6 +425,16 @@
|
|||||||
"nullable": true,
|
"nullable": true,
|
||||||
"mappedType": "text"
|
"mappedType": "text"
|
||||||
},
|
},
|
||||||
|
"allow_backorder": {
|
||||||
|
"name": "allow_backorder",
|
||||||
|
"type": "boolean",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"default": "false",
|
||||||
|
"mappedType": "boolean"
|
||||||
|
},
|
||||||
"location_id": {
|
"location_id": {
|
||||||
"name": "location_id",
|
"name": "location_id",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
@@ -423,12 +446,21 @@
|
|||||||
},
|
},
|
||||||
"quantity": {
|
"quantity": {
|
||||||
"name": "quantity",
|
"name": "quantity",
|
||||||
"type": "integer",
|
"type": "numeric",
|
||||||
"unsigned": false,
|
"unsigned": false,
|
||||||
"autoincrement": false,
|
"autoincrement": false,
|
||||||
"primary": false,
|
"primary": false,
|
||||||
"nullable": false,
|
"nullable": false,
|
||||||
"mappedType": "integer"
|
"mappedType": "decimal"
|
||||||
|
},
|
||||||
|
"raw_quantity": {
|
||||||
|
"name": "raw_quantity",
|
||||||
|
"type": "jsonb",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"mappedType": "json"
|
||||||
},
|
},
|
||||||
"external_id": {
|
"external_id": {
|
||||||
"name": "external_id",
|
"name": "external_id",
|
||||||
@@ -474,46 +506,80 @@
|
|||||||
"primary": false,
|
"primary": false,
|
||||||
"nullable": false,
|
"nullable": false,
|
||||||
"mappedType": "text"
|
"mappedType": "text"
|
||||||
|
},
|
||||||
|
"created_at": {
|
||||||
|
"name": "created_at",
|
||||||
|
"type": "timestamptz",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"length": 6,
|
||||||
|
"default": "now()",
|
||||||
|
"mappedType": "datetime"
|
||||||
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"name": "updated_at",
|
||||||
|
"type": "timestamptz",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"length": 6,
|
||||||
|
"default": "now()",
|
||||||
|
"mappedType": "datetime"
|
||||||
|
},
|
||||||
|
"deleted_at": {
|
||||||
|
"name": "deleted_at",
|
||||||
|
"type": "timestamptz",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": true,
|
||||||
|
"length": 6,
|
||||||
|
"mappedType": "datetime"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"name": "reservation_item",
|
"name": "reservation_item",
|
||||||
"schema": "public",
|
"schema": "public",
|
||||||
"indexes": [
|
"indexes": [
|
||||||
{
|
{
|
||||||
"keyName": "IDX_reservation_item_deleted_at",
|
"keyName": "IDX_reservation_item_inventory_item_id",
|
||||||
"columnNames": ["deleted_at"],
|
"columnNames": [],
|
||||||
"composite": false,
|
"composite": false,
|
||||||
"primary": false,
|
"primary": false,
|
||||||
"unique": false,
|
"unique": false,
|
||||||
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_reservation_item_deleted_at\" ON \"reservation_item\" (deleted_at) WHERE deleted_at IS NOT NULL"
|
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_reservation_item_inventory_item_id\" ON \"reservation_item\" (inventory_item_id) WHERE deleted_at IS NULL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keyName": "IDX_reservation_item_deleted_at",
|
||||||
|
"columnNames": [],
|
||||||
|
"composite": false,
|
||||||
|
"primary": false,
|
||||||
|
"unique": false,
|
||||||
|
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_reservation_item_deleted_at\" ON \"reservation_item\" (deleted_at) WHERE deleted_at IS NULL"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"keyName": "IDX_reservation_item_line_item_id",
|
"keyName": "IDX_reservation_item_line_item_id",
|
||||||
"columnNames": ["line_item_id"],
|
"columnNames": [],
|
||||||
"composite": false,
|
"composite": false,
|
||||||
"primary": false,
|
"primary": false,
|
||||||
"unique": false,
|
"unique": false,
|
||||||
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_reservation_item_line_item_id\" ON \"reservation_item\" (line_item_id)"
|
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_reservation_item_line_item_id\" ON \"reservation_item\" (line_item_id) WHERE deleted_at IS NULL"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"keyName": "IDX_reservation_item_location_id",
|
"keyName": "IDX_reservation_item_location_id",
|
||||||
"columnNames": ["location_id"],
|
"columnNames": [],
|
||||||
"composite": false,
|
"composite": false,
|
||||||
"primary": false,
|
"primary": false,
|
||||||
"unique": false,
|
"unique": false,
|
||||||
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_reservation_item_location_id\" ON \"reservation_item\" (location_id)"
|
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_reservation_item_location_id\" ON \"reservation_item\" (location_id) WHERE deleted_at IS NULL"
|
||||||
},
|
|
||||||
{
|
|
||||||
"keyName": "IDX_reservation_item_inventory_item_id",
|
|
||||||
"columnNames": ["inventory_item_id"],
|
|
||||||
"composite": false,
|
|
||||||
"primary": false,
|
|
||||||
"unique": false,
|
|
||||||
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_reservation_item_inventory_item_id\" ON \"reservation_item\" (inventory_item_id)"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"keyName": "reservation_item_pkey",
|
"keyName": "reservation_item_pkey",
|
||||||
"columnNames": ["id"],
|
"columnNames": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
"composite": false,
|
"composite": false,
|
||||||
"primary": true,
|
"primary": true,
|
||||||
"unique": true
|
"unique": true
|
||||||
@@ -523,9 +589,13 @@
|
|||||||
"foreignKeys": {
|
"foreignKeys": {
|
||||||
"reservation_item_inventory_item_id_foreign": {
|
"reservation_item_inventory_item_id_foreign": {
|
||||||
"constraintName": "reservation_item_inventory_item_id_foreign",
|
"constraintName": "reservation_item_inventory_item_id_foreign",
|
||||||
"columnNames": ["inventory_item_id"],
|
"columnNames": [
|
||||||
|
"inventory_item_id"
|
||||||
|
],
|
||||||
"localTableName": "public.reservation_item",
|
"localTableName": "public.reservation_item",
|
||||||
"referencedColumnNames": ["id"],
|
"referencedColumnNames": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
"referencedTableName": "public.inventory_item",
|
"referencedTableName": "public.inventory_item",
|
||||||
"deleteRule": "cascade",
|
"deleteRule": "cascade",
|
||||||
"updateRule": "cascade"
|
"updateRule": "cascade"
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
import { Migration } from "@mikro-orm/migrations"
|
||||||
|
|
||||||
|
export class Migration20241213063611 extends Migration {
|
||||||
|
async up(): Promise<void> {
|
||||||
|
this.addSql('drop index if exists "IDX_inventory_item_sku_unique";')
|
||||||
|
this.addSql(
|
||||||
|
'CREATE UNIQUE INDEX IF NOT EXISTS "IDX_inventory_item_sku" ON "inventory_item" (sku) WHERE deleted_at IS NULL;'
|
||||||
|
)
|
||||||
|
|
||||||
|
this.addSql(
|
||||||
|
'alter table if exists "inventory_level" add column if not exists "raw_stocked_quantity" jsonb not null, add column if not exists "raw_reserved_quantity" jsonb not null, add column if not exists "raw_incoming_quantity" jsonb not null;'
|
||||||
|
)
|
||||||
|
this.addSql(
|
||||||
|
'alter table if exists "inventory_level" alter column "stocked_quantity" type numeric using ("stocked_quantity"::numeric);'
|
||||||
|
)
|
||||||
|
this.addSql(
|
||||||
|
'alter table if exists "inventory_level" alter column "reserved_quantity" type numeric using ("reserved_quantity"::numeric);'
|
||||||
|
)
|
||||||
|
this.addSql(
|
||||||
|
'alter table if exists "inventory_level" alter column "incoming_quantity" type numeric using ("incoming_quantity"::numeric);'
|
||||||
|
)
|
||||||
|
this.addSql(
|
||||||
|
'CREATE UNIQUE INDEX IF NOT EXISTS "IDX_inventory_level_location_id_inventory_item_id" ON "inventory_level" (inventory_item_id, location_id) WHERE deleted_at IS NULL;'
|
||||||
|
)
|
||||||
|
|
||||||
|
this.addSql(
|
||||||
|
'alter table if exists "reservation_item" add column if not exists "allow_backorder" boolean not null default false, add column if not exists "raw_quantity" jsonb not null;'
|
||||||
|
)
|
||||||
|
this.addSql(
|
||||||
|
'alter table if exists "reservation_item" alter column "quantity" type numeric using ("quantity"::numeric);'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(): Promise<void> {
|
||||||
|
this.addSql('drop index if exists "IDX_inventory_item_sku";')
|
||||||
|
this.addSql(
|
||||||
|
'CREATE UNIQUE INDEX IF NOT EXISTS "IDX_inventory_item_sku_unique" ON "inventory_item" (sku);'
|
||||||
|
)
|
||||||
|
|
||||||
|
this.addSql(
|
||||||
|
'alter table if exists "inventory_level" alter column "stocked_quantity" type int using ("stocked_quantity"::int);'
|
||||||
|
)
|
||||||
|
this.addSql(
|
||||||
|
'alter table if exists "inventory_level" alter column "reserved_quantity" type int using ("reserved_quantity"::int);'
|
||||||
|
)
|
||||||
|
this.addSql(
|
||||||
|
'alter table if exists "inventory_level" alter column "incoming_quantity" type int using ("incoming_quantity"::int);'
|
||||||
|
)
|
||||||
|
this.addSql(
|
||||||
|
'drop index if exists "IDX_inventory_level_location_id_inventory_item_id";'
|
||||||
|
)
|
||||||
|
this.addSql(
|
||||||
|
'alter table if exists "inventory_level" drop column if exists "raw_stocked_quantity";'
|
||||||
|
)
|
||||||
|
this.addSql(
|
||||||
|
'alter table if exists "inventory_level" drop column if exists "raw_reserved_quantity";'
|
||||||
|
)
|
||||||
|
this.addSql(
|
||||||
|
'alter table if exists "inventory_level" drop column if exists "raw_incoming_quantity";'
|
||||||
|
)
|
||||||
|
|
||||||
|
this.addSql(
|
||||||
|
'alter table if exists "reservation_item" alter column "quantity" type integer using ("quantity"::integer);'
|
||||||
|
)
|
||||||
|
this.addSql(
|
||||||
|
'alter table if exists "reservation_item" drop column if exists "allow_backorder";'
|
||||||
|
)
|
||||||
|
this.addSql(
|
||||||
|
'alter table if exists "reservation_item" drop column if exists "raw_quantity";'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
export * from "./reservation-item"
|
export { default as InventoryItem } from "./inventory-item"
|
||||||
export * from "./inventory-item"
|
export { default as InventoryLevel } from "./inventory-level"
|
||||||
export * from "./inventory-level"
|
export { default as ReservationItem } from "./reservation-item"
|
||||||
|
|||||||
@@ -1,156 +1,43 @@
|
|||||||
import {
|
import { model } from "@medusajs/framework/utils"
|
||||||
createPsqlIndexStatementHelper,
|
import InventoryLevel from "./inventory-level"
|
||||||
DALUtils,
|
import ReservationItem from "./reservation-item"
|
||||||
generateEntityId,
|
|
||||||
Searchable,
|
|
||||||
} from "@medusajs/framework/utils"
|
|
||||||
import {
|
|
||||||
BeforeCreate,
|
|
||||||
Collection,
|
|
||||||
Entity,
|
|
||||||
Filter,
|
|
||||||
Formula,
|
|
||||||
OneToMany,
|
|
||||||
OnInit,
|
|
||||||
OptionalProps,
|
|
||||||
PrimaryKey,
|
|
||||||
Property,
|
|
||||||
Rel,
|
|
||||||
} from "@mikro-orm/core"
|
|
||||||
|
|
||||||
import { DAL } from "@medusajs/framework/types"
|
const InventoryItem = model
|
||||||
import { InventoryLevel } from "./inventory-level"
|
.define("InventoryItem", {
|
||||||
import { ReservationItem } from "./reservation-item"
|
id: model.id({ prefix: "iitem" }).primaryKey(),
|
||||||
|
sku: model.text().searchable().nullable(),
|
||||||
const InventoryItemDeletedAtIndex = createPsqlIndexStatementHelper({
|
origin_country: model.text().nullable(),
|
||||||
tableName: "inventory_item",
|
hs_code: model.text().searchable().nullable(),
|
||||||
columns: "deleted_at",
|
mid_code: model.text().searchable().nullable(),
|
||||||
where: "deleted_at IS NOT NULL",
|
material: model.text().nullable(),
|
||||||
})
|
weight: model.number().nullable(),
|
||||||
|
length: model.number().nullable(),
|
||||||
const InventoryItemSkuIndex = createPsqlIndexStatementHelper({
|
height: model.number().nullable(),
|
||||||
tableName: "inventory_item",
|
width: model.number().nullable(),
|
||||||
columns: "sku",
|
requires_shipping: model.boolean().default(true),
|
||||||
unique: true,
|
description: model.text().searchable().nullable(),
|
||||||
where: "deleted_at IS NULL",
|
title: model.text().searchable().nullable(),
|
||||||
})
|
thumbnail: model.text().nullable(),
|
||||||
|
metadata: model.json().nullable(),
|
||||||
type InventoryItemOptionalProps = DAL.SoftDeletableModelDateColumns
|
location_levels: model.hasMany(() => InventoryLevel, {
|
||||||
|
mappedBy: "inventory_item",
|
||||||
@Entity()
|
}),
|
||||||
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
|
reservation_items: model.hasMany(() => ReservationItem, {
|
||||||
export class InventoryItem {
|
mappedBy: "inventory_item",
|
||||||
[OptionalProps]: InventoryItemOptionalProps
|
}),
|
||||||
|
reserved_quantity: model.number().computed(),
|
||||||
@PrimaryKey({ columnType: "text" })
|
stocked_quantity: model.number().computed(),
|
||||||
id: string
|
|
||||||
|
|
||||||
@Property({
|
|
||||||
onCreate: () => new Date(),
|
|
||||||
columnType: "timestamptz",
|
|
||||||
defaultRaw: "now()",
|
|
||||||
})
|
})
|
||||||
created_at: Date
|
.cascades({
|
||||||
|
delete: ["location_levels", "reservation_items"],
|
||||||
@Property({
|
|
||||||
onCreate: () => new Date(),
|
|
||||||
onUpdate: () => new Date(),
|
|
||||||
columnType: "timestamptz",
|
|
||||||
defaultRaw: "now()",
|
|
||||||
})
|
})
|
||||||
updated_at: Date
|
.indexes([
|
||||||
|
|
||||||
@InventoryItemDeletedAtIndex.MikroORMIndex()
|
|
||||||
@Property({ columnType: "timestamptz", nullable: true })
|
|
||||||
deleted_at: Date | null = null
|
|
||||||
|
|
||||||
@InventoryItemSkuIndex.MikroORMIndex()
|
|
||||||
@Searchable()
|
|
||||||
@Property({ columnType: "text", nullable: true })
|
|
||||||
sku: string | null = null
|
|
||||||
|
|
||||||
@Property({ columnType: "text", nullable: true })
|
|
||||||
origin_country: string | null = null
|
|
||||||
|
|
||||||
@Searchable()
|
|
||||||
@Property({ columnType: "text", nullable: true })
|
|
||||||
hs_code: string | null = null
|
|
||||||
|
|
||||||
@Searchable()
|
|
||||||
@Property({ columnType: "text", nullable: true })
|
|
||||||
mid_code: string | null = null
|
|
||||||
|
|
||||||
@Property({ columnType: "text", nullable: true })
|
|
||||||
material: string | null = null
|
|
||||||
|
|
||||||
@Property({ type: "int", nullable: true })
|
|
||||||
weight: number | null = null
|
|
||||||
|
|
||||||
@Property({ type: "int", nullable: true })
|
|
||||||
length: number | null = null
|
|
||||||
|
|
||||||
@Property({ type: "int", nullable: true })
|
|
||||||
height: number | null = null
|
|
||||||
|
|
||||||
@Property({ type: "int", nullable: true })
|
|
||||||
width: number | null = null
|
|
||||||
|
|
||||||
@Property({ columnType: "boolean" })
|
|
||||||
requires_shipping: boolean = true
|
|
||||||
|
|
||||||
@Searchable()
|
|
||||||
@Property({ columnType: "text", nullable: true })
|
|
||||||
description: string | null = null
|
|
||||||
|
|
||||||
@Searchable()
|
|
||||||
@Property({ columnType: "text", nullable: true })
|
|
||||||
title: string | null = null
|
|
||||||
|
|
||||||
@Property({ columnType: "text", nullable: true })
|
|
||||||
thumbnail: string | null = null
|
|
||||||
|
|
||||||
@Property({ columnType: "jsonb", nullable: true })
|
|
||||||
metadata: Record<string, unknown> | null = null
|
|
||||||
|
|
||||||
@OneToMany(
|
|
||||||
() => InventoryLevel,
|
|
||||||
(inventoryLevel) => inventoryLevel.inventory_item,
|
|
||||||
{
|
{
|
||||||
cascade: ["soft-remove" as any],
|
name: "IDX_inventory_item_sku",
|
||||||
}
|
on: ["sku"],
|
||||||
)
|
unique: true,
|
||||||
location_levels = new Collection<Rel<InventoryLevel>>(this)
|
where: "deleted_at IS NULL",
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
@OneToMany(
|
export default InventoryItem
|
||||||
() => ReservationItem,
|
|
||||||
(reservationItem) => reservationItem.inventory_item,
|
|
||||||
{
|
|
||||||
cascade: ["soft-remove" as any],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
reservation_items = new Collection<Rel<ReservationItem>>(this)
|
|
||||||
|
|
||||||
@Formula(
|
|
||||||
(item) =>
|
|
||||||
`(SELECT SUM(reserved_quantity) FROM inventory_level il WHERE il.inventory_item_id = ${item}.id AND il.deleted_at IS NULL)`,
|
|
||||||
{ lazy: true, serializer: Number, hidden: true }
|
|
||||||
)
|
|
||||||
reserved_quantity: number
|
|
||||||
|
|
||||||
@Formula(
|
|
||||||
(item) =>
|
|
||||||
`(SELECT SUM(stocked_quantity) FROM inventory_level il WHERE il.inventory_item_id = ${item}.id AND il.deleted_at IS NULL)`,
|
|
||||||
{ lazy: true, serializer: Number, hidden: true }
|
|
||||||
)
|
|
||||||
stocked_quantity: number
|
|
||||||
|
|
||||||
@BeforeCreate()
|
|
||||||
beforeCreate(): void {
|
|
||||||
this.id = generateEntityId(this.id, "iitem")
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnInit()
|
|
||||||
onInit(): void {
|
|
||||||
this.id = generateEntityId(this.id, "iitem")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,135 +1,36 @@
|
|||||||
import { DALUtils, isDefined, MathBN } from "@medusajs/framework/utils"
|
import { model } from "@medusajs/framework/utils"
|
||||||
import {
|
import InventoryItem from "./inventory-item"
|
||||||
BeforeCreate,
|
|
||||||
Entity,
|
|
||||||
Filter,
|
|
||||||
ManyToOne,
|
|
||||||
OnInit,
|
|
||||||
OnLoad,
|
|
||||||
PrimaryKey,
|
|
||||||
Property,
|
|
||||||
Rel,
|
|
||||||
} from "@mikro-orm/core"
|
|
||||||
|
|
||||||
import { BigNumberRawValue } from "@medusajs/framework/types"
|
const InventoryLevel = model
|
||||||
import {
|
.define("InventoryLevel", {
|
||||||
BigNumber,
|
id: model.id({ prefix: "ilev" }).primaryKey(),
|
||||||
createPsqlIndexStatementHelper,
|
location_id: model.text(),
|
||||||
generateEntityId,
|
stocked_quantity: model.bigNumber().default(0),
|
||||||
MikroOrmBigNumberProperty,
|
reserved_quantity: model.bigNumber().default(0),
|
||||||
} from "@medusajs/framework/utils"
|
incoming_quantity: model.bigNumber().default(0),
|
||||||
import { InventoryItem } from "./inventory-item"
|
metadata: model.json().nullable(),
|
||||||
|
inventory_item: model.belongsTo(() => InventoryItem, {
|
||||||
const InventoryLevelDeletedAtIndex = createPsqlIndexStatementHelper({
|
mappedBy: "location_levels",
|
||||||
tableName: "inventory_level",
|
}),
|
||||||
columns: "deleted_at",
|
available_quantity: model.bigNumber().computed(),
|
||||||
where: "deleted_at IS NOT NULL",
|
|
||||||
})
|
|
||||||
|
|
||||||
const InventoryLevelInventoryItemIdIndex = createPsqlIndexStatementHelper({
|
|
||||||
tableName: "inventory_level",
|
|
||||||
columns: "inventory_item_id",
|
|
||||||
where: "deleted_at IS NULL",
|
|
||||||
})
|
|
||||||
|
|
||||||
const InventoryLevelLocationIdIndex = createPsqlIndexStatementHelper({
|
|
||||||
tableName: "inventory_level",
|
|
||||||
columns: "location_id",
|
|
||||||
where: "deleted_at IS NULL",
|
|
||||||
})
|
|
||||||
|
|
||||||
const InventoryLevelLocationIdInventoryItemIdIndex =
|
|
||||||
createPsqlIndexStatementHelper({
|
|
||||||
tableName: "inventory_level",
|
|
||||||
columns: ["inventory_item_id", "location_id"],
|
|
||||||
unique: true,
|
|
||||||
where: "deleted_at IS NULL",
|
|
||||||
})
|
})
|
||||||
|
.indexes([
|
||||||
|
{
|
||||||
|
name: "IDX_inventory_level_inventory_item_id",
|
||||||
|
on: ["inventory_item_id"],
|
||||||
|
where: "deleted_at IS NULL",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "IDX_inventory_level_location_id",
|
||||||
|
on: ["location_id"],
|
||||||
|
where: "deleted_at IS NULL",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "IDX_inventory_level_location_id_inventory_item_id",
|
||||||
|
on: ["inventory_item_id", "location_id"],
|
||||||
|
unique: true,
|
||||||
|
where: "deleted_at IS NULL",
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
@Entity()
|
export default InventoryLevel
|
||||||
@InventoryLevelLocationIdInventoryItemIdIndex.MikroORMIndex()
|
|
||||||
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
|
|
||||||
export class InventoryLevel {
|
|
||||||
@PrimaryKey({ columnType: "text" })
|
|
||||||
id: string
|
|
||||||
|
|
||||||
@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
|
|
||||||
|
|
||||||
@InventoryLevelDeletedAtIndex.MikroORMIndex()
|
|
||||||
@Property({ columnType: "timestamptz", nullable: true })
|
|
||||||
deleted_at: Date | null = null
|
|
||||||
|
|
||||||
@ManyToOne(() => InventoryItem, {
|
|
||||||
fieldName: "inventory_item_id",
|
|
||||||
type: "text",
|
|
||||||
mapToPk: true,
|
|
||||||
onDelete: "cascade",
|
|
||||||
})
|
|
||||||
@InventoryLevelInventoryItemIdIndex.MikroORMIndex()
|
|
||||||
inventory_item_id: string
|
|
||||||
|
|
||||||
@InventoryLevelLocationIdIndex.MikroORMIndex()
|
|
||||||
@Property({ type: "text" })
|
|
||||||
location_id: string
|
|
||||||
|
|
||||||
@MikroOrmBigNumberProperty()
|
|
||||||
stocked_quantity: BigNumber | number = 0
|
|
||||||
|
|
||||||
@Property({ columnType: "jsonb" })
|
|
||||||
raw_stocked_quantity: BigNumberRawValue
|
|
||||||
|
|
||||||
@MikroOrmBigNumberProperty()
|
|
||||||
reserved_quantity: BigNumber | number = 0
|
|
||||||
|
|
||||||
@Property({ columnType: "jsonb" })
|
|
||||||
raw_reserved_quantity: BigNumberRawValue
|
|
||||||
|
|
||||||
@MikroOrmBigNumberProperty()
|
|
||||||
incoming_quantity: BigNumber | number = 0
|
|
||||||
|
|
||||||
@Property({ columnType: "jsonb" })
|
|
||||||
raw_incoming_quantity: BigNumberRawValue
|
|
||||||
|
|
||||||
@Property({ columnType: "jsonb", nullable: true })
|
|
||||||
metadata: Record<string, unknown> | null
|
|
||||||
|
|
||||||
@ManyToOne(() => InventoryItem, {
|
|
||||||
persist: false,
|
|
||||||
})
|
|
||||||
inventory_item: Rel<InventoryItem>
|
|
||||||
|
|
||||||
available_quantity: BigNumber | number | null = null
|
|
||||||
|
|
||||||
@BeforeCreate()
|
|
||||||
beforeCreate(): void {
|
|
||||||
this.id = generateEntityId(this.id, "ilev")
|
|
||||||
this.inventory_item_id ??= this.inventory_item?.id
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnInit()
|
|
||||||
onInit(): void {
|
|
||||||
this.id = generateEntityId(this.id, "ilev")
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnLoad()
|
|
||||||
onLoad(): void {
|
|
||||||
if (isDefined(this.stocked_quantity) && isDefined(this.reserved_quantity)) {
|
|
||||||
this.available_quantity = new BigNumber(
|
|
||||||
MathBN.sub(this.raw_stocked_quantity, this.raw_reserved_quantity)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,125 +1,40 @@
|
|||||||
import {
|
import { model } from "@medusajs/framework/utils"
|
||||||
BeforeCreate,
|
import InventoryItem from "./inventory-item"
|
||||||
Entity,
|
|
||||||
Filter,
|
|
||||||
ManyToOne,
|
|
||||||
OnInit,
|
|
||||||
PrimaryKey,
|
|
||||||
Property,
|
|
||||||
Rel,
|
|
||||||
} from "@mikro-orm/core"
|
|
||||||
|
|
||||||
import { BigNumberRawValue } from "@medusajs/framework/types"
|
const ReservationItem = model
|
||||||
import {
|
.define("ReservationItem", {
|
||||||
BigNumber,
|
id: model.id({ prefix: "resitem" }).primaryKey(),
|
||||||
DALUtils,
|
line_item_id: model.text().nullable(),
|
||||||
MikroOrmBigNumberProperty,
|
allow_backorder: model.boolean().default(false),
|
||||||
Searchable,
|
location_id: model.text(),
|
||||||
createPsqlIndexStatementHelper,
|
quantity: model.bigNumber(),
|
||||||
generateEntityId,
|
raw_quantity: model.json(),
|
||||||
} from "@medusajs/framework/utils"
|
external_id: model.text().nullable(),
|
||||||
import { InventoryItem } from "./inventory-item"
|
description: model.text().searchable().nullable(),
|
||||||
|
created_by: model.text().nullable(),
|
||||||
const ReservationItemDeletedAtIndex = createPsqlIndexStatementHelper({
|
metadata: model.json().nullable(),
|
||||||
tableName: "reservation_item",
|
inventory_item: model
|
||||||
columns: "deleted_at",
|
.belongsTo(() => InventoryItem, {
|
||||||
where: "deleted_at IS NOT NULL",
|
mappedBy: "reservation_items",
|
||||||
})
|
})
|
||||||
const ReservationItemLineItemIdIndex = createPsqlIndexStatementHelper({
|
.searchable(),
|
||||||
tableName: "reservation_item",
|
|
||||||
columns: "line_item_id",
|
|
||||||
where: "deleted_at IS NULL",
|
|
||||||
})
|
|
||||||
|
|
||||||
const ReservationItemInventoryItemIdIndex = createPsqlIndexStatementHelper({
|
|
||||||
tableName: "reservation_item",
|
|
||||||
columns: "inventory_item_id",
|
|
||||||
where: "deleted_at IS NULL",
|
|
||||||
})
|
|
||||||
|
|
||||||
const ReservationItemLocationIdIndex = createPsqlIndexStatementHelper({
|
|
||||||
tableName: "reservation_item",
|
|
||||||
columns: "location_id",
|
|
||||||
where: "deleted_at IS NULL",
|
|
||||||
})
|
|
||||||
|
|
||||||
@Entity()
|
|
||||||
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
|
|
||||||
export class ReservationItem {
|
|
||||||
@PrimaryKey({ columnType: "text" })
|
|
||||||
id: string
|
|
||||||
|
|
||||||
@Property({
|
|
||||||
onCreate: () => new Date(),
|
|
||||||
columnType: "timestamptz",
|
|
||||||
defaultRaw: "now()",
|
|
||||||
})
|
})
|
||||||
created_at: Date
|
.indexes([
|
||||||
|
{
|
||||||
|
name: "IDX_reservation_item_line_item_id",
|
||||||
|
on: ["line_item_id"],
|
||||||
|
where: "deleted_at IS NULL",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "IDX_reservation_item_location_id",
|
||||||
|
on: ["location_id"],
|
||||||
|
where: "deleted_at IS NULL",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "IDX_reservation_item_inventory_item_id",
|
||||||
|
on: ["inventory_item_id"],
|
||||||
|
where: "deleted_at IS NULL",
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
@Property({
|
export default ReservationItem
|
||||||
onCreate: () => new Date(),
|
|
||||||
onUpdate: () => new Date(),
|
|
||||||
columnType: "timestamptz",
|
|
||||||
defaultRaw: "now()",
|
|
||||||
})
|
|
||||||
updated_at: Date
|
|
||||||
|
|
||||||
@ReservationItemDeletedAtIndex.MikroORMIndex()
|
|
||||||
@Property({ columnType: "timestamptz", nullable: true })
|
|
||||||
deleted_at: Date | null = null
|
|
||||||
|
|
||||||
@ReservationItemLineItemIdIndex.MikroORMIndex()
|
|
||||||
@Property({ type: "text", nullable: true })
|
|
||||||
line_item_id: string | null = null
|
|
||||||
|
|
||||||
@Property({ type: "boolean" })
|
|
||||||
allow_backorder: boolean = false
|
|
||||||
|
|
||||||
@ReservationItemLocationIdIndex.MikroORMIndex()
|
|
||||||
@Property({ type: "text" })
|
|
||||||
location_id: string
|
|
||||||
|
|
||||||
@MikroOrmBigNumberProperty()
|
|
||||||
quantity: BigNumber | number
|
|
||||||
|
|
||||||
@Property({ columnType: "jsonb" })
|
|
||||||
raw_quantity: BigNumberRawValue
|
|
||||||
|
|
||||||
@Property({ type: "text", nullable: true })
|
|
||||||
external_id: string | null = null
|
|
||||||
|
|
||||||
@Searchable()
|
|
||||||
@Property({ type: "text", nullable: true })
|
|
||||||
description: string | null = null
|
|
||||||
|
|
||||||
@Property({ type: "text", nullable: true })
|
|
||||||
created_by: string | null = null
|
|
||||||
|
|
||||||
@Property({ type: "jsonb", nullable: true })
|
|
||||||
metadata: Record<string, unknown> | null = null
|
|
||||||
|
|
||||||
@ReservationItemInventoryItemIdIndex.MikroORMIndex()
|
|
||||||
@ManyToOne(() => InventoryItem, {
|
|
||||||
fieldName: "inventory_item_id",
|
|
||||||
type: "text",
|
|
||||||
mapToPk: true,
|
|
||||||
onDelete: "cascade",
|
|
||||||
})
|
|
||||||
inventory_item_id: string
|
|
||||||
|
|
||||||
@Searchable()
|
|
||||||
@ManyToOne(() => InventoryItem, {
|
|
||||||
persist: false,
|
|
||||||
})
|
|
||||||
inventory_item: Rel<InventoryItem>
|
|
||||||
|
|
||||||
@BeforeCreate()
|
|
||||||
beforeCreate(): void {
|
|
||||||
this.id = generateEntityId(this.id, "resitem")
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnInit()
|
|
||||||
onInit(): void {
|
|
||||||
this.id = generateEntityId(this.id, "resitem")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
export * from "./inventory-level"
|
|
||||||
export { MikroOrmBaseRepository as BaseRepository } from "@medusajs/framework/utils"
|
export { MikroOrmBaseRepository as BaseRepository } from "@medusajs/framework/utils"
|
||||||
|
export * from "./inventory-level"
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { Context } from "@medusajs/framework/types"
|
import { Context } from "@medusajs/framework/types"
|
||||||
import { BigNumber, ModulesSdkUtils } from "@medusajs/framework/utils"
|
import { BigNumber, ModulesSdkUtils } from "@medusajs/framework/utils"
|
||||||
|
import { applyEntityHooks } from "../utils/apply-decorators"
|
||||||
|
|
||||||
|
import { InventoryLevel } from "@models"
|
||||||
import { InventoryLevelRepository } from "@repositories"
|
import { InventoryLevelRepository } from "@repositories"
|
||||||
import { InventoryLevel } from "../models/inventory-level"
|
|
||||||
|
|
||||||
type InjectedDependencies = {
|
type InjectedDependencies = {
|
||||||
inventoryLevelRepository: InventoryLevelRepository
|
inventoryLevelRepository: InventoryLevelRepository
|
||||||
@@ -10,7 +11,7 @@ type InjectedDependencies = {
|
|||||||
|
|
||||||
export default class InventoryLevelService extends ModulesSdkUtils.MedusaInternalService<
|
export default class InventoryLevelService extends ModulesSdkUtils.MedusaInternalService<
|
||||||
InjectedDependencies,
|
InjectedDependencies,
|
||||||
InventoryLevel
|
typeof InventoryLevel
|
||||||
>(InventoryLevel) {
|
>(InventoryLevel) {
|
||||||
protected readonly inventoryLevelRepository: InventoryLevelRepository
|
protected readonly inventoryLevelRepository: InventoryLevelRepository
|
||||||
|
|
||||||
@@ -67,3 +68,5 @@ export default class InventoryLevelService extends ModulesSdkUtils.MedusaInterna
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applyEntityHooks()
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
Context,
|
Context,
|
||||||
DAL,
|
DAL,
|
||||||
IInventoryService,
|
IInventoryService,
|
||||||
|
InferEntityType,
|
||||||
InternalModuleDeclaration,
|
InternalModuleDeclaration,
|
||||||
InventoryTypes,
|
InventoryTypes,
|
||||||
ModuleJoinerConfig,
|
ModuleJoinerConfig,
|
||||||
@@ -29,6 +30,7 @@ import {
|
|||||||
} from "@medusajs/framework/utils"
|
} from "@medusajs/framework/utils"
|
||||||
import { InventoryItem, InventoryLevel, ReservationItem } from "@models"
|
import { InventoryItem, InventoryLevel, ReservationItem } from "@models"
|
||||||
import { joinerConfig } from "../joiner-config"
|
import { joinerConfig } from "../joiner-config"
|
||||||
|
import { applyEntityHooks } from "../utils/apply-decorators"
|
||||||
import InventoryLevelService from "./inventory-level"
|
import InventoryLevelService from "./inventory-level"
|
||||||
|
|
||||||
type InjectedDependencies = {
|
type InjectedDependencies = {
|
||||||
@@ -46,6 +48,8 @@ type InventoryItemCheckLevel = {
|
|||||||
allow_backorder?: boolean
|
allow_backorder?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applyEntityHooks()
|
||||||
|
|
||||||
export default class InventoryModuleService
|
export default class InventoryModuleService
|
||||||
extends MedusaService<{
|
extends MedusaService<{
|
||||||
InventoryItem: {
|
InventoryItem: {
|
||||||
@@ -66,8 +70,12 @@ export default class InventoryModuleService
|
|||||||
{
|
{
|
||||||
protected baseRepository_: DAL.RepositoryService
|
protected baseRepository_: DAL.RepositoryService
|
||||||
|
|
||||||
protected readonly inventoryItemService_: ModulesSdkTypes.IMedusaInternalService<InventoryItem>
|
protected readonly inventoryItemService_: ModulesSdkTypes.IMedusaInternalService<
|
||||||
protected readonly reservationItemService_: ModulesSdkTypes.IMedusaInternalService<ReservationItem>
|
typeof InventoryItem
|
||||||
|
>
|
||||||
|
protected readonly reservationItemService_: ModulesSdkTypes.IMedusaInternalService<
|
||||||
|
typeof ReservationItem
|
||||||
|
>
|
||||||
protected readonly inventoryLevelService_: InventoryLevelService
|
protected readonly inventoryLevelService_: InventoryLevelService
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@@ -263,7 +271,7 @@ export default class InventoryModuleService
|
|||||||
async createReservationItems_(
|
async createReservationItems_(
|
||||||
input: InventoryTypes.CreateReservationItemInput[],
|
input: InventoryTypes.CreateReservationItemInput[],
|
||||||
@MedusaContext() context: Context = {}
|
@MedusaContext() context: Context = {}
|
||||||
): Promise<ReservationItem[]> {
|
): Promise<InferEntityType<typeof ReservationItem>[]> {
|
||||||
const inventoryLevels = await this.ensureInventoryLevels(
|
const inventoryLevels = await this.ensureInventoryLevels(
|
||||||
input.map(
|
input.map(
|
||||||
({ location_id, inventory_item_id, quantity, allow_backorder }) => ({
|
({ location_id, inventory_item_id, quantity, allow_backorder }) => ({
|
||||||
@@ -417,7 +425,7 @@ export default class InventoryModuleService
|
|||||||
async createInventoryLevels_(
|
async createInventoryLevels_(
|
||||||
input: InventoryTypes.CreateInventoryLevelInput[],
|
input: InventoryTypes.CreateInventoryLevelInput[],
|
||||||
@MedusaContext() context: Context = {}
|
@MedusaContext() context: Context = {}
|
||||||
): Promise<InventoryLevel[]> {
|
): Promise<InferEntityType<typeof InventoryLevel>[]> {
|
||||||
return await this.inventoryLevelService_.create(input, context)
|
return await this.inventoryLevelService_.create(input, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -473,7 +481,7 @@ export default class InventoryModuleService
|
|||||||
id: string
|
id: string
|
||||||
})[],
|
})[],
|
||||||
@MedusaContext() context: Context = {}
|
@MedusaContext() context: Context = {}
|
||||||
): Promise<InventoryItem[]> {
|
): Promise<InferEntityType<typeof InventoryItem>[]> {
|
||||||
return await this.inventoryItemService_.update(input, context)
|
return await this.inventoryItemService_.update(input, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -670,7 +678,7 @@ export default class InventoryModuleService
|
|||||||
async updateReservationItems_(
|
async updateReservationItems_(
|
||||||
input: (InventoryTypes.UpdateReservationItemInput & { id: string })[],
|
input: (InventoryTypes.UpdateReservationItemInput & { id: string })[],
|
||||||
@MedusaContext() context: Context = {}
|
@MedusaContext() context: Context = {}
|
||||||
): Promise<ReservationItem[]> {
|
): Promise<InferEntityType<typeof ReservationItem>[]> {
|
||||||
const ids = input.map((u) => u.id)
|
const ids = input.map((u) => u.id)
|
||||||
const reservationItems = await this.listReservationItems(
|
const reservationItems = await this.listReservationItems(
|
||||||
{ id: ids },
|
{ id: ids },
|
||||||
@@ -989,7 +997,7 @@ export default class InventoryModuleService
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
const results: InventoryLevel[] = []
|
const results: InferEntityType<typeof InventoryLevel>[] = []
|
||||||
|
|
||||||
for (const data of all) {
|
for (const data of all) {
|
||||||
const result = await this.adjustInventory_(
|
const result = await this.adjustInventory_(
|
||||||
@@ -1024,7 +1032,7 @@ export default class InventoryModuleService
|
|||||||
locationId: string,
|
locationId: string,
|
||||||
adjustment: BigNumberInput,
|
adjustment: BigNumberInput,
|
||||||
@MedusaContext() context: Context = {}
|
@MedusaContext() context: Context = {}
|
||||||
): Promise<InventoryLevel> {
|
): Promise<InferEntityType<typeof InventoryLevel>> {
|
||||||
const inventoryLevel = await this.retrieveInventoryLevelByItemAndLocation(
|
const inventoryLevel = await this.retrieveInventoryLevelByItemAndLocation(
|
||||||
inventoryItemId,
|
inventoryItemId,
|
||||||
locationId,
|
locationId,
|
||||||
|
|||||||
45
packages/modules/inventory/src/utils/apply-decorators.ts
Normal file
45
packages/modules/inventory/src/utils/apply-decorators.ts
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import {
|
||||||
|
BigNumber,
|
||||||
|
isDefined,
|
||||||
|
MathBN,
|
||||||
|
toMikroORMEntity,
|
||||||
|
} from "@medusajs/framework/utils"
|
||||||
|
import { Formula, OnInit } from "@mikro-orm/core"
|
||||||
|
|
||||||
|
import InventoryItem from "../models/inventory-item"
|
||||||
|
import InventoryLevel from "../models/inventory-level"
|
||||||
|
|
||||||
|
function applyHook() {
|
||||||
|
const MikroORMEntity = toMikroORMEntity(InventoryLevel)
|
||||||
|
|
||||||
|
MikroORMEntity.prototype["onInit"] = function () {
|
||||||
|
if (isDefined(this.stocked_quantity) && isDefined(this.reserved_quantity)) {
|
||||||
|
this.available_quantity = new BigNumber(
|
||||||
|
MathBN.sub(this.raw_stocked_quantity, this.raw_reserved_quantity)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OnInit()(MikroORMEntity.prototype, "onInit")
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyFormulas() {
|
||||||
|
const MikroORMEntity = toMikroORMEntity(InventoryItem)
|
||||||
|
|
||||||
|
Formula(
|
||||||
|
(item) =>
|
||||||
|
`(SELECT SUM(reserved_quantity) FROM inventory_level il WHERE il.inventory_item_id = ${item}.id AND il.deleted_at IS NULL)`,
|
||||||
|
{ lazy: true, serializer: Number, hidden: true, type: "number" }
|
||||||
|
)(MikroORMEntity.prototype, "reserved_quantity")
|
||||||
|
|
||||||
|
Formula(
|
||||||
|
(item) =>
|
||||||
|
`(SELECT SUM(stocked_quantity) FROM inventory_level il WHERE il.inventory_item_id = ${item}.id AND il.deleted_at IS NULL)`,
|
||||||
|
{ lazy: true, serializer: Number, hidden: true, type: "number" }
|
||||||
|
)(MikroORMEntity.prototype, "stocked_quantity")
|
||||||
|
}
|
||||||
|
|
||||||
|
export const applyEntityHooks = () => {
|
||||||
|
applyHook()
|
||||||
|
applyFormulas()
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user