feat(medusa): Preserve custom adjustments when refreshing adjustments (#3085)

This commit is contained in:
Frane Polić authored and GitHub committed 2023-02-06 19:22:05 +01:00
1 parent d0adaf57ed
commit 5b63533c77
10 files changed
+299 -41

No files matched your search

@@ -21,6 +21,7 @@ import { ShippingOptionServiceMock } from "../__mocks__/shipping-option"
import { CustomerServiceMock } from "../__mocks__/customer"
import TaxCalculationStrategy from "../../strategies/tax-calculation"
import SystemTaxService from "../system-tax"
import { IsNull, Not } from "typeorm"
const eventBusService = {
emit: jest.fn(),
@@ -515,6 +516,7 @@ describe("CartService", () => {
expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledTimes(1)
expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledWith({
item_id: [IdMap.getId("merger")],
discount_id: expect.objectContaining(Not(IsNull())),
})
expect(
@@ -745,6 +747,7 @@ describe("CartService", () => {
expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledTimes(1)
expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledWith({
item_id: [IdMap.getId("itemToRemove")],
discount_id: expect.objectContaining(Not(IsNull())),
})
expect(
@@ -786,6 +789,7 @@ describe("CartService", () => {
expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledTimes(1)
expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledWith({
item_id: [IdMap.getId("itemToRemove")],
discount_id: expect.objectContaining(Not(IsNull())),
})
expect(
@@ -965,6 +969,7 @@ describe("CartService", () => {
expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledTimes(1)
expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledWith({
item_id: [IdMap.getId("existingUpdate")],
discount_id: expect.objectContaining(Not(IsNull())),
})
expect(
@@ -2259,6 +2264,7 @@ describe("CartService", () => {
expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledTimes(1)
expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledWith({
item_id: ["li1", "li2"],
discount_id: expect.objectContaining(Not(IsNull())),
})
expect(
@@ -2309,6 +2315,7 @@ describe("CartService", () => {
expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledTimes(1)
expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledWith({
item_id: ["li1", "li2"],
discount_id: expect.objectContaining(Not(IsNull())),
})
expect(
@@ -2368,6 +2375,7 @@ describe("CartService", () => {
expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledTimes(1)
expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledWith({
item_id: ["li1", "li2"],
discount_id: expect.objectContaining(Not(IsNull())),
})
expect(
+2 -1
View File
@@ -1,6 +1,6 @@
import { isEmpty, isEqual } from "lodash"
import { isDefined, MedusaError } from "medusa-core-utils"
import { DeepPartial, EntityManager, In } from "typeorm"
import { DeepPartial, EntityManager, In, IsNull, Not } from "typeorm"
import { IPriceSelectionStrategy, TransactionBaseService } from "../interfaces"
import SalesChannelFeatureFlag from "../loaders/feature-flags/sales-channels"
import {
@@ -2604,6 +2604,7 @@ class CartService extends TransactionBaseService {
.withTransaction(transactionManager)
.delete({
item_id: nonReturnLineIDs,
discount_id: Not(IsNull()),
})
// potentially create/update line item adjustments
@@ -1,5 +1,5 @@
import { isDefined, MedusaError } from "medusa-core-utils"
import { EntityManager, In } from "typeorm"
import { EntityManager, FindOperator, In } from "typeorm"
import { Cart, DiscountRuleType, LineItem, LineItemAdjustment } from "../models"
import { LineItemAdjustmentRepository } from "../repositories/line-item-adjustment"
@@ -153,7 +153,12 @@ class LineItemAdjustmentService extends TransactionBaseService {
* @return the result of the delete operation
*/
async delete(
selectorOrIds: string | string[] | FilterableLineItemAdjustmentProps
selectorOrIds:
| string
| string[]
| (FilterableLineItemAdjustmentProps & {
discount_id?: FindOperator<string | null>
})
): Promise<void> {
return this.atomicPhase_(async (manager) => {
const lineItemAdjustmentRepo: LineItemAdjustmentRepository =
+14 -3
View File
@@ -373,7 +373,9 @@ export default class OrderEditService extends TransactionBaseService {
quantity: data.quantity,
})
await this.refreshAdjustments(orderEditId)
await this.refreshAdjustments(orderEditId, {
preserveCustomAdjustments: true,
})
})
}
@@ -434,7 +436,10 @@ export default class OrderEditService extends TransactionBaseService {
})
}
async refreshAdjustments(orderEditId: string) {
async refreshAdjustments(
orderEditId: string,
config = { preserveCustomAdjustments: false }
) {
const manager = this.transactionManager_ ?? this.manager_
const lineItemAdjustmentServiceTx =
@@ -461,7 +466,13 @@ export default class OrderEditService extends TransactionBaseService {
orderEdit.items.forEach((item) => {
if (item.adjustments?.length) {
item.adjustments.forEach((adjustment) => {
clonedItemAdjustmentIds.push(adjustment.id)
const preserveAdjustment = config.preserveCustomAdjustments
? !!adjustment.discount_id
: true
if (preserveAdjustment) {
clonedItemAdjustmentIds.push(adjustment.id)
}
})
}
})
+24 -26
View File
@@ -447,26 +447,28 @@ class TotalsService extends TransactionBaseService {
const allocationMap: LineAllocationsMap = {}
if (!options.exclude_discounts) {
let lineDiscounts: LineDiscountAmount[] = []
const discount = orderOrCart.discounts?.find(
({ rule }) => rule.type !== DiscountRuleType.FREE_SHIPPING
)
if (discount) {
lineDiscounts = this.getLineDiscounts(orderOrCart, discount)
}
const lineDiscounts: LineDiscountAmount[] = this.getLineDiscounts(
orderOrCart,
discount
)
for (const ld of lineDiscounts) {
const adjustmentAmount = ld.amount + ld.customAdjustmentsAmount
if (allocationMap[ld.item.id]) {
allocationMap[ld.item.id].discount = {
amount: ld.amount,
unit_amount: Math.round(ld.amount / ld.item.quantity),
amount: adjustmentAmount,
unit_amount: Math.round(adjustmentAmount / ld.item.quantity),
}
} else {
allocationMap[ld.item.id] = {
discount: {
amount: ld.amount,
unit_amount: Math.round(ld.amount / ld.item.quantity),
amount: adjustmentAmount,
unit_amount: Math.round(adjustmentAmount / ld.item.quantity),
},
}
}
@@ -717,7 +719,7 @@ class TotalsService extends TransactionBaseService {
swaps?: Swap[]
claims?: ClaimOrder[]
},
discount: Discount
discount?: Discount
): LineDiscountAmount[] {
let merged: LineItem[] = [...(cartOrOrder.items ?? [])]
@@ -736,18 +738,24 @@ class TotalsService extends TransactionBaseService {
return merged.map((item) => {
const adjustments = item?.adjustments || []
const discountAdjustments = adjustments.filter(
(adjustment) => adjustment.discount_id === discount.id
const discountAdjustments = discount
? adjustments.filter(
(adjustment) => adjustment.discount_id === discount.id
)
: []
const customAdjustments = adjustments.filter(
(adjustment) => adjustment.discount_id === null
)
const sumAdjustments = (total, adjustment) => total + adjustment.amount
return {
item,
amount: item.allow_discounts
? discountAdjustments.reduce(
(total, adjustment) => total + adjustment.amount,
0
)
? discountAdjustments.reduce(sumAdjustments, 0)
: 0,
customAdjustmentsAmount: customAdjustments.reduce(sumAdjustments, 0),
}
})
}
@@ -994,16 +1002,6 @@ class TotalsService extends TransactionBaseService {
excludeNonDiscounts: true,
})
// we only support having free shipping and one other discount, so first
// find the discount, which is not free shipping.
const discount = cartOrOrder.discounts?.find(
({ rule }) => rule.type !== DiscountRuleType.FREE_SHIPPING
)
if (!discount) {
return 0
}
const discountTotal = this.getLineItemAdjustmentsTotal(cartOrOrder)
if (subtotal < 0) {
+1
View File
@@ -62,4 +62,5 @@ export type LineDiscount = {
export type LineDiscountAmount = {
item: LineItem
amount: number
customAdjustmentsAmount: number
}