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:
1 parent
99cc4b0571
commit
78ff64e783
6 files changed
+87
-4
No files matched your search
@@ -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)
|
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 () => {
|
it("successfully removes adjustments upon update without discounts", async () => {
|
||||||
const discountData = {
|
const discountData = {
|
||||||
code: "MEDUSA185DKK",
|
code: "MEDUSA185DKK",
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export interface StorePostCartsCartReq {
|
|||||||
*/
|
*/
|
||||||
discounts?: Array<{
|
discounts?: Array<{
|
||||||
/**
|
/**
|
||||||
* The code that a Discount is identifed by.
|
* The code that a Discount is identified by.
|
||||||
*/
|
*/
|
||||||
code: string
|
code: string
|
||||||
}>
|
}>
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ class Discount {
|
|||||||
* - code
|
* - code
|
||||||
* properties:
|
* properties:
|
||||||
* code:
|
* code:
|
||||||
* description: "The code that a Discount is identifed by."
|
* description: "The code that a Discount is identified by."
|
||||||
* type: string
|
* type: string
|
||||||
* customer_id:
|
* customer_id:
|
||||||
* description: "The ID of the Customer to associate the Cart with."
|
* description: "The ID of the Customer to associate the Cart with."
|
||||||
|
|||||||
@@ -1443,7 +1443,9 @@ class CartService extends TransactionBaseService {
|
|||||||
async (transactionManager: EntityManager) => {
|
async (transactionManager: EntityManager) => {
|
||||||
const discounts = await this.discountService_
|
const discounts = await this.discountService_
|
||||||
.withTransaction(transactionManager)
|
.withTransaction(transactionManager)
|
||||||
.listByCodes(discountCodes, { relations: ["rule", "regions"] })
|
.listByCodes(discountCodes, {
|
||||||
|
relations: ["rule", "rule.conditions", "regions"],
|
||||||
|
})
|
||||||
|
|
||||||
await this.discountService_
|
await this.discountService_
|
||||||
.withTransaction(transactionManager)
|
.withTransaction(transactionManager)
|
||||||
|
|||||||
@@ -16,7 +16,13 @@ import {
|
|||||||
} from "."
|
} from "."
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
|
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 {
|
import {
|
||||||
AllocationType as DiscountAllocation,
|
AllocationType as DiscountAllocation,
|
||||||
DiscountRule,
|
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(
|
const isValidForRegion = await this.isValidForRegion(
|
||||||
disc,
|
disc,
|
||||||
cart.region_id
|
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 {
|
hasReachedLimit(discount: Discount): boolean {
|
||||||
const count = discount.usage_count || 0
|
const count = discount.usage_count || 0
|
||||||
const limit = discount.usage_limit
|
const limit = discount.usage_limit
|
||||||
|
|||||||
Reference in new issue
Block a user