feat: Add discountable flag to product (#329)
This commit is contained in:
@@ -28,7 +28,6 @@ describe("/admin/discounts", () => {
|
|||||||
|
|
||||||
describe("POST /admin/discounts", () => {
|
describe("POST /admin/discounts", () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
const manager = dbConnection.manager;
|
|
||||||
try {
|
try {
|
||||||
await adminSeeder(dbConnection);
|
await adminSeeder(dbConnection);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -105,8 +104,9 @@ describe("/admin/discounts", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("testing for soft-deletion + uniqueness on discount codes", () => {
|
describe("testing for soft-deletion + uniqueness on discount codes", () => {
|
||||||
const manager = dbConnection.manager;
|
let manager;
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
manager = dbConnection.manager;
|
||||||
try {
|
try {
|
||||||
await adminSeeder(dbConnection);
|
await adminSeeder(dbConnection);
|
||||||
await manager.insert(DiscountRule, {
|
await manager.insert(DiscountRule, {
|
||||||
@@ -120,6 +120,8 @@ describe("/admin/discounts", () => {
|
|||||||
id: "test-discount",
|
id: "test-discount",
|
||||||
code: "TESTING",
|
code: "TESTING",
|
||||||
rule_id: "test-discount-rule",
|
rule_id: "test-discount-rule",
|
||||||
|
is_dynamic: false,
|
||||||
|
is_disabled: false,
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw err;
|
throw err;
|
||||||
@@ -127,6 +129,7 @@ describe("/admin/discounts", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
|
manager = dbConnection.manager;
|
||||||
await manager.query(`DELETE FROM "discount"`);
|
await manager.query(`DELETE FROM "discount"`);
|
||||||
await manager.query(`DELETE FROM "discount_rule"`);
|
await manager.query(`DELETE FROM "discount_rule"`);
|
||||||
await manager.query(`DELETE FROM "user"`);
|
await manager.query(`DELETE FROM "user"`);
|
||||||
@@ -173,7 +176,7 @@ describe("/admin/discounts", () => {
|
|||||||
expect(response.status).toEqual(200);
|
expect(response.status).toEqual(200);
|
||||||
expect(response.data.discount).toEqual(
|
expect(response.data.discount).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
code: "HELLOWORLD",
|
code: "TESTING",
|
||||||
usage_limit: 10,
|
usage_limit: 10,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -92,6 +92,8 @@ describe("/admin/products", () => {
|
|||||||
expect(response.data.product).toEqual(
|
expect(response.data.product).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
title: "Test product",
|
title: "Test product",
|
||||||
|
discountable: true,
|
||||||
|
is_giftcard: false,
|
||||||
handle: "test-product",
|
handle: "test-product",
|
||||||
images: expect.arrayContaining([
|
images: expect.arrayContaining([
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
@@ -148,6 +150,43 @@ describe("/admin/products", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("creates a giftcard", async () => {
|
||||||
|
const api = useApi();
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
title: "Test Giftcard",
|
||||||
|
is_giftcard: true,
|
||||||
|
description: "test-giftcard-description",
|
||||||
|
options: [{ title: "Denominations" }],
|
||||||
|
variants: [
|
||||||
|
{
|
||||||
|
title: "Test variant",
|
||||||
|
prices: [{ currency_code: "usd", amount: 100 }],
|
||||||
|
options: [{ value: "100" }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await api
|
||||||
|
.post("/admin/products", payload, {
|
||||||
|
headers: {
|
||||||
|
Authorization: "Bearer test_token",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(response.status).toEqual(200);
|
||||||
|
|
||||||
|
expect(response.data.product).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
title: "Test Giftcard",
|
||||||
|
discountable: false,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it("updates a product (update tags, delete collection, delete type, replaces images)", async () => {
|
it("updates a product (update tags, delete collection, delete type, replaces images)", async () => {
|
||||||
const api = useApi();
|
const api = useApi();
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,12 @@ describe("/store/carts", () => {
|
|||||||
await manager.query(`DELETE FROM "discount"`);
|
await manager.query(`DELETE FROM "discount"`);
|
||||||
await manager.query(`DELETE FROM "discount_rule"`);
|
await manager.query(`DELETE FROM "discount_rule"`);
|
||||||
await manager.query(`DELETE FROM "shipping_method"`);
|
await manager.query(`DELETE FROM "shipping_method"`);
|
||||||
await manager.query(`DELETE FROM "shipping_option"`);
|
await manager.query(`DELETE FROM "line_item"`);
|
||||||
await manager.query(`DELETE FROM "cart"`);
|
await manager.query(`DELETE FROM "cart"`);
|
||||||
|
await manager.query(`DELETE FROM "money_amount"`);
|
||||||
|
await manager.query(`DELETE FROM "product_variant"`);
|
||||||
|
await manager.query(`DELETE FROM "product"`);
|
||||||
|
await manager.query(`DELETE FROM "shipping_option"`);
|
||||||
await manager.query(`DELETE FROM "address"`);
|
await manager.query(`DELETE FROM "address"`);
|
||||||
await manager.query(`DELETE FROM "customer"`);
|
await manager.query(`DELETE FROM "customer"`);
|
||||||
await manager.query(
|
await manager.query(
|
||||||
@@ -233,6 +237,44 @@ describe("/store/carts", () => {
|
|||||||
expect(cartWithShippingMethod.status).toEqual(200);
|
expect(cartWithShippingMethod.status).toEqual(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("adds a giftcard to cart, but ensures discount only applied to discountable items", async () => {
|
||||||
|
const api = useApi();
|
||||||
|
|
||||||
|
// Add standard line item to cart
|
||||||
|
await api.post(
|
||||||
|
"/store/carts/test-cart/line-items",
|
||||||
|
{
|
||||||
|
variant_id: "test-variant",
|
||||||
|
quantity: 1,
|
||||||
|
},
|
||||||
|
{ withCredentials: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
// Add gift card to cart
|
||||||
|
await api.post(
|
||||||
|
"/store/carts/test-cart/line-items",
|
||||||
|
{
|
||||||
|
variant_id: "giftcard-denom",
|
||||||
|
quantity: 1,
|
||||||
|
},
|
||||||
|
{ withCredentials: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
// Add a 10% discount to the cart
|
||||||
|
const cartWithGiftcard = await api.post(
|
||||||
|
"/store/carts/test-cart",
|
||||||
|
{
|
||||||
|
discounts: [{ code: "10PERCENT" }],
|
||||||
|
},
|
||||||
|
{ withCredentials: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
// Ensure that the discount is only applied to the standard item
|
||||||
|
expect(cartWithGiftcard.data.cart.total).toBe(1900); // 1000 (giftcard) + 900 (standard item with 10% discount)
|
||||||
|
expect(cartWithGiftcard.data.cart.discount_total).toBe(100);
|
||||||
|
expect(cartWithGiftcard.status).toEqual(200);
|
||||||
|
});
|
||||||
|
|
||||||
it("adds no more than 1 shipping method per shipping profile", async () => {
|
it("adds no more than 1 shipping method per shipping profile", async () => {
|
||||||
const api = useApi();
|
const api = useApi();
|
||||||
const addShippingMethod = async (option_id) => {
|
const addShippingMethod = async (option_id) => {
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ const {
|
|||||||
ShippingOption,
|
ShippingOption,
|
||||||
ShippingMethod,
|
ShippingMethod,
|
||||||
Address,
|
Address,
|
||||||
|
ProductVariant,
|
||||||
|
Product,
|
||||||
|
MoneyAmount,
|
||||||
} = require("@medusajs/medusa");
|
} = require("@medusajs/medusa");
|
||||||
|
|
||||||
module.exports = async (connection, data = {}) => {
|
module.exports = async (connection, data = {}) => {
|
||||||
@@ -17,6 +20,10 @@ module.exports = async (connection, data = {}) => {
|
|||||||
type: "default",
|
type: "default",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const gcProfile = await manager.findOne(ShippingProfile, {
|
||||||
|
type: "gift_card",
|
||||||
|
});
|
||||||
|
|
||||||
await manager.insert(Address, {
|
await manager.insert(Address, {
|
||||||
id: "test-general-address",
|
id: "test-general-address",
|
||||||
first_name: "superman",
|
first_name: "superman",
|
||||||
@@ -47,9 +54,27 @@ module.exports = async (connection, data = {}) => {
|
|||||||
|
|
||||||
freeDisc.regions = [r];
|
freeDisc.regions = [r];
|
||||||
freeDisc.rule = freeRule;
|
freeDisc.rule = freeRule;
|
||||||
|
|
||||||
await manager.save(freeDisc);
|
await manager.save(freeDisc);
|
||||||
|
|
||||||
|
const tenPercentRule = manager.create(DiscountRule, {
|
||||||
|
id: "tenpercent-rule",
|
||||||
|
description: "Ten percent rule",
|
||||||
|
type: "percentage",
|
||||||
|
value: 10,
|
||||||
|
allocation: "total",
|
||||||
|
});
|
||||||
|
|
||||||
|
const tenPercent = manager.create(Discount, {
|
||||||
|
id: "10Percent",
|
||||||
|
code: "10PERCENT",
|
||||||
|
is_dynamic: false,
|
||||||
|
is_disabled: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
tenPercent.regions = [r];
|
||||||
|
tenPercent.rule = tenPercentRule;
|
||||||
|
await manager.save(tenPercent);
|
||||||
|
|
||||||
const d = await manager.create(Discount, {
|
const d = await manager.create(Discount, {
|
||||||
id: "test-discount",
|
id: "test-discount",
|
||||||
code: "CREATED",
|
code: "CREATED",
|
||||||
@@ -100,6 +125,17 @@ module.exports = async (connection, data = {}) => {
|
|||||||
data: {},
|
data: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await manager.insert(ShippingOption, {
|
||||||
|
id: "gc-option",
|
||||||
|
name: "Digital copy",
|
||||||
|
provider_id: "test-ful",
|
||||||
|
region_id: "test-region",
|
||||||
|
profile_id: gcProfile.id,
|
||||||
|
price_type: "flat_rate",
|
||||||
|
amount: 0,
|
||||||
|
data: {},
|
||||||
|
});
|
||||||
|
|
||||||
await manager.insert(ShippingOption, {
|
await manager.insert(ShippingOption, {
|
||||||
id: "test-option-2",
|
id: "test-option-2",
|
||||||
name: "test-option-2",
|
name: "test-option-2",
|
||||||
@@ -111,6 +147,62 @@ module.exports = async (connection, data = {}) => {
|
|||||||
data: {},
|
data: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await manager.insert(Product, {
|
||||||
|
id: "giftcard-product",
|
||||||
|
title: "Giftcard",
|
||||||
|
is_giftcard: true,
|
||||||
|
discountable: false,
|
||||||
|
profile_id: gcProfile.id,
|
||||||
|
options: [{ id: "denom", title: "Denomination" }],
|
||||||
|
});
|
||||||
|
|
||||||
|
await manager.insert(ProductVariant, {
|
||||||
|
id: "giftcard-denom",
|
||||||
|
title: "1000",
|
||||||
|
product_id: "giftcard-product",
|
||||||
|
inventory_quantity: 1,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
option_id: "denom",
|
||||||
|
value: "1000",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
await manager.insert(Product, {
|
||||||
|
id: "test-product",
|
||||||
|
title: "test product",
|
||||||
|
profile_id: defaultProfile.id,
|
||||||
|
options: [{ id: "test-option", title: "Size" }],
|
||||||
|
});
|
||||||
|
|
||||||
|
await manager.insert(ProductVariant, {
|
||||||
|
id: "test-variant",
|
||||||
|
title: "test variant",
|
||||||
|
product_id: "test-product",
|
||||||
|
inventory_quantity: 1,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
option_id: "test-option",
|
||||||
|
value: "Size",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const ma = manager.create(MoneyAmount, {
|
||||||
|
variant_id: "test-variant",
|
||||||
|
currency_code: "usd",
|
||||||
|
amount: 1000,
|
||||||
|
});
|
||||||
|
await manager.save(ma);
|
||||||
|
|
||||||
|
const ma2 = manager.create(MoneyAmount, {
|
||||||
|
variant_id: "giftcard-denom",
|
||||||
|
currency_code: "usd",
|
||||||
|
amount: 1000,
|
||||||
|
});
|
||||||
|
await manager.save(ma2);
|
||||||
|
|
||||||
const cart = manager.create(Cart, {
|
const cart = manager.create(Cart, {
|
||||||
id: "test-cart",
|
id: "test-cart",
|
||||||
customer_id: "some-customer",
|
customer_id: "some-customer",
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
"build": "babel src -d dist --extensions \".ts,.js\""
|
"build": "babel src -d dist --extensions \".ts,.js\""
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@medusajs/medusa": "^1.1.32",
|
"@medusajs/medusa": "1.1.33-dev-1627995051381",
|
||||||
"medusa-interfaces": "^1.1.18",
|
"medusa-interfaces": "^1.1.18",
|
||||||
"typeorm": "^0.2.31"
|
"typeorm": "^0.2.31"
|
||||||
},
|
},
|
||||||
|
|||||||
+896
-38
File diff suppressed because it is too large
Load Diff
@@ -35,6 +35,7 @@ describe("POST /admin/products", () => {
|
|||||||
expect(ProductServiceMock.create).toHaveBeenCalledTimes(1)
|
expect(ProductServiceMock.create).toHaveBeenCalledTimes(1)
|
||||||
expect(ProductServiceMock.create).toHaveBeenCalledWith({
|
expect(ProductServiceMock.create).toHaveBeenCalledWith({
|
||||||
title: "Test Product",
|
title: "Test Product",
|
||||||
|
discountable: true,
|
||||||
description: "Test Description",
|
description: "Test Description",
|
||||||
tags: [{ id: "test", value: "test" }],
|
tags: [{ id: "test", value: "test" }],
|
||||||
handle: "test-product",
|
handle: "test-product",
|
||||||
@@ -92,6 +93,7 @@ describe("POST /admin/products", () => {
|
|||||||
expect(ProductServiceMock.create).toHaveBeenCalledTimes(1)
|
expect(ProductServiceMock.create).toHaveBeenCalledTimes(1)
|
||||||
expect(ProductServiceMock.create).toHaveBeenCalledWith({
|
expect(ProductServiceMock.create).toHaveBeenCalledWith({
|
||||||
title: "Gift Card",
|
title: "Gift Card",
|
||||||
|
discountable: true,
|
||||||
description: "make someone happy",
|
description: "make someone happy",
|
||||||
options: [{ title: "Denominations" }],
|
options: [{ title: "Denominations" }],
|
||||||
handle: "test-gift-card",
|
handle: "test-gift-card",
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ describe("GET /admin/products/:id", () => {
|
|||||||
"description",
|
"description",
|
||||||
"handle",
|
"handle",
|
||||||
"is_giftcard",
|
"is_giftcard",
|
||||||
|
"discountable",
|
||||||
"thumbnail",
|
"thumbnail",
|
||||||
"profile_id",
|
"profile_id",
|
||||||
"collection_id",
|
"collection_id",
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ import { defaultRelations, defaultFields } from "."
|
|||||||
* is_giftcard:
|
* is_giftcard:
|
||||||
* description: A flag to indicate if the Product represents a Gift Card. Purchasing Products with this flag set to `true` will result in a Gift Card being created.
|
* description: A flag to indicate if the Product represents a Gift Card. Purchasing Products with this flag set to `true` will result in a Gift Card being created.
|
||||||
* type: boolean
|
* type: boolean
|
||||||
|
* discountable:
|
||||||
|
* description: A flag to indicate if discounts can be applied to the LineItems generated from this Product
|
||||||
|
* type: boolean
|
||||||
* images:
|
* images:
|
||||||
* description: Images of the Product.
|
* description: Images of the Product.
|
||||||
* type: array
|
* type: array
|
||||||
@@ -184,6 +187,7 @@ export default async (req, res) => {
|
|||||||
subtitle: Validator.string().allow(""),
|
subtitle: Validator.string().allow(""),
|
||||||
description: Validator.string().allow(""),
|
description: Validator.string().allow(""),
|
||||||
is_giftcard: Validator.boolean().default(false),
|
is_giftcard: Validator.boolean().default(false),
|
||||||
|
discountable: Validator.boolean().default(true),
|
||||||
images: Validator.array()
|
images: Validator.array()
|
||||||
.items(Validator.string())
|
.items(Validator.string())
|
||||||
.optional(),
|
.optional(),
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ export const defaultFields = [
|
|||||||
"description",
|
"description",
|
||||||
"handle",
|
"handle",
|
||||||
"is_giftcard",
|
"is_giftcard",
|
||||||
|
"discountable",
|
||||||
"thumbnail",
|
"thumbnail",
|
||||||
"profile_id",
|
"profile_id",
|
||||||
"collection_id",
|
"collection_id",
|
||||||
@@ -93,6 +94,7 @@ export const allowedFields = [
|
|||||||
"description",
|
"description",
|
||||||
"handle",
|
"handle",
|
||||||
"is_giftcard",
|
"is_giftcard",
|
||||||
|
"discountable",
|
||||||
"thumbnail",
|
"thumbnail",
|
||||||
"profile_id",
|
"profile_id",
|
||||||
"collection_id",
|
"collection_id",
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ import { defaultRelations, defaultFields } from "."
|
|||||||
* is_giftcard:
|
* is_giftcard:
|
||||||
* description: A flag to indicate if the Product represents a Gift Card. Purchasing Products with this flag set to `true` will result in a Gift Card being created.
|
* description: A flag to indicate if the Product represents a Gift Card. Purchasing Products with this flag set to `true` will result in a Gift Card being created.
|
||||||
* type: boolean
|
* type: boolean
|
||||||
|
* discountable:
|
||||||
|
* description: A flag to indicate if discounts can be applied to the LineItems generated from this Product
|
||||||
|
* type: boolean
|
||||||
* images:
|
* images:
|
||||||
* description: Images of the Product.
|
* description: Images of the Product.
|
||||||
* type: array
|
* type: array
|
||||||
@@ -189,6 +192,7 @@ export default async (req, res) => {
|
|||||||
.optional()
|
.optional()
|
||||||
.allow(null, ""),
|
.allow(null, ""),
|
||||||
description: Validator.string().optional(),
|
description: Validator.string().optional(),
|
||||||
|
discountable: Validator.boolean().optional(),
|
||||||
type: Validator.object()
|
type: Validator.object()
|
||||||
.keys({
|
.keys({
|
||||||
id: Validator.string().optional(),
|
id: Validator.string().optional(),
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import {MigrationInterface, QueryRunner} from "typeorm";
|
||||||
|
|
||||||
|
export class addDiscountableToProduct1627995307200 implements MigrationInterface {
|
||||||
|
name = 'addDiscountableToProduct1627995307200'
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "product" ADD "discountable" boolean NOT NULL DEFAULT true`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "product" DROP COLUMN "discountable"`);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -136,6 +136,9 @@ export class Product {
|
|||||||
})
|
})
|
||||||
tags: ProductTag[]
|
tags: ProductTag[]
|
||||||
|
|
||||||
|
@Column({ default: true })
|
||||||
|
discountable: boolean
|
||||||
|
|
||||||
@CreateDateColumn({ type: "timestamptz" })
|
@CreateDateColumn({ type: "timestamptz" })
|
||||||
created_at: Date
|
created_at: Date
|
||||||
|
|
||||||
@@ -184,6 +187,9 @@ export class Product {
|
|||||||
* is_giftcard:
|
* is_giftcard:
|
||||||
* description: "Whether the Product represents a Gift Card. Products that represent Gift Cards will automatically generate a redeemable Gift Card code once they are purchased."
|
* description: "Whether the Product represents a Gift Card. Products that represent Gift Cards will automatically generate a redeemable Gift Card code once they are purchased."
|
||||||
* type: boolean
|
* type: boolean
|
||||||
|
* discountable:
|
||||||
|
* description: "Whether the Product can be discounted. Discounts will not apply to Line Items of this Product when this flag is set to `false`.
|
||||||
|
* type: boolean
|
||||||
* images:
|
* images:
|
||||||
* description: "Images of the Product"
|
* description: "Images of the Product"
|
||||||
* type: array
|
* type: array
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ describe("LineItemService", () => {
|
|||||||
title: "Test product",
|
title: "Test product",
|
||||||
thumbnail: "",
|
thumbnail: "",
|
||||||
is_giftcard: true,
|
is_giftcard: true,
|
||||||
|
discountable: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ class LineItemService extends BaseService {
|
|||||||
thumbnail: variant.product.thumbnail,
|
thumbnail: variant.product.thumbnail,
|
||||||
variant_id: variant.id,
|
variant_id: variant.id,
|
||||||
quantity: quantity || 1,
|
quantity: quantity || 1,
|
||||||
allow_discounts: !variant.product.is_giftcard,
|
allow_discounts: variant.product.discountable,
|
||||||
is_giftcard: variant.product.is_giftcard,
|
is_giftcard: variant.product.is_giftcard,
|
||||||
metadata: config?.metadata || {},
|
metadata: config?.metadata || {},
|
||||||
should_merge: shouldMerge,
|
should_merge: shouldMerge,
|
||||||
|
|||||||
@@ -288,6 +288,11 @@ class ProductService extends BaseService {
|
|||||||
rest.thumbnail = images[0]
|
rest.thumbnail = images[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if product is a giftcard, we should disallow discounts
|
||||||
|
if (rest.is_giftcard) {
|
||||||
|
rest.discountable = false
|
||||||
|
}
|
||||||
|
|
||||||
let product = productRepo.create(rest)
|
let product = productRepo.create(rest)
|
||||||
|
|
||||||
if (images && images.length) {
|
if (images && images.length) {
|
||||||
|
|||||||
Reference in New Issue
Block a user