feat(medusa): Add line item totals to cart totals decoration (#1740)

This commit is contained in:
Sebastian Rindom
2022-06-28 12:11:47 +02:00
committed by GitHub
parent 2a32609b74
commit c6dc9086cf
20 changed files with 334 additions and 48 deletions
@@ -3,6 +3,7 @@ import { EntityManager } from "typeorm"
import { defaultStoreCartFields, defaultStoreCartRelations } from "."
import { CartService } from "../../../../services"
import { validator } from "../../../../utils/validator"
import { decorateLineItemsWithTotals } from "./decorate-line-items-with-totals"
/**
* @oas [post] /carts/{id}/shipping-methods
@@ -59,7 +60,9 @@ export default async (req, res) => {
relations: defaultStoreCartRelations,
})
res.status(200).json({ cart: updatedCart })
const data = await decorateLineItemsWithTotals(updatedCart, req)
res.status(200).json({ cart: data })
}
export class StorePostCartsCartShippingMethodReq {
@@ -1,6 +1,7 @@
import { EntityManager } from "typeorm"
import { IdempotencyKey } from "../../../../models/idempotency-key"
import { CartService, IdempotencyKeyService } from "../../../../services"
import { decorateLineItemsWithTotals } from "./decorate-line-items-with-totals"
/**
* @oas [post] /carts/{id}/taxes
@@ -64,6 +65,7 @@ export default async (req, res) => {
const cart = await cartService.withTransaction(manager).retrieve(
id,
{
relations: ["items", "items.adjustments"],
select: [
"total",
"subtotal",
@@ -76,9 +78,13 @@ export default async (req, res) => {
{ force_taxes: true }
)
const data = await decorateLineItemsWithTotals(cart, req, {
force_taxes: true,
})
return {
response_code: 200,
response_body: { cart },
response_body: { cart: data },
}
}
)
@@ -15,6 +15,7 @@ import { defaultStoreCartFields, defaultStoreCartRelations } from "."
import { CartService, LineItemService } from "../../../../services"
import { validator } from "../../../../utils/validator"
import { AddressPayload } from "../../../../types/common"
import { decorateLineItemsWithTotals } from "./decorate-line-items-with-totals"
/**
* @oas [post] /carts
@@ -144,7 +145,9 @@ export default async (req, res) => {
relations: defaultStoreCartRelations,
})
res.status(200).json({ cart })
const data = await decorateLineItemsWithTotals(cart, req)
res.status(200).json({ cart: data })
})
}
@@ -3,6 +3,7 @@ import { EntityManager } from "typeorm"
import { defaultStoreCartFields, defaultStoreCartRelations } from "."
import { CartService, LineItemService } from "../../../../services"
import { validator } from "../../../../utils/validator"
import { decorateLineItemsWithTotals } from "./decorate-line-items-with-totals"
/**
* @oas [post] /carts/{id}/line-items
@@ -63,7 +64,9 @@ export default async (req, res) => {
relations: defaultStoreCartRelations,
})
res.status(200).json({ cart })
const data = await decorateLineItemsWithTotals(cart, req)
res.status(200).json({ cart: data })
}
export class StorePostCartsCartLineItemsReq {
@@ -1,5 +1,6 @@
import { defaultStoreCartFields, defaultStoreCartRelations } from "."
import { CartService } from "../../../../services"
import { decorateLineItemsWithTotals } from "./decorate-line-items-with-totals"
/**
* @oas [post] /carts/{id}/payment-sessions
@@ -32,5 +33,6 @@ export default async (req, res) => {
relations: defaultStoreCartRelations,
})
res.status(200).json({ cart })
const data = await decorateLineItemsWithTotals(cart, req)
res.status(200).json({ cart: data })
}
@@ -0,0 +1,27 @@
import { Request } from "express"
import { TotalsService } from "../../../../services"
import { Cart, LineItem } from "../../../../models"
export const decorateLineItemsWithTotals = async (
cart: Cart,
req: Request,
options: { force_taxes: boolean } = { force_taxes: false }
): Promise<Cart> => {
const totalsService: TotalsService = req.scope.resolve("totalsService")
if (cart.items && cart.region) {
const items = await Promise.all(
cart.items.map(async (item: LineItem) => {
const itemTotals = await totalsService.getLineItemTotals(item, cart, {
include_tax: options.force_taxes || cart.region.automatic_taxes,
})
return Object.assign(item, itemTotals)
})
)
return Object.assign(cart, { items })
}
return cart
}
@@ -1,6 +1,7 @@
import { EntityManager } from "typeorm"
import { defaultStoreCartFields, defaultStoreCartRelations } from "."
import { CartService } from "../../../../services"
import { decorateLineItemsWithTotals } from "./decorate-line-items-with-totals"
/**
* @oas [delete] /carts/{id}/discounts/{code}
@@ -46,6 +47,7 @@ export default async (req, res) => {
select: defaultStoreCartFields,
relations: defaultStoreCartRelations,
})
const data = await decorateLineItemsWithTotals(cart, req)
res.status(200).json({ cart })
res.status(200).json({ cart: data })
}
@@ -1,6 +1,7 @@
import { EntityManager } from "typeorm"
import { defaultStoreCartFields, defaultStoreCartRelations } from "."
import { CartService } from "../../../../services"
import { decorateLineItemsWithTotals } from "./decorate-line-items-with-totals"
/**
* @oas [delete] /carts/{id}/line-items/{line_id}
@@ -46,6 +47,7 @@ export default async (req, res) => {
select: defaultStoreCartFields,
relations: defaultStoreCartRelations,
})
const data = await decorateLineItemsWithTotals(cart, req)
res.status(200).json({ cart })
res.status(200).json({ cart: data })
}
@@ -1,5 +1,6 @@
import { defaultStoreCartFields, defaultStoreCartRelations } from "."
import { CartService } from "../../../../services"
import { decorateLineItemsWithTotals } from "./decorate-line-items-with-totals"
/**
* @oas [delete] /carts/{id}/payment-sessions/{provider_id}
@@ -32,5 +33,6 @@ export default async (req, res) => {
relations: defaultStoreCartRelations,
})
res.status(200).json({ cart })
const data = await decorateLineItemsWithTotals(cart, req)
res.status(200).json({ cart: data })
}
@@ -1,5 +1,6 @@
import { defaultStoreCartFields, defaultStoreCartRelations } from "."
import { CartService } from "../../../../services"
import { decorateLineItemsWithTotals } from "./decorate-line-items-with-totals"
/**
* @oas [get] /carts/{id}
@@ -47,5 +48,6 @@ export default async (req, res) => {
relations: defaultStoreCartRelations,
})
res.json({ cart })
const data = await decorateLineItemsWithTotals(cart, req)
res.json({ cart: data })
}
@@ -1,4 +1,5 @@
import { CartService } from "../../../../services"
import { decorateLineItemsWithTotals } from "./decorate-line-items-with-totals"
/**
* @oas [post] /carts/{id}/payment-sessions/{provider_id}/refresh
@@ -44,5 +45,6 @@ export default async (req, res) => {
],
})
res.status(200).json({ cart })
const data = await decorateLineItemsWithTotals(cart, req)
res.status(200).json({ cart: data })
}
@@ -2,6 +2,7 @@ import { IsString } from "class-validator"
import { defaultStoreCartFields, defaultStoreCartRelations } from "."
import { CartService } from "../../../../services"
import { validator } from "../../../../utils/validator"
import { decorateLineItemsWithTotals } from "./decorate-line-items-with-totals"
/**
* @oas [post] /carts/{id}/payment-session
@@ -39,7 +40,8 @@ export default async (req, res) => {
relations: defaultStoreCartRelations,
})
res.status(200).json({ cart })
const data = await decorateLineItemsWithTotals(cart, req)
res.status(200).json({ cart: data })
}
export class StorePostCartsCartPaymentSessionReq {
@@ -12,6 +12,7 @@ import { CartUpdateProps } from "../../../../types/cart"
import { AddressPayload } from "../../../../types/common"
import { validator } from "../../../../utils/validator"
import { IsType } from "../../../../utils/validators/is-type"
import { decorateLineItemsWithTotals } from "./decorate-line-items-with-totals"
/**
* @oas [post] /store/carts/{id}
@@ -118,8 +119,9 @@ export default async (req, res) => {
select: defaultStoreCartFields,
relations: defaultStoreCartRelations,
})
const data = await decorateLineItemsWithTotals(cart, req)
res.json({ cart })
res.json({ cart: data })
}
class GiftCard {
@@ -4,6 +4,7 @@ import { EntityManager } from "typeorm"
import { defaultStoreCartFields, defaultStoreCartRelations } from "."
import { CartService } from "../../../../services"
import { validator } from "../../../../utils/validator"
import { decorateLineItemsWithTotals } from "./decorate-line-items-with-totals"
/**
* @oas [post] /carts/{id}/line-items/{line_id}
@@ -78,8 +79,9 @@ export default async (req, res) => {
select: defaultStoreCartFields,
relations: defaultStoreCartRelations,
})
const data = await decorateLineItemsWithTotals(cart, req)
res.status(200).json({ cart })
res.status(200).json({ cart: data })
}
export class StorePostCartsCartLineItemsItemReq {
@@ -2,6 +2,7 @@ import { IsObject } from "class-validator"
import { defaultStoreCartFields, defaultStoreCartRelations } from "."
import { CartService } from "../../../../services"
import { validator } from "../../../../utils/validator"
import { decorateLineItemsWithTotals } from "./decorate-line-items-with-totals"
/**
* @oas [post] /carts/{id}/payment-sessions/{provider_id}
@@ -41,8 +42,9 @@ export default async (req, res) => {
select: defaultStoreCartFields,
relations: defaultStoreCartRelations,
})
const data = await decorateLineItemsWithTotals(cart, req)
res.status(200).json({ cart })
res.status(200).json({ cart: data })
}
export class StorePostCartsCartPaymentSessionUpdateReq {
+16 -29
View File
@@ -30,10 +30,7 @@ export class LineItem extends BaseEntity {
@Column({ nullable: true })
cart_id: string
@ManyToOne(
() => Cart,
(cart) => cart.items
)
@ManyToOne(() => Cart, (cart) => cart.items)
@JoinColumn({ name: "cart_id" })
cart: Cart
@@ -41,10 +38,7 @@ export class LineItem extends BaseEntity {
@Column({ nullable: true })
order_id: string
@ManyToOne(
() => Order,
(order) => order.items
)
@ManyToOne(() => Order, (order) => order.items)
@JoinColumn({ name: "order_id" })
order: Order
@@ -52,10 +46,7 @@ export class LineItem extends BaseEntity {
@Column({ nullable: true })
swap_id: string
@ManyToOne(
() => Swap,
(swap) => swap.additional_items
)
@ManyToOne(() => Swap, (swap) => swap.additional_items)
@JoinColumn({ name: "swap_id" })
swap: Swap
@@ -63,27 +54,16 @@ export class LineItem extends BaseEntity {
@Column({ nullable: true })
claim_order_id: string
@ManyToOne(
() => ClaimOrder,
(co) => co.additional_items
)
@ManyToOne(() => ClaimOrder, (co) => co.additional_items)
@JoinColumn({ name: "claim_order_id" })
claim_order: ClaimOrder
@OneToMany(
() => LineItemTaxLine,
(tl) => tl.item,
{ cascade: ["insert"] }
)
@OneToMany(() => LineItemTaxLine, (tl) => tl.item, { cascade: ["insert"] })
tax_lines: LineItemTaxLine[]
@OneToMany(
() => LineItemAdjustment,
(lia) => lia.item,
{
cascade: ["insert"],
}
)
@OneToMany(() => LineItemAdjustment, (lia) => lia.item, {
cascade: ["insert"],
})
adjustments: LineItemAdjustment[]
@Column()
@@ -136,7 +116,14 @@ export class LineItem extends BaseEntity {
@DbAwareColumn({ type: "jsonb", nullable: true })
metadata: Record<string, unknown>
refundable: number | null
refundable?: number | null
subtotal?: number | null
tax_total?: number | null
total?: number | null
original_total?: number | null
original_tax_total?: number | null
discount_total?: number | null
gift_card_total?: number | null
@BeforeInsert()
private beforeInsert(): void {
+4 -3
View File
@@ -1,4 +1,4 @@
import _ from "lodash"
import { isEmpty, isEqual } from "lodash"
import { MedusaError, Validator } from "medusa-core-utils"
import { DeepPartial, EntityManager, In } from "typeorm"
import { TransactionBaseService } from "../interfaces"
@@ -546,7 +546,7 @@ class CartService extends TransactionBaseService<CartService> {
if (lineItem.should_merge) {
currentItem = cart.items.find((item) => {
if (item.should_merge && item.variant_id === lineItem.variant_id) {
return _.isEqual(item.metadata, lineItem.metadata)
return isEqual(item.metadata, lineItem.metadata)
}
return false
})
@@ -1786,7 +1786,7 @@ class CartService extends TransactionBaseService<CartService> {
let updated = { ...shippingAddress }
// If the country code of a shipping address is set we need to clear it
if (!_.isEmpty(shippingAddress) && shippingAddress.country_code) {
if (!isEmpty(shippingAddress) && shippingAddress.country_code) {
updated = {
...updated,
country_code: null,
@@ -1938,6 +1938,7 @@ class CartService extends TransactionBaseService<CartService> {
"region.tax_rates",
],
})
const calculationContext = this.totalsService_
.withTransaction(transactionManager)
.getCalculationContext(cart)
-1
View File
@@ -689,7 +689,6 @@ class TotalsService extends BaseService {
const calculationContext = this.getCalculationContext(cartOrOrder, {
exclude_shipping: true,
})
const lineItemAllocation =
calculationContext.allocation_map[lineItem.id] || {}