medusa-plugin-tracing 0.1.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.
Files changed (73) hide show
  1. package/.medusa/server/medusa-config.d.ts +1 -0
  2. package/.medusa/server/medusa-config.js +23 -0
  3. package/.medusa/server/src/admin/index.js +6576 -0
  4. package/.medusa/server/src/admin/index.mjs +6574 -0
  5. package/.medusa/server/src/api/admin/invalidation-reasons/[id]/route.d.ts +5 -0
  6. package/.medusa/server/src/api/admin/invalidation-reasons/[id]/route.js +34 -0
  7. package/.medusa/server/src/api/admin/invalidation-reasons/route.d.ts +5 -0
  8. package/.medusa/server/src/api/admin/invalidation-reasons/route.js +37 -0
  9. package/.medusa/server/src/api/admin/serial-numbers/[id]/route.d.ts +5 -0
  10. package/.medusa/server/src/api/admin/serial-numbers/[id]/route.js +34 -0
  11. package/.medusa/server/src/api/admin/serial-numbers/route.d.ts +5 -0
  12. package/.medusa/server/src/api/admin/serial-numbers/route.js +40 -0
  13. package/.medusa/server/src/api/admin/stock-lots/[id]/route.d.ts +5 -0
  14. package/.medusa/server/src/api/admin/stock-lots/[id]/route.js +39 -0
  15. package/.medusa/server/src/api/admin/stock-lots/[id]/serial-numbers/route.d.ts +2 -0
  16. package/.medusa/server/src/api/admin/stock-lots/[id]/serial-numbers/route.js +21 -0
  17. package/.medusa/server/src/api/admin/stock-lots/disable/route.d.ts +3 -0
  18. package/.medusa/server/src/api/admin/stock-lots/disable/route.js +16 -0
  19. package/.medusa/server/src/api/admin/stock-lots/enable/route.d.ts +3 -0
  20. package/.medusa/server/src/api/admin/stock-lots/enable/route.js +16 -0
  21. package/.medusa/server/src/api/admin/stock-lots/route.d.ts +5 -0
  22. package/.medusa/server/src/api/admin/stock-lots/route.js +43 -0
  23. package/.medusa/server/src/api/middlewares.d.ts +2 -0
  24. package/.medusa/server/src/api/middlewares.js +149 -0
  25. package/.medusa/server/src/api/validators.d.ts +316 -0
  26. package/.medusa/server/src/api/validators.js +128 -0
  27. package/.medusa/server/src/links/inventory-item-stock-lot.d.ts +2 -0
  28. package/.medusa/server/src/links/inventory-item-stock-lot.js +18 -0
  29. package/.medusa/server/src/links/order-serial-number.d.ts +2 -0
  30. package/.medusa/server/src/links/order-serial-number.js +18 -0
  31. package/.medusa/server/src/links/serial-number-order.d.ts +2 -0
  32. package/.medusa/server/src/links/serial-number-order.js +15 -0
  33. package/.medusa/server/src/links/stock-location-stock-lot.d.ts +2 -0
  34. package/.medusa/server/src/links/stock-location-stock-lot.js +18 -0
  35. package/.medusa/server/src/links/stock-lot-inventory-item.d.ts +2 -0
  36. package/.medusa/server/src/links/stock-lot-inventory-item.js +15 -0
  37. package/.medusa/server/src/links/stock-lot-stock-location.d.ts +2 -0
  38. package/.medusa/server/src/links/stock-lot-stock-location.js +15 -0
  39. package/.medusa/server/src/modules/tracing/index.d.ts +50 -0
  40. package/.medusa/server/src/modules/tracing/index.js +25 -0
  41. package/.medusa/server/src/modules/tracing/migrations/Migration20260409171919.d.ts +5 -0
  42. package/.medusa/server/src/modules/tracing/migrations/Migration20260409171919.js +29 -0
  43. package/.medusa/server/src/modules/tracing/models/invalidation-reason.d.ts +25 -0
  44. package/.medusa/server/src/modules/tracing/models/invalidation-reason.js +14 -0
  45. package/.medusa/server/src/modules/tracing/models/serial-number.d.ts +30 -0
  46. package/.medusa/server/src/modules/tracing/models/serial-number.js +23 -0
  47. package/.medusa/server/src/modules/tracing/models/stock-lot-activity.d.ts +1 -0
  48. package/.medusa/server/src/modules/tracing/models/stock-lot-activity.js +3 -0
  49. package/.medusa/server/src/modules/tracing/models/stock-lot.d.ts +30 -0
  50. package/.medusa/server/src/modules/tracing/models/stock-lot.js +20 -0
  51. package/.medusa/server/src/modules/tracing/service.d.ts +109 -0
  52. package/.medusa/server/src/modules/tracing/service.js +52 -0
  53. package/.medusa/server/src/subscribers/fulfillment-created.d.ts +8 -0
  54. package/.medusa/server/src/subscribers/fulfillment-created.js +52 -0
  55. package/.medusa/server/src/workflows/tracing/adjust-stock-order.d.ts +7 -0
  56. package/.medusa/server/src/workflows/tracing/adjust-stock-order.js +47 -0
  57. package/.medusa/server/src/workflows/tracing/create-stock-lot.d.ts +45 -0
  58. package/.medusa/server/src/workflows/tracing/create-stock-lot.js +34 -0
  59. package/.medusa/server/src/workflows/tracing/delete-stock-lot.d.ts +38 -0
  60. package/.medusa/server/src/workflows/tracing/delete-stock-lot.js +36 -0
  61. package/.medusa/server/src/workflows/tracing/steps/assign-from-stock-lot.d.ts +1 -0
  62. package/.medusa/server/src/workflows/tracing/steps/assign-from-stock-lot.js +48 -0
  63. package/.medusa/server/src/workflows/tracing/steps/assign-serial-number.d.ts +1 -0
  64. package/.medusa/server/src/workflows/tracing/steps/assign-serial-number.js +3 -0
  65. package/.medusa/server/src/workflows/tracing/steps/invalidate-serial-number.d.ts +1 -0
  66. package/.medusa/server/src/workflows/tracing/steps/invalidate-serial-number.js +3 -0
  67. package/.medusa/server/src/workflows/tracing/steps/return-to-stock-lot.d.ts +1 -0
  68. package/.medusa/server/src/workflows/tracing/steps/return-to-stock-lot.js +3 -0
  69. package/.medusa/server/src/workflows/tracing/update-stock-lot.d.ts +46 -0
  70. package/.medusa/server/src/workflows/tracing/update-stock-lot.js +42 -0
  71. package/LICENSE +21 -0
  72. package/README.md +52 -0
  73. package/package.json +89 -0
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createStockLotWorkflow = void 0;
4
+ const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
5
+ const core_flows_1 = require("@medusajs/medusa/core-flows");
6
+ const tracing_1 = require("../../modules/tracing");
7
+ const createStockLotStep = (0, workflows_sdk_1.createStep)('create-stock-lot', async (input, { container }) => {
8
+ const tracingService = container.resolve(tracing_1.TRACING_MODULE);
9
+ const stockLot = await tracingService.createStockLots(input);
10
+ return new workflows_sdk_1.StepResponse(stockLot, stockLot.id);
11
+ },
12
+ // Compensation: delete the lot if a later step fails
13
+ async (stockLotId, { container }) => {
14
+ if (!stockLotId)
15
+ return;
16
+ const tracingService = container.resolve(tracing_1.TRACING_MODULE);
17
+ await tracingService.deleteStockLots([stockLotId]);
18
+ });
19
+ exports.createStockLotWorkflow = (0, workflows_sdk_1.createWorkflow)('create-stock-lot', (input) => {
20
+ const stockLot = createStockLotStep(input);
21
+ const adjustmentInput = (0, workflows_sdk_1.transform)({ input }, data => {
22
+ const adjustment = Math.max(data.input.stocked_quantity || 0, data.input.initial_quantity || 0);
23
+ return [
24
+ {
25
+ inventory_item_id: data.input.inventory_item_id,
26
+ location_id: data.input.stock_location_id,
27
+ adjustment: adjustment
28
+ }
29
+ ];
30
+ });
31
+ (0, core_flows_1.adjustInventoryLevelsStep)(adjustmentInput);
32
+ return new workflows_sdk_1.WorkflowResponse(stockLot);
33
+ });
34
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlLXN0b2NrLWxvdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy93b3JrZmxvd3MvdHJhY2luZy9jcmVhdGUtc3RvY2stbG90LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFFQU0wQztBQUMxQyw0REFBdUU7QUFDdkUsbURBQXNEO0FBSXRELE1BQU0sa0JBQWtCLEdBQUcsSUFBQSwwQkFBVSxFQUNwQyxrQkFBa0IsRUFDbEIsS0FBSyxFQUFFLEtBQThCLEVBQUUsRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFO0lBQ3ZELE1BQU0sY0FBYyxHQUFtQixTQUFTLENBQUMsT0FBTyxDQUFDLHdCQUFjLENBQUMsQ0FBQTtJQUN4RSxNQUFNLFFBQVEsR0FBRyxNQUFNLGNBQWMsQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDNUQsT0FBTyxJQUFJLDRCQUFZLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQTtBQUMvQyxDQUFDO0FBQ0QscURBQXFEO0FBQ3JELEtBQUssRUFBRSxVQUE4QixFQUFFLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRTtJQUN2RCxJQUFJLENBQUMsVUFBVTtRQUFFLE9BQU07SUFDdkIsTUFBTSxjQUFjLEdBQW1CLFNBQVMsQ0FBQyxPQUFPLENBQUMsd0JBQWMsQ0FBQyxDQUFBO0lBQ3hFLE1BQU0sY0FBYyxDQUFDLGVBQWUsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUE7QUFDbkQsQ0FBQyxDQUNELENBQUE7QUFFWSxRQUFBLHNCQUFzQixHQUFHLElBQUEsOEJBQWMsRUFDbkQsa0JBQWtCLEVBQ2xCLENBQUMsS0FBOEIsRUFBRSxFQUFFO0lBQ2xDLE1BQU0sUUFBUSxHQUFHLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxDQUFBO0lBRTFDLE1BQU0sZUFBZSxHQUFHLElBQUEseUJBQVMsRUFBQyxFQUFFLEtBQUssRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFO1FBQ25ELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQzFCLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLElBQUksQ0FBQyxFQUNoQyxJQUFJLENBQUMsS0FBSyxDQUFDLGdCQUFnQixJQUFJLENBQUMsQ0FDaEMsQ0FBQTtRQUNELE9BQU87WUFDTjtnQkFDQyxpQkFBaUIsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLGlCQUFpQjtnQkFDL0MsV0FBVyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsaUJBQWlCO2dCQUN6QyxVQUFVLEVBQUUsVUFBVTthQUN0QjtTQUNELENBQUE7SUFDRixDQUFDLENBQUMsQ0FBQTtJQUNGLElBQUEsc0NBQXlCLEVBQUMsZUFBZSxDQUFDLENBQUE7SUFFMUMsT0FBTyxJQUFJLGdDQUFnQixDQUFDLFFBQVEsQ0FBQyxDQUFBO0FBQ3RDLENBQUMsQ0FDRCxDQUFBIn0=
@@ -0,0 +1,38 @@
1
+ export declare const deleteStockLotWorkflow: import("@medusajs/framework/workflows-sdk").ReturnWorkflow<{
2
+ id: string;
3
+ }, {
4
+ id: string;
5
+ inventory_item_id: string;
6
+ stock_location_id: string;
7
+ lot_number: string;
8
+ description: string | null;
9
+ enabled: boolean;
10
+ initial_quantity: number;
11
+ stocked_quantity: number;
12
+ serial_numbers: {
13
+ id: string;
14
+ order_id: string;
15
+ value: string;
16
+ invalidated: boolean;
17
+ invalidation_reason: {
18
+ id: string;
19
+ value: string;
20
+ serial_numbers: /*elided*/ any[];
21
+ metadata: Record<string, unknown> | null;
22
+ created_at: Date;
23
+ updated_at: Date;
24
+ deleted_at: Date | null;
25
+ };
26
+ stock_lot: /*elided*/ any;
27
+ metadata: Record<string, unknown> | null;
28
+ created_at: Date;
29
+ updated_at: Date;
30
+ deleted_at: Date | null;
31
+ invalidation_reason_id: string | null;
32
+ stock_lot_id: string;
33
+ }[];
34
+ metadata: Record<string, unknown> | null;
35
+ created_at: Date;
36
+ updated_at: Date;
37
+ deleted_at: Date | null;
38
+ }, []>;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deleteStockLotWorkflow = void 0;
4
+ const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
5
+ const core_flows_1 = require("@medusajs/medusa/core-flows");
6
+ const tracing_1 = require("../../modules/tracing");
7
+ const calculateAdjustmentStep = (0, workflows_sdk_1.createStep)('calculate-adjustment', async (input, { container }) => {
8
+ const tracingService = container.resolve(tracing_1.TRACING_MODULE);
9
+ const currentStockLot = await tracingService.retrieveStockLot(input.id);
10
+ return new workflows_sdk_1.StepResponse(currentStockLot.stocked_quantity);
11
+ });
12
+ const deleteStockLotStep = (0, workflows_sdk_1.createStep)('delete-stock-lot', async (input, { container }) => {
13
+ const tracingService = container.resolve(tracing_1.TRACING_MODULE);
14
+ const stockLot = await tracingService.retrieveStockLot(input.id);
15
+ if (!stockLot) {
16
+ throw new Error(`Stock lot with id ${input.id} not found`);
17
+ }
18
+ await tracingService.deleteStockLots([input.id]);
19
+ return new workflows_sdk_1.StepResponse(stockLot);
20
+ });
21
+ exports.deleteStockLotWorkflow = (0, workflows_sdk_1.createWorkflow)('delete-stock-lot', (input) => {
22
+ const adjustment = calculateAdjustmentStep(input);
23
+ const stockLot = deleteStockLotStep(input);
24
+ if (adjustment !== 0) {
25
+ const adjustmentInput = (0, workflows_sdk_1.transform)({ adjustment, stockLot }, input => [
26
+ {
27
+ inventory_item_id: input.stockLot.inventory_item_id,
28
+ location_id: input.stockLot.stock_location_id,
29
+ adjustment: input.adjustment
30
+ }
31
+ ]);
32
+ (0, core_flows_1.adjustInventoryLevelsStep)(adjustmentInput);
33
+ }
34
+ return new workflows_sdk_1.WorkflowResponse(stockLot);
35
+ });
36
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVsZXRlLXN0b2NrLWxvdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy93b3JrZmxvd3MvdHJhY2luZy9kZWxldGUtc3RvY2stbG90LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFFQU0wQztBQUMxQyw0REFBdUU7QUFDdkUsbURBQXNEO0FBR3RELE1BQU0sdUJBQXVCLEdBQUcsSUFBQSwwQkFBVSxFQUN6QyxzQkFBc0IsRUFDdEIsS0FBSyxFQUFFLEtBQXFCLEVBQUUsRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFO0lBQzlDLE1BQU0sY0FBYyxHQUFtQixTQUFTLENBQUMsT0FBTyxDQUFDLHdCQUFjLENBQUMsQ0FBQTtJQUN4RSxNQUFNLGVBQWUsR0FBRyxNQUFNLGNBQWMsQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUE7SUFDdkUsT0FBTyxJQUFJLDRCQUFZLENBQUMsZUFBZSxDQUFDLGdCQUFnQixDQUFDLENBQUE7QUFDMUQsQ0FBQyxDQUNELENBQUE7QUFFRCxNQUFNLGtCQUFrQixHQUFHLElBQUEsMEJBQVUsRUFDcEMsa0JBQWtCLEVBQ2xCLEtBQUssRUFBRSxLQUFxQixFQUFFLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRTtJQUM5QyxNQUFNLGNBQWMsR0FBbUIsU0FBUyxDQUFDLE9BQU8sQ0FBQyx3QkFBYyxDQUFDLENBQUE7SUFDeEUsTUFBTSxRQUFRLEdBQUcsTUFBTSxjQUFjLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBQ2hFLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNmLE1BQU0sSUFBSSxLQUFLLENBQUMscUJBQXFCLEtBQUssQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFBO0lBQzNELENBQUM7SUFDRCxNQUFNLGNBQWMsQ0FBQyxlQUFlLENBQUMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQTtJQUNoRCxPQUFPLElBQUksNEJBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQTtBQUNsQyxDQUFDLENBQ0QsQ0FBQTtBQUVZLFFBQUEsc0JBQXNCLEdBQUcsSUFBQSw4QkFBYyxFQUNuRCxrQkFBa0IsRUFDbEIsQ0FBQyxLQUFxQixFQUFFLEVBQUU7SUFDekIsTUFBTSxVQUFVLEdBQUcsdUJBQXVCLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDakQsTUFBTSxRQUFRLEdBQUcsa0JBQWtCLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDMUMsSUFBSSxVQUFVLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDdEIsTUFBTSxlQUFlLEdBQUcsSUFBQSx5QkFBUyxFQUFDLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDcEU7Z0JBQ0MsaUJBQWlCLEVBQUUsS0FBSyxDQUFDLFFBQVEsQ0FBQyxpQkFBaUI7Z0JBQ25ELFdBQVcsRUFBRSxLQUFLLENBQUMsUUFBUSxDQUFDLGlCQUFpQjtnQkFDN0MsVUFBVSxFQUFFLEtBQUssQ0FBQyxVQUFVO2FBQzVCO1NBQ0QsQ0FBQyxDQUFBO1FBQ0YsSUFBQSxzQ0FBeUIsRUFBQyxlQUFlLENBQUMsQ0FBQTtJQUMzQyxDQUFDO0lBQ0QsT0FBTyxJQUFJLGdDQUFnQixDQUFDLFFBQVEsQ0FBQyxDQUFBO0FBQ3RDLENBQUMsQ0FDRCxDQUFBIn0=
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ // find stock lot and assign
3
+ // create serial number
4
+ // return data for fulfillment creation step to create fulfillment with serial number and lot info
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
7
+ const tracing_1 = require("../../../modules/tracing");
8
+ const utils_1 = require("@medusajs/framework/utils");
9
+ // change to use fulfillment data input, not order id
10
+ const assignFromStockLotStep = (0, workflows_sdk_1.createStep)('assign-from-stock-lot', async ({ order_id }, { container }) => {
11
+ const tracingService = container.resolve(tracing_1.TRACING_MODULE);
12
+ const inventoryModuleService = container.resolve(utils_1.Modules.INVENTORY);
13
+ const query = container.resolve('query');
14
+ const { data: orders } = await query.graph({
15
+ entity: 'order',
16
+ fields: [
17
+ 'id',
18
+ 'items.*',
19
+ 'items.variant.*',
20
+ 'items.variant.inventory.*',
21
+ 'items.variant.inventory.location_levels.*'
22
+ ],
23
+ filters: { id: order_id }
24
+ });
25
+ const order = orders[0];
26
+ if (order.items && order.items.length > 0) {
27
+ for (const item of order.items) {
28
+ if (!item?.variant || !item?.variant.inventory)
29
+ continue;
30
+ for (const inv of item.variant?.inventory ?? []) {
31
+ if (!inv?.id)
32
+ continue;
33
+ for (const locLevel of inv?.location_levels ?? []) {
34
+ if (!locLevel?.location_id)
35
+ continue;
36
+ // Find the first available lot for this inventory item + location
37
+ const lot = await tracingService.findFirstAvailable(inv.id, locLevel.location_id);
38
+ if (!lot)
39
+ continue;
40
+ // Adjust the lot's reserved quantity
41
+ await tracingService.adjustLotQuantity(lot.id, -item.quantity);
42
+ }
43
+ }
44
+ }
45
+ }
46
+ return new workflows_sdk_1.StepResponse({ order_id });
47
+ });
48
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzaWduLWZyb20tc3RvY2stbG90LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy90cmFjaW5nL3N0ZXBzL2Fzc2lnbi1mcm9tLXN0b2NrLWxvdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsNEJBQTRCO0FBQzVCLHVCQUF1QjtBQUN2QixrR0FBa0c7O0FBRWxHLHFFQUswQztBQUMxQyxzREFBeUQ7QUFFekQscURBQW1EO0FBTW5ELHFEQUFxRDtBQUNyRCxNQUFNLHNCQUFzQixHQUFHLElBQUEsMEJBQVUsRUFDeEMsdUJBQXVCLEVBQ3ZCLEtBQUssRUFBRSxFQUFFLFFBQVEsRUFBK0IsRUFBRSxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUU7SUFDbEUsTUFBTSxjQUFjLEdBQW1CLFNBQVMsQ0FBQyxPQUFPLENBQUMsd0JBQWMsQ0FBQyxDQUFBO0lBQ3hFLE1BQU0sc0JBQXNCLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxlQUFPLENBQUMsU0FBUyxDQUFDLENBQUE7SUFFbkUsTUFBTSxLQUFLLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQTtJQUN4QyxNQUFNLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxHQUFHLE1BQU0sS0FBSyxDQUFDLEtBQUssQ0FBQztRQUMxQyxNQUFNLEVBQUUsT0FBTztRQUNmLE1BQU0sRUFBRTtZQUNQLElBQUk7WUFDSixTQUFTO1lBQ1QsaUJBQWlCO1lBQ2pCLDJCQUEyQjtZQUMzQiwyQ0FBMkM7U0FDM0M7UUFDRCxPQUFPLEVBQUUsRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFO0tBQ3pCLENBQUMsQ0FBQTtJQUNGLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUV2QixJQUFJLEtBQUssQ0FBQyxLQUFLLElBQUksS0FBSyxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDM0MsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDaEMsSUFBSSxDQUFDLElBQUksRUFBRSxPQUFPLElBQUksQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLFNBQVM7Z0JBQUUsU0FBUTtZQUN4RCxLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsU0FBUyxJQUFJLEVBQUUsRUFBRSxDQUFDO2dCQUNqRCxJQUFJLENBQUMsR0FBRyxFQUFFLEVBQUU7b0JBQUUsU0FBUTtnQkFDdEIsS0FBSyxNQUFNLFFBQVEsSUFBSSxHQUFHLEVBQUUsZUFBZSxJQUFJLEVBQUUsRUFBRSxDQUFDO29CQUNuRCxJQUFJLENBQUMsUUFBUSxFQUFFLFdBQVc7d0JBQUUsU0FBUTtvQkFDcEMsa0VBQWtFO29CQUNsRSxNQUFNLEdBQUcsR0FBRyxNQUFNLGNBQWMsQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLFFBQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQTtvQkFDakYsSUFBSSxDQUFDLEdBQUc7d0JBQUUsU0FBUTtvQkFDbEIscUNBQXFDO29CQUNyQyxNQUFNLGNBQWMsQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFBO2dCQUMvRCxDQUFDO1lBQ0YsQ0FBQztRQUNGLENBQUM7SUFDRixDQUFDO0lBRUQsT0FBTyxJQUFJLDRCQUFZLENBQUMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFBO0FBQ3RDLENBQUMsQ0FDRCxDQUFBIn0=
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzaWduLXNlcmlhbC1udW1iZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvd29ya2Zsb3dzL3RyYWNpbmcvc3RlcHMvYXNzaWduLXNlcmlhbC1udW1iZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW52YWxpZGF0ZS1zZXJpYWwtbnVtYmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy90cmFjaW5nL3N0ZXBzL2ludmFsaWRhdGUtc2VyaWFsLW51bWJlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIn0=
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmV0dXJuLXRvLXN0b2NrLWxvdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy93b3JrZmxvd3MvdHJhY2luZy9zdGVwcy9yZXR1cm4tdG8tc3RvY2stbG90LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIifQ==
@@ -0,0 +1,46 @@
1
+ export declare const updateStockLotWorkflow: import("@medusajs/framework/workflows-sdk").ReturnWorkflow<{
2
+ inventory_item_id?: string | undefined;
3
+ stock_location_id?: string | undefined;
4
+ enabled?: boolean | undefined;
5
+ lot_number?: string | undefined;
6
+ description?: string | null | undefined;
7
+ stocked_quantity?: number | undefined;
8
+ metadata?: Record<string, unknown> | null | undefined;
9
+ } & {
10
+ id: string;
11
+ }, {
12
+ id: string;
13
+ inventory_item_id: string;
14
+ stock_location_id: string;
15
+ lot_number: string;
16
+ description: string | null;
17
+ enabled: boolean;
18
+ initial_quantity: number;
19
+ stocked_quantity: number;
20
+ serial_numbers: {
21
+ id: string;
22
+ order_id: string;
23
+ value: string;
24
+ invalidated: boolean;
25
+ invalidation_reason: {
26
+ id: string;
27
+ value: string;
28
+ serial_numbers: /*elided*/ any[];
29
+ metadata: Record<string, unknown> | null;
30
+ created_at: Date;
31
+ updated_at: Date;
32
+ deleted_at: Date | null;
33
+ };
34
+ stock_lot: /*elided*/ any;
35
+ metadata: Record<string, unknown> | null;
36
+ created_at: Date;
37
+ updated_at: Date;
38
+ deleted_at: Date | null;
39
+ invalidation_reason_id: string | null;
40
+ stock_lot_id: string;
41
+ }[];
42
+ metadata: Record<string, unknown> | null;
43
+ created_at: Date;
44
+ updated_at: Date;
45
+ deleted_at: Date | null;
46
+ }, []>;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.updateStockLotWorkflow = void 0;
4
+ const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
5
+ const core_flows_1 = require("@medusajs/medusa/core-flows");
6
+ const tracing_1 = require("../../modules/tracing");
7
+ const calculateAdjustmentStep = (0, workflows_sdk_1.createStep)('calculate-adjustment', async (input, { container }) => {
8
+ const tracingService = container.resolve(tracing_1.TRACING_MODULE);
9
+ const currentStockLot = await tracingService.retrieveStockLot(input.id);
10
+ let adjustment = 0;
11
+ if (input.enabled !== undefined && input.enabled !== currentStockLot.enabled) {
12
+ adjustment += input.enabled
13
+ ? currentStockLot.stocked_quantity
14
+ : -currentStockLot.stocked_quantity;
15
+ }
16
+ else if (input.stocked_quantity !== undefined &&
17
+ input.stocked_quantity !== currentStockLot.stocked_quantity) {
18
+ adjustment = input.stocked_quantity - currentStockLot.stocked_quantity;
19
+ }
20
+ return new workflows_sdk_1.StepResponse(adjustment);
21
+ });
22
+ const updateStockLotStep = (0, workflows_sdk_1.createStep)('update-stock-lot', async (input, { container }) => {
23
+ const tracingService = container.resolve(tracing_1.TRACING_MODULE);
24
+ const stockLot = await tracingService.updateStockLots(input);
25
+ return new workflows_sdk_1.StepResponse(stockLot, stockLot.id);
26
+ });
27
+ exports.updateStockLotWorkflow = (0, workflows_sdk_1.createWorkflow)('update-stock-lot', (input) => {
28
+ const adjustment = calculateAdjustmentStep(input);
29
+ const stockLot = updateStockLotStep(input);
30
+ if (adjustment !== 0) {
31
+ const adjustmentInput = (0, workflows_sdk_1.transform)({ adjustment, stockLot }, input => [
32
+ {
33
+ inventory_item_id: input.stockLot.inventory_item_id,
34
+ location_id: input.stockLot.stock_location_id,
35
+ adjustment: input.adjustment
36
+ }
37
+ ]);
38
+ (0, core_flows_1.adjustInventoryLevelsStep)(adjustmentInput);
39
+ }
40
+ return new workflows_sdk_1.WorkflowResponse(stockLot);
41
+ });
42
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBkYXRlLXN0b2NrLWxvdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy93b3JrZmxvd3MvdHJhY2luZy91cGRhdGUtc3RvY2stbG90LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFFQU0wQztBQUMxQyw0REFBdUU7QUFDdkUsbURBQXNEO0FBSXRELE1BQU0sdUJBQXVCLEdBQUcsSUFBQSwwQkFBVSxFQUN6QyxzQkFBc0IsRUFDdEIsS0FBSyxFQUFFLEtBQStDLEVBQUUsRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFO0lBQ3hFLE1BQU0sY0FBYyxHQUFtQixTQUFTLENBQUMsT0FBTyxDQUFDLHdCQUFjLENBQUMsQ0FBQTtJQUN4RSxNQUFNLGVBQWUsR0FBRyxNQUFNLGNBQWMsQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUE7SUFDdkUsSUFBSSxVQUFVLEdBQVcsQ0FBQyxDQUFBO0lBQzFCLElBQUksS0FBSyxDQUFDLE9BQU8sS0FBSyxTQUFTLElBQUksS0FBSyxDQUFDLE9BQU8sS0FBSyxlQUFlLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDOUUsVUFBVSxJQUFJLEtBQUssQ0FBQyxPQUFPO1lBQzFCLENBQUMsQ0FBQyxlQUFlLENBQUMsZ0JBQWdCO1lBQ2xDLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxnQkFBZ0IsQ0FBQTtJQUNyQyxDQUFDO1NBQU0sSUFDTixLQUFLLENBQUMsZ0JBQWdCLEtBQUssU0FBUztRQUNwQyxLQUFLLENBQUMsZ0JBQWdCLEtBQUssZUFBZSxDQUFDLGdCQUFnQixFQUMxRCxDQUFDO1FBQ0YsVUFBVSxHQUFHLEtBQUssQ0FBQyxnQkFBZ0IsR0FBRyxlQUFlLENBQUMsZ0JBQWdCLENBQUE7SUFDdkUsQ0FBQztJQUNELE9BQU8sSUFBSSw0QkFBWSxDQUFDLFVBQVUsQ0FBQyxDQUFBO0FBQ3BDLENBQUMsQ0FDRCxDQUFBO0FBRUQsTUFBTSxrQkFBa0IsR0FBRyxJQUFBLDBCQUFVLEVBQ3BDLGtCQUFrQixFQUNsQixLQUFLLEVBQUUsS0FBK0MsRUFBRSxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUU7SUFDeEUsTUFBTSxjQUFjLEdBQW1CLFNBQVMsQ0FBQyxPQUFPLENBQUMsd0JBQWMsQ0FBQyxDQUFBO0lBQ3hFLE1BQU0sUUFBUSxHQUFHLE1BQU0sY0FBYyxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUM1RCxPQUFPLElBQUksNEJBQVksQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0FBQy9DLENBQUMsQ0FDRCxDQUFBO0FBRVksUUFBQSxzQkFBc0IsR0FBRyxJQUFBLDhCQUFjLEVBQ25ELGtCQUFrQixFQUNsQixDQUFDLEtBQStDLEVBQUUsRUFBRTtJQUNuRCxNQUFNLFVBQVUsR0FBRyx1QkFBdUIsQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUNqRCxNQUFNLFFBQVEsR0FBRyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUMxQyxJQUFJLFVBQVUsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUN0QixNQUFNLGVBQWUsR0FBRyxJQUFBLHlCQUFTLEVBQUMsRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNwRTtnQkFDQyxpQkFBaUIsRUFBRSxLQUFLLENBQUMsUUFBUSxDQUFDLGlCQUFpQjtnQkFDbkQsV0FBVyxFQUFFLEtBQUssQ0FBQyxRQUFRLENBQUMsaUJBQWlCO2dCQUM3QyxVQUFVLEVBQUUsS0FBSyxDQUFDLFVBQVU7YUFDNUI7U0FDRCxDQUFDLENBQUE7UUFDRixJQUFBLHNDQUF5QixFQUFDLGVBQWUsQ0FBQyxDQUFBO0lBQzNDLENBQUM7SUFDRCxPQUFPLElBQUksZ0NBQWdCLENBQUMsUUFBUSxDQUFDLENBQUE7QUFDdEMsQ0FBQyxDQUNELENBQUEifQ==
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2026 Lacey Pevey
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,52 @@
1
+ # medusa-plugin-tracing
2
+
3
+ Inventory tracing plugin for Medusa v2. Track stock lots and serial numbers with FIFO lot selection and inventory synchronization.
4
+
5
+ [Documentation](https://pevey.com/medusa-plugin-tracing)
6
+
7
+ If you are not familiar with Medusa, you can learn more on [the project web site](https://www.medusajs.com/).
8
+
9
+ ## Features
10
+
11
+ - Stock lot management with lot numbers, descriptions, and quantities
12
+ - Serial number tracking per stock lot with order assignment
13
+ - Invalidation reasons for tracking rejected serial numbers
14
+ - FIFO lot selection for automatic stock assignment
15
+ - Inventory quantity synchronization via workflows
16
+ - Enable/disable stock lots in bulk
17
+ - Widget on Inventory Item detail page showing stock lots
18
+ - Admin API for stock lots, serial numbers, and invalidation reasons
19
+
20
+ ## Installation
21
+
22
+ Inside your medusa backend root folder:
23
+
24
+ ```bash
25
+ yarn add medusa-plugin-tracing
26
+ ```
27
+
28
+ Replace "yarn add" with the correct command for your package manager if you are using (for example) npm, pnpm, or bun.
29
+
30
+ ## Configuration
31
+
32
+ Enable in your `medusa-config.ts` file. Example:
33
+
34
+ ```ts
35
+ module.exports = defineConfig({
36
+ //... other config
37
+ plugins: [
38
+ {
39
+ resolve: 'medusa-plugin-tracing',
40
+ options: {}
41
+ }
42
+ // ... other plugins
43
+ ]
44
+ })
45
+ ```
46
+
47
+ ## Usage
48
+
49
+ - Manage stock lots from the Inventory Item detail page widget in the Medusa admin.
50
+ - Create stock lots with lot numbers and initial quantities.
51
+ - Serial numbers are automatically tracked when assigned to orders.
52
+ - Use the admin API for programmatic stock lot and serial number management.
package/package.json ADDED
@@ -0,0 +1,89 @@
1
+ {
2
+ "name": "medusa-plugin-tracing",
3
+ "version": "0.1.1",
4
+ "description": "Inventory tracing plugin for Medusa v2 with stock lots and serial numbers",
5
+ "author": "Lacey Pevey",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/pevey/medusa-plugins"
10
+ },
11
+ "homepage": "https://pevey.com/medusa-plugin-tracing",
12
+ "files": [
13
+ ".medusa/server"
14
+ ],
15
+ "exports": {
16
+ "./package.json": "./package.json",
17
+ "./admin": {
18
+ "import": "./.medusa/server/src/admin/index.mjs",
19
+ "require": "./.medusa/server/src/admin/index.js",
20
+ "default": "./.medusa/server/src/admin/index.js"
21
+ },
22
+ "./.medusa/server/src/modules/*": {
23
+ "types": "./.medusa/server/src/modules/*/index.d.ts",
24
+ "default": "./.medusa/server/src/modules/*/index.js"
25
+ },
26
+ "./modules/*": {
27
+ "types": "./.medusa/server/src/modules/*/index.d.ts",
28
+ "default": "./.medusa/server/src/modules/*/index.js"
29
+ },
30
+ "./providers/*": {
31
+ "types": "./.medusa/server/src/providers/*/index.d.ts",
32
+ "default": "./.medusa/server/src/providers/*/index.js"
33
+ },
34
+ "./*": {
35
+ "types": "./.medusa/server/src/*.d.ts",
36
+ "default": "./.medusa/server/src/*.js"
37
+ },
38
+ ".": {
39
+ "types": "./.medusa/server/src/modules/tracing/index.d.ts",
40
+ "default": "./.medusa/server/src/modules/tracing/index.js"
41
+ }
42
+ },
43
+ "keywords": [
44
+ "medusa-v2",
45
+ "medusa",
46
+ "tracing",
47
+ "inventory",
48
+ "stock lots",
49
+ "serial numbers",
50
+ "lot tracking"
51
+ ],
52
+ "scripts": {
53
+ "build": "medusa plugin:build",
54
+ "clean:snapshots": "find . -name '.snapshot-*.json' -path '*/migrations/*' -delete",
55
+ "dev": "medusa plugin:develop",
56
+ "prepublishOnly": "medusa plugin:build",
57
+ "test:unit": "TEST_TYPE=unit NODE_OPTIONS=--experimental-vm-modules jest --silent --runInBand --detectOpenHandles --forceExit --passWithNoTests",
58
+ "test:integration:http": "TEST_TYPE=integration:http NODE_OPTIONS=--experimental-vm-modules jest --silent=false --runInBand --detectOpenHandles --forceExit"
59
+ },
60
+ "devDependencies": {
61
+ "@medusajs/admin-sdk": "2.13.6",
62
+ "@medusajs/cli": "2.13.6",
63
+ "@medusajs/framework": "2.13.6",
64
+ "@medusajs/icons": "2.13.6",
65
+ "@medusajs/ui": "4.0.25",
66
+ "@swc/core": "^1.7.28",
67
+ "@swc/jest": "^0.2.39",
68
+ "@types/jest": "^30.0.0",
69
+ "@types/node": "^20.0.0",
70
+ "@types/react": "^18.3.2",
71
+ "@types/react-dom": "^18.2.25",
72
+ "jest": "^29.7.0",
73
+ "prop-types": "^15.8.1",
74
+ "react": "^18.2.0",
75
+ "react-dom": "^18.2.0",
76
+ "ts-node": "^10.9.2",
77
+ "typescript": "^5.6.2",
78
+ "vite": "^5.2.11",
79
+ "yalc": "^1.0.0-pre.53"
80
+ },
81
+ "peerDependencies": {
82
+ "@medusajs/framework": "2.13.6",
83
+ "@medusajs/js-sdk": "2.13.6",
84
+ "@medusajs/medusa": "2.13.6"
85
+ },
86
+ "engines": {
87
+ "node": ">=20"
88
+ }
89
+ }