feat(medusa): storefront return (#194)
* feat: adds endpoint to lookup an order by its display_id and email * feat: adds storefront returns * fix: pr comments
This commit is contained in:
@@ -0,0 +1,160 @@
|
|||||||
|
const { dropDatabase } = require("pg-god");
|
||||||
|
const path = require("path");
|
||||||
|
const {
|
||||||
|
Region,
|
||||||
|
Order,
|
||||||
|
Customer,
|
||||||
|
ShippingProfile,
|
||||||
|
Product,
|
||||||
|
ProductVariant,
|
||||||
|
MoneyAmount,
|
||||||
|
LineItem,
|
||||||
|
} = require("@medusajs/medusa");
|
||||||
|
|
||||||
|
const setupServer = require("../../../helpers/setup-server");
|
||||||
|
const { useApi } = require("../../../helpers/use-api");
|
||||||
|
const { initDb } = require("../../../helpers/use-db");
|
||||||
|
|
||||||
|
jest.setTimeout(30000);
|
||||||
|
|
||||||
|
describe("/store/carts", () => {
|
||||||
|
let medusaProcess;
|
||||||
|
let dbConnection;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
const cwd = path.resolve(path.join(__dirname, "..", ".."));
|
||||||
|
dbConnection = await initDb({ cwd });
|
||||||
|
medusaProcess = await setupServer({ cwd });
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
dbConnection.close();
|
||||||
|
await dropDatabase({ databaseName: "medusa-integration" });
|
||||||
|
|
||||||
|
medusaProcess.kill();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GET /store/orders", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
const manager = dbConnection.manager;
|
||||||
|
await manager.query(
|
||||||
|
`ALTER SEQUENCE order_display_id_seq RESTART WITH 111`
|
||||||
|
);
|
||||||
|
await manager.insert(Region, {
|
||||||
|
id: "region",
|
||||||
|
name: "Test Region",
|
||||||
|
currency_code: "usd",
|
||||||
|
tax_rate: 0,
|
||||||
|
});
|
||||||
|
await manager.insert(Customer, {
|
||||||
|
id: "cus_1234",
|
||||||
|
email: "test@email.com",
|
||||||
|
});
|
||||||
|
await manager.insert(Order, {
|
||||||
|
id: "order_test",
|
||||||
|
email: "test@email.com",
|
||||||
|
display_id: 111,
|
||||||
|
customer_id: "cus_1234",
|
||||||
|
region_id: "region",
|
||||||
|
tax_rate: 0,
|
||||||
|
currency_code: "usd",
|
||||||
|
});
|
||||||
|
|
||||||
|
const defaultProfile = await manager.findOne(ShippingProfile, {
|
||||||
|
type: "default",
|
||||||
|
});
|
||||||
|
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",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
await manager.insert(LineItem, {
|
||||||
|
id: "test-item",
|
||||||
|
fulfilled_quantity: 1,
|
||||||
|
title: "Line Item",
|
||||||
|
description: "Line Item Desc",
|
||||||
|
thumbnail: "https://test.js/1234",
|
||||||
|
unit_price: 8000,
|
||||||
|
quantity: 1,
|
||||||
|
variant_id: "test-variant",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
const manager = dbConnection.manager;
|
||||||
|
await manager.query(`DELETE FROM "line_item"`);
|
||||||
|
|
||||||
|
await manager.query(`DELETE FROM "order"`);
|
||||||
|
await manager.query(`DELETE FROM "customer"`);
|
||||||
|
await manager.query(`DELETE FROM "region"`);
|
||||||
|
|
||||||
|
await manager.query(`DELETE FROM "product_option_value"`);
|
||||||
|
await manager.query(`DELETE FROM "product_option"`);
|
||||||
|
await manager.query(`DELETE FROM "money_amount"`);
|
||||||
|
await manager.query(`DELETE FROM "product_variant"`);
|
||||||
|
await manager.query(`DELETE FROM "product"`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("looks up order", async () => {
|
||||||
|
const api = useApi();
|
||||||
|
|
||||||
|
const response = await api
|
||||||
|
.get("/store/orders?display_id=111&email=test@email.com")
|
||||||
|
.catch((err) => {
|
||||||
|
return err.response;
|
||||||
|
});
|
||||||
|
expect(response.status).toEqual(200);
|
||||||
|
expect(response.data.order.display_id).toEqual(111);
|
||||||
|
expect(response.data.order.email).toEqual("test@email.com");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("fails if display_id + email not provided", async () => {
|
||||||
|
const api = useApi();
|
||||||
|
|
||||||
|
const response = await api
|
||||||
|
.get("/store/orders?display_id=111")
|
||||||
|
.catch((err) => {
|
||||||
|
return err.response;
|
||||||
|
});
|
||||||
|
expect(response.status).toEqual(400);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("fails if display_id + email not provided", async () => {
|
||||||
|
const api = useApi();
|
||||||
|
|
||||||
|
const response = await api
|
||||||
|
.get("/store/orders?email=test@email.com")
|
||||||
|
.catch((err) => {
|
||||||
|
return err.response;
|
||||||
|
});
|
||||||
|
expect(response.status).toEqual(400);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("fails if email not correct", async () => {
|
||||||
|
const api = useApi();
|
||||||
|
|
||||||
|
const response = await api
|
||||||
|
.get("/store/orders?display_id=111&email=test1@email.com")
|
||||||
|
.catch((err) => {
|
||||||
|
return err.response;
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(response.status).toEqual(404);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,178 @@
|
|||||||
|
const { dropDatabase } = require("pg-god");
|
||||||
|
const path = require("path");
|
||||||
|
const {
|
||||||
|
Region,
|
||||||
|
Order,
|
||||||
|
Customer,
|
||||||
|
ShippingProfile,
|
||||||
|
Product,
|
||||||
|
ProductVariant,
|
||||||
|
ShippingOption,
|
||||||
|
LineItem,
|
||||||
|
} = require("@medusajs/medusa");
|
||||||
|
|
||||||
|
const setupServer = require("../../../helpers/setup-server");
|
||||||
|
const { useApi } = require("../../../helpers/use-api");
|
||||||
|
const { initDb } = require("../../../helpers/use-db");
|
||||||
|
|
||||||
|
jest.setTimeout(30000);
|
||||||
|
|
||||||
|
describe("/store/carts", () => {
|
||||||
|
let medusaProcess;
|
||||||
|
let dbConnection;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
const cwd = path.resolve(path.join(__dirname, "..", ".."));
|
||||||
|
dbConnection = await initDb({ cwd });
|
||||||
|
medusaProcess = await setupServer({ cwd });
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
dbConnection.close();
|
||||||
|
await dropDatabase({ databaseName: "medusa-integration" });
|
||||||
|
|
||||||
|
medusaProcess.kill();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("POST /store/returns", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
const manager = dbConnection.manager;
|
||||||
|
await manager.query(
|
||||||
|
`ALTER SEQUENCE order_display_id_seq RESTART WITH 111`
|
||||||
|
);
|
||||||
|
|
||||||
|
await manager.insert(Region, {
|
||||||
|
id: "region",
|
||||||
|
name: "Test Region",
|
||||||
|
currency_code: "usd",
|
||||||
|
tax_rate: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
await manager.insert(Customer, {
|
||||||
|
id: "cus_1234",
|
||||||
|
email: "test@email.com",
|
||||||
|
});
|
||||||
|
|
||||||
|
await manager.insert(Order, {
|
||||||
|
id: "order_test",
|
||||||
|
email: "test@email.com",
|
||||||
|
display_id: 111,
|
||||||
|
customer_id: "cus_1234",
|
||||||
|
region_id: "region",
|
||||||
|
tax_rate: 0,
|
||||||
|
currency_code: "usd",
|
||||||
|
});
|
||||||
|
|
||||||
|
const defaultProfile = await manager.findOne(ShippingProfile, {
|
||||||
|
type: "default",
|
||||||
|
});
|
||||||
|
|
||||||
|
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",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
await manager.insert(LineItem, {
|
||||||
|
id: "test-item",
|
||||||
|
order_id: "order_test",
|
||||||
|
fulfilled_quantity: 1,
|
||||||
|
title: "Line Item",
|
||||||
|
description: "Line Item Desc",
|
||||||
|
thumbnail: "https://test.js/1234",
|
||||||
|
unit_price: 8000,
|
||||||
|
quantity: 1,
|
||||||
|
variant_id: "test-variant",
|
||||||
|
});
|
||||||
|
|
||||||
|
await manager.insert(ShippingOption, {
|
||||||
|
id: "test-option",
|
||||||
|
name: "Test ret",
|
||||||
|
profile_id: defaultProfile.id,
|
||||||
|
region_id: "region",
|
||||||
|
provider_id: "test-ful",
|
||||||
|
data: {},
|
||||||
|
price_type: "flat_rate",
|
||||||
|
amount: 1000,
|
||||||
|
is_return: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
const manager = dbConnection.manager;
|
||||||
|
await manager.query(`DELETE FROM "shipping_method"`);
|
||||||
|
await manager.query(`DELETE FROM "shipping_option"`);
|
||||||
|
await manager.query(`DELETE FROM "return_item"`);
|
||||||
|
await manager.query(`DELETE FROM "return"`);
|
||||||
|
await manager.query(`DELETE FROM "line_item"`);
|
||||||
|
await manager.query(`DELETE FROM "order"`);
|
||||||
|
await manager.query(`DELETE FROM "customer"`);
|
||||||
|
await manager.query(`DELETE FROM "region"`);
|
||||||
|
|
||||||
|
await manager.query(`DELETE FROM "product_option_value"`);
|
||||||
|
await manager.query(`DELETE FROM "product_option"`);
|
||||||
|
await manager.query(`DELETE FROM "money_amount"`);
|
||||||
|
await manager.query(`DELETE FROM "product_variant"`);
|
||||||
|
await manager.query(`DELETE FROM "product"`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("creates a return", async () => {
|
||||||
|
const api = useApi();
|
||||||
|
|
||||||
|
const response = await api
|
||||||
|
.post("/store/returns", {
|
||||||
|
order_id: "order_test",
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
item_id: "test-item",
|
||||||
|
quantity: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
return err.response;
|
||||||
|
});
|
||||||
|
expect(response.status).toEqual(200);
|
||||||
|
|
||||||
|
expect(response.data.return.refund_amount).toEqual(8000);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("creates a return with shipping method", async () => {
|
||||||
|
const api = useApi();
|
||||||
|
|
||||||
|
const response = await api
|
||||||
|
.post("/store/returns", {
|
||||||
|
order_id: "order_test",
|
||||||
|
return_shipping: {
|
||||||
|
option_id: "test-option",
|
||||||
|
},
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
item_id: "test-item",
|
||||||
|
quantity: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
return err.response;
|
||||||
|
});
|
||||||
|
expect(response.status).toEqual(200);
|
||||||
|
|
||||||
|
expect(response.data.return.refund_amount).toEqual(7000);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -8,7 +8,8 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@medusajs/medusa": "^1.1.3",
|
"@medusajs/medusa": "^1.1.3",
|
||||||
"medusa-interfaces": "^1.1.0"
|
"medusa-interfaces": "^1.1.0",
|
||||||
|
"typeorm": "^0.2.31"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/cli": "^7.12.10",
|
"@babel/cli": "^7.12.10",
|
||||||
@@ -16,4 +17,4 @@
|
|||||||
"@babel/node": "^7.12.10",
|
"@babel/node": "^7.12.10",
|
||||||
"babel-preset-medusa-package": "^1.1.0"
|
"babel-preset-medusa-package": "^1.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,10 @@ class TestFulService extends FulfillmentService {
|
|||||||
return Promise.resolve({});
|
return Promise.resolve({});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createReturn() {
|
||||||
|
return Promise.resolve({});
|
||||||
|
}
|
||||||
|
|
||||||
createFulfillment() {
|
createFulfillment() {
|
||||||
// No data is being sent anywhere
|
// No data is being sent anywhere
|
||||||
return Promise.resolve({});
|
return Promise.resolve({});
|
||||||
|
|||||||
@@ -4064,6 +4064,28 @@ typeorm@^0.2.29:
|
|||||||
yargonaut "^1.1.2"
|
yargonaut "^1.1.2"
|
||||||
yargs "^16.0.3"
|
yargs "^16.0.3"
|
||||||
|
|
||||||
|
typeorm@^0.2.31:
|
||||||
|
version "0.2.31"
|
||||||
|
resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.2.31.tgz#82b8a1b233224f81c738f53b0380386ccf360917"
|
||||||
|
integrity sha512-dVvCEVHH48DG0QPXAKfo0l6ecQrl3A8ucGP4Yw4myz4YEDMProebTQo8as83uyES+nrwCbu3qdkL4ncC2+qcMA==
|
||||||
|
dependencies:
|
||||||
|
"@sqltools/formatter" "1.2.2"
|
||||||
|
app-root-path "^3.0.0"
|
||||||
|
buffer "^5.5.0"
|
||||||
|
chalk "^4.1.0"
|
||||||
|
cli-highlight "^2.1.10"
|
||||||
|
debug "^4.1.1"
|
||||||
|
dotenv "^8.2.0"
|
||||||
|
glob "^7.1.6"
|
||||||
|
js-yaml "^3.14.0"
|
||||||
|
mkdirp "^1.0.4"
|
||||||
|
reflect-metadata "^0.1.13"
|
||||||
|
sha.js "^2.4.11"
|
||||||
|
tslib "^1.13.0"
|
||||||
|
xml2js "^0.4.23"
|
||||||
|
yargonaut "^1.1.2"
|
||||||
|
yargs "^16.0.3"
|
||||||
|
|
||||||
uid-safe@~2.1.5:
|
uid-safe@~2.1.5:
|
||||||
version "2.1.5"
|
version "2.1.5"
|
||||||
resolved "https://registry.yarnpkg.com/uid-safe/-/uid-safe-2.1.5.tgz#2b3d5c7240e8fc2e58f8aa269e5ee49c0857bd3a"
|
resolved "https://registry.yarnpkg.com/uid-safe/-/uid-safe-2.1.5.tgz#2b3d5c7240e8fc2e58f8aa269e5ee49c0857bd3a"
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import orderRoutes from "./orders"
|
|||||||
import customerRoutes from "./customers"
|
import customerRoutes from "./customers"
|
||||||
import shippingOptionRoutes from "./shipping-options"
|
import shippingOptionRoutes from "./shipping-options"
|
||||||
import regionRoutes from "./regions"
|
import regionRoutes from "./regions"
|
||||||
|
import returnRoutes from "./returns"
|
||||||
import swapRoutes from "./swaps"
|
import swapRoutes from "./swaps"
|
||||||
import variantRoutes from "./variants"
|
import variantRoutes from "./variants"
|
||||||
import giftCardRoutes from "./gift-cards"
|
import giftCardRoutes from "./gift-cards"
|
||||||
@@ -38,6 +39,7 @@ export default (app, container, config) => {
|
|||||||
regionRoutes(route)
|
regionRoutes(route)
|
||||||
swapRoutes(route)
|
swapRoutes(route)
|
||||||
variantRoutes(route)
|
variantRoutes(route)
|
||||||
|
returnRoutes(route)
|
||||||
giftCardRoutes(route)
|
giftCardRoutes(route)
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ const route = Router()
|
|||||||
export default app => {
|
export default app => {
|
||||||
app.use("/orders", route)
|
app.use("/orders", route)
|
||||||
|
|
||||||
|
route.get("/", middlewares.wrap(require("./lookup-order").default))
|
||||||
route.get("/:id", middlewares.wrap(require("./get-order").default))
|
route.get("/:id", middlewares.wrap(require("./get-order").default))
|
||||||
|
|
||||||
route.get(
|
route.get(
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
import { Validator, MedusaError } from "medusa-core-utils"
|
||||||
|
import { defaultRelations, defaultFields } from "./index"
|
||||||
|
|
||||||
|
export default async (req, res) => {
|
||||||
|
const schema = Validator.object().keys({
|
||||||
|
display_id: Validator.number().required(),
|
||||||
|
email: Validator.string().required(),
|
||||||
|
shipping_address: Validator.object()
|
||||||
|
.keys({
|
||||||
|
postal_code: Validator.string(),
|
||||||
|
})
|
||||||
|
.optional(),
|
||||||
|
})
|
||||||
|
|
||||||
|
const { value, error } = schema.validate(req.query)
|
||||||
|
if (error) {
|
||||||
|
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const orderService = req.scope.resolve("orderService")
|
||||||
|
|
||||||
|
const orders = await orderService.list(
|
||||||
|
{
|
||||||
|
display_id: value.display_id,
|
||||||
|
email: value.email,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
select: defaultFields,
|
||||||
|
relations: defaultRelations,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (orders.length !== 1) {
|
||||||
|
res.sendStatus(404)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const order = orders[0]
|
||||||
|
|
||||||
|
res.json({ order })
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,170 @@
|
|||||||
|
import { MedusaError, Validator } from "medusa-core-utils"
|
||||||
|
import { defaultRelations, defaultFields } from "./"
|
||||||
|
|
||||||
|
export default async (req, res) => {
|
||||||
|
const schema = Validator.object().keys({
|
||||||
|
order_id: Validator.string().required(),
|
||||||
|
items: Validator.array()
|
||||||
|
.items({
|
||||||
|
item_id: Validator.string().required(),
|
||||||
|
quantity: Validator.number().required(),
|
||||||
|
})
|
||||||
|
.required(),
|
||||||
|
return_shipping: Validator.object()
|
||||||
|
.keys({
|
||||||
|
option_id: Validator.string().optional(),
|
||||||
|
})
|
||||||
|
.optional(),
|
||||||
|
})
|
||||||
|
|
||||||
|
const { value, error } = schema.validate(req.body)
|
||||||
|
if (error) {
|
||||||
|
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
|
||||||
|
}
|
||||||
|
|
||||||
|
const idempotencyKeyService = req.scope.resolve("idempotencyKeyService")
|
||||||
|
|
||||||
|
const headerKey = req.get("Idempotency-Key") || ""
|
||||||
|
|
||||||
|
let idempotencyKey
|
||||||
|
try {
|
||||||
|
idempotencyKey = await idempotencyKeyService.initializeRequest(
|
||||||
|
headerKey,
|
||||||
|
req.method,
|
||||||
|
req.params,
|
||||||
|
req.path
|
||||||
|
)
|
||||||
|
} catch (error) {
|
||||||
|
res.status(409).send("Failed to create idempotency key")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res.setHeader("Access-Control-Expose-Headers", "Idempotency-Key")
|
||||||
|
res.setHeader("Idempotency-Key", idempotencyKey.idempotency_key)
|
||||||
|
|
||||||
|
try {
|
||||||
|
const orderService = req.scope.resolve("orderService")
|
||||||
|
const returnService = req.scope.resolve("returnService")
|
||||||
|
const eventBus = req.scope.resolve("eventBusService")
|
||||||
|
|
||||||
|
let inProgress = true
|
||||||
|
let err = false
|
||||||
|
|
||||||
|
while (inProgress) {
|
||||||
|
switch (idempotencyKey.recovery_point) {
|
||||||
|
case "started": {
|
||||||
|
const { key, error } = await idempotencyKeyService.workStage(
|
||||||
|
idempotencyKey.idempotency_key,
|
||||||
|
async manager => {
|
||||||
|
const order = await orderService
|
||||||
|
.withTransaction(manager)
|
||||||
|
.retrieve(value.order_id, {
|
||||||
|
select: ["refunded_total", "total"],
|
||||||
|
relations: ["items"],
|
||||||
|
})
|
||||||
|
|
||||||
|
const returnObj = {
|
||||||
|
order_id: value.order_id,
|
||||||
|
idempotency_key: idempotencyKey.idempotency_key,
|
||||||
|
items: value.items,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.return_shipping) {
|
||||||
|
returnObj.shipping_method = value.return_shipping
|
||||||
|
}
|
||||||
|
|
||||||
|
const createdReturn = await returnService
|
||||||
|
.withTransaction(manager)
|
||||||
|
.create(returnObj, order)
|
||||||
|
|
||||||
|
if (value.return_shipping) {
|
||||||
|
await returnService
|
||||||
|
.withTransaction(manager)
|
||||||
|
.fulfill(createdReturn.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
await eventBus
|
||||||
|
.withTransaction(manager)
|
||||||
|
.emit("order.return_requested", {
|
||||||
|
id: value.order_id,
|
||||||
|
return_id: createdReturn.id,
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
recovery_point: "return_requested",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
inProgress = false
|
||||||
|
err = error
|
||||||
|
} else {
|
||||||
|
idempotencyKey = key
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
case "return_requested": {
|
||||||
|
const { key, error } = await idempotencyKeyService.workStage(
|
||||||
|
idempotencyKey.idempotency_key,
|
||||||
|
async manager => {
|
||||||
|
let order = await orderService
|
||||||
|
.withTransaction(manager)
|
||||||
|
.retrieve(value.order_id, { relations: ["returns"] })
|
||||||
|
|
||||||
|
let ret = await returnService.withTransaction(manager).list({
|
||||||
|
idempotency_key: idempotencyKey.idempotency_key,
|
||||||
|
})
|
||||||
|
if (!ret.length) {
|
||||||
|
throw new MedusaError(
|
||||||
|
MedusaError.Types.INVALID_DATA,
|
||||||
|
`Return not found`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
ret = ret[0]
|
||||||
|
|
||||||
|
return {
|
||||||
|
response_code: 200,
|
||||||
|
response_body: { return: ret },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
inProgress = false
|
||||||
|
err = error
|
||||||
|
} else {
|
||||||
|
idempotencyKey = key
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
case "finished": {
|
||||||
|
inProgress = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
idempotencyKey = await idempotencyKeyService.update(
|
||||||
|
idempotencyKey.idempotency_key,
|
||||||
|
{
|
||||||
|
recovery_point: "finished",
|
||||||
|
response_code: 500,
|
||||||
|
response_body: { message: "Unknown recovery point" },
|
||||||
|
}
|
||||||
|
)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(idempotencyKey.response_code).json(idempotencyKey.response_body)
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { Router } from "express"
|
||||||
|
import middlewares from "../../../middlewares"
|
||||||
|
|
||||||
|
const route = Router()
|
||||||
|
|
||||||
|
export default app => {
|
||||||
|
app.use("/returns", route)
|
||||||
|
|
||||||
|
route.post("/", middlewares.wrap(require("./create-return").default))
|
||||||
|
|
||||||
|
return app
|
||||||
|
}
|
||||||
@@ -240,6 +240,15 @@ class ReturnService extends BaseService {
|
|||||||
this.validateReturnLineItem_
|
this.validateReturnLineItem_
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (data.shipping_method) {
|
||||||
|
if (typeof data.shipping_method.price === "undefined") {
|
||||||
|
const opt = await this.shippingOptionService_.retrieve(
|
||||||
|
data.shipping_method.option_id
|
||||||
|
)
|
||||||
|
data.shipping_method.price = opt.amount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let toRefund = data.refund_amount
|
let toRefund = data.refund_amount
|
||||||
if (typeof toRefund !== "undefined") {
|
if (typeof toRefund !== "undefined") {
|
||||||
const refundable = orderLike.total - orderLike.refunded_total
|
const refundable = orderLike.total - orderLike.refunded_total
|
||||||
|
|||||||
+6
-890
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user