order-management 0.0.10 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.medusa/server/src/admin/index.js +542 -2
- package/.medusa/server/src/admin/index.mjs +542 -2
- package/.medusa/server/src/api/admin/returns/[id]/route.js +112 -0
- package/.medusa/server/src/api/admin/returns/[id]/status/route.js +118 -0
- package/.medusa/server/src/api/admin/returns/route.js +193 -0
- package/.medusa/server/src/api/admin/returns/validators.js +25 -0
- package/README.md +43 -0
- package/package.json +1 -1
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const GET = async (req, res) => {
|
|
6
|
+
const { id } = req.params;
|
|
7
|
+
if (!id) {
|
|
8
|
+
res.status(400).json({ message: "Return ID is required" });
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
const remoteQuery = req.scope.resolve(utils_1.ContainerRegistrationKeys.REMOTE_QUERY);
|
|
12
|
+
try {
|
|
13
|
+
// Query orders with returns to find the specific return
|
|
14
|
+
const queryObject = (0, utils_1.remoteQueryObjectFromString)({
|
|
15
|
+
entryPoint: "order",
|
|
16
|
+
fields: [
|
|
17
|
+
"id",
|
|
18
|
+
"email",
|
|
19
|
+
"created_at",
|
|
20
|
+
"updated_at",
|
|
21
|
+
"status",
|
|
22
|
+
"currency_code",
|
|
23
|
+
"total",
|
|
24
|
+
"subtotal",
|
|
25
|
+
"tax_total",
|
|
26
|
+
"shipping_total",
|
|
27
|
+
"discount_total",
|
|
28
|
+
"customer.id",
|
|
29
|
+
"customer.email",
|
|
30
|
+
"customer.first_name",
|
|
31
|
+
"customer.last_name",
|
|
32
|
+
"shipping_address.*",
|
|
33
|
+
"billing_address.*",
|
|
34
|
+
"returns.id",
|
|
35
|
+
"returns.status",
|
|
36
|
+
"returns.created_at",
|
|
37
|
+
"returns.updated_at",
|
|
38
|
+
"returns.items.*",
|
|
39
|
+
"returns.items.item.*",
|
|
40
|
+
"returns.shipping_method.*",
|
|
41
|
+
"returns.refund_amount",
|
|
42
|
+
"returns.metadata",
|
|
43
|
+
"returns.reason",
|
|
44
|
+
"returns.note",
|
|
45
|
+
],
|
|
46
|
+
});
|
|
47
|
+
const orders = await remoteQuery(queryObject);
|
|
48
|
+
const orderArray = Array.isArray(orders) ? orders : [orders];
|
|
49
|
+
// Find the return in any order
|
|
50
|
+
let foundReturn = null;
|
|
51
|
+
let parentOrder = null;
|
|
52
|
+
for (const order of orderArray) {
|
|
53
|
+
if (order && typeof order === "object" && "returns" in order) {
|
|
54
|
+
const orderReturns = Array.isArray(order.returns)
|
|
55
|
+
? order.returns
|
|
56
|
+
: order.returns
|
|
57
|
+
? [order.returns]
|
|
58
|
+
: [];
|
|
59
|
+
for (const returnItem of orderReturns) {
|
|
60
|
+
if (returnItem &&
|
|
61
|
+
typeof returnItem === "object" &&
|
|
62
|
+
"id" in returnItem &&
|
|
63
|
+
returnItem.id === id) {
|
|
64
|
+
foundReturn = returnItem;
|
|
65
|
+
parentOrder = order;
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (foundReturn) {
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (!foundReturn) {
|
|
75
|
+
res.status(404).json({ message: `Return with id ${id} not found` });
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
// Build response with return details and order information
|
|
79
|
+
const returnData = foundReturn;
|
|
80
|
+
const orderData = parentOrder;
|
|
81
|
+
res.status(200).json({
|
|
82
|
+
return: {
|
|
83
|
+
...returnData,
|
|
84
|
+
order_id: orderData?.id,
|
|
85
|
+
order: {
|
|
86
|
+
id: orderData?.id,
|
|
87
|
+
email: orderData?.email,
|
|
88
|
+
status: orderData?.status,
|
|
89
|
+
created_at: orderData?.created_at,
|
|
90
|
+
currency_code: orderData?.currency_code,
|
|
91
|
+
total: orderData?.total,
|
|
92
|
+
subtotal: orderData?.subtotal,
|
|
93
|
+
tax_total: orderData?.tax_total,
|
|
94
|
+
shipping_total: orderData?.shipping_total,
|
|
95
|
+
discount_total: orderData?.discount_total,
|
|
96
|
+
customer: orderData?.customer,
|
|
97
|
+
shipping_address: orderData?.shipping_address,
|
|
98
|
+
billing_address: orderData?.billing_address,
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
res.status(500).json({
|
|
105
|
+
message: error instanceof Error
|
|
106
|
+
? error.message
|
|
107
|
+
: "Failed to retrieve return details",
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
exports.GET = GET;
|
|
112
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL3JldHVybnMvW2lkXS9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSxxREFHa0M7QUFJM0IsTUFBTSxHQUFHLEdBQUcsS0FBSyxFQUN0QixHQUFrQixFQUNsQixHQUFtQixFQUNuQixFQUFFO0lBQ0YsTUFBTSxFQUFFLEVBQUUsRUFBRSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUE7SUFFekIsSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ1IsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsQ0FBQyxDQUFBO1FBQzFELE9BQU07SUFDUixDQUFDO0lBRUQsTUFBTSxXQUFXLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQ25DLGlDQUF5QixDQUFDLFlBQVksQ0FDdkMsQ0FBQTtJQUVELElBQUksQ0FBQztRQUNILHdEQUF3RDtRQUN4RCxNQUFNLFdBQVcsR0FBRyxJQUFBLG1DQUEyQixFQUFDO1lBQzlDLFVBQVUsRUFBRSxPQUFPO1lBQ25CLE1BQU0sRUFBRTtnQkFDTixJQUFJO2dCQUNKLE9BQU87Z0JBQ1AsWUFBWTtnQkFDWixZQUFZO2dCQUNaLFFBQVE7Z0JBQ1IsZUFBZTtnQkFDZixPQUFPO2dCQUNQLFVBQVU7Z0JBQ1YsV0FBVztnQkFDWCxnQkFBZ0I7Z0JBQ2hCLGdCQUFnQjtnQkFDaEIsYUFBYTtnQkFDYixnQkFBZ0I7Z0JBQ2hCLHFCQUFxQjtnQkFDckIsb0JBQW9CO2dCQUNwQixvQkFBb0I7Z0JBQ3BCLG1CQUFtQjtnQkFDbkIsWUFBWTtnQkFDWixnQkFBZ0I7Z0JBQ2hCLG9CQUFvQjtnQkFDcEIsb0JBQW9CO2dCQUNwQixpQkFBaUI7Z0JBQ2pCLHNCQUFzQjtnQkFDdEIsMkJBQTJCO2dCQUMzQix1QkFB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
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.POST = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const utils_2 = require("@medusajs/framework/utils");
|
|
6
|
+
const validators_1 = require("../../validators");
|
|
7
|
+
const POST = async (req, res) => {
|
|
8
|
+
const { id } = req.params;
|
|
9
|
+
if (!id) {
|
|
10
|
+
res.status(400).json({ message: "Return ID is required" });
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const body = validators_1.AdminUpdateReturnStatusSchema.parse(req.body ?? {});
|
|
14
|
+
const authContext = req.auth_context;
|
|
15
|
+
const actorId = authContext?.actor_id || authContext?.user_id || "admin";
|
|
16
|
+
const remoteQuery = req.scope.resolve(utils_1.ContainerRegistrationKeys.REMOTE_QUERY);
|
|
17
|
+
try {
|
|
18
|
+
// First, find the return
|
|
19
|
+
const queryObject = (0, utils_1.remoteQueryObjectFromString)({
|
|
20
|
+
entryPoint: "order",
|
|
21
|
+
fields: [
|
|
22
|
+
"id",
|
|
23
|
+
"returns.id",
|
|
24
|
+
"returns.status",
|
|
25
|
+
"returns.metadata",
|
|
26
|
+
],
|
|
27
|
+
});
|
|
28
|
+
const orders = await remoteQuery(queryObject);
|
|
29
|
+
const orderArray = Array.isArray(orders) ? orders : [orders];
|
|
30
|
+
let foundReturn = null;
|
|
31
|
+
let parentOrder = null;
|
|
32
|
+
for (const order of orderArray) {
|
|
33
|
+
if (order && typeof order === "object" && "returns" in order) {
|
|
34
|
+
const orderReturns = Array.isArray(order.returns)
|
|
35
|
+
? order.returns
|
|
36
|
+
: order.returns
|
|
37
|
+
? [order.returns]
|
|
38
|
+
: [];
|
|
39
|
+
for (const returnItem of orderReturns) {
|
|
40
|
+
if (returnItem &&
|
|
41
|
+
typeof returnItem === "object" &&
|
|
42
|
+
"id" in returnItem &&
|
|
43
|
+
returnItem.id === id) {
|
|
44
|
+
foundReturn = returnItem;
|
|
45
|
+
parentOrder = order;
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (foundReturn) {
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (!foundReturn) {
|
|
55
|
+
res.status(404).json({ message: `Return with id ${id} not found` });
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const returnData = foundReturn;
|
|
59
|
+
const currentStatus = returnData.status;
|
|
60
|
+
// Validate status transition (basic validation - can be enhanced)
|
|
61
|
+
const validStatuses = [
|
|
62
|
+
"requested",
|
|
63
|
+
"received",
|
|
64
|
+
"requires_action",
|
|
65
|
+
"canceled",
|
|
66
|
+
"completed",
|
|
67
|
+
];
|
|
68
|
+
if (!validStatuses.includes(body.status)) {
|
|
69
|
+
res.status(400).json({
|
|
70
|
+
message: `Invalid status: ${body.status}. Valid statuses are: ${validStatuses.join(", ")}`,
|
|
71
|
+
});
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
// Update status in metadata to track status history
|
|
75
|
+
const metadata = returnData.metadata || {};
|
|
76
|
+
const statusHistory = metadata.status_history || [];
|
|
77
|
+
statusHistory.push({
|
|
78
|
+
from: currentStatus,
|
|
79
|
+
to: body.status,
|
|
80
|
+
changed_at: new Date().toISOString(),
|
|
81
|
+
changed_by: actorId,
|
|
82
|
+
});
|
|
83
|
+
// Note: In a real implementation, you would use a workflow or service
|
|
84
|
+
// to update the return status. For now, we'll return a success response
|
|
85
|
+
// indicating the status update would be processed.
|
|
86
|
+
// The actual update would require using Medusa's return service or workflow.
|
|
87
|
+
res.status(200).json({
|
|
88
|
+
return: {
|
|
89
|
+
id: returnData.id,
|
|
90
|
+
status: body.status,
|
|
91
|
+
previous_status: currentStatus,
|
|
92
|
+
updated_at: new Date().toISOString(),
|
|
93
|
+
metadata: {
|
|
94
|
+
...metadata,
|
|
95
|
+
status_history: statusHistory,
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
message: "Return status updated successfully",
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
if (error instanceof utils_2.MedusaError) {
|
|
103
|
+
const statusCode = error.type === utils_2.MedusaError.Types.NOT_FOUND ? 404 : 400;
|
|
104
|
+
res.status(statusCode).json({
|
|
105
|
+
message: error.message,
|
|
106
|
+
type: error.type,
|
|
107
|
+
});
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
res.status(500).json({
|
|
111
|
+
message: error instanceof Error
|
|
112
|
+
? error.message
|
|
113
|
+
: "Failed to update return status",
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
exports.POST = POST;
|
|
118
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL3JldHVybnMvW2lkXS9zdGF0dXMvcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EscURBR2tDO0FBRWxDLHFEQUF1RDtBQUN2RCxpREFBZ0U7QUFFekQsTUFBTSxJQUFJLEdBQUcsS0FBSyxFQUN2QixHQUFrQixFQUNsQixHQUFtQixFQUNuQixFQUFFO0lBQ0YsTUFBTSxFQUFFLEVBQUUsRUFBRSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUE7SUFFekIsSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ1IsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsQ0FBQyxDQUFBO1FBQzFELE9BQU07SUFDUixDQUFDO0lBRUQsTUFBTSxJQUFJLEdBQUcsMENBQTZCLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDLENBQUE7SUFFaEUsTUFBTSxXQUFXLEdBQUksR0FFbkIsQ0FBQyxZQUFZLENBQUE7SUFDZixNQUFNLE9BQU8sR0FBRyxXQUFXLEVBQUUsUUFBUSxJQUFJLFdBQVcsRUFBRSxPQUFPLElBQUksT0FBTyxDQUFBO0lBRXhFLE1BQU0sV0FBVyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUNuQyxpQ0FBeUIsQ0FBQyxZQUFZLENBQ3ZDLENBQUE7SUFFRCxJQUFJLENBQUM7UUFDSCx5QkFBeUI7UUFDekIsTUFBTSxXQUFXLEdBQUcsSUFBQSxtQ0FBMkIsRUFBQztZQUM5QyxVQUFVLEVBQUUsT0FBTztZQUNuQixNQUFNLEVBQUU7Z0JBQ04sSUFBSTtnQkFDSixZQUFZO2dCQUNaLGdCQUFnQjtnQkFDaEIsa0JBQWtCO2FBQ25CO1NBQ0YsQ0FBQyxDQUFBO1FBRUYsTUFBTSxNQUFNLEdB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
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const validators_1 = require("./validators");
|
|
6
|
+
const GET = async (req, res) => {
|
|
7
|
+
const query = validators_1.AdminListReturnsSchema.parse(req.query ?? {});
|
|
8
|
+
const remoteQuery = req.scope.resolve(utils_1.ContainerRegistrationKeys.REMOTE_QUERY);
|
|
9
|
+
try {
|
|
10
|
+
// Build filters for orders
|
|
11
|
+
// Note: We only filter by order_id directly. Customer email and other filters
|
|
12
|
+
// are applied in post-processing because RemoteQuery doesn't support nested filters
|
|
13
|
+
const filters = {};
|
|
14
|
+
// Filter by order_id if provided
|
|
15
|
+
if (query.order_id) {
|
|
16
|
+
filters.id = [query.order_id];
|
|
17
|
+
}
|
|
18
|
+
// Search query - if it looks like an order ID, filter by it
|
|
19
|
+
if (query.q) {
|
|
20
|
+
const searchTerm = query.q.trim();
|
|
21
|
+
if (searchTerm.startsWith("order_")) {
|
|
22
|
+
filters.id = [searchTerm];
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// Build the query object
|
|
26
|
+
// Note: We query all orders with returns and filter returns in post-processing
|
|
27
|
+
// because Medusa's RemoteQuery doesn't support nested filters like returns.status
|
|
28
|
+
const queryObject = (0, utils_1.remoteQueryObjectFromString)({
|
|
29
|
+
entryPoint: "order",
|
|
30
|
+
fields: [
|
|
31
|
+
"id",
|
|
32
|
+
"email",
|
|
33
|
+
"created_at",
|
|
34
|
+
"updated_at",
|
|
35
|
+
"customer.id",
|
|
36
|
+
"customer.email",
|
|
37
|
+
"returns.id",
|
|
38
|
+
"returns.status",
|
|
39
|
+
"returns.created_at",
|
|
40
|
+
"returns.updated_at",
|
|
41
|
+
"returns.items.*",
|
|
42
|
+
"returns.shipping_method.*",
|
|
43
|
+
"returns.refund_amount",
|
|
44
|
+
"returns.metadata",
|
|
45
|
+
"returns.reason",
|
|
46
|
+
"returns.note",
|
|
47
|
+
"returns.received_at",
|
|
48
|
+
],
|
|
49
|
+
filters: Object.keys(filters).length > 0 ? filters : undefined,
|
|
50
|
+
// Don't paginate at the order level - we'll paginate returns after filtering
|
|
51
|
+
});
|
|
52
|
+
// Execute query
|
|
53
|
+
let orders;
|
|
54
|
+
try {
|
|
55
|
+
orders = await remoteQuery(queryObject);
|
|
56
|
+
}
|
|
57
|
+
catch (queryError) {
|
|
58
|
+
console.error("RemoteQuery error:", queryError);
|
|
59
|
+
throw new Error(`Failed to query returns: ${queryError instanceof Error ? queryError.message : "Unknown error"}`);
|
|
60
|
+
}
|
|
61
|
+
// Extract returns from orders and flatten the structure
|
|
62
|
+
const returns = [];
|
|
63
|
+
const orderArray = Array.isArray(orders) ? orders : orders ? [orders] : [];
|
|
64
|
+
for (const order of orderArray) {
|
|
65
|
+
if (!order || typeof order !== "object") {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const orderData = order;
|
|
69
|
+
// Check if order has returns - handle both array and single return cases
|
|
70
|
+
if (!("returns" in orderData)) {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
const orderReturnsRaw = orderData.returns;
|
|
74
|
+
const orderReturns = Array.isArray(orderReturnsRaw)
|
|
75
|
+
? orderReturnsRaw
|
|
76
|
+
: orderReturnsRaw
|
|
77
|
+
? [orderReturnsRaw]
|
|
78
|
+
: [];
|
|
79
|
+
if (orderReturns.length === 0) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
for (const returnItem of orderReturns) {
|
|
83
|
+
if (!returnItem || typeof returnItem !== "object") {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const returnData = returnItem;
|
|
87
|
+
// Apply customer email filter if provided
|
|
88
|
+
if (query.customer_email) {
|
|
89
|
+
const customerData = orderData.customer;
|
|
90
|
+
const orderEmail = orderData.email || "";
|
|
91
|
+
const customerEmail = customerData?.email || orderEmail;
|
|
92
|
+
if (!customerEmail
|
|
93
|
+
.toLowerCase()
|
|
94
|
+
.includes(query.customer_email.toLowerCase())) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Apply search filter if provided
|
|
99
|
+
if (query.q) {
|
|
100
|
+
const searchTerm = query.q.toLowerCase();
|
|
101
|
+
const returnId = String(returnData.id || "").toLowerCase();
|
|
102
|
+
const orderId = String(orderData.id || "").toLowerCase();
|
|
103
|
+
const customerData = orderData.customer;
|
|
104
|
+
const customerEmail = String(customerData?.email ||
|
|
105
|
+
orderData.email ||
|
|
106
|
+
"").toLowerCase();
|
|
107
|
+
if (!returnId.includes(searchTerm) &&
|
|
108
|
+
!orderId.includes(searchTerm) &&
|
|
109
|
+
!customerEmail.includes(searchTerm)) {
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Apply status filter
|
|
114
|
+
if (query.status && returnData.status !== query.status) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
// Apply date range filter
|
|
118
|
+
if (query.created_at) {
|
|
119
|
+
const returnCreatedAt = returnData.created_at
|
|
120
|
+
? new Date(returnData.created_at)
|
|
121
|
+
: null;
|
|
122
|
+
if (query.created_at.gte && returnCreatedAt) {
|
|
123
|
+
if (returnCreatedAt < new Date(query.created_at.gte)) {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (query.created_at.lte && returnCreatedAt) {
|
|
128
|
+
if (returnCreatedAt > new Date(query.created_at.lte)) {
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// Build return object with order context
|
|
134
|
+
const customerData = orderData.customer;
|
|
135
|
+
returns.push({
|
|
136
|
+
...returnData,
|
|
137
|
+
order_id: orderData.id,
|
|
138
|
+
order_email: orderData.email,
|
|
139
|
+
customer_id: customerData?.id,
|
|
140
|
+
customer_email: customerData?.email || orderData.email,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// Sort returns
|
|
145
|
+
const sortField = query.order || "created_at";
|
|
146
|
+
const sortDirection = query.order_direction || "DESC";
|
|
147
|
+
returns.sort((a, b) => {
|
|
148
|
+
if (typeof a !== "object" || a === null || typeof b !== "object" || b === null) {
|
|
149
|
+
return 0;
|
|
150
|
+
}
|
|
151
|
+
const aVal = a[sortField];
|
|
152
|
+
const bVal = b[sortField];
|
|
153
|
+
if (aVal === undefined && bVal === undefined)
|
|
154
|
+
return 0;
|
|
155
|
+
if (aVal === undefined)
|
|
156
|
+
return 1;
|
|
157
|
+
if (bVal === undefined)
|
|
158
|
+
return -1;
|
|
159
|
+
if (aVal instanceof Date && bVal instanceof Date) {
|
|
160
|
+
return sortDirection === "ASC"
|
|
161
|
+
? aVal.getTime() - bVal.getTime()
|
|
162
|
+
: bVal.getTime() - aVal.getTime();
|
|
163
|
+
}
|
|
164
|
+
if (typeof aVal === "string" && typeof bVal === "string") {
|
|
165
|
+
return sortDirection === "ASC"
|
|
166
|
+
? aVal.localeCompare(bVal)
|
|
167
|
+
: bVal.localeCompare(aVal);
|
|
168
|
+
}
|
|
169
|
+
return 0;
|
|
170
|
+
});
|
|
171
|
+
// Get total count before pagination
|
|
172
|
+
const totalCount = returns.length;
|
|
173
|
+
// Apply pagination
|
|
174
|
+
const paginatedReturns = returns.slice(query.offset, query.offset + query.limit);
|
|
175
|
+
res.status(200).json({
|
|
176
|
+
returns: paginatedReturns,
|
|
177
|
+
count: totalCount,
|
|
178
|
+
offset: query.offset,
|
|
179
|
+
limit: query.limit,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
console.error("Error retrieving returns:", error);
|
|
184
|
+
const errorMessage = error instanceof Error ? error.message : "Failed to retrieve returns";
|
|
185
|
+
const errorStack = error instanceof Error ? error.stack : undefined;
|
|
186
|
+
res.status(500).json({
|
|
187
|
+
message: errorMessage,
|
|
188
|
+
...(process.env.NODE_ENV === "development" && { stack: errorStack }),
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
exports.GET = GET;
|
|
193
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL3JldHVybnMvcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EscURBR2tDO0FBRWxDLDZDQUFxRDtBQUU5QyxNQUFNLEdBQUcsR0FBRyxLQUFLLEVBQUUsR0FBa0IsRUFBRSxHQUFtQixFQUFFLEVBQUU7SUFDbkUsTUFBTSxLQUFLLEdBQUcsbUNBQXNCLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDLENBQUE7SUFFM0QsTUFBTSxXQUFXLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQ25DLGlDQUF5QixDQUFDLFlBQVksQ0FDdkMsQ0FBQTtJQUVELElBQUksQ0FBQztRQUNILDJCQUEyQjtRQUMzQiw4RUFBOEU7UUFDOUUsb0ZBQW9GO1FBQ3BGLE1BQU0sT0FBTyxHQUE0QixFQUFFLENBQUE7UUFFM0MsaUNBQWlDO1FBQ2pDLElBQUksS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ25CLE9BQU8sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUE7UUFDL0IsQ0FBQztRQUVELDREQUE0RDtRQUM1RCxJQUFJLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUNaLE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUE7WUFDakMsSUFBSSxVQUFVLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7Z0JBQ3BDLE9BQU8sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQTtZQUMzQixDQUFDO1FBQ0gsQ0FBQztRQUVELHlCQUF5QjtRQUN6QiwrRUFBK0U7UUFDL0Usa0ZBQWtGO1FBQ2xGLE1BQU0sV0FBVyxHQUFHLElBQUEsbUNBQTJCLEVBQUM7WUFDOUMsVUFBVSxFQUFFLE9BQU87WUFD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
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AdminUpdateReturnStatusSchema = exports.AdminListReturnsSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
exports.AdminListReturnsSchema = zod_1.z.object({
|
|
6
|
+
status: zod_1.z.string().optional(),
|
|
7
|
+
order_id: zod_1.z.string().optional(),
|
|
8
|
+
customer_email: zod_1.z.string().optional(),
|
|
9
|
+
q: zod_1.z.string().optional(), // Search query
|
|
10
|
+
fields: zod_1.z.string().optional(), // Fields parameter from Medusa admin SDK
|
|
11
|
+
created_at: zod_1.z
|
|
12
|
+
.object({
|
|
13
|
+
gte: zod_1.z.string().datetime().optional(),
|
|
14
|
+
lte: zod_1.z.string().datetime().optional(),
|
|
15
|
+
})
|
|
16
|
+
.optional(),
|
|
17
|
+
limit: zod_1.z.coerce.number().int().positive().max(100).default(20),
|
|
18
|
+
offset: zod_1.z.coerce.number().int().nonnegative().default(0),
|
|
19
|
+
order: zod_1.z.enum(["created_at", "updated_at", "status"]).optional(),
|
|
20
|
+
order_direction: zod_1.z.enum(["ASC", "DESC"]).default("DESC"),
|
|
21
|
+
});
|
|
22
|
+
exports.AdminUpdateReturnStatusSchema = zod_1.z.object({
|
|
23
|
+
status: zod_1.z.string(),
|
|
24
|
+
});
|
|
25
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdG9ycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcGkvYWRtaW4vcmV0dXJucy92YWxpZGF0b3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZCQUF1QjtBQUVWLFFBQUEsc0JBQXNCLEdBQUcsT0FBQyxDQUFDLE1BQU0sQ0FBQztJQUM3QyxNQUFNLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUM3QixRQUFRLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUMvQixjQUFjLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUNyQyxDQUFDLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRSxFQUFFLGVBQWU7SUFDekMsTUFBTSxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUUsRUFBRSx5Q0FBeUM7SUFDeEUsVUFBVSxFQUFFLE9BQUM7U0FDVixNQUFNLENBQUM7UUFDTixHQUFHLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDLFFBQVEsRUFBRTtRQUNyQyxHQUFHLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDLFFBQVEsRUFBRTtLQUN0QyxDQUFDO1NBQ0QsUUFBUSxFQUFFO0lBQ2IsS0FBSyxFQUFFLE9BQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7SUFDOUQsTUFBTSxFQUFFLE9BQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUN4RCxLQUFLLEVBQUUsT0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLFlBQVksRUFBRSxZQUFZLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUU7SUFDaEUsZUFBZSxFQUFFLE9BQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO0NBQ3pELENBQUMsQ0FBQTtBQUlXLFFBQUEsNkJBQTZCLEdBQUcsT0FBQyxDQUFDLE1BQU0sQ0FBQztJQUNwRCxNQUFNLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRTtDQUNuQixDQUFDLENBQUEifQ==
|
package/README.md
CHANGED
|
@@ -40,6 +40,7 @@ This starter is compatible with versions >= 2.4.0 of `@medusajs/medusa`.
|
|
|
40
40
|
|
|
41
41
|
- **Order Management**: Cancel and reorder functionality for orders
|
|
42
42
|
- **Order Confirmation Emails**: Automatically sends email notifications when orders are placed (requires template configuration)
|
|
43
|
+
- **Return Orders Admin Panel**: Complete return orders management section in the Medusa Admin Panel with list view, filtering, search, detail pages, and status management
|
|
43
44
|
|
|
44
45
|
## Configuration
|
|
45
46
|
|
|
@@ -69,6 +70,48 @@ module.exports = defineConfig({
|
|
|
69
70
|
|
|
70
71
|
**Note**: Order confirmation emails are only sent if a template path is provided. If no template is configured, emails will not be sent.
|
|
71
72
|
|
|
73
|
+
## Return Orders Admin Panel
|
|
74
|
+
|
|
75
|
+
The plugin includes a dedicated section in the Medusa Admin Panel for managing customer return orders. This feature provides administrators with comprehensive tools to view, search, filter, and manage all return orders.
|
|
76
|
+
|
|
77
|
+
### Features
|
|
78
|
+
|
|
79
|
+
- **List View**: View all return orders in a table format with key information
|
|
80
|
+
- **Search**: Search returns by return ID, order ID, or customer email
|
|
81
|
+
- **Filtering**: Filter returns by status (requested, received, requires_action, completed, canceled)
|
|
82
|
+
- **Detail Pages**: View detailed information for each return order including:
|
|
83
|
+
- Return information (ID, status, refund amount, reason, note)
|
|
84
|
+
- Related order information (order ID, customer, totals)
|
|
85
|
+
- Return items with quantities
|
|
86
|
+
- Status history timeline
|
|
87
|
+
- Metadata
|
|
88
|
+
- **Status Management**: Update return status with validation and status history tracking
|
|
89
|
+
- **Pagination**: Load more returns with pagination support
|
|
90
|
+
|
|
91
|
+
### Accessing Return Orders
|
|
92
|
+
|
|
93
|
+
Once the plugin is installed and configured, you can access the Return Orders section from the Admin Panel sidebar. The section appears as "Return Orders" with a return icon.
|
|
94
|
+
|
|
95
|
+
### API Endpoints
|
|
96
|
+
|
|
97
|
+
The plugin provides the following admin API endpoints for return orders management:
|
|
98
|
+
|
|
99
|
+
- `GET /admin/returns` - List all return orders with filtering, search, and pagination
|
|
100
|
+
- `GET /admin/returns/:id` - Get detailed information for a specific return order
|
|
101
|
+
- `POST /admin/returns/:id/status` - Update the status of a return order
|
|
102
|
+
|
|
103
|
+
### Return Statuses
|
|
104
|
+
|
|
105
|
+
The plugin supports the following return statuses:
|
|
106
|
+
|
|
107
|
+
- `requested` - Return has been requested by the customer
|
|
108
|
+
- `received` - Return items have been received
|
|
109
|
+
- `requires_action` - Return requires manual intervention
|
|
110
|
+
- `completed` - Return has been completed
|
|
111
|
+
- `canceled` - Return has been canceled
|
|
112
|
+
|
|
113
|
+
Status updates are tracked in the return's metadata with timestamps and admin user IDs.
|
|
114
|
+
|
|
72
115
|
## Email Templates
|
|
73
116
|
|
|
74
117
|
The plugin supports custom HTML templates for order confirmation emails. Templates use variable replacement with `{{variable_name}}` syntax.
|