medusa-pos-plugin 0.0.1
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 +23 -0
- package/.medusa/server/src/admin/index.mjs +24 -0
- package/.medusa/server/src/api/admin/pos/catalog/route.js +139 -0
- package/.medusa/server/src/api/admin/pos/draft-orders/[id]/confirm-lite/route.js +41 -0
- package/.medusa/server/src/api/admin/pos/draft-orders/[id]/customer/route.js +68 -0
- package/.medusa/server/src/api/admin/pos/draft-orders/[id]/finalize/route.js +424 -0
- package/.medusa/server/src/api/admin/pos/draft-orders/[id]/items/route.js +452 -0
- package/.medusa/server/src/api/admin/pos/draft-orders/[id]/items/update/route.js +137 -0
- package/.medusa/server/src/api/admin/pos/draft-orders/[id]/manual-discount/route.js +386 -0
- package/.medusa/server/src/api/admin/pos/draft-orders/[id]/promotions/route.js +59 -0
- package/.medusa/server/src/api/admin/pos/draft-orders/[id]/route.js +178 -0
- package/.medusa/server/src/api/admin/pos/draft-orders/[id]/wallet-debit/route.js +220 -0
- package/.medusa/server/src/api/admin/pos/draft-orders/route.js +193 -0
- package/.medusa/server/src/api/admin/pos/manual-discounts/route.js +76 -0
- package/.medusa/server/src/api/admin/pos/orders/[id]/fulfill/route.js +103 -0
- package/.medusa/server/src/api/admin/pos/orders/[id]/returns/route.js +512 -0
- package/.medusa/server/src/api/admin/pos/orders/fulfill-pos-items.js +63 -0
- package/.medusa/server/src/api/admin/pos/orders/validators.js +62 -0
- package/.medusa/server/src/api/admin/pos/payments/config/route.js +15 -0
- package/.medusa/server/src/api/admin/pos/payments/device/[orderId]/route.js +39 -0
- package/.medusa/server/src/api/admin/pos/payments/device/cancel/route.js +27 -0
- package/.medusa/server/src/api/admin/pos/payments/device/route.js +107 -0
- package/.medusa/server/src/api/admin/pos/payments/qr/[qrId]/close/route.js +36 -0
- package/.medusa/server/src/api/admin/pos/payments/qr/[qrId]/route.js +42 -0
- package/.medusa/server/src/api/admin/pos/payments/qr/route.js +78 -0
- package/.medusa/server/src/index.js +8 -0
- package/.medusa/server/src/types.js +3 -0
- package/.medusa/server/src/utils/pos-draft-edit.js +178 -0
- package/.medusa/server/src/utils/pos-finalize.js +166 -0
- package/.medusa/server/src/utils/pos-inventory.js +265 -0
- package/.medusa/server/src/utils/pos-returns.js +339 -0
- package/.medusa/server/src/utils/razorpay-pos-device.js +122 -0
- package/.medusa/server/src/utils/razorpay-pos.js +134 -0
- package/README.md +39 -0
- package/index.js +9 -0
- package/package.json +82 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = GET;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const POSMAN_PREFIX = "POSMAN-";
|
|
6
|
+
/**
|
|
7
|
+
* GET /admin/pos/manual-discounts
|
|
8
|
+
* Lists POS manual-discount promotions (POSMAN-*) for POS + external UI.
|
|
9
|
+
* Includes inactive codes (hidden from Admin active promotions).
|
|
10
|
+
*/
|
|
11
|
+
async function GET(req, res) {
|
|
12
|
+
const query = (req.query || {});
|
|
13
|
+
const limit = Math.min(Math.max(Number(query.limit) || 50, 1), 100);
|
|
14
|
+
const offset = Math.max(Number(query.offset) || 0, 0);
|
|
15
|
+
const q = (query.q || "").trim().toLowerCase();
|
|
16
|
+
try {
|
|
17
|
+
const promotionModule = req.scope.resolve(utils_1.Modules.PROMOTION);
|
|
18
|
+
// Fetch a window of promotions; filter POSMAN in-process (prefix match).
|
|
19
|
+
const take = Math.min(offset + limit + 200, 500);
|
|
20
|
+
const [rows] = await promotionModule.listAndCountPromotions({}, {
|
|
21
|
+
take,
|
|
22
|
+
skip: 0,
|
|
23
|
+
order: { created_at: "DESC" },
|
|
24
|
+
relations: ["application_method"],
|
|
25
|
+
});
|
|
26
|
+
let manual = (rows || []).filter((p) => {
|
|
27
|
+
const code = String(p.code || "");
|
|
28
|
+
const source = p.metadata?.source;
|
|
29
|
+
return code.startsWith(POSMAN_PREFIX) || source === "pos_manual";
|
|
30
|
+
});
|
|
31
|
+
if (q) {
|
|
32
|
+
manual = manual.filter((p) => {
|
|
33
|
+
const hay = [
|
|
34
|
+
p.code,
|
|
35
|
+
p.metadata?.draft_order_id,
|
|
36
|
+
p.metadata?.applied_by,
|
|
37
|
+
String(p.metadata?.amount ?? ""),
|
|
38
|
+
]
|
|
39
|
+
.filter(Boolean)
|
|
40
|
+
.join(" ")
|
|
41
|
+
.toLowerCase();
|
|
42
|
+
return hay.includes(q);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
const count = manual.length;
|
|
46
|
+
const page = manual.slice(offset, offset + limit).map((p) => ({
|
|
47
|
+
id: p.id,
|
|
48
|
+
code: p.code,
|
|
49
|
+
status: p.status,
|
|
50
|
+
amount: p.metadata?.amount ??
|
|
51
|
+
p.application_method?.value ??
|
|
52
|
+
null,
|
|
53
|
+
currency_code: p.metadata?.currency_code ??
|
|
54
|
+
p.application_method?.currency_code ??
|
|
55
|
+
null,
|
|
56
|
+
draft_order_id: p.metadata?.draft_order_id ?? null,
|
|
57
|
+
applied_by: p.metadata?.applied_by ?? null,
|
|
58
|
+
applied_at: p.metadata?.applied_at ?? p.created_at ?? null,
|
|
59
|
+
created_at: p.created_at ?? null,
|
|
60
|
+
metadata: p.metadata ?? null,
|
|
61
|
+
}));
|
|
62
|
+
res.json({
|
|
63
|
+
manual_discounts: page,
|
|
64
|
+
count,
|
|
65
|
+
limit,
|
|
66
|
+
offset,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
console.error("[pos manual-discounts] GET error:", error);
|
|
71
|
+
res.status(500).json({
|
|
72
|
+
message: error?.message || "Failed to list manual discounts",
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL3Bvcy9tYW51YWwtZGlzY291bnRzL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBZ0JBLGtCQStFQztBQTlGRCxxREFBbUQ7QUFFbkQsTUFBTSxhQUFhLEdBQUcsU0FBUyxDQUFBO0FBUS9COzs7O0dBSUc7QUFDSSxLQUFLLFVBQVUsR0FBRyxDQUFDLEdBQWtCLEVBQUUsR0FBbUI7SUFDL0QsTUFBTSxLQUFLLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBYyxDQUFBO0lBQzVDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQTtJQUNuRSxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFBO0lBQ3JELE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQTtJQUU5QyxJQUFJLENBQUM7UUFDSCxNQUFNLGVBQWUsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxlQUFPLENBQUMsU0FBUyxDQUsxRCxDQUFBO1FBRUQseUVBQXlFO1FBQ3pFLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxHQUFHLEtBQUssR0FBRyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUE7UUFDaEQsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLE1BQU0sZUFBZSxDQUFDLHNCQUFzQixDQUN6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
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.POST = POST;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const validators_1 = require("../../validators");
|
|
6
|
+
const fulfill_pos_items_1 = require("../../fulfill-pos-items");
|
|
7
|
+
const pos_returns_1 = require("../../../../../../utils/pos-returns");
|
|
8
|
+
function isRecord(value) {
|
|
9
|
+
return Boolean(value && typeof value === "object");
|
|
10
|
+
}
|
|
11
|
+
function itemFromUnknown(value) {
|
|
12
|
+
if (!isRecord(value) || typeof value.id !== "string")
|
|
13
|
+
return null;
|
|
14
|
+
const detail = isRecord(value.detail) ? value.detail : null;
|
|
15
|
+
return {
|
|
16
|
+
id: value.id,
|
|
17
|
+
quantity: (0, pos_returns_1.toAmount)(value.quantity) || null,
|
|
18
|
+
detail,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* POST /admin/pos/orders/:id/fulfill
|
|
23
|
+
*
|
|
24
|
+
* Record in-store handover as a Medusa fulfillment so later returns are allowed.
|
|
25
|
+
*/
|
|
26
|
+
async function POST(req, res) {
|
|
27
|
+
const orderId = req.params.id;
|
|
28
|
+
if (typeof orderId !== "string" || !orderId) {
|
|
29
|
+
res.status(400).json({ message: "Order id is required", type: "INVALID_DATA" });
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const parseResult = validators_1.PosFulfillOrderSchema.safeParse(req.body ?? {});
|
|
33
|
+
if (!parseResult.success) {
|
|
34
|
+
res.status(400).json({
|
|
35
|
+
message: "Invalid request data",
|
|
36
|
+
errors: parseResult.error.flatten(),
|
|
37
|
+
type: "INVALID_DATA",
|
|
38
|
+
});
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const body = parseResult.data;
|
|
42
|
+
const query = req.scope.resolve(utils_1.ContainerRegistrationKeys.QUERY);
|
|
43
|
+
const { data } = await query
|
|
44
|
+
.graph({
|
|
45
|
+
entity: "order",
|
|
46
|
+
fields: [
|
|
47
|
+
"id",
|
|
48
|
+
"status",
|
|
49
|
+
"items.id",
|
|
50
|
+
"items.quantity",
|
|
51
|
+
"items.detail.quantity",
|
|
52
|
+
"items.detail.fulfilled_quantity",
|
|
53
|
+
],
|
|
54
|
+
filters: { id: orderId },
|
|
55
|
+
})
|
|
56
|
+
.catch(() => ({ data: [] }));
|
|
57
|
+
const order = data[0];
|
|
58
|
+
if (!order) {
|
|
59
|
+
res.status(404).json({ message: "Order not found", type: "NOT_FOUND" });
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const status = typeof order.status === "string" ? order.status : "";
|
|
63
|
+
if (status === "canceled" || status === "cancelled" || status === "draft") {
|
|
64
|
+
res.status(400).json({ message: "Order cannot be fulfilled", type: "NOT_ALLOWED" });
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const orderItems = (Array.isArray(order.items) ? order.items : [])
|
|
68
|
+
.map((item) => itemFromUnknown(item))
|
|
69
|
+
.filter((item) => !!item);
|
|
70
|
+
const selections = body.items?.length
|
|
71
|
+
? body.items
|
|
72
|
+
: orderItems.map((item) => ({
|
|
73
|
+
id: item.id,
|
|
74
|
+
quantity: Math.max(1, Math.floor((0, pos_returns_1.toAmount)(item.quantity))),
|
|
75
|
+
}));
|
|
76
|
+
const fulfillItems = (0, pos_returns_1.getItemsToFulfill)(orderItems, selections);
|
|
77
|
+
if (!fulfillItems.length) {
|
|
78
|
+
res.status(200).json({ order_id: orderId, fulfilled: [] });
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
await (0, fulfill_pos_items_1.fulfillPosOrderItems)({
|
|
83
|
+
container: req.scope,
|
|
84
|
+
query,
|
|
85
|
+
orderId,
|
|
86
|
+
items: fulfillItems,
|
|
87
|
+
locationId: body.location_id,
|
|
88
|
+
actorId: (0, fulfill_pos_items_1.actorIdFromRequest)(req),
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
const message = (0, pos_returns_1.getThrownErrorMessage)(error, "Failed to fulfill POS order");
|
|
93
|
+
console.error("POS fulfill failed", error);
|
|
94
|
+
res.status(500).json({
|
|
95
|
+
message: "Failed to fulfill POS order",
|
|
96
|
+
error: message,
|
|
97
|
+
type: "INTERNAL_ERROR",
|
|
98
|
+
});
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
res.status(200).json({ order_id: orderId, fulfilled: fulfillItems });
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL3Bvcy9vcmRlcnMvW2lkXS9mdWxmaWxsL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBc0NBLG9CQW9GQztBQXpIRCxxREFBcUU7QUFDckUsaURBQXdEO0FBQ3hELCtEQUFrRjtBQUNsRixxRUFLNEM7QUFVNUMsU0FBUyxRQUFRLENBQUMsS0FBYztJQUM5QixPQUFPLE9BQU8sQ0FBQyxLQUFLLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxDQUFDLENBQUE7QUFDcEQsQ0FBQztBQUVELFNBQVMsZUFBZSxDQUFDLEtBQWM7SUFDckMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSSxPQUFPLEtBQUssQ0FBQyxFQUFFLEtBQUssUUFBUTtRQUFFLE9BQU8sSUFBSSxDQUFBO0lBQ2pFLE1BQU0sTUFBTSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQTtJQUMzRCxPQUFPO1FBQ0wsRUFBRSxFQUFFLEtBQUssQ0FBQyxFQUFFO1FBQ1osUUFBUSxFQUFFLElBQUEsc0JBQVEsRUFBQyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksSUFBSTtRQUMxQyxNQUFNO0tBQ1AsQ0FBQTtBQUNILENBQUM7QUFFRDs7OztHQUlHO0FBQ0ksS0FBSyxVQUFVLElBQUksQ0FBQyxHQUFrQixFQUFFLEdBQW1CO0lBQ2hFLE1BQU0sT0FBTyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFBO0lBQzdCLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDNUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFP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
|