diff --git a/packages/medusa/src/api/routes/admin/products/create-product.js b/packages/medusa/src/api/routes/admin/products/create-product.js index 2afbe02077..5c5db62821 100644 --- a/packages/medusa/src/api/routes/admin/products/create-product.js +++ b/packages/medusa/src/api/routes/admin/products/create-product.js @@ -5,10 +5,32 @@ export default async (req, res) => { title: Validator.string().required(), description: Validator.string(), tags: Validator.string(), + options: Validator.array().items({ + title: Validator.string().required(), + }), images: Validator.array().items(Validator.string()), - variants: Validator.array().items(Validator.string()), + variants: Validator.array().items({ + title: Validator.string().required(), + sku: Validator.string(), + ean: Validator.string(), + prices: Validator.array() + .items({ + currency_code: Validator.string().required(), + amount: Validator.number().required(), + }) + .required(), + options: Validator.array() + .items({ + value: Validator.string().required(), + }) + .default([]), + inventory_quantity: Validator.number().optional(), + allow_backorder: Validator.boolean().optional(), + manage_inventory: Validator.boolean().optional(), + metadata: Validator.object().optional(), + }), metadata: Validator.object(), - handle: Validator.string().required(), + handle: Validator.string(), }) const { value, error } = schema.validate(req.body) @@ -17,8 +39,31 @@ export default async (req, res) => { } try { + const { variants } = value + delete value.variants + const productService = req.scope.resolve("productService") let newProduct = await productService.createDraft(value) + + if (variants) { + const optionIds = value.options.map( + o => newProduct.options.find(newO => newO.title === o.title)._id + ) + + await Promise.all( + variants.map(v => { + const variant = { + ...v, + options: v.options.map((o, index) => ({ + ...o, + option_id: optionIds[index], + })), + } + return productService.createVariant(newProduct._id, variant) + }) + ) + } + newProduct = await productService.decorate(newProduct, [ "title", "description", diff --git a/packages/medusa/src/models/product-variant.js b/packages/medusa/src/models/product-variant.js index 7d42680117..c7e0e535a8 100644 --- a/packages/medusa/src/models/product-variant.js +++ b/packages/medusa/src/models/product-variant.js @@ -14,6 +14,8 @@ class ProductVariantModel extends BaseModel { title: { type: String, required: true }, prices: { type: [MoneyAmountSchema], default: [], required: true }, options: { type: [OptionValueSchema], default: [] }, + sku: { type: String, unique: true, sparse: true }, + ean: { type: String, unique: true, sparse: true }, image: { type: String, default: "" }, published: { type: Boolean, default: false }, inventory_quantity: { type: Number, default: 0 }, diff --git a/packages/medusa/src/models/product.js b/packages/medusa/src/models/product.js index cc1cf31a64..fe38f47892 100644 --- a/packages/medusa/src/models/product.js +++ b/packages/medusa/src/models/product.js @@ -13,7 +13,7 @@ class ProductModel extends BaseModel { title: { type: String, required: true }, description: { type: String, default: "" }, tags: { type: String, default: "" }, - handle: { type: String, required: true, unique: true }, + handle: { type: String, unique: true, sparse: true }, images: { type: [String], default: [] }, options: { type: [OptionSchema], default: [] }, variants: { type: [String], default: [] },