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.
- package/.medusa/server/src/admin/index.js +1832 -0
- package/.medusa/server/src/admin/index.mjs +1831 -0
- package/.medusa/server/src/api/admin/plugin/route.js +7 -0
- package/.medusa/server/src/api/admin/quickbooks/callback/route.js +95 -0
- package/.medusa/server/src/api/admin/quickbooks/connect/route.js +12 -0
- package/.medusa/server/src/api/admin/quickbooks/connection/route.js +32 -0
- package/.medusa/server/src/api/admin/quickbooks/disconnect/route.js +16 -0
- package/.medusa/server/src/api/admin/quickbooks/settings/route.js +33 -0
- package/.medusa/server/src/api/admin/quickbooks/webhooks/route.js +95 -0
- package/.medusa/server/src/api/store/plugin/route.js +7 -0
- package/.medusa/server/src/modules/quickbooks/index.js +13 -0
- package/.medusa/server/src/modules/quickbooks/migrations/Migration20260107000000.js +19 -0
- package/.medusa/server/src/modules/quickbooks/models/index.js +10 -0
- package/.medusa/server/src/modules/quickbooks/models/quickbooks-connection.js +20 -0
- package/.medusa/server/src/modules/quickbooks/models/quickbooks-settings.js +27 -0
- package/.medusa/server/src/modules/quickbooks/models/quickbooks-sync-mapping.js +20 -0
- package/.medusa/server/src/modules/quickbooks/services/quickbooks-service.js +425 -0
- package/.medusa/server/src/subscribers/quickbooks-order-sync.js +18 -0
- package/.medusa/server/src/subscribers/quickbooks-product-sync.js +26 -0
- package/.medusa/server/src/subscribers/quickbooks-sync.js +22 -0
- package/.medusa/server/src/workflows/index.js +23 -0
- package/.medusa/server/src/workflows/steps/order/sync-order-to-quickbooks.js +41 -0
- package/.medusa/server/src/workflows/steps/order/transform-order.js +78 -0
- package/.medusa/server/src/workflows/steps/order/update-order-mapping.js +17 -0
- package/.medusa/server/src/workflows/steps/order/validate-order-sync.js +23 -0
- package/.medusa/server/src/workflows/steps/reverse-sync/sync-customer-from-quickbooks.js +102 -0
- package/.medusa/server/src/workflows/steps/reverse-sync/sync-inventory-from-quickbooks.js +62 -0
- package/.medusa/server/src/workflows/steps/reverse-sync/sync-order-status-from-quickbooks.js +76 -0
- package/.medusa/server/src/workflows/steps/sync-customer-to-quickbooks.js +55 -0
- package/.medusa/server/src/workflows/steps/sync-product-to-quickbooks.js +59 -0
- package/.medusa/server/src/workflows/steps/transform-customer.js +41 -0
- package/.medusa/server/src/workflows/steps/transform-product.js +39 -0
- package/.medusa/server/src/workflows/steps/update-product-sync-mapping.js +17 -0
- package/.medusa/server/src/workflows/steps/update-sync-mapping.js +17 -0
- package/.medusa/server/src/workflows/steps/validate-customer-sync.js +17 -0
- package/.medusa/server/src/workflows/steps/validate-product-sync.js +17 -0
- package/.medusa/server/src/workflows/sync-customer-from-quickbooks.js +10 -0
- package/.medusa/server/src/workflows/sync-customer-to-quickbooks.js +32 -0
- package/.medusa/server/src/workflows/sync-inventory-from-quickbooks.js +10 -0
- package/.medusa/server/src/workflows/sync-order-status-from-quickbooks.js +10 -0
- package/.medusa/server/src/workflows/sync-order-to-quickbooks.js +28 -0
- package/.medusa/server/src/workflows/sync-product-to-quickbooks.js +31 -0
- package/README.md +104 -0
- 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
|
+
}
|