Fix/pricing update fixes (#5275)
* fix for merging line items and quantity prices * add changeset * fix draft order unit_price calculation * update test to reflect only quantity change * fix unit tests * update conditional
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { CartServiceMock } from "../../../../../services/__mocks__/cart"
|
||||
import { IdMap } from "medusa-test-utils"
|
||||
import { request } from "../../../../../helpers/test-request"
|
||||
import { CartServiceMock } from "../../../../../services/__mocks__/cart"
|
||||
|
||||
describe("POST /store/carts/:id/line-items/:line_id", () => {
|
||||
describe("successfully updates a line item", () => {
|
||||
@@ -34,6 +34,7 @@ describe("POST /store/carts/:id/line-items/:line_id", () => {
|
||||
region_id: IdMap.getId("region-france"),
|
||||
quantity: 3,
|
||||
metadata: {},
|
||||
should_calculate_prices: true,
|
||||
}
|
||||
)
|
||||
})
|
||||
@@ -126,6 +127,7 @@ describe("POST /store/carts/:id/line-items/:line_id", () => {
|
||||
quantity: 3,
|
||||
region_id: expect.any(String),
|
||||
variant_id: expect.any(String),
|
||||
should_calculate_prices: true,
|
||||
}
|
||||
)
|
||||
})
|
||||
@@ -170,6 +172,7 @@ describe("POST /store/carts/:id/line-items/:line_id", () => {
|
||||
quantity: 3,
|
||||
region_id: expect.any(String),
|
||||
variant_id: expect.any(String),
|
||||
should_calculate_prices: true,
|
||||
}
|
||||
)
|
||||
})
|
||||
@@ -215,6 +218,7 @@ describe("POST /store/carts/:id/line-items/:line_id", () => {
|
||||
quantity: 3,
|
||||
region_id: expect.any(String),
|
||||
variant_id: expect.any(String),
|
||||
should_calculate_prices: true,
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { IsInt, IsOptional } from "class-validator"
|
||||
import { MedusaError } from "medusa-core-utils"
|
||||
import { EntityManager } from "typeorm"
|
||||
import { defaultStoreCartFields, defaultStoreCartRelations } from "."
|
||||
|
||||
import { CartService } from "../../../../services"
|
||||
import { EntityManager } from "typeorm"
|
||||
import { MedusaError } from "medusa-core-utils"
|
||||
import { cleanResponseData } from "../../../../utils/clean-response-data"
|
||||
import { handleAddOrUpdateLineItem } from "./create-line-item/utils/handler-steps"
|
||||
|
||||
@@ -91,6 +92,7 @@ export default async (req, res) => {
|
||||
region_id: cart.region_id,
|
||||
quantity: validated.quantity,
|
||||
metadata: validated.metadata || {},
|
||||
should_calculate_prices: true,
|
||||
}
|
||||
|
||||
await cartService
|
||||
|
||||
@@ -1,10 +1,34 @@
|
||||
import { FlagRouter } from "@medusajs/utils"
|
||||
import { isEmpty, isEqual } from "lodash"
|
||||
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||
import { DeepPartial, EntityManager, In, IsNull, Not } from "typeorm"
|
||||
import {
|
||||
CustomerService,
|
||||
Address,
|
||||
Cart,
|
||||
CustomShippingOption,
|
||||
Customer,
|
||||
Discount,
|
||||
DiscountRule,
|
||||
DiscountRuleType,
|
||||
LineItem,
|
||||
PaymentSession,
|
||||
PaymentSessionStatus,
|
||||
SalesChannel,
|
||||
ShippingMethod,
|
||||
} from "../models"
|
||||
import {
|
||||
AddressPayload,
|
||||
FindConfig,
|
||||
TotalField,
|
||||
WithRequiredProperty,
|
||||
} from "../types/common"
|
||||
import {
|
||||
CartCreateProps,
|
||||
CartUpdateProps,
|
||||
FilterableCartProps,
|
||||
LineItemUpdate,
|
||||
LineItemValidateData,
|
||||
isCart,
|
||||
} from "../types/cart"
|
||||
import {
|
||||
CustomShippingOptionService,
|
||||
CustomerService,
|
||||
DiscountService,
|
||||
EventBusService,
|
||||
GiftCardService,
|
||||
@@ -24,46 +48,23 @@ import {
|
||||
TaxProviderService,
|
||||
TotalsService,
|
||||
} from "."
|
||||
import { DeepPartial, EntityManager, In, IsNull, Not } from "typeorm"
|
||||
import { IPriceSelectionStrategy, TransactionBaseService } from "../interfaces"
|
||||
import IsolateProductDomainFeatureFlag from "../loaders/feature-flags/isolate-product-domain"
|
||||
import SalesChannelFeatureFlag from "../loaders/feature-flags/sales-channels"
|
||||
import {
|
||||
Address,
|
||||
Cart,
|
||||
Customer,
|
||||
CustomShippingOption,
|
||||
Discount,
|
||||
DiscountRule,
|
||||
DiscountRuleType,
|
||||
LineItem,
|
||||
PaymentSession,
|
||||
PaymentSessionStatus,
|
||||
SalesChannel,
|
||||
ShippingMethod,
|
||||
} from "../models"
|
||||
import { MedusaError, isDefined } from "medusa-core-utils"
|
||||
import { buildQuery, isString, setMetadata } from "../utils"
|
||||
import { isEmpty, isEqual } from "lodash"
|
||||
|
||||
import { AddressRepository } from "../repositories/address"
|
||||
import { CartRepository } from "../repositories/cart"
|
||||
import { LineItemRepository } from "../repositories/line-item"
|
||||
import { PaymentSessionRepository } from "../repositories/payment-session"
|
||||
import { ShippingMethodRepository } from "../repositories/shipping-method"
|
||||
import {
|
||||
CartCreateProps,
|
||||
CartUpdateProps,
|
||||
FilterableCartProps,
|
||||
isCart,
|
||||
LineItemUpdate,
|
||||
LineItemValidateData,
|
||||
} from "../types/cart"
|
||||
import {
|
||||
AddressPayload,
|
||||
FindConfig,
|
||||
TotalField,
|
||||
WithRequiredProperty,
|
||||
} from "../types/common"
|
||||
import { PaymentSessionInput } from "../types/payment"
|
||||
import { buildQuery, isString, setMetadata } from "../utils"
|
||||
import { validateEmail } from "../utils/is-email"
|
||||
import { FlagRouter } from "@medusajs/utils"
|
||||
import { IsNumber } from "class-validator"
|
||||
import IsolateProductDomainFeatureFlag from "../loaders/feature-flags/isolate-product-domain"
|
||||
import { LineItemRepository } from "../repositories/line-item"
|
||||
import { PaymentSessionInput } from "../types/payment"
|
||||
import { PaymentSessionRepository } from "../repositories/payment-session"
|
||||
import SalesChannelFeatureFlag from "../loaders/feature-flags/sales-channels"
|
||||
import { ShippingMethodRepository } from "../repositories/shipping-method"
|
||||
import { validateEmail } from "../utils/is-email"
|
||||
|
||||
type InjectedDependencies = {
|
||||
manager: EntityManager
|
||||
@@ -797,7 +798,7 @@ class CartService extends TransactionBaseService {
|
||||
): Promise<void> {
|
||||
const items: LineItem[] = Array.isArray(lineItems) ? lineItems : [lineItems]
|
||||
|
||||
const select: (keyof Cart)[] = ["id"]
|
||||
const select: (keyof Cart)[] = ["id", "customer_id", "region_id"]
|
||||
|
||||
if (this.featureFlagRouter_.isFeatureEnabled("sales_channels")) {
|
||||
select.push("sales_channel_id")
|
||||
@@ -900,10 +901,33 @@ class CartService extends TransactionBaseService {
|
||||
}
|
||||
|
||||
if (currentItem) {
|
||||
const variantsPricing = await this.pricingService_
|
||||
.withTransaction(transactionManager)
|
||||
.getProductVariantsPricing(
|
||||
[
|
||||
{
|
||||
variantId: item.variant_id!,
|
||||
quantity: item.quantity,
|
||||
},
|
||||
],
|
||||
{
|
||||
region_id: cart.region_id,
|
||||
customer_id: cart.customer_id,
|
||||
include_discount_prices: true,
|
||||
}
|
||||
)
|
||||
|
||||
const { calculated_price } =
|
||||
variantsPricing[currentItem.variant_id!]
|
||||
|
||||
lineItemsToUpdate[currentItem.id] = {
|
||||
quantity: item.quantity,
|
||||
has_shipping: false,
|
||||
}
|
||||
|
||||
if (isDefined(calculated_price)) {
|
||||
lineItemsToUpdate[currentItem.id].unit_price = calculated_price
|
||||
}
|
||||
} else {
|
||||
// Since the variant is eager loaded, we are removing it before the line item is being created.
|
||||
delete (item as Partial<LineItem>).variant
|
||||
@@ -977,8 +1001,9 @@ class CartService extends TransactionBaseService {
|
||||
async updateLineItem(
|
||||
cartId: string,
|
||||
lineItemId: string,
|
||||
lineItemUpdate: LineItemUpdate
|
||||
update: LineItemUpdate
|
||||
): Promise<Cart> {
|
||||
const { should_calculate_prices, ...lineItemUpdate } = update
|
||||
return await this.atomicPhase_(
|
||||
async (transactionManager: EntityManager) => {
|
||||
const select: (keyof Cart)[] = ["id", "region_id", "customer_id"]
|
||||
@@ -1021,24 +1046,26 @@ class CartService extends TransactionBaseService {
|
||||
)
|
||||
}
|
||||
|
||||
const variantsPricing = await this.pricingService_
|
||||
.withTransaction(transactionManager)
|
||||
.getProductVariantsPricing(
|
||||
[
|
||||
if (should_calculate_prices) {
|
||||
const variantsPricing = await this.pricingService_
|
||||
.withTransaction(transactionManager)
|
||||
.getProductVariantsPricing(
|
||||
[
|
||||
{
|
||||
variantId: lineItem.variant_id,
|
||||
quantity: lineItemUpdate.quantity,
|
||||
},
|
||||
],
|
||||
{
|
||||
variantId: lineItem.variant_id,
|
||||
quantity: lineItemUpdate.quantity,
|
||||
},
|
||||
],
|
||||
{
|
||||
region_id: cart.region_id,
|
||||
customer_id: cart.customer_id,
|
||||
include_discount_prices: true,
|
||||
}
|
||||
)
|
||||
region_id: cart.region_id,
|
||||
customer_id: cart.customer_id,
|
||||
include_discount_prices: true,
|
||||
}
|
||||
)
|
||||
|
||||
const { calculated_price } = variantsPricing[lineItem.variant_id]
|
||||
lineItemUpdate.unit_price = calculated_price ?? undefined
|
||||
const { calculated_price } = variantsPricing[lineItem.variant_id]
|
||||
lineItemUpdate.unit_price = calculated_price ?? undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
import { ValidateNested } from "class-validator"
|
||||
import { IsType } from "../utils/validators/is-type"
|
||||
import {
|
||||
AddressPayload,
|
||||
DateComparisonOperator,
|
||||
StringComparisonOperator,
|
||||
} from "./common"
|
||||
import { Cart, CartType } from "../models/cart"
|
||||
import { AddressPayload, DateComparisonOperator, StringComparisonOperator } from "./common"
|
||||
|
||||
import { IsType } from "../utils/validators/is-type"
|
||||
import { Region } from "../models"
|
||||
import { ValidateNested } from "class-validator"
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function isCart(object: any): object is Cart {
|
||||
@@ -29,10 +34,11 @@ export type LineItemUpdate = {
|
||||
metadata?: Record<string, unknown>
|
||||
region_id?: string
|
||||
variant_id?: string
|
||||
should_calculate_prices?: boolean
|
||||
}
|
||||
|
||||
export type LineItemValidateData = {
|
||||
variant?: { product_id: string };
|
||||
variant?: { product_id: string }
|
||||
variant_id: string
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user