feat: Implement PriceList and extend MoneyAmount (#1152)
* init * added buld id validation to repo * admin done * updated price reqs * intial implementation of PriceList * integration tests for price lists * updated admin/product integration tests * update updateVariantPrices method * remove comment from error handler * add integration test for batch deleting prices associated with price list * make update to prices through variant service limited to default prices * update store/products.js snapshot * add api unit tests and update product integration tests to validate that prices from Price List are ignored * fix product test * requested changes * cascade * ensure delete variant cascades to MoneyAmount * addresses PR feedback * removed unused endpoint * update mock * fix failing store integration tests * remove medusajs ressource * re add env.template * Update integration-tests/api/__tests__/admin/price-list.js Co-authored-by: Philip Korsholm <88927411+pKorsholm@users.noreply.github.com> * Update integration-tests/api/__tests__/admin/price-list.js Co-authored-by: Philip Korsholm <88927411+pKorsholm@users.noreply.github.com> * fix: update snapshots Co-authored-by: Sebastian Rindom <skrindom@gmail.com> Co-authored-by: Philip Korsholm <88927411+pKorsholm@users.noreply.github.com>
This commit is contained in:
co-authored by
Philip Korsholm
Sebastian Rindom
parent
23f8399c16
commit
5300926db8
@@ -5,14 +5,14 @@ import {
|
||||
DeleteDateColumn,
|
||||
Entity,
|
||||
Index,
|
||||
JoinTable,
|
||||
ManyToMany,
|
||||
PrimaryColumn,
|
||||
UpdateDateColumn,
|
||||
UpdateDateColumn
|
||||
} from "typeorm"
|
||||
import { ulid } from "ulid"
|
||||
import { Customer } from ".."
|
||||
import { DbAwareColumn, resolveDbType } from "../utils/db-aware-column"
|
||||
import { Customer } from "./customer"
|
||||
import { PriceList } from "./price-list"
|
||||
|
||||
@Entity()
|
||||
export class CustomerGroup {
|
||||
@@ -23,22 +23,22 @@ export class CustomerGroup {
|
||||
@Column()
|
||||
name: string
|
||||
|
||||
@ManyToMany(() => Customer, (customer) => customer.groups, {
|
||||
onDelete: "CASCADE",
|
||||
})
|
||||
@JoinTable({
|
||||
name: "customer_group_customers",
|
||||
joinColumn: {
|
||||
name: "customer_group_id",
|
||||
referencedColumnName: "id",
|
||||
},
|
||||
inverseJoinColumn: {
|
||||
name: "customer_id",
|
||||
referencedColumnName: "id",
|
||||
},
|
||||
})
|
||||
@ManyToMany(
|
||||
() => Customer,
|
||||
(customer) => customer.groups,
|
||||
{
|
||||
onDelete: "CASCADE",
|
||||
}
|
||||
)
|
||||
customers: Customer[]
|
||||
|
||||
@ManyToMany(
|
||||
() => PriceList,
|
||||
(priceList) => priceList.customer_groups,
|
||||
{ onDelete: "CASCADE" }
|
||||
)
|
||||
price_lists: PriceList[]
|
||||
|
||||
@CreateDateColumn({ type: resolveDbType("timestamptz") })
|
||||
created_at: Date
|
||||
|
||||
|
||||
@@ -8,11 +8,12 @@ import {
|
||||
JoinColumn,
|
||||
ManyToOne,
|
||||
PrimaryColumn,
|
||||
UpdateDateColumn,
|
||||
UpdateDateColumn
|
||||
} from "typeorm"
|
||||
import { ulid } from "ulid"
|
||||
import { resolveDbType } from "../utils/db-aware-column"
|
||||
import { Currency } from "./currency"
|
||||
import { PriceList } from "./price-list"
|
||||
import { ProductVariant } from "./product-variant"
|
||||
import { Region } from "./region"
|
||||
|
||||
@@ -31,16 +32,34 @@ export class MoneyAmount {
|
||||
@Column({ type: "int" })
|
||||
amount: number
|
||||
|
||||
@Column({ type: "int", nullable: true, default: null })
|
||||
sale_amount?: number
|
||||
@Column({ type: "int", nullable: true })
|
||||
min_quantity: number | null
|
||||
|
||||
@Column({ type: "int", nullable: true })
|
||||
max_quantity: number | null
|
||||
|
||||
@Column({ nullable: true })
|
||||
price_list_id: string | null
|
||||
|
||||
@ManyToOne(
|
||||
() => PriceList,
|
||||
(priceList) => priceList.prices,
|
||||
{ cascade: true, onDelete: "CASCADE" }
|
||||
)
|
||||
@JoinColumn({ name: "price_list_id" })
|
||||
price_list: PriceList | null
|
||||
|
||||
@Index()
|
||||
@Column({ nullable: true })
|
||||
variant_id: string
|
||||
|
||||
@ManyToOne(() => ProductVariant, (variant) => variant.prices, {
|
||||
onDelete: "CASCADE",
|
||||
})
|
||||
@ManyToOne(
|
||||
() => ProductVariant,
|
||||
(variant) => variant.prices,
|
||||
{
|
||||
onDelete: "CASCADE",
|
||||
}
|
||||
)
|
||||
@JoinColumn({ name: "variant_id" })
|
||||
variant: ProductVariant
|
||||
|
||||
@@ -86,8 +105,11 @@ export class MoneyAmount {
|
||||
* amount:
|
||||
* description: "The amount in the smallest currecny unit (e.g. cents 100 cents to charge $1) that the Product Variant will cost."
|
||||
* type: integer
|
||||
* sale_amount:
|
||||
* description: "An optional sale amount that the Product Variant will be available for when defined."
|
||||
* min_quantity:
|
||||
* description: "The minimum quantity that the Money Amount applies to. If this value is not set, the Money Amount applies to all quantities."
|
||||
* type: integer
|
||||
* max_quantity:
|
||||
* description: "The maximum quantity that the Money Amount applies to. If this value is not set, the Money Amount applies to all quantities."
|
||||
* type: integer
|
||||
* variant_id:
|
||||
* description: "The id of the Product Variant that the Money Amount belongs to."
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
import {
|
||||
BeforeInsert,
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
DeleteDateColumn,
|
||||
Entity,
|
||||
JoinTable,
|
||||
ManyToMany,
|
||||
OneToMany,
|
||||
PrimaryColumn,
|
||||
UpdateDateColumn
|
||||
} from "typeorm"
|
||||
import { ulid } from "ulid"
|
||||
import { PriceListStatus, PriceListType } from "../types/price-list"
|
||||
import { DbAwareColumn, resolveDbType } from "../utils/db-aware-column"
|
||||
import { CustomerGroup } from "./customer-group"
|
||||
import { MoneyAmount } from "./money-amount"
|
||||
|
||||
@Entity()
|
||||
export class PriceList {
|
||||
@PrimaryColumn()
|
||||
id: string
|
||||
|
||||
@Column()
|
||||
name: string
|
||||
|
||||
@Column()
|
||||
description: string
|
||||
|
||||
@DbAwareColumn({ type: "enum", enum: PriceListType, default: "sale" })
|
||||
type: PriceListType
|
||||
|
||||
@DbAwareColumn({ type: "enum", enum: PriceListStatus, default: "draft" })
|
||||
status: PriceListStatus
|
||||
|
||||
@Column({
|
||||
type: resolveDbType("timestamptz"),
|
||||
nullable: true,
|
||||
})
|
||||
starts_at: Date
|
||||
|
||||
@Column({ type: resolveDbType("timestamptz"), nullable: true })
|
||||
ends_at: Date
|
||||
|
||||
@JoinTable({
|
||||
name: "price_list_customer_groups",
|
||||
joinColumn: {
|
||||
name: "price_list_id",
|
||||
referencedColumnName: "id",
|
||||
},
|
||||
inverseJoinColumn: {
|
||||
name: "customer_group_id",
|
||||
referencedColumnName: "id",
|
||||
},
|
||||
})
|
||||
@ManyToMany(
|
||||
() => CustomerGroup,
|
||||
(cg) => cg.price_lists,
|
||||
{ onDelete: "CASCADE" }
|
||||
)
|
||||
customer_groups: CustomerGroup[]
|
||||
|
||||
@OneToMany(
|
||||
() => MoneyAmount,
|
||||
(moneyAmount) => moneyAmount.price_list,
|
||||
{ onDelete: "CASCADE" }
|
||||
)
|
||||
prices: MoneyAmount[]
|
||||
|
||||
@CreateDateColumn({ type: resolveDbType("timestamptz") })
|
||||
created_at: Date
|
||||
|
||||
@UpdateDateColumn({ type: resolveDbType("timestamptz") })
|
||||
updated_at: Date
|
||||
|
||||
@DeleteDateColumn({ type: resolveDbType("timestamptz") })
|
||||
deleted_at: Date
|
||||
|
||||
@BeforeInsert()
|
||||
private beforeInsert(): undefined | void {
|
||||
if (this.id) {
|
||||
return
|
||||
}
|
||||
const id = ulid()
|
||||
this.id = `pl_${id}`
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @schema price_list
|
||||
* title: "Price List"
|
||||
* description: "Price Lists represents a set of prices that overrides the default price for one or more product variants."
|
||||
* x-resourceId: price_list
|
||||
* properties:
|
||||
* id:
|
||||
* description: "The id of the Price List. This value will be prefixed by `pl_`."
|
||||
* type: string
|
||||
* type:
|
||||
* description: "The type of Price List. This can be one of either `sale` or `override`."
|
||||
* type: string
|
||||
* enum:
|
||||
* - sale
|
||||
* - override
|
||||
* starts_at:
|
||||
* description: "The date with timezone that the Price List starts being valid."
|
||||
* type: date-time
|
||||
* ends_at:
|
||||
* description: "The date with timezone that the Price List stops being valid."
|
||||
* type: date-time
|
||||
* customer_groups:
|
||||
* description: "The Customer Groups that the Price List applies to."
|
||||
* type: array
|
||||
* items:
|
||||
* $ref: "#/components/schemas/customer_group"
|
||||
* created_at:
|
||||
* description: "The date with timezone at which the resource was created."
|
||||
* type: string
|
||||
* format: date-time
|
||||
* updated_at:
|
||||
* description: "The date with timezone at which the resource was last updated."
|
||||
* type: string
|
||||
* format: date-time
|
||||
* deleted_at:
|
||||
* description: "The date with timezone at which the resource was deleted."
|
||||
* type: string
|
||||
* format: date-time
|
||||
*/
|
||||
Reference in New Issue
Block a user