fix(medusa): Include adjustments when authorizing payment (#1697)

This commit is contained in:
Oliver Windall Juhl
2022-06-19 12:58:47 +02:00
committed by GitHub
parent 4be7d40771
commit 6b23208d63
6 changed files with 92 additions and 34 deletions
+51 -12
View File
@@ -486,7 +486,8 @@ describe("/store/carts", () => {
regions: ["test-region"], regions: ["test-region"],
} }
let discountCart, discount let discountCart
let discount
beforeEach(async () => { beforeEach(async () => {
try { try {
discount = await simpleDiscountFactory( discount = await simpleDiscountFactory(
@@ -718,15 +719,17 @@ describe("/store/carts", () => {
) )
.catch((err) => console.log(err)) .catch((err) => console.log(err))
expect(response.data.cart.items).toEqual([ expect(response.data.cart.items).toEqual(
expect.objectContaining({ expect.arrayContaining([
cart_id: "test-cart-3", expect.objectContaining({
unit_price: 8000, cart_id: "test-cart-3",
variant_id: "test-variant-sale-cg", unit_price: 8000,
quantity: 3, variant_id: "test-variant-sale-cg",
adjustments: [], quantity: 3,
}), adjustments: [],
]) }),
])
)
}) })
it("updates line item of a cart containing a total fixed discount", async () => { it("updates line item of a cart containing a total fixed discount", async () => {
@@ -1363,7 +1366,14 @@ describe("/store/carts", () => {
.catch((error) => console.log(error)) .catch((error) => console.log(error))
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.cart.items[0].unit_price).toEqual(500) expect(response.data.cart.items).toEqual(
expect.arrayContaining([
expect.objectContaining({
variant_id: "test-variant-sale-cg",
unit_price: 500,
}),
])
)
}) })
it("updates prices when cart region id is updated", async () => { it("updates prices when cart region id is updated", async () => {
@@ -1479,11 +1489,38 @@ describe("/store/carts", () => {
const getRes = await api.post(`/store/carts/test-cart-2/complete-cart`) const getRes = await api.post(`/store/carts/test-cart-2/complete-cart`)
expect(getRes.status).toEqual(200) expect(getRes.status).toEqual(200)
expect(getRes.data.type).toEqual("order")
const variantRes = await api.get("/store/variants/test-variant") const variantRes = await api.get("/store/variants/test-variant")
expect(variantRes.data.variant.inventory_quantity).toEqual(0) expect(variantRes.data.variant.inventory_quantity).toEqual(0)
}) })
it("calculates correct payment totals on cart completion taking into account line item adjustments", async () => {
const api = useApi()
await api.post("/store/carts/test-cart-3", {
discounts: [{ code: "CREATED" }],
})
const createdOrder = await api.post(
`/store/carts/test-cart-3/complete-cart`
)
expect(createdOrder.data.type).toEqual("order")
expect(createdOrder.data.data.discount_total).toEqual(10000)
expect(createdOrder.data.data.subtotal).toEqual(16000)
expect(createdOrder.data.data.total).toEqual(6000)
expect(createdOrder.data.data.payments).toEqual(
expect.arrayContaining([
expect.objectContaining({
amount: 6000,
}),
])
)
expect(createdOrder.status).toEqual(200)
})
it("returns early, if cart is already completed", async () => { it("returns early, if cart is already completed", async () => {
const manager = dbConnection.manager const manager = dbConnection.manager
const api = useApi() const api = useApi()
@@ -1739,7 +1776,9 @@ describe("/store/carts", () => {
.catch((err) => console.log(err)) .catch((err) => console.log(err))
// Ensure that the discount is only applied to the standard item // Ensure that the discount is only applied to the standard item
const itemId = cartWithGiftcard.data.cart.items.find(item => !item.is_giftcard).id const itemId = cartWithGiftcard.data.cart.items.find(
(item) => !item.is_giftcard
).id
expect(cartWithGiftcard.data.cart.items).toEqual( expect(cartWithGiftcard.data.cart.items).toEqual(
expect.arrayContaining([ expect.arrayContaining([
expect.objectContaining({ expect.objectContaining({
+19 -1
View File
@@ -50,6 +50,7 @@ module.exports = async (connection, data = {}) => {
const r = manager.create(Region, { const r = manager.create(Region, {
id: "test-region", id: "test-region",
name: "Test Region", name: "Test Region",
payment_providers: [{ id: "test-pay" }],
currency_code: "usd", currency_code: "usd",
tax_rate: 0, tax_rate: 0,
}) })
@@ -819,6 +820,23 @@ module.exports = async (connection, data = {}) => {
completed_at: null, completed_at: null,
items: [], items: [],
}) })
await manager.save(cart3)
const ps = manager.create(PaymentSession, {
id: "test-cart-session",
cart_id: "test-cart-3",
provider_id: "test-pay",
is_selected: true,
data: {},
status: "authorized",
})
await manager.save(ps)
cart3.payment_sessions = [ps]
cart3.payment_session = ps
await manager.save(cart3) await manager.save(cart3)
await manager.insert(ShippingMethod, { await manager.insert(ShippingMethod, {
@@ -842,7 +860,7 @@ module.exports = async (connection, data = {}) => {
await manager.save(li2) await manager.save(li2)
const cart4 = manager.create(Cart, { const cart4 = manager.create(Cart, {
id: "test-cart-3", id: "test-cart-4",
email: "some-customer@email.com", email: "some-customer@email.com",
shipping_address: { shipping_address: {
id: "test-shipping-address", id: "test-shipping-address",
@@ -8,10 +8,10 @@ import {
} from "class-validator" } from "class-validator"
import { defaultStoreCartFields, defaultStoreCartRelations } from "." import { defaultStoreCartFields, defaultStoreCartRelations } from "."
import { CartService } from "../../../../services" import { CartService } from "../../../../services"
import { AddressPayload } from "../../../../types/common"
import { CartUpdateProps } from "../../../../types/cart" import { CartUpdateProps } from "../../../../types/cart"
import { IsType } from "../../../../utils/validators/is-type" import { AddressPayload } from "../../../../types/common"
import { validator } from "../../../../utils/validator" import { validator } from "../../../../utils/validator"
import { IsType } from "../../../../utils/validators/is-type"
/** /**
* @oas [post] /store/carts/{id} * @oas [post] /store/carts/{id}
@@ -90,7 +90,7 @@ export default async (req, res) => {
// Update the cart // Update the cart
const { shipping_address, billing_address, ...rest } = validated const { shipping_address, billing_address, ...rest } = validated
const cartDataToUpdate: CartUpdateProps = { ...rest }; const cartDataToUpdate: CartUpdateProps = { ...rest }
if (typeof shipping_address === "string") { if (typeof shipping_address === "string") {
cartDataToUpdate.shipping_address_id = shipping_address cartDataToUpdate.shipping_address_id = shipping_address
} else { } else {
@@ -1,8 +1,8 @@
import LineItemAdjustmentService from "../line-item-adjustment" import { MockManager, MockRepository } from "medusa-test-utils"
import { MockManager, MockRepository, IdMap } from "medusa-test-utils"
import { EventBusServiceMock } from "../__mocks__/event-bus"
import { DiscountServiceMock } from "../__mocks__/discount"
import { In } from "typeorm" import { In } from "typeorm"
import LineItemAdjustmentService from "../line-item-adjustment"
import { DiscountServiceMock } from "../__mocks__/discount"
import { EventBusServiceMock } from "../__mocks__/event-bus"
describe("LineItemAdjustmentService", () => { describe("LineItemAdjustmentService", () => {
describe("list", () => { describe("list", () => {
@@ -101,7 +101,7 @@ describe("LineItemAdjustmentService", () => {
} }
const lineItemAdjustmentRepo = MockRepository({ const lineItemAdjustmentRepo = MockRepository({
create: (f) => Promise.resolve(lineItemAdjustment), create: (f) => lineItemAdjustment,
save: (f) => Promise.resolve(lineItemAdjustment), save: (f) => Promise.resolve(lineItemAdjustment),
}) })
@@ -270,11 +270,11 @@ describe("LineItemAdjustmentService", () => {
it("calls createAdjustmentForLineItem once when given a line item", () => { it("calls createAdjustmentForLineItem once when given a line item", () => {
const cart = { const cart = {
id: "cart1", id: "cart1",
discounts: ["disc-1"], discounts: ["disc-1"],
items: [{ id: "li-1" }], items: [{ id: "li-1" }],
}, }
lineItem = { id: "li-1" } const lineItem = { id: "li-1" }
lineItemAdjustmentService.createAdjustments(cart, lineItem) lineItemAdjustmentService.createAdjustments(cart, lineItem)
expect( expect(
+2 -1
View File
@@ -3,6 +3,7 @@ import { MedusaError, Validator } from "medusa-core-utils"
import { DeepPartial, EntityManager, In } from "typeorm" import { DeepPartial, EntityManager, In } from "typeorm"
import { TransactionBaseService } from "../interfaces" import { TransactionBaseService } from "../interfaces"
import { IPriceSelectionStrategy } from "../interfaces/price-selection-strategy" import { IPriceSelectionStrategy } from "../interfaces/price-selection-strategy"
import { DiscountRuleType } from "../models"
import { Address } from "../models/address" import { Address } from "../models/address"
import { Cart } from "../models/cart" import { Cart } from "../models/cart"
import { CustomShippingOption } from "../models/custom-shipping-option" import { CustomShippingOption } from "../models/custom-shipping-option"
@@ -1221,7 +1222,7 @@ class CartService extends TransactionBaseService<CartService> {
const freshCart = await this.retrieve(cart.id, { const freshCart = await this.retrieve(cart.id, {
select: ["total"], select: ["total"],
relations: ["payment_sessions"], relations: ["payment_sessions", "items", "items.adjustments"],
}) })
if (session.status === "authorized") { if (session.status === "authorized") {
@@ -1,14 +1,14 @@
import { EntityManager } from "typeorm"
import { BaseService } from "medusa-interfaces"
import { MedusaError } from "medusa-core-utils" import { MedusaError } from "medusa-core-utils"
import { BaseService } from "medusa-interfaces"
import { EntityManager } from "typeorm"
import { Cart } from "../models/cart"
import { LineItem } from "../models/line-item"
import { LineItemAdjustment } from "../models/line-item-adjustment"
import { ProductVariant } from "../models/product-variant"
import { LineItemAdjustmentRepository } from "../repositories/line-item-adjustment" import { LineItemAdjustmentRepository } from "../repositories/line-item-adjustment"
import { FindConfig } from "../types/common" import { FindConfig } from "../types/common"
import { LineItemAdjustment } from "../models/line-item-adjustment"
import { FilterableLineItemAdjustmentProps } from "../types/line-item-adjustment" import { FilterableLineItemAdjustmentProps } from "../types/line-item-adjustment"
import { LineItem } from "../models/line-item"
import { Cart } from "../models/cart"
import DiscountService from "./discount" import DiscountService from "./discount"
import { ProductVariant } from "../models/product-variant"
type LineItemAdjustmentServiceProps = { type LineItemAdjustmentServiceProps = {
manager: EntityManager manager: EntityManager
@@ -96,7 +96,7 @@ class LineItemAdjustmentService extends BaseService {
const lineItemAdjustmentRepo: LineItemAdjustmentRepository = const lineItemAdjustmentRepo: LineItemAdjustmentRepository =
manager.getCustomRepository(this.lineItemAdjustmentRepo_) manager.getCustomRepository(this.lineItemAdjustmentRepo_)
const lineItemAdjustment = await lineItemAdjustmentRepo.create(data) const lineItemAdjustment = lineItemAdjustmentRepo.create(data)
return await lineItemAdjustmentRepo.save(lineItemAdjustment) return await lineItemAdjustmentRepo.save(lineItemAdjustment)
}) })