@devx-retailos/cms 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/retailos/cms/accumulation/[storeId]/route.js +34 -0
- package/.medusa/server/src/api/admin/retailos/cms/export/route.js +52 -0
- package/.medusa/server/src/api/admin/retailos/cms/handovers/[id]/route.js +35 -0
- package/.medusa/server/src/api/admin/retailos/cms/handovers/route.js +78 -0
- package/.medusa/server/src/api/admin/retailos/cms/operation/route.js +124 -0
- package/.medusa/server/src/api/admin/retailos/cms/petty-cash/route.js +31 -0
- package/.medusa/server/src/api/admin/retailos/cms/shift-logs/route.js +36 -0
- package/.medusa/server/src/links/employee-to-cms-handover.js +13 -0
- package/.medusa/server/src/links/store-to-cms-handover.js +13 -0
- package/.medusa/server/src/modules/cms/constants.js +5 -0
- package/.medusa/server/src/modules/cms/index.js +53 -0
- package/.medusa/server/src/modules/cms/migrations/Migration20260622000000.js +30 -0
- package/.medusa/server/src/modules/cms/migrations/Migration20260622000001.js +16 -0
- package/.medusa/server/src/modules/cms/models/cms-accumulation.js +11 -0
- package/.medusa/server/src/modules/cms/models/cms-handover.js +17 -0
- package/.medusa/server/src/modules/cms/models/index.js +15 -0
- package/.medusa/server/src/modules/cms/models/petty-cash-transaction.js +24 -0
- package/.medusa/server/src/modules/cms/models/petty-cash.js +11 -0
- package/.medusa/server/src/modules/cms/permissions.js +36 -0
- package/.medusa/server/src/modules/cms/services/cms-module-service.js +210 -0
- package/.medusa/server/src/modules/cms/services/index.js +9 -0
- package/README.md +155 -0
- package/package.json +60 -0
- package/src/admin/.gitkeep +0 -0
- package/src/api/admin/retailos/cms/accumulation/[storeId]/__tests__/route.test.ts +68 -0
- package/src/api/admin/retailos/cms/accumulation/[storeId]/route.ts +35 -0
- package/src/api/admin/retailos/cms/export/__tests__/route.test.ts +126 -0
- package/src/api/admin/retailos/cms/export/route.ts +58 -0
- package/src/api/admin/retailos/cms/handovers/[id]/__tests__/route.test.ts +68 -0
- package/src/api/admin/retailos/cms/handovers/[id]/route.ts +36 -0
- package/src/api/admin/retailos/cms/handovers/__tests__/route.test.ts +104 -0
- package/src/api/admin/retailos/cms/handovers/route.ts +79 -0
- package/src/api/admin/retailos/cms/operation/__tests__/route.test.ts +169 -0
- package/src/api/admin/retailos/cms/operation/route.ts +130 -0
- package/src/api/admin/retailos/cms/petty-cash/__tests__/route.test.ts +73 -0
- package/src/api/admin/retailos/cms/petty-cash/route.ts +35 -0
- package/src/api/admin/retailos/cms/shift-logs/__tests__/route.test.ts +77 -0
- package/src/api/admin/retailos/cms/shift-logs/route.ts +38 -0
- package/src/links/employee-to-cms-handover.ts +11 -0
- package/src/links/store-to-cms-handover.ts +11 -0
- package/src/modules/cms/__tests__/cms-module-service.test.ts +333 -0
- package/src/modules/cms/__tests__/permissions.test.ts +36 -0
- package/src/modules/cms/constants.ts +1 -0
- package/src/modules/cms/index.ts +24 -0
- package/src/modules/cms/migrations/Migration20260622000000.ts +58 -0
- package/src/modules/cms/migrations/Migration20260622000001.ts +17 -0
- package/src/modules/cms/models/cms-accumulation.ts +10 -0
- package/src/modules/cms/models/cms-handover.ts +16 -0
- package/src/modules/cms/models/index.ts +4 -0
- package/src/modules/cms/models/petty-cash-transaction.ts +23 -0
- package/src/modules/cms/models/petty-cash.ts +10 -0
- package/src/modules/cms/permissions.ts +34 -0
- package/src/modules/cms/services/cms-module-service.ts +284 -0
- package/src/modules/cms/services/index.ts +13 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
4
|
+
const CmsAccumulation = utils_1.model.define("retailos_cms_accumulation", {
|
|
5
|
+
id: utils_1.model.id({ prefix: "cmsa" }).primaryKey(),
|
|
6
|
+
store_id: utils_1.model.text().searchable(),
|
|
7
|
+
cash_in_store: utils_1.model.number(),
|
|
8
|
+
metadata: utils_1.model.json().nullable(),
|
|
9
|
+
});
|
|
10
|
+
exports.default = CmsAccumulation;
|
|
11
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY21zLWFjY3VtdWxhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL2Ntcy9tb2RlbHMvY21zLWFjY3VtdWxhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHFEQUFpRDtBQUVqRCxNQUFNLGVBQWUsR0FBRyxhQUFLLENBQUMsTUFBTSxDQUFDLDJCQUEyQixFQUFFO0lBQ2hFLEVBQUUsRUFBRSxhQUFLLENBQUMsRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUMsVUFBVSxFQUFFO0lBQzdDLFFBQVEsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsVUFBVSxFQUFFO0lBQ25DLGFBQWEsRUFBRSxhQUFLLENBQUMsTUFBTSxFQUFFO0lBQzdCLFFBQVEsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsUUFBUSxFQUFFO0NBQ2xDLENBQUMsQ0FBQTtBQUVGLGtCQUFlLGVBQWUsQ0FBQSJ9
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
4
|
+
const CmsHandover = utils_1.model.define("retailos_cms_handover", {
|
|
5
|
+
id: utils_1.model.id({ prefix: "cmsh" }).primaryKey(),
|
|
6
|
+
store_id: utils_1.model.text().searchable(),
|
|
7
|
+
employee_id: utils_1.model.text().searchable(),
|
|
8
|
+
handover_id: utils_1.model.text().nullable(), // free-text correlation field: the brand can pass their own ID (e.g. a bank slip number, a vault reference, a POS transaction ID) so they can cross-reference this handover record with their own external system.
|
|
9
|
+
handover_amount: utils_1.model.number().nullable(),
|
|
10
|
+
total_cash: utils_1.model.number().nullable(),
|
|
11
|
+
type: utils_1.model.text().nullable(),
|
|
12
|
+
image_url: utils_1.model.text().nullable(),
|
|
13
|
+
remark: utils_1.model.text().nullable(),
|
|
14
|
+
metadata: utils_1.model.json().nullable(),
|
|
15
|
+
});
|
|
16
|
+
exports.default = CmsHandover;
|
|
17
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY21zLWhhbmRvdmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL21vZHVsZXMvY21zL21vZGVscy9jbXMtaGFuZG92ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxxREFBaUQ7QUFFakQsTUFBTSxXQUFXLEdBQUcsYUFBSyxDQUFDLE1BQU0sQ0FBQyx1QkFBdUIsRUFBRTtJQUN4RCxFQUFFLEVBQUUsYUFBSyxDQUFDLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLFVBQVUsRUFBRTtJQUM3QyxRQUFRLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFVBQVUsRUFBRTtJQUNuQyxXQUFXLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFVBQVUsRUFBRTtJQUN0QyxXQUFXLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRSxFQUFFLG1OQUFtTjtJQUN6UCxlQUFlLEVBQUUsYUFBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUMxQyxVQUFVLEVBQUUsYUFBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUNyQyxJQUFJLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUM3QixTQUFTLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUNsQyxNQUFNLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUMvQixRQUFRLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtDQUNsQyxDQUFDLENBQUE7QUFFRixrQkFBZSxXQUFXLENBQUEifQ==
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.PettyCashTransaction = exports.PettyCash = exports.CmsAccumulation = exports.CmsHandover = void 0;
|
|
7
|
+
var cms_handover_1 = require("./cms-handover");
|
|
8
|
+
Object.defineProperty(exports, "CmsHandover", { enumerable: true, get: function () { return __importDefault(cms_handover_1).default; } });
|
|
9
|
+
var cms_accumulation_1 = require("./cms-accumulation");
|
|
10
|
+
Object.defineProperty(exports, "CmsAccumulation", { enumerable: true, get: function () { return __importDefault(cms_accumulation_1).default; } });
|
|
11
|
+
var petty_cash_1 = require("./petty-cash");
|
|
12
|
+
Object.defineProperty(exports, "PettyCash", { enumerable: true, get: function () { return __importDefault(petty_cash_1).default; } });
|
|
13
|
+
var petty_cash_transaction_1 = require("./petty-cash-transaction");
|
|
14
|
+
Object.defineProperty(exports, "PettyCashTransaction", { enumerable: true, get: function () { return __importDefault(petty_cash_transaction_1).default; } });
|
|
15
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy9jbXMvbW9kZWxzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLCtDQUF1RDtBQUE5Qyw0SEFBQSxPQUFPLE9BQWU7QUFDL0IsdURBQStEO0FBQXRELG9JQUFBLE9BQU8sT0FBbUI7QUFDbkMsMkNBQW1EO0FBQTFDLHdIQUFBLE9BQU8sT0FBYTtBQUM3QixtRUFBMEU7QUFBakUsK0lBQUEsT0FBTyxPQUF3QiJ9
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
4
|
+
const PettyCashTransaction = utils_1.model.define("retailos_petty_cash_transaction", {
|
|
5
|
+
id: utils_1.model.id({ prefix: "pct" }).primaryKey(),
|
|
6
|
+
store_id: utils_1.model.text().searchable(),
|
|
7
|
+
employee_id: utils_1.model.text().searchable(),
|
|
8
|
+
transaction_type: utils_1.model.text(),
|
|
9
|
+
entry_type: utils_1.model.text().nullable(),
|
|
10
|
+
source: utils_1.model.text().nullable(),
|
|
11
|
+
amount: utils_1.model.number(),
|
|
12
|
+
opening_balance: utils_1.model.number().nullable(),
|
|
13
|
+
closing_balance: utils_1.model.number().nullable(),
|
|
14
|
+
expense_amount: utils_1.model.number(),
|
|
15
|
+
difference_amount: utils_1.model.number(),
|
|
16
|
+
category: utils_1.model.text().nullable(),
|
|
17
|
+
sub_category: utils_1.model.text().nullable(),
|
|
18
|
+
reason: utils_1.model.text().nullable(),
|
|
19
|
+
image_url: utils_1.model.text().nullable(),
|
|
20
|
+
date: utils_1.model.dateTime().nullable(),
|
|
21
|
+
metadata: utils_1.model.json().nullable(),
|
|
22
|
+
});
|
|
23
|
+
exports.default = PettyCashTransaction;
|
|
24
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGV0dHktY2FzaC10cmFuc2FjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL2Ntcy9tb2RlbHMvcGV0dHktY2FzaC10cmFuc2FjdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHFEQUFpRDtBQUVqRCxNQUFNLG9CQUFvQixHQUFHLGFBQUssQ0FBQyxNQUFNLENBQUMsaUNBQWlDLEVBQUU7SUFDM0UsRUFBRSxFQUFFLGFBQUssQ0FBQyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxVQUFVLEVBQUU7SUFDNUMsUUFBUSxFQUFFLGFBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxVQUFVLEVBQUU7SUFDbkMsV0FBVyxFQUFFLGFBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxVQUFVLEVBQUU7SUFDdEMsZ0JBQWdCLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRTtJQUM5QixVQUFVLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUNuQyxNQUFNLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUMvQixNQUFNLEVBQUUsYUFBSyxDQUFDLE1BQU0sRUFBRTtJQUN0QixlQUFlLEVBQUUsYUFBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUMxQyxlQUFlLEVBQUUsYUFBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUMxQyxjQUFjLEVBQUUsYUFBSyxDQUFDLE1BQU0sRUFBRTtJQUM5QixpQkFBaUIsRUFBRSxhQUFLLENBQUMsTUFBTSxFQUFFO0lBQ2pDLFFBQVEsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQ2pDLFlBQVksRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQ3JDLE1BQU0sRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQy9CLFNBQVMsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQ2xDLElBQUksRUFBRSxhQUFLLENBQUMsUUFBUSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQ2pDLFFBQVEsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsUUFBUSxFQUFFO0NBQ2xDLENBQUMsQ0FBQTtBQUVGLGtCQUFlLG9CQUFvQixDQUFBIn0=
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
4
|
+
const PettyCash = utils_1.model.define("retailos_petty_cash", {
|
|
5
|
+
id: utils_1.model.id({ prefix: "pc" }).primaryKey(),
|
|
6
|
+
store_id: utils_1.model.text().searchable(),
|
|
7
|
+
balance: utils_1.model.number(),
|
|
8
|
+
metadata: utils_1.model.json().nullable(),
|
|
9
|
+
});
|
|
10
|
+
exports.default = PettyCash;
|
|
11
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGV0dHktY2FzaC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL2Ntcy9tb2RlbHMvcGV0dHktY2FzaC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHFEQUFpRDtBQUVqRCxNQUFNLFNBQVMsR0FBRyxhQUFLLENBQUMsTUFBTSxDQUFDLHFCQUFxQixFQUFFO0lBQ3BELEVBQUUsRUFBRSxhQUFLLENBQUMsRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsVUFBVSxFQUFFO0lBQzNDLFFBQVEsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsVUFBVSxFQUFFO0lBQ25DLE9BQU8sRUFBRSxhQUFLLENBQUMsTUFBTSxFQUFFO0lBQ3ZCLFFBQVEsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsUUFBUSxFQUFFO0NBQ2xDLENBQUMsQ0FBQTtBQUVGLGtCQUFlLFNBQVMsQ0FBQSJ9
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CMS_PERMISSIONS = void 0;
|
|
4
|
+
exports.CMS_PERMISSIONS = [
|
|
5
|
+
{
|
|
6
|
+
key: "cms.handover.read",
|
|
7
|
+
description: "View cash handover records",
|
|
8
|
+
registered_by: "cms",
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
key: "cms.handover.create",
|
|
12
|
+
description: "Create a cash handover record",
|
|
13
|
+
registered_by: "cms",
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
key: "cms.shift.operate",
|
|
17
|
+
description: "Open and close shift (day start / day end)",
|
|
18
|
+
registered_by: "cms",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
key: "cms.petty_cash.read",
|
|
22
|
+
description: "View petty cash balance and transactions",
|
|
23
|
+
registered_by: "cms",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
key: "cms.petty_cash.operate",
|
|
27
|
+
description: "Add petty cash or record expenses",
|
|
28
|
+
registered_by: "cms",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
key: "cms.accumulation.read",
|
|
32
|
+
description: "View current cash accumulation for a store",
|
|
33
|
+
registered_by: "cms",
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVybWlzc2lvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy9jbXMvcGVybWlzc2lvbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBRWEsUUFBQSxlQUFlLEdBQTZCO0lBQ3ZEO1FBQ0UsR0FBRyxFQUFFLG1CQUFtQjtRQUN4QixXQUFXLEVBQUUsNEJBQTRCO1FBQ3pDLGFBQWEsRUFBRSxLQUFLO0tBQ3JCO0lBQ0Q7UUFDRSxHQUFHLEVBQUUscUJBQXFCO1FBQzFCLFdBQVcsRUFBRSwrQkFBK0I7UUFDNUMsYUFBYSxFQUFFLEtBQUs7S0FDckI7SUFDRDtRQUNFLEdBQUcsRUFBRSxtQkFBbUI7UUFDeEIsV0FBVyxFQUFFLDRDQUE0QztRQUN6RCxhQUFhLEVBQUUsS0FBSztLQUNyQjtJQUNEO1FBQ0UsR0FBRyxFQUFFLHFCQUFxQjtRQUMxQixXQUFXLEVBQUUsMENBQTBDO1FBQ3ZELGFBQWEsRUFBRSxLQUFLO0tBQ3JCO0lBQ0Q7UUFDRSxHQUFHLEVBQUUsd0JBQXdCO1FBQzdCLFdBQVcsRUFBRSxtQ0FBbUM7UUFDaEQsYUFBYSxFQUFFLEtBQUs7S0FDckI7SUFDRDtRQUNFLEdBQUcsRUFBRSx1QkFBdUI7UUFDNUIsV0FBVyxFQUFFLDRDQUE0QztRQUN6RCxhQUFhLEVBQUUsS0FBSztLQUNyQjtDQUNGLENBQUEifQ==
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
7
|
+
const core_1 = require("@devx-retailos/core");
|
|
8
|
+
const cms_handover_1 = __importDefault(require("../models/cms-handover"));
|
|
9
|
+
const cms_accumulation_1 = __importDefault(require("../models/cms-accumulation"));
|
|
10
|
+
const petty_cash_1 = __importDefault(require("../models/petty-cash"));
|
|
11
|
+
const petty_cash_transaction_1 = __importDefault(require("../models/petty-cash-transaction"));
|
|
12
|
+
class CmsModuleService extends (0, utils_1.MedusaService)({
|
|
13
|
+
CmsHandover: cms_handover_1.default,
|
|
14
|
+
CmsAccumulation: cms_accumulation_1.default,
|
|
15
|
+
PettyCash: petty_cash_1.default,
|
|
16
|
+
PettyCashTransaction: petty_cash_transaction_1.default,
|
|
17
|
+
}) {
|
|
18
|
+
constructor(...args) {
|
|
19
|
+
super(...args);
|
|
20
|
+
const container = (args[0] ?? {});
|
|
21
|
+
this.logger_ = container.logger ?? (0, core_1.createNoopLogger)();
|
|
22
|
+
this.logger_.debug("[retailos/cms] service initialized");
|
|
23
|
+
}
|
|
24
|
+
async dayStart(input) {
|
|
25
|
+
const { store_id, employee_id, opening_amount } = input;
|
|
26
|
+
if (opening_amount < 0) {
|
|
27
|
+
throw new Error("[retailos/cms] opening_amount must be >= 0");
|
|
28
|
+
}
|
|
29
|
+
const existing = await this.listCmsAccumulations({ store_id: [store_id] });
|
|
30
|
+
if (existing.length === 0) {
|
|
31
|
+
await this.createCmsAccumulations([{ store_id, cash_in_store: opening_amount }]);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
await this.updateCmsAccumulations([{ id: existing[0].id, cash_in_store: opening_amount }]);
|
|
35
|
+
}
|
|
36
|
+
await this.createPettyCashTransactions([{
|
|
37
|
+
store_id,
|
|
38
|
+
employee_id,
|
|
39
|
+
transaction_type: "open",
|
|
40
|
+
entry_type: "CR",
|
|
41
|
+
source: null,
|
|
42
|
+
amount: opening_amount,
|
|
43
|
+
opening_balance: opening_amount,
|
|
44
|
+
closing_balance: null,
|
|
45
|
+
expense_amount: 0,
|
|
46
|
+
difference_amount: 0,
|
|
47
|
+
category: null,
|
|
48
|
+
sub_category: null,
|
|
49
|
+
reason: null,
|
|
50
|
+
image_url: null,
|
|
51
|
+
date: new Date(),
|
|
52
|
+
metadata: null,
|
|
53
|
+
}]);
|
|
54
|
+
this.logger_.info("cms.day_started", { store_id, employee_id, opening_amount });
|
|
55
|
+
}
|
|
56
|
+
async dayEnd(input) {
|
|
57
|
+
const { store_id, employee_id, closing_amount } = input;
|
|
58
|
+
if (closing_amount < 0) {
|
|
59
|
+
throw new Error("[retailos/cms] closing_amount must be >= 0");
|
|
60
|
+
}
|
|
61
|
+
const accumulations = await this.listCmsAccumulations({ store_id: [store_id] });
|
|
62
|
+
const current_cash = accumulations[0] ? accumulations[0].cash_in_store : 0;
|
|
63
|
+
const difference = closing_amount - current_cash;
|
|
64
|
+
await this.createPettyCashTransactions([{
|
|
65
|
+
store_id,
|
|
66
|
+
employee_id,
|
|
67
|
+
transaction_type: "close",
|
|
68
|
+
entry_type: "DB",
|
|
69
|
+
source: null,
|
|
70
|
+
amount: closing_amount,
|
|
71
|
+
opening_balance: current_cash,
|
|
72
|
+
closing_balance: closing_amount,
|
|
73
|
+
expense_amount: 0,
|
|
74
|
+
difference_amount: difference,
|
|
75
|
+
category: null,
|
|
76
|
+
sub_category: null,
|
|
77
|
+
reason: null,
|
|
78
|
+
image_url: null,
|
|
79
|
+
date: new Date(),
|
|
80
|
+
metadata: null,
|
|
81
|
+
}]);
|
|
82
|
+
this.logger_.info("cms.day_ended", { store_id, employee_id, closing_amount, difference });
|
|
83
|
+
}
|
|
84
|
+
async handover(input) {
|
|
85
|
+
const { store_id, handover_amount, type } = input;
|
|
86
|
+
if (handover_amount < 0) {
|
|
87
|
+
throw new Error("[retailos/cms] handover_amount must be >= 0");
|
|
88
|
+
}
|
|
89
|
+
const [created] = await this.createCmsHandovers([{
|
|
90
|
+
store_id,
|
|
91
|
+
employee_id: input.employee_id,
|
|
92
|
+
handover_id: input.handover_id ?? null,
|
|
93
|
+
handover_amount,
|
|
94
|
+
total_cash: input.total_cash ?? null,
|
|
95
|
+
type: type ?? null,
|
|
96
|
+
image_url: input.image_url ?? null,
|
|
97
|
+
remark: input.remark ?? null,
|
|
98
|
+
metadata: input.metadata ?? null,
|
|
99
|
+
}]);
|
|
100
|
+
const accumulations = await this.listCmsAccumulations({ store_id: [store_id] });
|
|
101
|
+
const current = accumulations[0] ? accumulations[0].cash_in_store : 0;
|
|
102
|
+
let updated_cash = current;
|
|
103
|
+
if (type === "CR") {
|
|
104
|
+
updated_cash = current + handover_amount;
|
|
105
|
+
}
|
|
106
|
+
else if (type === "DB") {
|
|
107
|
+
updated_cash = current - handover_amount;
|
|
108
|
+
}
|
|
109
|
+
if (accumulations.length === 0) {
|
|
110
|
+
await this.createCmsAccumulations([{ store_id, cash_in_store: updated_cash }]);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
await this.updateCmsAccumulations([{ id: accumulations[0].id, cash_in_store: updated_cash }]);
|
|
114
|
+
}
|
|
115
|
+
this.logger_.info("[retailos/cms] handover created", {
|
|
116
|
+
id: created?.id,
|
|
117
|
+
store_id,
|
|
118
|
+
handover_amount,
|
|
119
|
+
type,
|
|
120
|
+
});
|
|
121
|
+
return created;
|
|
122
|
+
}
|
|
123
|
+
async addPettyCash(input) {
|
|
124
|
+
const { store_id, employee_id, amount, source } = input;
|
|
125
|
+
if (amount <= 0) {
|
|
126
|
+
throw new Error("[retailos/cms] amount must be > 0");
|
|
127
|
+
}
|
|
128
|
+
const existing = await this.listPettyCashes({ store_id: [store_id] });
|
|
129
|
+
const current_balance = existing[0] ? existing[0].balance : 0;
|
|
130
|
+
const new_balance = current_balance + amount;
|
|
131
|
+
if (existing.length === 0) {
|
|
132
|
+
await this.createPettyCashes([{ store_id, balance: new_balance }]);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
await this.updatePettyCashes([{ id: existing[0].id, balance: new_balance }]);
|
|
136
|
+
}
|
|
137
|
+
const [tx] = await this.createPettyCashTransactions([{
|
|
138
|
+
store_id,
|
|
139
|
+
employee_id,
|
|
140
|
+
transaction_type: "petty_cash",
|
|
141
|
+
entry_type: "CR",
|
|
142
|
+
source: source ?? null,
|
|
143
|
+
amount,
|
|
144
|
+
opening_balance: current_balance,
|
|
145
|
+
closing_balance: new_balance,
|
|
146
|
+
expense_amount: 0,
|
|
147
|
+
difference_amount: 0,
|
|
148
|
+
category: null,
|
|
149
|
+
sub_category: null,
|
|
150
|
+
reason: null,
|
|
151
|
+
image_url: null,
|
|
152
|
+
date: new Date(),
|
|
153
|
+
metadata: null,
|
|
154
|
+
}]);
|
|
155
|
+
this.logger_.info("[retailos/cms] petty cash added", { store_id, amount, new_balance });
|
|
156
|
+
return tx;
|
|
157
|
+
}
|
|
158
|
+
async addExpense(input) {
|
|
159
|
+
const { store_id, employee_id, amount } = input;
|
|
160
|
+
if (amount <= 0) {
|
|
161
|
+
throw new Error("[retailos/cms] expense amount must be > 0");
|
|
162
|
+
}
|
|
163
|
+
const existing = await this.listPettyCashes({ store_id: [store_id] });
|
|
164
|
+
const current_balance = existing[0] ? existing[0].balance : 0;
|
|
165
|
+
const new_balance = current_balance - amount;
|
|
166
|
+
if (existing.length === 0) {
|
|
167
|
+
await this.createPettyCashes([{ store_id, balance: new_balance }]);
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
await this.updatePettyCashes([{ id: existing[0].id, balance: new_balance }]);
|
|
171
|
+
}
|
|
172
|
+
const [tx] = await this.createPettyCashTransactions([{
|
|
173
|
+
store_id,
|
|
174
|
+
employee_id,
|
|
175
|
+
transaction_type: "petty_cash",
|
|
176
|
+
entry_type: "DB",
|
|
177
|
+
source: null,
|
|
178
|
+
amount,
|
|
179
|
+
opening_balance: current_balance,
|
|
180
|
+
closing_balance: new_balance,
|
|
181
|
+
expense_amount: amount,
|
|
182
|
+
difference_amount: 0,
|
|
183
|
+
category: input.category ?? null,
|
|
184
|
+
sub_category: input.sub_category ?? null,
|
|
185
|
+
reason: input.reason ?? null,
|
|
186
|
+
image_url: input.image_url ?? null,
|
|
187
|
+
date: new Date(),
|
|
188
|
+
metadata: input.metadata ?? null,
|
|
189
|
+
}]);
|
|
190
|
+
this.logger_.info("[retailos/cms] expense recorded", { store_id, amount, category: input.category });
|
|
191
|
+
return tx;
|
|
192
|
+
}
|
|
193
|
+
async getAccumulation(store_id) {
|
|
194
|
+
const rows = await this.listCmsAccumulations({ store_id: [store_id] });
|
|
195
|
+
return rows[0] ?? null;
|
|
196
|
+
}
|
|
197
|
+
async getShiftLogs(filters) {
|
|
198
|
+
const dbFilters = {};
|
|
199
|
+
if (filters.store_id)
|
|
200
|
+
dbFilters.store_id = [filters.store_id];
|
|
201
|
+
dbFilters.transaction_type = ["open", "close"];
|
|
202
|
+
const rows = await this.listPettyCashTransactions(dbFilters, {
|
|
203
|
+
take: filters.limit ?? 100,
|
|
204
|
+
order: { created_at: "DESC" },
|
|
205
|
+
});
|
|
206
|
+
return rows;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
exports.default = CmsModuleService;
|
|
210
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY21zLW1vZHVsZS1zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL21vZHVsZXMvY21zL3NlcnZpY2VzL2Ntcy1tb2R1bGUtc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLHFEQUF5RDtBQUN6RCw4Q0FBbUU7QUFDbkUsMEVBQWdEO0FBQ2hELGtGQUF3RDtBQUN4RCxzRUFBNEM7QUFDNUMsOEZBQW1FO0FBd0RuRSxNQUFNLGdCQUFpQixTQUFRLElBQUEscUJBQWEsRUFBQztJQUMzQyxXQUFXLEVBQVgsc0JBQVc7SUFDWCxlQUFlLEVBQWYsMEJBQWU7SUFDZixTQUFTLEVBQVQsb0JBQVM7SUFDVCxvQkFBb0IsRUFBcEIsZ0NBQW9CO0NBQ3JCLENBQUM7SUFHQSxZQUFZLEdBQUcsSUFBVztRQUN4QixLQUFLLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQTtRQUNkLE1BQU0sU0FBUyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBd0IsQ0FBQTtRQUN4RCxJQUFJLENBQUMsT0FBTyxHQUFHLFNBQVMsQ0FBQyxNQUFNLElBQUksSUFBQSx1QkFBZ0IsR0FBRSxDQUFBO1FBQ3JELElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLG9DQUFvQyxDQUFDLENBQUE7SUFDMUQsQ0FBQztJQUVELEtBQUssQ0FBQyxRQUFRLENBQUMsS0FBb0I7UUFDakMsTUFBTSxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUUsY0FBYyxFQUFFLEdBQUcsS0FBSyxDQUFBO1FBQ3ZELElBQUksY0FBYyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3ZCLE1BQU0sSUFBSSxLQUFLLENBQUMsNENBQTRDLENBQUMsQ0FBQTtRQUMvRCxDQUFDO1FBRUQsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsb0JBQW9CLENBQUMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFB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
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.CmsModuleService = void 0;
|
|
7
|
+
var cms_module_service_1 = require("./cms-module-service");
|
|
8
|
+
Object.defineProperty(exports, "CmsModuleService", { enumerable: true, get: function () { return __importDefault(cms_module_service_1).default; } });
|
|
9
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy9jbXMvc2VydmljZXMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsMkRBQWtFO0FBQXpELHVJQUFBLE9BQU8sT0FBb0IifQ==
|
package/README.md
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# @devx-retailos/cms
|
|
2
|
+
|
|
3
|
+
Cash Management System (CMS) for retailOS. Manages shift operations, cash handovers, petty cash, and in-store cash accumulation for POS stores.
|
|
4
|
+
|
|
5
|
+
Covers the full cash lifecycle for a shift: open → intraday handovers and petty-cash movements → close, with a running per-store accumulation balance.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pnpm add @devx-retailos/cms
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Register in `medusa-config.ts`:
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { CmsModule } from "@devx-retailos/cms"
|
|
19
|
+
|
|
20
|
+
export default defineConfig({
|
|
21
|
+
modules: [
|
|
22
|
+
{
|
|
23
|
+
resolve: "@devx-retailos/cms",
|
|
24
|
+
options: {},
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
})
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Sync permissions at startup (alongside other retailOS modules):
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import { CMS_PERMISSIONS } from "@devx-retailos/cms"
|
|
34
|
+
import { syncAllPermissions } from "@devx-retailos/rbac"
|
|
35
|
+
|
|
36
|
+
await syncAllPermissions([...CMS_PERMISSIONS])
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Run migrations after adding the module:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
medusa plugin:db:generate @devx-retailos/cms
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Configuration
|
|
48
|
+
|
|
49
|
+
No plugin options are required. The module registers under the identifier `"cms"` and is fully configured through Medusa's dependency injection system.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Usage
|
|
54
|
+
|
|
55
|
+
Resolve the service from the Medusa container:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import { CMS_MODULE } from "@devx-retailos/cms"
|
|
59
|
+
import type { CmsModuleService } from "@devx-retailos/cms"
|
|
60
|
+
|
|
61
|
+
const cmsService: CmsModuleService = container.resolve(CMS_MODULE)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Shift operations
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
// Open a shift
|
|
68
|
+
await cmsService.dayStart({
|
|
69
|
+
store_id: "store_01",
|
|
70
|
+
employee_id: "emp_01",
|
|
71
|
+
opening_amount: 5000,
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
// Close a shift
|
|
75
|
+
await cmsService.dayEnd({
|
|
76
|
+
store_id: "store_01",
|
|
77
|
+
employee_id: "emp_01",
|
|
78
|
+
closing_amount: 4800,
|
|
79
|
+
})
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Cash handover
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
const handover = await cmsService.handover({
|
|
86
|
+
store_id: "store_01",
|
|
87
|
+
employee_id: "emp_01",
|
|
88
|
+
handover_amount: 2000,
|
|
89
|
+
type: "CR", // "CR" = cash coming in, "DB" = cash going out
|
|
90
|
+
remark: "shift change",
|
|
91
|
+
})
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Petty cash
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
// Add petty cash
|
|
98
|
+
await cmsService.addPettyCash({
|
|
99
|
+
store_id: "store_01",
|
|
100
|
+
employee_id: "emp_01",
|
|
101
|
+
amount: 500,
|
|
102
|
+
source: "self", // "self" | "from_petty_cash"
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
// Record an expense
|
|
106
|
+
await cmsService.addExpense({
|
|
107
|
+
store_id: "store_01",
|
|
108
|
+
employee_id: "emp_01",
|
|
109
|
+
amount: 150,
|
|
110
|
+
category: "supplies",
|
|
111
|
+
sub_category: "stationery",
|
|
112
|
+
reason: "pens and paper",
|
|
113
|
+
})
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Queries
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
// Current in-store cash balance
|
|
120
|
+
const accumulation = await cmsService.getAccumulation("store_01")
|
|
121
|
+
|
|
122
|
+
// Shift open/close log
|
|
123
|
+
const logs = await cmsService.getShiftLogs({
|
|
124
|
+
store_id: "store_01",
|
|
125
|
+
from: new Date("2024-01-01"),
|
|
126
|
+
to: new Date("2024-01-31"),
|
|
127
|
+
limit: 50,
|
|
128
|
+
})
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Permissions
|
|
134
|
+
|
|
135
|
+
| Key | Description |
|
|
136
|
+
|-----|-------------|
|
|
137
|
+
| `cms.handover.read` | View cash handover records |
|
|
138
|
+
| `cms.handover.create` | Create a cash handover record |
|
|
139
|
+
| `cms.shift.operate` | Open and close a shift (day start / day end) |
|
|
140
|
+
| `cms.petty_cash.read` | View petty cash balance and transactions |
|
|
141
|
+
| `cms.petty_cash.operate` | Add petty cash or record expenses |
|
|
142
|
+
| `cms.accumulation.read` | View current cash accumulation for a store |
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Extension points
|
|
147
|
+
|
|
148
|
+
This module has no pluggable adapters or strategy interfaces. All cash logic is handled internally by `CmsModuleService`.
|
|
149
|
+
|
|
150
|
+
Module links — resolved automatically by Medusa's link layer:
|
|
151
|
+
|
|
152
|
+
| Link | Cardinality |
|
|
153
|
+
|------|-------------|
|
|
154
|
+
| Store → CmsHandover | 1:N |
|
|
155
|
+
| Employee → CmsHandover | 1:N |
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@devx-retailos/cms",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Cash Management System for retailOS: shift ops, handovers, petty cash, accumulation.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"main": "./.medusa/server/src/modules/cms/index.js",
|
|
7
|
+
"types": "./.medusa/server/src/modules/cms/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./.medusa/server/src/modules/cms/index.d.ts",
|
|
11
|
+
"import": "./.medusa/server/src/modules/cms/index.js",
|
|
12
|
+
"require": "./.medusa/server/src/modules/cms/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./permissions": {
|
|
15
|
+
"types": "./.medusa/server/src/modules/cms/permissions.d.ts",
|
|
16
|
+
"import": "./.medusa/server/src/modules/cms/permissions.js",
|
|
17
|
+
"require": "./.medusa/server/src/modules/cms/permissions.js"
|
|
18
|
+
},
|
|
19
|
+
"./package.json": "./package.json",
|
|
20
|
+
"./.medusa/server/src/modules/cms": "./.medusa/server/src/modules/cms/index.js",
|
|
21
|
+
"./.medusa/server/src/modules/cms/*": "./.medusa/server/src/modules/cms/*"
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
".medusa",
|
|
25
|
+
"src"
|
|
26
|
+
],
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@devx-retailos/core": "0.0.2",
|
|
29
|
+
"@devx-retailos/employee": "0.0.3",
|
|
30
|
+
"@devx-retailos/rbac": "0.0.2"
|
|
31
|
+
},
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"@medusajs/framework": "^2.15.0",
|
|
34
|
+
"@medusajs/medusa": "^2.15.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@medusajs/admin-sdk": "2.15.5",
|
|
38
|
+
"@medusajs/admin-shared": "2.15.5",
|
|
39
|
+
"@medusajs/cli": "2.15.5",
|
|
40
|
+
"@medusajs/framework": "2.15.5",
|
|
41
|
+
"@medusajs/medusa": "2.15.5",
|
|
42
|
+
"typescript": "^5.7.2",
|
|
43
|
+
"zod": "^3.23.0"
|
|
44
|
+
},
|
|
45
|
+
"publishConfig": {
|
|
46
|
+
"access": "public"
|
|
47
|
+
},
|
|
48
|
+
"sideEffects": false,
|
|
49
|
+
"keywords": [
|
|
50
|
+
"medusa-plugin"
|
|
51
|
+
],
|
|
52
|
+
"scripts": {
|
|
53
|
+
"build": "medusa plugin:build",
|
|
54
|
+
"develop": "medusa plugin:develop",
|
|
55
|
+
"db:generate": "medusa plugin:db:generate",
|
|
56
|
+
"test": "vitest run",
|
|
57
|
+
"typecheck": "tsc --noEmit",
|
|
58
|
+
"clean": "rm -rf .medusa dist .turbo *.tsbuildinfo"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from "vitest"
|
|
2
|
+
import { GET } from "../route"
|
|
3
|
+
|
|
4
|
+
function makeService() {
|
|
5
|
+
return {
|
|
6
|
+
getAccumulation: vi.fn(),
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function makeReq(params: Record<string, string>, service = makeService()) {
|
|
11
|
+
return {
|
|
12
|
+
params,
|
|
13
|
+
scope: {
|
|
14
|
+
resolve: vi.fn().mockImplementation((key: string) => {
|
|
15
|
+
if (key === "cms") return service
|
|
16
|
+
throw new Error("not found")
|
|
17
|
+
}),
|
|
18
|
+
},
|
|
19
|
+
_service: service,
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function makeRes() {
|
|
24
|
+
return {
|
|
25
|
+
status: vi.fn().mockReturnThis(),
|
|
26
|
+
json: vi.fn().mockReturnThis(),
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
describe("GET /accumulation/[storeId]", () => {
|
|
31
|
+
it("returns accumulation when it exists", async () => {
|
|
32
|
+
const service = makeService()
|
|
33
|
+
const accumulation = { id: "cmsa_1", store_id: "s1", cash_in_store: 750 }
|
|
34
|
+
service.getAccumulation.mockResolvedValue(accumulation)
|
|
35
|
+
const req = makeReq({ storeId: "s1" }, service)
|
|
36
|
+
const res = makeRes()
|
|
37
|
+
|
|
38
|
+
await GET(req as any, res as any)
|
|
39
|
+
|
|
40
|
+
expect(service.getAccumulation).toHaveBeenCalledWith("s1")
|
|
41
|
+
expect(res.status).toHaveBeenCalledWith(200)
|
|
42
|
+
expect(res.json).toHaveBeenCalledWith({ accumulation })
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it("returns default zero accumulation when none exists", async () => {
|
|
46
|
+
const service = makeService()
|
|
47
|
+
service.getAccumulation.mockResolvedValue(null)
|
|
48
|
+
const req = makeReq({ storeId: "s1" }, service)
|
|
49
|
+
const res = makeRes()
|
|
50
|
+
|
|
51
|
+
await GET(req as any, res as any)
|
|
52
|
+
|
|
53
|
+
expect(res.status).toHaveBeenCalledWith(200)
|
|
54
|
+
expect(res.json).toHaveBeenCalledWith({ accumulation: { store_id: "s1", cash_in_store: 0 } })
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
it("returns 500 when service throws", async () => {
|
|
58
|
+
const service = makeService()
|
|
59
|
+
service.getAccumulation.mockRejectedValue(new Error("db error"))
|
|
60
|
+
const req = makeReq({ storeId: "s1" }, service)
|
|
61
|
+
const res = makeRes()
|
|
62
|
+
|
|
63
|
+
await GET(req as any, res as any)
|
|
64
|
+
|
|
65
|
+
expect(res.status).toHaveBeenCalledWith(500)
|
|
66
|
+
expect(res.json).toHaveBeenCalledWith(expect.objectContaining({ code: "INTERNAL_ERROR" }))
|
|
67
|
+
})
|
|
68
|
+
})
|