diff --git a/packages/medusa-core-utils/src/__tests__/transform-idable-fields.js b/packages/medusa-core-utils/src/__tests__/transform-idable-fields.js new file mode 100644 index 0000000000..c8f8113cf5 --- /dev/null +++ b/packages/medusa-core-utils/src/__tests__/transform-idable-fields.js @@ -0,0 +1,105 @@ +import { transformIdableFields } from "../transform-idable-fields" + +describe("transformIdableFields", () => { + test("one field", () => { + const test = { + shipping_address: "test_id", + } + + const result = transformIdableFields(test, ["shipping_address"]) + + expect(test).toEqual(test) + + expect(result).toEqual({ + shipping_address_id: "test_id", + }) + }) + + test("duplicate field", () => { + const test = { + shipping_address: "test_id", + shipping_address_id: "something else", + } + + const result = transformIdableFields(test, ["shipping_address"]) + + expect(test).toEqual(test) + + expect(result).toEqual({ + shipping_address_id: "test_id", + }) + }) + + test("many fields", () => { + const test = { + shipping_address: "test_id", + customer: "cus_test", + region: "reg_test", + something: "else", + } + + const result = transformIdableFields(test, [ + "shipping_address", + "customer", + "region", + ]) + + expect(test).toEqual(test) + + expect(result).toEqual({ + shipping_address_id: "test_id", + customer_id: "cus_test", + region_id: "reg_test", + something: "else", + }) + }) + + test("mix fields", () => { + const test = { + shipping_address: { + address_1: "my home", + }, + customer: "cus_test", + region: "reg_test", + something: "else", + } + + const result = transformIdableFields(test, [ + "shipping_address", + "customer", + "region", + ]) + + expect(test).toEqual(test) + + expect(result).toEqual({ + shipping_address: { + address_1: "my home", + }, + customer_id: "cus_test", + region_id: "reg_test", + something: "else", + }) + }) + + test("no fields", () => { + const test = { + something: "else", + and: "more", + maybe: "one more", + } + + const result = transformIdableFields(test, [ + "shipping_address", + "customer", + "region", + ]) + + expect(test).toEqual(test) + expect(result).toEqual({ + something: "else", + and: "more", + maybe: "one more", + }) + }) +}) diff --git a/packages/medusa-core-utils/src/index.js b/packages/medusa-core-utils/src/index.js index d30a469a72..c12fd278ef 100644 --- a/packages/medusa-core-utils/src/index.js +++ b/packages/medusa-core-utils/src/index.js @@ -1,5 +1,6 @@ export { countries } from "./countries" export { isoCountryLookup } from "./countries" +export { transformIdableFields } from "./transform-idable-fields" export { default as Validator } from "./validator" export { default as MedusaError } from "./errors" export { default as getConfigFile } from "./get-config-file" diff --git a/packages/medusa-core-utils/src/transform-idable-fields.js b/packages/medusa-core-utils/src/transform-idable-fields.js new file mode 100644 index 0000000000..eabfaeace5 --- /dev/null +++ b/packages/medusa-core-utils/src/transform-idable-fields.js @@ -0,0 +1,22 @@ +/** + * Takes an object and a list of fields to tranform in that object. If the field + * exists on the object and its value is a string it will append `_id` to the + * field name. This is used when allowing API calls to hold either ID or object + * values in the payload. The method returns a new object with the + * transformation. + * @param {Object} obj - the object to transform + * @param {Array} fields - the fields to apply transformation to + * @returns {Object} the transformed object + */ +export const transformIdableFields = (obj, fields) => { + const ret = { ...obj } + + for (const key of fields) { + if (key in obj && typeof ret[key] === "string") { + ret[`${key}_id`] = ret[key] + delete ret[key] + } + } + + return ret +} diff --git a/packages/medusa/src/api/routes/admin/draft-orders/create-draft-order.js b/packages/medusa/src/api/routes/admin/draft-orders/create-draft-order.js index 3c0e358a9e..216618836b 100644 --- a/packages/medusa/src/api/routes/admin/draft-orders/create-draft-order.js +++ b/packages/medusa/src/api/routes/admin/draft-orders/create-draft-order.js @@ -1,4 +1,8 @@ -import { MedusaError, Validator } from "medusa-core-utils" +import { + MedusaError, + Validator, + transformIdableFields, +} from "medusa-core-utils" import { defaultFields, defaultRelations } from "." /** @@ -133,11 +137,13 @@ export default async (req, res) => { metadata: Validator.object().optional(), }) - const { value, error } = schema.validate(req.body) + let { value, error } = schema.validate(req.body) if (error) { throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details) } + value = transformIdableFields(value, ["shipping_address", "billing_address"]) + try { const draftOrderService = req.scope.resolve("draftOrderService") let draftOrder = await draftOrderService.create(value) diff --git a/packages/medusa/src/services/cart.js b/packages/medusa/src/services/cart.js index 958b73000d..6c2bd03792 100644 --- a/packages/medusa/src/services/cart.js +++ b/packages/medusa/src/services/cart.js @@ -306,8 +306,8 @@ class CartService extends BaseService { const regCountries = region.countries.map(({ iso_2 }) => iso_2) - if (data.shipping_address && typeof data.shipping_address === `string`) { - const addr = await addressRepo.findOne(data.shipping_address) + if (data.shipping_address_id) { + const addr = await addressRepo.findOne(data.shipping_address_id) data.shipping_address = addr } @@ -650,16 +650,14 @@ class CartService extends BaseService { } const addrRepo = manager.getCustomRepository(this.addressRepository_) - if ("shipping_address" in update) { - await this.updateShippingAddress_( - cart, - update.shipping_address, - addrRepo - ) + if ("shipping_address_id" in update || "shipping_address" in update) { + const address = update.shipping_address_id || update.shipping_address + await this.updateShippingAddress_(cart, address, addrRepo) } - if ("billing_address" in update) { - await this.updateBillingAddress_(cart, update.billing_address, addrRepo) + if ("billing_address_id" in update || "billing_address" in update) { + const address = update.billing_address_id || update.billing_address + await this.updateBillingAddress_(cart, address, addrRepo) } if ("discounts" in update) {