Skip to content

Commit

Permalink
feat(medusa): Cart and totals improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
adrien2p committed Oct 20, 2022
1 parent 2f00bd1 commit dc56aa5
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,7 @@ export default async (req, res) => {

const cart = await cartService
.withTransaction(manager)
.retrieve(draftOrder.cart_id, {
select: ["total"],
relations: [
"discounts",
"discounts.rule",
"shipping_methods",
"region",
"items",
],
})
.retrieveWithTotals(draftOrder.cart_id)

await paymentProviderService
.withTransaction(manager)
Expand Down
73 changes: 38 additions & 35 deletions packages/medusa/src/services/cart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
Discount,
DiscountRuleType,
LineItem,
LineItemTaxLine,
PaymentSession,
SalesChannel,
ShippingMethod,
Expand Down Expand Up @@ -1432,27 +1433,18 @@ class CartService extends TransactionBaseService {
this.cartRepository_
)

const cart = await this.retrieve(cartId, {
select: ["total"],
relations: [
"items",
"items.adjustments",
"region",
"payment_sessions",
],
const cart = await this.retrieveWithTotals(cartId, {
relations: ["payment_sessions"],
})

if (typeof cart.total === "undefined") {
throw new MedusaError(
MedusaError.Types.UNEXPECTED_STATE,
"cart.total should be defined"
)
}

// If cart total is 0, we don't perform anything payment related
if (cart.total <= 0) {
if (cart.total! <= 0) {
cart.payment_authorized_at = new Date()
return await cartRepository.save(cart)
await cartRepository.save({
id: cart.id,
payment_authorized_at: cart.payment_authorized_at,
})
return cart
}

if (!cart.payment_session) {
Expand All @@ -1466,22 +1458,28 @@ class CartService extends TransactionBaseService {
.withTransaction(transactionManager)
.authorizePayment(cart.payment_session, context)) as PaymentSession

const freshCart = (await this.retrieve(cart.id, {
select: ["total"],
relations: ["payment_sessions", "items", "items.adjustments"],
const freshCart = (await this.retrieveNew(cart.id, {
relations: ["payment_sessions"],
})) as Cart & { payment_session: PaymentSession }

if (session.status === "authorized") {
freshCart.payment = await this.paymentProviderService_
.withTransaction(transactionManager)
.createPayment(freshCart)
.createPayment({
id: cart.id,
region: cart.region,
total: cart.total!,
payment_session: freshCart.payment_session,
})
freshCart.payment_authorized_at = new Date()
}

const updatedCart = await cartRepository.save(freshCart)

await this.eventBus_
.withTransaction(transactionManager)
.emit(CartService.Events.UPDATED, updatedCart)

return updatedCart
}
)
Expand Down Expand Up @@ -2161,19 +2159,8 @@ class CartService extends TransactionBaseService {
async createTaxLines(id: string): Promise<Cart> {
return await this.atomicPhase_(
async (transactionManager: EntityManager) => {
const cart = await this.retrieve(id, {
relations: [
"customer",
"discounts",
"discounts.rule",
"gift_cards",
"items",
"items.adjustments",
"region",
"region.tax_rates",
"shipping_address",
"shipping_methods",
],
const cart = await this.retrieveWithTotals(id, {
relations: ["customer"],
})

const calculationContext = await this.totalsService_
Expand All @@ -2192,7 +2179,7 @@ class CartService extends TransactionBaseService {
async deleteTaxLines(id: string): Promise<void> {
return await this.atomicPhase_(
async (transactionManager: EntityManager) => {
const cart = await this.retrieve(id, {
const cart = await this.retrieveNew(id, {
relations: [
"items",
"items.tax_lines",
Expand All @@ -2215,11 +2202,27 @@ class CartService extends TransactionBaseService {
exclude_shipping: true,
})

const taxLines = await this.taxProviderService_
.withTransaction(this.manager_)
.getTaxLines(cart.items, calculationContext)

const taxLinesMap = new Map<string, LineItemTaxLine[]>()

taxLines.forEach((taxLine) => {
if ("item_id" in taxLine) {
const itemTaxLines = taxLinesMap.get(taxLine.item_id) ?? []
itemTaxLines.push(taxLine)
taxLinesMap.set(taxLine.item_id, itemTaxLines)
}
})

cart.items = await Promise.all(
(cart.items || []).map(async (item) => {
const tax_lines = taxLinesMap.get(item.id)
const itemTotals = await totalsService.getLineItemTotals(item, cart, {
include_tax: totalsConfig?.force_taxes || cart.region.automatic_taxes,
calculation_context: calculationContext,
tax_lines,
})

return Object.assign(item, itemTotals)
Expand Down
14 changes: 9 additions & 5 deletions packages/medusa/src/services/payment-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
PaymentSession,
PaymentSessionStatus,
Refund,
Region,
} from "../models"

type PaymentProviderKey = `pp_${string}` | "systemPaymentProviderService"
Expand Down Expand Up @@ -298,11 +299,14 @@ export default class PaymentProviderService extends TransactionBaseService {
}
}

async createPayment(
cart: Cart & { payment_session: PaymentSession }
): Promise<Payment> {
async createPayment(data: {
id: string
total: number
region: Region
payment_session: PaymentSession
}): Promise<Payment> {
return await this.atomicPhase_(async (transactionManager) => {
const { payment_session: paymentSession, region, total } = cart
const { payment_session: paymentSession, region, total } = data

const provider = this.retrieveProvider(paymentSession.provider_id)
const paymentData = await provider
Expand All @@ -318,7 +322,7 @@ export default class PaymentProviderService extends TransactionBaseService {
amount: total,
currency_code: region.currency_code,
data: paymentData,
cart_id: cart.id,
cart_id: data.id,
})

return paymentRepo.save(created)
Expand Down
1 change: 1 addition & 0 deletions packages/medusa/src/services/tax-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ class TaxProviderService extends TransactionBaseService {
lineItems: LineItem[],
calculationContext: TaxCalculationContext
): Promise<(ShippingMethodTaxLine | LineItemTaxLine)[]> {
console.log("getTaxLines")
const calculationLines = await Promise.all(
lineItems.map(async (l) => {
if (l.is_return) {
Expand Down
4 changes: 4 additions & 0 deletions packages/medusa/src/services/totals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ type LineItemTotalsOptions = {
use_tax_lines?: boolean
exclude_gift_cards?: boolean
calculation_context?: TaxCalculationContext
tax_lines?: (ShippingMethodTaxLine | LineItemTaxLine)[]
}

type GetLineItemTotalOptions = {
Expand Down Expand Up @@ -816,6 +817,9 @@ class TotalsService extends TransactionBaseService {

lineItemTotals.total += lineItemTotals.tax_total
lineItemTotals.original_total += lineItemTotals.original_tax_total
} else if (options.tax_lines) {
// If the consumer giving us the tax lines then use them
lineItemTotals.tax_lines = options.tax_lines as LineItemTaxLine[]
} else {
let taxLines: LineItemTaxLine[]

Expand Down
2 changes: 1 addition & 1 deletion packages/medusa/src/strategies/cart-completion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class CartCompletionStrategy extends AbstractCartCompletionStrategy {
.workStage(idempotencyKey.idempotency_key, async (manager) => {
const cart = await cartService
.withTransaction(manager)
.retrieve(id)
.retrieveWithTotals(id)

if (cart.completed_at) {
return {
Expand Down

0 comments on commit dc56aa5

Please sign in to comment.