quickbooks-medusa-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.
Files changed (44) hide show
  1. package/.medusa/server/src/admin/index.js +1832 -0
  2. package/.medusa/server/src/admin/index.mjs +1831 -0
  3. package/.medusa/server/src/api/admin/plugin/route.js +7 -0
  4. package/.medusa/server/src/api/admin/quickbooks/callback/route.js +95 -0
  5. package/.medusa/server/src/api/admin/quickbooks/connect/route.js +12 -0
  6. package/.medusa/server/src/api/admin/quickbooks/connection/route.js +32 -0
  7. package/.medusa/server/src/api/admin/quickbooks/disconnect/route.js +16 -0
  8. package/.medusa/server/src/api/admin/quickbooks/settings/route.js +33 -0
  9. package/.medusa/server/src/api/admin/quickbooks/webhooks/route.js +95 -0
  10. package/.medusa/server/src/api/store/plugin/route.js +7 -0
  11. package/.medusa/server/src/modules/quickbooks/index.js +13 -0
  12. package/.medusa/server/src/modules/quickbooks/migrations/Migration20260107000000.js +19 -0
  13. package/.medusa/server/src/modules/quickbooks/models/index.js +10 -0
  14. package/.medusa/server/src/modules/quickbooks/models/quickbooks-connection.js +20 -0
  15. package/.medusa/server/src/modules/quickbooks/models/quickbooks-settings.js +27 -0
  16. package/.medusa/server/src/modules/quickbooks/models/quickbooks-sync-mapping.js +20 -0
  17. package/.medusa/server/src/modules/quickbooks/services/quickbooks-service.js +425 -0
  18. package/.medusa/server/src/subscribers/quickbooks-order-sync.js +18 -0
  19. package/.medusa/server/src/subscribers/quickbooks-product-sync.js +26 -0
  20. package/.medusa/server/src/subscribers/quickbooks-sync.js +22 -0
  21. package/.medusa/server/src/workflows/index.js +23 -0
  22. package/.medusa/server/src/workflows/steps/order/sync-order-to-quickbooks.js +41 -0
  23. package/.medusa/server/src/workflows/steps/order/transform-order.js +78 -0
  24. package/.medusa/server/src/workflows/steps/order/update-order-mapping.js +17 -0
  25. package/.medusa/server/src/workflows/steps/order/validate-order-sync.js +23 -0
  26. package/.medusa/server/src/workflows/steps/reverse-sync/sync-customer-from-quickbooks.js +102 -0
  27. package/.medusa/server/src/workflows/steps/reverse-sync/sync-inventory-from-quickbooks.js +62 -0
  28. package/.medusa/server/src/workflows/steps/reverse-sync/sync-order-status-from-quickbooks.js +76 -0
  29. package/.medusa/server/src/workflows/steps/sync-customer-to-quickbooks.js +55 -0
  30. package/.medusa/server/src/workflows/steps/sync-product-to-quickbooks.js +59 -0
  31. package/.medusa/server/src/workflows/steps/transform-customer.js +41 -0
  32. package/.medusa/server/src/workflows/steps/transform-product.js +39 -0
  33. package/.medusa/server/src/workflows/steps/update-product-sync-mapping.js +17 -0
  34. package/.medusa/server/src/workflows/steps/update-sync-mapping.js +17 -0
  35. package/.medusa/server/src/workflows/steps/validate-customer-sync.js +17 -0
  36. package/.medusa/server/src/workflows/steps/validate-product-sync.js +17 -0
  37. package/.medusa/server/src/workflows/sync-customer-from-quickbooks.js +10 -0
  38. package/.medusa/server/src/workflows/sync-customer-to-quickbooks.js +32 -0
  39. package/.medusa/server/src/workflows/sync-inventory-from-quickbooks.js +10 -0
  40. package/.medusa/server/src/workflows/sync-order-status-from-quickbooks.js +10 -0
  41. package/.medusa/server/src/workflows/sync-order-to-quickbooks.js +28 -0
  42. package/.medusa/server/src/workflows/sync-product-to-quickbooks.js +31 -0
  43. package/README.md +104 -0
  44. package/package.json +75 -0
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.updateSyncMappingStep = void 0;
4
+ const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
5
+ const quickbooks_1 = require("../../modules/quickbooks");
6
+ exports.updateSyncMappingStep = (0, workflows_sdk_1.createStep)("update-sync-mapping", async (input, { container }) => {
7
+ const service = container.resolve(quickbooks_1.QUICKBOOKS_MODULE);
8
+ await service.createOrUpdateMapping({
9
+ medusa_entity_id: input.medusaCustomerId,
10
+ medusa_entity_type: "customer",
11
+ quickbooks_entity_id: input.quickbooksCustomer.Id,
12
+ quickbooks_entity_type: "Customer",
13
+ sync_status: "synced"
14
+ });
15
+ return new workflows_sdk_1.StepResponse({ success: true });
16
+ });
17
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBkYXRlLXN5bmMtbWFwcGluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy93b3JrZmxvd3Mvc3RlcHMvdXBkYXRlLXN5bmMtbWFwcGluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxxRUFBNEU7QUFDNUUseURBQTREO0FBUS9DLFFBQUEscUJBQXFCLEdBQUcsSUFBQSwwQkFBVSxFQUMzQyxxQkFBcUIsRUFDckIsS0FBSyxFQUFFLEtBQTZCLEVBQUUsRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFO0lBQ25ELE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsOEJBQWlCLENBQTRCLENBQUE7SUFFL0UsTUFBTSxPQUFPLENBQUMscUJBQXFCLENBQUM7UUFDaEMsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLGdCQUFnQjtRQUN4QyxrQkFBa0IsRUFBRSxVQUFVO1FBQzlCLG9CQUFvQixFQUFFLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFO1FBQ2pELHNCQUFzQixFQUFFLFVBQVU7UUFDbEMsV0FBVyxFQUFFLFFBQVE7S0FDeEIsQ0FBQyxDQUFBO0lBRUYsT0FBTyxJQUFJLDRCQUFZLENBQUMsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQTtBQUM5QyxDQUFDLENBQ0osQ0FBQSJ9
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateCustomerSyncStep = void 0;
4
+ const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
5
+ const quickbooks_1 = require("../../modules/quickbooks");
6
+ exports.validateCustomerSyncStep = (0, workflows_sdk_1.createStep)("validate-customer-sync", async (input, { container }) => {
7
+ const service = container.resolve(quickbooks_1.QUICKBOOKS_MODULE);
8
+ const settings = await service.getOrCreateSettings();
9
+ if (!settings.auto_sync_customers) {
10
+ return new workflows_sdk_1.StepResponse({ success: false, reason: "Auto-sync disabled", customer: null });
11
+ }
12
+ if (!input.customer?.email) {
13
+ return new workflows_sdk_1.StepResponse({ success: false, reason: "Customer missing email", customer: null });
14
+ }
15
+ return new workflows_sdk_1.StepResponse({ success: true, customer: input.customer, reason: null });
16
+ });
17
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGUtY3VzdG9tZXItc3luYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy93b3JrZmxvd3Mvc3RlcHMvdmFsaWRhdGUtY3VzdG9tZXItc3luYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxxRUFBNEU7QUFDNUUseURBQTREO0FBYS9DLFFBQUEsd0JBQXdCLEdBQUcsSUFBQSwwQkFBVSxFQUM5Qyx3QkFBd0IsRUFDeEIsS0FBSyxFQUFFLEtBQWdDLEVBQUUsRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFO0lBQ3RELE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsOEJBQWlCLENBQTRCLENBQUE7SUFDL0UsTUFBTSxRQUFRLEdBQUcsTUFBTSxPQUFPLENBQUMsbUJBQW1CLEVBQUUsQ0FBQTtJQUVwRCxJQUFJLENBQUMsUUFBUSxDQUFDLG1CQUFtQixFQUFFLENBQUM7UUFDaEMsT0FBTyxJQUFJLDRCQUFZLENBQTZCLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsb0JBQW9CLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUE7SUFDekgsQ0FBQztJQUVELElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLEtBQUssRUFBRSxDQUFDO1FBQ3pCLE9BQU8sSUFBSSw0QkFBWSxDQUE2QixFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLHdCQUF3QixFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFBO0lBQzdILENBQUM7SUFFRCxPQUFPLElBQUksNEJBQVksQ0FBNkIsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxLQUFLLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFBO0FBQ2xILENBQUMsQ0FDSixDQUFBIn0=
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateProductSyncStep = void 0;
4
+ const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
5
+ const quickbooks_1 = require("../../modules/quickbooks");
6
+ exports.validateProductSyncStep = (0, workflows_sdk_1.createStep)("validate-product-sync", async (input, { container }) => {
7
+ const service = container.resolve(quickbooks_1.QUICKBOOKS_MODULE);
8
+ const settings = await service.getOrCreateSettings();
9
+ if (!settings.auto_sync_products) {
10
+ return new workflows_sdk_1.StepResponse({ success: false, reason: "Auto-sync disabled", product: null });
11
+ }
12
+ // We sync variants mostly, but input might be product
13
+ // If input is product, we check if it has variants
14
+ // Doing basic check here.
15
+ return new workflows_sdk_1.StepResponse({ success: true, product: input.product, reason: null });
16
+ });
17
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGUtcHJvZHVjdC1zeW5jLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy9zdGVwcy92YWxpZGF0ZS1wcm9kdWN0LXN5bmMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscUVBQTRFO0FBQzVFLHlEQUE0RDtBQWEvQyxRQUFBLHVCQUF1QixHQUFHLElBQUEsMEJBQVUsRUFDN0MsdUJBQXVCLEVBQ3ZCLEtBQUssRUFBRSxLQUErQixFQUFFLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRTtJQUNyRCxNQUFNLE9BQU8sR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLDhCQUFpQixDQUE0QixDQUFBO0lBQy9FLE1BQU0sUUFBUSxHQUFHLE1BQU0sT0FBTyxDQUFDLG1CQUFtQixFQUFFLENBQUE7SUFFcEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBQy9CLE9BQU8sSUFBSSw0QkFBWSxDQUE0QixFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLG9CQUFvQixFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFBO0lBQ3ZILENBQUM7SUFFRCxzREFBc0Q7SUFDdEQsbURBQW1EO0lBQ25ELDBCQUEwQjtJQUUxQixPQUFPLElBQUksNEJBQVksQ0FBNEIsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFBO0FBQy9HLENBQUMsQ0FDSixDQUFBIn0=
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.syncCustomerFromQuickBooksWorkflow = void 0;
4
+ const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
5
+ const sync_customer_from_quickbooks_1 = require("./steps/reverse-sync/sync-customer-from-quickbooks");
6
+ exports.syncCustomerFromQuickBooksWorkflow = (0, workflows_sdk_1.createWorkflow)("sync-customer-from-quickbooks", (input) => {
7
+ const result = (0, sync_customer_from_quickbooks_1.syncCustomerFromQuickBooksStep)(input);
8
+ return new workflows_sdk_1.WorkflowResponse(result);
9
+ });
10
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1jdXN0b21lci1mcm9tLXF1aWNrYm9va3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvd29ya2Zsb3dzL3N5bmMtY3VzdG9tZXItZnJvbS1xdWlja2Jvb2tzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFFQUFvRjtBQUNwRixzR0FBbUc7QUFNdEYsUUFBQSxrQ0FBa0MsR0FBRyxJQUFBLDhCQUFjLEVBQzVELCtCQUErQixFQUMvQixDQUFDLEtBQThDLEVBQUUsRUFBRTtJQUUvQyxNQUFNLE1BQU0sR0FBRyxJQUFBLDhEQUE4QixFQUFDLEtBQUssQ0FBQyxDQUFBO0lBRXBELE9BQU8sSUFBSSxnQ0FBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQTtBQUN2QyxDQUFDLENBQ0osQ0FBQSJ9
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.syncCustomerToQuickBooksWorkflow = void 0;
4
+ const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
5
+ const validate_customer_sync_1 = require("./steps/validate-customer-sync");
6
+ const transform_customer_1 = require("./steps/transform-customer");
7
+ const sync_customer_to_quickbooks_1 = require("./steps/sync-customer-to-quickbooks");
8
+ const update_sync_mapping_1 = require("./steps/update-sync-mapping");
9
+ exports.syncCustomerToQuickBooksWorkflow = (0, workflows_sdk_1.createWorkflow)("sync-customer-to-quickbooks", (input) => {
10
+ // 1. Validate
11
+ const validationResult = (0, validate_customer_sync_1.validateCustomerSyncStep)({ customer: input.customer });
12
+ // Conditional logic is tricky in workflows without conditional steps
13
+ // But since Medusa workflows graph is static, we usually just run steps and they return "skipped" or success/fail.
14
+ // However, `validateCustomerSyncStep` returns a generic object.
15
+ // If validation fails, we should probably stop.
16
+ // For now, I'll assume valid input, or use `when` if available in this version, or standard flow.
17
+ // Note: step returns are promises of StepResponse.
18
+ // 2. Transform
19
+ const qbCustomerData = (0, transform_customer_1.transformCustomerStep)({ customer: input.customer });
20
+ // 3. Sync
21
+ const qbCustomer = (0, sync_customer_to_quickbooks_1.syncCustomerToQuickBooksStep)({
22
+ qbCustomerData,
23
+ medusaCustomerId: input.customer.id
24
+ });
25
+ // 4. Update Mapping
26
+ (0, update_sync_mapping_1.updateSyncMappingStep)({
27
+ medusaCustomerId: input.customer.id,
28
+ quickbooksCustomer: qbCustomer
29
+ });
30
+ return new workflows_sdk_1.WorkflowResponse(qbCustomer);
31
+ });
32
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1jdXN0b21lci10by1xdWlja2Jvb2tzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy9zeW5jLWN1c3RvbWVyLXRvLXF1aWNrYm9va3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscUVBQW9GO0FBQ3BGLDJFQUF5RTtBQUN6RSxtRUFBa0U7QUFDbEUscUZBQWtGO0FBQ2xGLHFFQUFtRTtBQU10RCxRQUFBLGdDQUFnQyxHQUFHLElBQUEsOEJBQWMsRUFDMUQsNkJBQTZCLEVBQzdCLENBQUMsS0FBNEMsRUFBRSxFQUFFO0lBRTdDLGNBQWM7SUFDZCxNQUFNLGdCQUFnQixHQUFHLElBQUEsaURBQXdCLEVBQUMsRUFBRSxRQUFRLEVBQUUsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUE7SUFFL0UscUVBQXFFO0lBQ3JFLG1IQUFtSDtJQUNuSCxnRUFBZ0U7SUFDaEUsZ0RBQWdEO0lBQ2hELGtHQUFrRztJQUNsRyxtREFBbUQ7SUFFbkQsZUFBZTtJQUNmLE1BQU0sY0FBYyxHQUFHLElBQUEsMENBQXFCLEVBQUMsRUFBRSxRQUFRLEVBQUUsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUE7SUFFMUUsVUFBVTtJQUNWLE1BQU0sVUFBVSxHQUFHLElBQUEsMERBQTRCLEVBQUM7UUFDNUMsY0FBYztRQUNkLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxRQUFRLENBQUMsRUFBRTtLQUN0QyxDQUFDLENBQUE7SUFFRixvQkFBb0I7SUFDcEIsSUFBQSwyQ0FBcUIsRUFBQztRQUNsQixnQkFBZ0IsRUFBRSxLQUFLLENBQUMsUUFBUSxDQUFDLEVBQUU7UUFDbkMsa0JBQWtCLEVBQUUsVUFBVTtLQUNqQyxDQUFDLENBQUE7SUFFRixPQUFPLElBQUksZ0NBQWdCLENBQUMsVUFBVSxDQUFDLENBQUE7QUFDM0MsQ0FBQyxDQUNKLENBQUEifQ==
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.syncInventoryFromQuickBooksWorkflow = void 0;
4
+ const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
5
+ const sync_inventory_from_quickbooks_1 = require("./steps/reverse-sync/sync-inventory-from-quickbooks");
6
+ exports.syncInventoryFromQuickBooksWorkflow = (0, workflows_sdk_1.createWorkflow)("sync-inventory-from-quickbooks", (input) => {
7
+ const result = (0, sync_inventory_from_quickbooks_1.syncInventoryFromQuickBooksStep)(input);
8
+ return new workflows_sdk_1.WorkflowResponse(result);
9
+ });
10
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1pbnZlbnRvcnktZnJvbS1xdWlja2Jvb2tzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy9zeW5jLWludmVudG9yeS1mcm9tLXF1aWNrYm9va3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscUVBQW9GO0FBQ3BGLHdHQUFxRztBQU14RixRQUFBLG1DQUFtQyxHQUFHLElBQUEsOEJBQWMsRUFDN0QsZ0NBQWdDLEVBQ2hDLENBQUMsS0FBK0MsRUFBRSxFQUFFO0lBRWhELE1BQU0sTUFBTSxHQUFHLElBQUEsZ0VBQStCLEVBQUMsS0FBSyxDQUFDLENBQUE7SUFFckQsT0FBTyxJQUFJLGdDQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFBO0FBQ3ZDLENBQUMsQ0FDSixDQUFBIn0=
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.syncOrderStatusFromQuickBooksWorkflow = void 0;
4
+ const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
5
+ const sync_order_status_from_quickbooks_1 = require("./steps/reverse-sync/sync-order-status-from-quickbooks");
6
+ exports.syncOrderStatusFromQuickBooksWorkflow = (0, workflows_sdk_1.createWorkflow)("sync-order-status-from-quickbooks", (input) => {
7
+ const result = (0, sync_order_status_from_quickbooks_1.syncOrderStatusFromQuickBooksStep)(input);
8
+ return new workflows_sdk_1.WorkflowResponse(result);
9
+ });
10
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1vcmRlci1zdGF0dXMtZnJvbS1xdWlja2Jvb2tzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy9zeW5jLW9yZGVyLXN0YXR1cy1mcm9tLXF1aWNrYm9va3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EscUVBQW9GO0FBQ3BGLDhHQUEwRztBQU83RixRQUFBLHFDQUFxQyxHQUFHLElBQUEsOEJBQWMsRUFDL0QsbUNBQW1DLEVBQ25DLENBQUMsS0FBaUQsRUFBRSxFQUFFO0lBQ2xELE1BQU0sTUFBTSxHQUFHLElBQUEscUVBQWlDLEVBQUMsS0FBSyxDQUFDLENBQUE7SUFDdkQsT0FBTyxJQUFJLGdDQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFBO0FBQ3ZDLENBQUMsQ0FDSixDQUFBIn0=
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.syncOrderToQuickBooksWorkflow = void 0;
4
+ const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
5
+ const validate_order_sync_1 = require("./steps/order/validate-order-sync");
6
+ const transform_order_1 = require("./steps/order/transform-order");
7
+ const sync_order_to_quickbooks_1 = require("./steps/order/sync-order-to-quickbooks");
8
+ const update_order_mapping_1 = require("./steps/order/update-order-mapping");
9
+ exports.syncOrderToQuickBooksWorkflow = (0, workflows_sdk_1.createWorkflow)("sync-order-to-quickbooks", (input) => {
10
+ // 1. Validate
11
+ (0, validate_order_sync_1.validateOrderSyncStep)({ order: input.order });
12
+ // 2. Transform
13
+ const { qbData, type } = (0, transform_order_1.transformOrderStep)({ order: input.order });
14
+ // 3. Sync
15
+ const qbOrder = (0, sync_order_to_quickbooks_1.syncOrderToQuickBooksStep)({
16
+ qbData,
17
+ type,
18
+ medusaOrderId: input.order.id
19
+ });
20
+ // 4. Update Mapping
21
+ (0, update_order_mapping_1.updateOrderSyncMappingStep)({
22
+ medusaOrderId: input.order.id,
23
+ quickbooksOrder: qbOrder,
24
+ type
25
+ });
26
+ return new workflows_sdk_1.WorkflowResponse(qbOrder);
27
+ });
28
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1vcmRlci10by1xdWlja2Jvb2tzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy9zeW5jLW9yZGVyLXRvLXF1aWNrYm9va3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscUVBQW9GO0FBQ3BGLDJFQUF5RTtBQUN6RSxtRUFBa0U7QUFDbEUscUZBQWtGO0FBQ2xGLDZFQUErRTtBQU1sRSxRQUFBLDZCQUE2QixHQUFHLElBQUEsOEJBQWMsRUFDdkQsMEJBQTBCLEVBQzFCLENBQUMsS0FBeUMsRUFBRSxFQUFFO0lBRTFDLGNBQWM7SUFDZCxJQUFBLDJDQUFxQixFQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFBO0lBRTdDLGVBQWU7SUFDZixNQUFNLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLElBQUEsb0NBQWtCLEVBQUMsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUE7SUFFbkUsVUFBVTtJQUNWLE1BQU0sT0FBTyxHQUFHLElBQUEsb0RBQXlCLEVBQUM7UUFDdEMsTUFBTTtRQUNOLElBQUk7UUFDSixhQUFhLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUFFO0tBQ2hDLENBQUMsQ0FBQTtJQUVGLG9CQUFvQjtJQUNwQixJQUFBLGlEQUEwQixFQUFDO1FBQ3ZCLGFBQWEsRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQUU7UUFDN0IsZUFBZSxFQUFFLE9BQU87UUFDeEIsSUFBSTtLQUNQLENBQUMsQ0FBQTtJQUVGLE9BQU8sSUFBSSxnQ0FBZ0IsQ0FBQyxPQUFPLENBQUMsQ0FBQTtBQUN4QyxDQUFDLENBQ0osQ0FBQSJ9
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.syncProductToQuickBooksWorkflow = void 0;
4
+ const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
5
+ const validate_product_sync_1 = require("./steps/validate-product-sync");
6
+ const transform_product_1 = require("./steps/transform-product");
7
+ const sync_product_to_quickbooks_1 = require("./steps/sync-product-to-quickbooks");
8
+ const update_product_sync_mapping_1 = require("./steps/update-product-sync-mapping");
9
+ exports.syncProductToQuickBooksWorkflow = (0, workflows_sdk_1.createWorkflow)("sync-product-to-quickbooks", (input) => {
10
+ // 1. Validate
11
+ (0, validate_product_sync_1.validateProductSyncStep)({ product: input.product });
12
+ // 2. Transform
13
+ const qbItemData = (0, transform_product_1.transformProductStep)({
14
+ product: input.product,
15
+ variant: input.variant
16
+ });
17
+ // 3. Sync
18
+ const qbItem = (0, sync_product_to_quickbooks_1.syncProductToQuickBooksStep)({
19
+ qbItemData,
20
+ medusaVariantId: input.variant.id
21
+ });
22
+ // 4. Update Mapping
23
+ (0, update_product_sync_mapping_1.updateProductSyncMappingStep)({
24
+ medusaVariantId: input.variant.id,
25
+ quickbooksItem: qbItem
26
+ });
27
+ return new workflows_sdk_1.WorkflowResponse(qbItem);
28
+ });
29
+ // NOTE: This implementation is flawed because it assumes single variant.
30
+ // I will rewrite this file in next step to properly loop or expect single variant input.
31
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1wcm9kdWN0LXRvLXF1aWNrYm9va3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvd29ya2Zsb3dzL3N5bmMtcHJvZHVjdC10by1xdWlja2Jvb2tzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFFQUFvRjtBQUNwRix5RUFBdUU7QUFDdkUsaUVBQWdFO0FBQ2hFLG1GQUFnRjtBQUNoRixxRkFBa0Y7QUFPckUsUUFBQSwrQkFBK0IsR0FBRyxJQUFBLDhCQUFjLEVBQ3pELDRCQUE0QixFQUM1QixDQUFDLEtBQTJDLEVBQUUsRUFBRTtJQUU1QyxjQUFjO0lBQ2QsSUFBQSwrQ0FBdUIsRUFBQyxFQUFFLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQTtJQUVuRCxlQUFlO0lBQ2YsTUFBTSxVQUFVLEdBQUcsSUFBQSx3Q0FBb0IsRUFBQztRQUNwQyxPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU87UUFDdEIsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPO0tBQ3pCLENBQUMsQ0FBQTtJQUVGLFVBQVU7SUFDVixNQUFNLE1BQU0sR0FBRyxJQUFBLHdEQUEyQixFQUFDO1FBQ3ZDLFVBQVU7UUFDVixlQUFlLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFO0tBQ3BDLENBQUMsQ0FBQTtJQUVGLG9CQUFvQjtJQUNwQixJQUFBLDBEQUE0QixFQUFDO1FBQ3pCLGVBQWUsRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUU7UUFDakMsY0FBYyxFQUFFLE1BQU07S0FDekIsQ0FBQyxDQUFBO0lBRUYsT0FBTyxJQUFJLGdDQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFBO0FBQ3ZDLENBQUMsQ0FDSixDQUFBO0FBQ0QseUVBQXlFO0FBQ3pFLHlGQUF5RiJ9
package/README.md ADDED
@@ -0,0 +1,104 @@
1
+ # Medusa QuickBooks Plugin
2
+
3
+ A robust, bi-directional QuickBooks Online integration for Medusa v2. This plugin facilitates seamless synchronization of Customers, Products, Inventory, and Orders between your Medusa store and QuickBooks Online.
4
+
5
+ ## Features
6
+
7
+ ### 🔐 Authentication & Security
8
+ - **OAuth 2.0 Support**: Securely connect to QuickBooks Online via the Medusa Admin.
9
+ - **Auto-Token Refresh**: Automatically handles token expiration and refreshing for uninterrupted background operations.
10
+ - **Environment Support**: Easy switching between Sandbox and Production environments.
11
+
12
+ ### 🔄 Bi-Directional Synchronization
13
+ - **Customers**:
14
+ - **Medusa -> QuickBooks**: Syncs new and updated customers. Handles duplicate prevention via email matching.
15
+ - **QuickBooks -> Medusa**: Webhooks update Medusa customers when changed in QuickBooks (Name, Company, Address, Phone).
16
+ - **Products & Inventory**:
17
+ - **SKU & UPC Sync**: Maps Medusa `sku` and `upc` (or `ean`/`barcode`) to QuickBooks Item fields.
18
+ - **Inventory**: Bi-directional inventory updates. Webhooks from QuickBooks update Medusa variant details.
19
+ - **Orders & Invoices**:
20
+ - **Smart Sync**:
21
+ - **Sales Receipt**: Created for `captured` payments (e.g., Credit Card).
22
+ - **Invoice**: Created for `awaiting` payments (e.g., Wire Transfer).
23
+ - **Payment Capture**: Automatically captures Medusa payments when a QuickBooks Invoice is marked as PAID.
24
+ - **Payment Methods**: Maps providers (e.g., `stripe` -> `Credit Card`, `manual` -> `Cash`).
25
+
26
+ ### ⚙️ Admin Dashboard
27
+ - **Connection Status**: Visual widget showing connection state and token validity.
28
+ - **Settings**: Configure default Income, Expense (COGS), and Asset accounts for automatic Item creation.
29
+
30
+ ---
31
+
32
+ ## Installation
33
+
34
+ 1. **Install the plugin**
35
+ ```bash
36
+ yarn add medusa-plugin-quickbooks
37
+ # or
38
+ npm install medusa-plugin-quickbooks
39
+ ```
40
+
41
+ 2. **Add to `medusa-config.ts`**
42
+ ```typescript
43
+ module.exports = defineConfig({
44
+ plugins: [
45
+ {
46
+ resolve: "medusa-plugin-quickbooks",
47
+ options: {
48
+ clientId: process.env.QUICKBOOKS_CLIENT_ID,
49
+ clientSecret: process.env.QUICKBOOKS_CLIENT_SECRET,
50
+ redirectUri: process.env.QUICKBOOKS_REDIRECT_URI,
51
+ environment: process.env.QUICKBOOKS_ENVIRONMENT || "sandbox",
52
+ // Optional default callbacks
53
+ // incomeAccountId: "...",
54
+ },
55
+ },
56
+ ],
57
+ });
58
+ ```
59
+
60
+ 3. **Configure Environment Variables**
61
+ Add these to your `.env`:
62
+ ```bash
63
+ QUICKBOOKS_CLIENT_ID=your_client_id
64
+ QUICKBOOKS_CLIENT_SECRET=your_client_secret
65
+ QUICKBOOKS_REDIRECT_URI=http://localhost:9000/app/quickbooks/callback
66
+ QUICKBOOKS_ENVIRONMENT=sandbox # or production
67
+ QUICKBOOKS_WEBHOOK_VERIFIER_TOKEN=your_webhook_token
68
+ ```
69
+
70
+ 4. **Run Migrations**
71
+ ```bash
72
+ npx medusa db:migrate
73
+ ```
74
+
75
+ ---
76
+
77
+ ## Setup Guide
78
+
79
+ ### 1. Intuit Developer Portal
80
+ 1. Go to [Intuit Developer Portal](https://developer.intuit.com/).
81
+ 2. Create a new App (select "com.intuit.quickbooks.accounting" scope).
82
+ 3. Get your **Client ID** and **Client Secret**.
83
+ 4. Set the **Redirect URI** in the keys tab to match your deployment (e.g., `https://your-admin.com/app/quickbooks/callback`).
84
+
85
+ ### 2. Configure Webhooks (For Reverse Sync)
86
+ 1. In the Intuit App dashboard, go to **Webhooks**.
87
+ 2. Enter your endpoint URL: `https://your-medusa-server.com/admin/quickbooks/webhooks`.
88
+ 3. Select events to trigger: `Customer`, `Item`, `Invoice`, `SalesReceipt`.
89
+ 4. Copy the **Verifier Token** to your `.env`.
90
+
91
+ ### 3. Connect in Medusa Admin
92
+ 1. Go to the Medusa Admin dashboard.
93
+ 2. Navigate to **Associations** (or the sidebar link if configured).
94
+ 3. Click "Connect to QuickBooks".
95
+ 4. Follow the OAuth flow.
96
+ 5. Once connected, go to **Settings** and configure your Default Accounts (Income/Asset/Expense) to ensure Products sync correctly.
97
+
98
+ ---
99
+
100
+ ## Troubleshooting
101
+
102
+ - **Token Expired?** The plugin automatically refreshes tokens. If a connection is completely revoked, simply disconnect and reconnect in the Admin.
103
+ - **Inventory not syncing?** Ensure the `upc` or `sku` matches exactly. Inventory sync relies on mapping or SKU matching.
104
+ - **Webhooks not firing?** Check your server logs for `[QB Webhook]` entries and verify the `QUICKBOOKS_WEBHOOK_VERIFIER_TOKEN`.
package/package.json ADDED
@@ -0,0 +1,75 @@
1
+ {
2
+ "name": "quickbooks-medusa-plugin",
3
+ "version": "0.0.1",
4
+ "description": "Medusa v2 plugin for QuickBooks Online bi-directional sync (Customers, Products, Orders, Inventory).",
5
+ "author": "bootssecurity",
6
+ "license": "MIT",
7
+ "files": [
8
+ ".medusa/server"
9
+ ],
10
+ "exports": {
11
+ "./package.json": "./package.json",
12
+ "./workflows": "./.medusa/server/src/workflows/index.js",
13
+ "./.medusa/server/src/modules/*": "./.medusa/server/src/modules/*/index.js",
14
+ "./modules/*": "./.medusa/server/src/modules/*/index.js",
15
+ "./providers/*": "./.medusa/server/src/providers/*/index.js",
16
+ "./*": "./.medusa/server/src/*.js",
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
+ },
23
+ "keywords": [
24
+ "medusa",
25
+ "medusa-v2",
26
+ "quickbooks",
27
+ "accounting",
28
+ "sync",
29
+ "erp",
30
+ "intuit"
31
+ ],
32
+ "scripts": {
33
+ "build": "medusa plugin:build",
34
+ "dev": "medusa plugin:develop",
35
+ "prepublishOnly": "medusa plugin:build"
36
+ },
37
+ "devDependencies": {
38
+ "@medusajs/admin-sdk": "2.12.3",
39
+ "@medusajs/cli": "2.12.3",
40
+ "@medusajs/framework": "2.12.3",
41
+ "@medusajs/icons": "2.12.3",
42
+ "@medusajs/medusa": "2.12.3",
43
+ "@medusajs/test-utils": "2.12.3",
44
+ "@medusajs/ui": "4.0.25",
45
+ "@swc/core": "1.5.7",
46
+ "@types/node": "^20.0.0",
47
+ "@types/react": "^18.3.2",
48
+ "@types/react-dom": "^18.2.25",
49
+ "prop-types": "^15.8.1",
50
+ "react": "^18.2.0",
51
+ "react-dom": "^18.2.0",
52
+ "ts-node": "^10.9.2",
53
+ "typescript": "^5.6.2",
54
+ "vite": "^5.2.11",
55
+ "yalc": "^1.0.0-pre.53"
56
+ },
57
+ "peerDependencies": {
58
+ "@medusajs/admin-sdk": "2.12.3",
59
+ "@medusajs/cli": "2.12.3",
60
+ "@medusajs/framework": "2.12.3",
61
+ "@medusajs/icons": "2.12.3",
62
+ "@medusajs/medusa": "2.12.3",
63
+ "@medusajs/test-utils": "2.12.3",
64
+ "@medusajs/ui": "4.0.25"
65
+ },
66
+ "resolutions": {
67
+ "jsonwebtoken": "^9.0.0"
68
+ },
69
+ "engines": {
70
+ "node": ">=20"
71
+ },
72
+ "dependencies": {
73
+ "node-quickbooks": "^2.0.47"
74
+ }
75
+ }