From eda26f6e818a56672cdcce1d794c307c5490f956 Mon Sep 17 00:00:00 2001 From: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com> Date: Thu, 29 Dec 2022 19:32:04 +0100 Subject: [PATCH] fix(medusa): Add tax inclusive flag to return lines from line item (#2909) --- .changeset/quiet-lobsters-search.md | 5 + .../admin/order/ff-tax-inclusive-pricing.js | 115 +++++++++++++++++- packages/medusa/src/services/line-item.ts | 21 ++-- packages/medusa/src/services/totals.ts | 24 ++-- 4 files changed, 135 insertions(+), 30 deletions(-) create mode 100644 .changeset/quiet-lobsters-search.md diff --git a/.changeset/quiet-lobsters-search.md b/.changeset/quiet-lobsters-search.md new file mode 100644 index 0000000000..6092b93d50 --- /dev/null +++ b/.changeset/quiet-lobsters-search.md @@ -0,0 +1,5 @@ +--- +"@medusajs/medusa": patch +--- + +fix(medusa): Add tax inclusive flag to return lines from line item diff --git a/integration-tests/api/__tests__/admin/order/ff-tax-inclusive-pricing.js b/integration-tests/api/__tests__/admin/order/ff-tax-inclusive-pricing.js index 7fe74319c7..d2708417ab 100644 --- a/integration-tests/api/__tests__/admin/order/ff-tax-inclusive-pricing.js +++ b/integration-tests/api/__tests__/admin/order/ff-tax-inclusive-pricing.js @@ -11,10 +11,17 @@ const { simpleRegionFactory, simpleShippingOptionFactory, simpleOrderFactory, + simpleProductFactory, } = require("../../../factories") jest.setTimeout(30000) +const adminReqConfig = { + headers: { + Authorization: "Bearer test_token", + }, +} + describe("[MEDUSA_FF_TAX_INCLUSIVE_PRICING] /admin/orders", () => { let medusaProcess let dbConnection @@ -83,11 +90,7 @@ describe("[MEDUSA_FF_TAX_INCLUSIVE_PRICING] /admin/orders", () => { option_id: includesTaxShippingOption.id, price: 10, }, - { - headers: { - Authorization: "Bearer test_token", - }, - } + adminReqConfig ) expect(orderWithShippingMethodRes.status).toEqual(200) @@ -101,4 +104,106 @@ describe("[MEDUSA_FF_TAX_INCLUSIVE_PRICING] /admin/orders", () => { ) }) }) + + describe("POST /admin/orders/:id/swaps", () => { + const prodId = "prod_1234" + const variant1 = "variant_1234" + const variant2 = "variant_5678" + const regionId = "test-region" + const lineItemId = "litem_1234" + const orderId = "order_1234" + + beforeEach(async () => { + await adminSeeder(dbConnection) + + await simpleRegionFactory(dbConnection, { + id: regionId, + includes_tax: true, + currency_code: "usd", + tax_rate: 10, + }) + + await simpleProductFactory(dbConnection, { + id: prodId, + variants: [ + { + id: variant1, + prices: [{ currency: "usd", amount: 1000, region_id: regionId }], + }, + { + id: variant2, + prices: [{ currency: "usd", amount: 1000, region_id: regionId }], + }, + ], + }) + + await simpleOrderFactory(dbConnection, { + id: orderId, + email: "test@testson.com", + fulfillment_status: "fulfilled", + payment_status: "captured", + region: regionId, + currency_code: "usd", + line_items: [ + { + id: lineItemId, + variant_id: variant1, + tax_lines: [ + { + rate: 10, + name: "VAT", + code: "vat", + }, + ], + unit_price: 1000, + includes_tax: true, + quantity: 1, + fulfilled_quantity: 1, + shipped_quantity: 1, + }, + ], + }) + }) + + afterEach(async () => { + const db = useDb() + await db.teardown() + }) + + it("creates a swap with tax inclusive return lines", async () => { + const api = useApi() + + const response = await api.post( + `/admin/orders/${orderId}/swaps`, + { + return_items: [ + { + item_id: lineItemId, + quantity: 1, + }, + ], + additional_items: [{ variant_id: variant2, quantity: 1 }], + }, + adminReqConfig + ) + + let swap = response.data.order.swaps[0] + const order = response.data.order + + swap = await api.get(`/admin/swaps/${swap.id}`, adminReqConfig) + + swap = swap.data.swap + + let swapCart = await api.get(`/store/carts/${swap.cart_id}`) + + swapCart = swapCart.data.cart + + const returnedItemOnSwap = swapCart.items.find((itm) => itm.is_return) + const returnedItemOnOrder = order.items[0] + + expect(returnedItemOnSwap.total).toEqual(-1000) + expect(returnedItemOnOrder.total).toEqual(1000) + expect(response.status).toEqual(200) + }) + }) }) diff --git a/packages/medusa/src/services/line-item.ts b/packages/medusa/src/services/line-item.ts index b1b5e7f504..177d58a153 100644 --- a/packages/medusa/src/services/line-item.ts +++ b/packages/medusa/src/services/line-item.ts @@ -2,20 +2,23 @@ import { MedusaError } from "medusa-core-utils" import { EntityManager, In } from "typeorm" import { DeepPartial } from "typeorm/common/DeepPartial" -import { CartRepository } from "../repositories/cart" -import { LineItemRepository } from "../repositories/line-item" -import { LineItemTaxLineRepository } from "../repositories/line-item-tax-line" +import { TransactionBaseService } from "../interfaces" +import OrderEditingFeatureFlag from "../loaders/feature-flags/order-editing" +import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing" import { LineItem, LineItemAdjustment, LineItemTaxLine, ProductVariant, } from "../models" +import { CartRepository } from "../repositories/cart" +import { LineItemRepository } from "../repositories/line-item" +import { LineItemTaxLineRepository } from "../repositories/line-item-tax-line" import { FindConfig, Selector } from "../types/common" +import { GenerateInputData, GenerateLineItemContext } from "../types/line-item" +import { ProductVariantPricing } from "../types/pricing" +import { buildQuery, isString, setMetadata } from "../utils" import { FlagRouter } from "../utils/flag-router" -import LineItemAdjustmentService from "./line-item-adjustment" -import OrderEditingFeatureFlag from "../loaders/feature-flags/order-editing" -import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing" import { PricingService, ProductService, @@ -23,10 +26,7 @@ import { RegionService, TaxProviderService, } from "./index" -import { buildQuery, isString, setMetadata } from "../utils" -import { TransactionBaseService } from "../interfaces" -import { GenerateInputData, GenerateLineItemContext } from "../types/line-item" -import { ProductVariantPricing } from "../types/pricing" +import LineItemAdjustmentService from "./line-item-adjustment" type InjectedDependencies = { manager: EntityManager @@ -159,6 +159,7 @@ class LineItemService extends TransactionBaseService { unit_price: -1 * lineItem.unit_price, quantity: lineItem.return_item.quantity, allow_discounts: lineItem.allow_discounts, + includes_tax: !!lineItem.includes_tax, tax_lines: lineItem.tax_lines.map((taxLine) => { return itemTaxLineRepo.create({ name: taxLine.name, diff --git a/packages/medusa/src/services/totals.ts b/packages/medusa/src/services/totals.ts index 5b9169b4ad..79ba4766f3 100644 --- a/packages/medusa/src/services/totals.ts +++ b/packages/medusa/src/services/totals.ts @@ -1,4 +1,5 @@ import { isDefined, MedusaError } from "medusa-core-utils" +import { EntityManager } from "typeorm" import { ITaxCalculationStrategy, TaxCalculationContext, @@ -25,14 +26,10 @@ import { LineDiscountAmount, SubtotalOptions, } from "../types/totals" -import { - TaxProviderService, - NewTotalsService, -} from "./index" -import { EntityManager } from "typeorm" +import { NewTotalsService, TaxProviderService } from "./index" -import { calculatePriceTaxAmount } from "../utils" import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing" +import { calculatePriceTaxAmount } from "../utils" import { FlagRouter } from "../utils/flag-router" type ShippingMethodTotals = { @@ -806,7 +803,7 @@ class TotalsService extends TransactionBaseService { // Tax Information if (options.include_tax) { - // When we have an order with a nulled or undefined tax rate we know that it is an + // When we have an order with a tax rate we know that it is an // order from the old tax system. The following is a backward compat // calculation. if (isOrder(cartOrOrder) && cartOrOrder.tax_rate != null) { @@ -979,14 +976,11 @@ class TotalsService extends TransactionBaseService { giftCardable = subtotal - discountTotal } - return await this.newTotalsService_.getGiftCardTotals( - giftCardable, - { - region: cartOrOrder.region, - giftCards: cartOrOrder.gift_cards || [], - giftCardTransactions: cartOrOrder['gift_card_transactions'] || [] - } - ) + return await this.newTotalsService_.getGiftCardTotals(giftCardable, { + region: cartOrOrder.region, + giftCards: cartOrOrder.gift_cards || [], + giftCardTransactions: cartOrOrder["gift_card_transactions"] || [], + }) } /**