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:
Kasper Fabricius Kristensen
2022-03-18 15:18:50 +01:00
committed by GitHub
co-authored by Philip Korsholm Sebastian Rindom
parent 23f8399c16
commit 5300926db8
52 changed files with 4234 additions and 505 deletions
+17 -17
View File
@@ -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
+30 -8
View File
@@ -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."
+127
View File
@@ -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
*/