fix(medusa): validate customer for group discount (#3797)
* fix: validate customer for group discount * fix: remove logger * fix: add generated desc * fix: add an integration test case * refactor: update error message * fix: typo * refactor: move condition --------- Co-authored-by: fPolic <frane@medusajs.com>
This commit is contained in:
5
.changeset/calm-needles-change.md
Normal file
5
.changeset/calm-needles-change.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@medusajs/medusa": patch
|
||||
---
|
||||
|
||||
fix(medusa); validate customer id when applying a customer group discount
|
||||
@@ -1083,6 +1083,63 @@ describe("/store/carts", () => {
|
||||
expect(response.status).toEqual(200)
|
||||
})
|
||||
|
||||
it("throws if no customer is associated with the cart while applying a customer groups discount", async () => {
|
||||
const api = useApi()
|
||||
|
||||
await simpleCustomerGroupFactory(dbConnection, {
|
||||
id: "customer-group-2",
|
||||
name: "Loyal",
|
||||
})
|
||||
|
||||
await simpleCartFactory(
|
||||
dbConnection,
|
||||
{
|
||||
id: "test-customer-discount",
|
||||
region: {
|
||||
id: "test-region",
|
||||
name: "Test region",
|
||||
tax_rate: 12,
|
||||
},
|
||||
line_items: [
|
||||
{
|
||||
variant_id: "test-variant",
|
||||
unit_price: 100,
|
||||
},
|
||||
],
|
||||
},
|
||||
100
|
||||
)
|
||||
|
||||
await simpleDiscountFactory(dbConnection, {
|
||||
id: "test-discount",
|
||||
code: "TEST",
|
||||
regions: ["test-region"],
|
||||
rule: {
|
||||
type: "percentage",
|
||||
value: "10",
|
||||
allocation: "total",
|
||||
conditions: [
|
||||
{
|
||||
type: "customer_groups",
|
||||
operator: "in",
|
||||
customer_groups: ["customer-group-2"],
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
try {
|
||||
await api.post("/store/carts/test-customer-discount", {
|
||||
discounts: [{ code: "TEST" }],
|
||||
})
|
||||
} catch (error) {
|
||||
expect(error.response.status).toEqual(400)
|
||||
expect(error.response.data.message).toEqual(
|
||||
"Discount TEST is only valid for specific customer"
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
it("successfully removes adjustments upon update without discounts", async () => {
|
||||
const discountData = {
|
||||
code: "MEDUSA185DKK",
|
||||
|
||||
@@ -44,7 +44,7 @@ export interface StorePostCartsCartReq {
|
||||
*/
|
||||
discounts?: Array<{
|
||||
/**
|
||||
* The code that a Discount is identifed by.
|
||||
* The code that a Discount is identified by.
|
||||
*/
|
||||
code: string
|
||||
}>
|
||||
|
||||
@@ -168,7 +168,7 @@ class Discount {
|
||||
* - code
|
||||
* properties:
|
||||
* code:
|
||||
* description: "The code that a Discount is identifed by."
|
||||
* description: "The code that a Discount is identified by."
|
||||
* type: string
|
||||
* customer_id:
|
||||
* description: "The ID of the Customer to associate the Cart with."
|
||||
|
||||
@@ -1443,7 +1443,9 @@ class CartService extends TransactionBaseService {
|
||||
async (transactionManager: EntityManager) => {
|
||||
const discounts = await this.discountService_
|
||||
.withTransaction(transactionManager)
|
||||
.listByCodes(discountCodes, { relations: ["rule", "regions"] })
|
||||
.listByCodes(discountCodes, {
|
||||
relations: ["rule", "rule.conditions", "regions"],
|
||||
})
|
||||
|
||||
await this.discountService_
|
||||
.withTransaction(transactionManager)
|
||||
|
||||
@@ -16,7 +16,13 @@ import {
|
||||
} from "."
|
||||
import { TransactionBaseService } from "../interfaces"
|
||||
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
|
||||
import { Cart, Discount, LineItem, Region } from "../models"
|
||||
import {
|
||||
Cart,
|
||||
Discount,
|
||||
DiscountConditionType,
|
||||
LineItem,
|
||||
Region,
|
||||
} from "../models"
|
||||
import {
|
||||
AllocationType as DiscountAllocation,
|
||||
DiscountRule,
|
||||
@@ -705,6 +711,13 @@ class DiscountService extends TransactionBaseService {
|
||||
)
|
||||
}
|
||||
|
||||
if (!cart.customer_id && this.hasCustomersGroupCondition(disc)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.NOT_ALLOWED,
|
||||
`Discount ${disc.code} is only valid for specific customer`
|
||||
)
|
||||
}
|
||||
|
||||
const isValidForRegion = await this.isValidForRegion(
|
||||
disc,
|
||||
cart.region_id
|
||||
@@ -734,6 +747,12 @@ class DiscountService extends TransactionBaseService {
|
||||
})
|
||||
}
|
||||
|
||||
hasCustomersGroupCondition(discount: Discount): boolean {
|
||||
return discount.rule.conditions.some(
|
||||
(cond) => cond.type === DiscountConditionType.CUSTOMER_GROUPS
|
||||
)
|
||||
}
|
||||
|
||||
hasReachedLimit(discount: Discount): boolean {
|
||||
const count = discount.usage_count || 0
|
||||
const limit = discount.usage_limit
|
||||
|
||||
Reference in New Issue
Block a user