ACUMATICA

Acumatica CRM Integration

March 10, 2024 13 min read

Introduction

Integrating Acumatica with CRM systems enables bidirectional synchronization of customers, contacts, opportunities, and sales data. This creates a unified view of customer relationships and sales pipeline.

Data Synchronization

The integration handles synchronization of:

  • Accounts and Customers
  • Contacts
  • Leads and Opportunities
  • Sales Orders and Quotes
  • Activities and Tasks

Contact Sync

async function syncContactToAcumatica(contact) {
    const customerData = {
        CustomerID: { value: contact.accountId },
        CustomerName: { value: contact.accountName },
        Email: { value: contact.email },
        Phone1: { value: contact.phone },
        Address: {
            AddressLine1: { value: contact.street },
            City: { value: contact.city },
            State: { value: contact.state },
            PostalCode: { value: contact.zip }
        }
    };

    const result = await createOrUpdateCustomer(
        baseUrl, 
        token, 
        'AR303000', 
        customerData
    );

    await updateCRMMapping('contact', contact.id, result.CustomerID);
}

Opportunity Management

async function syncOpportunity(opportunity) {
    const opportunityData = {
        OpportunityID: { value: opportunity.id },
        Subject: { value: opportunity.name },
        Stage: { value: mapCRMStage(opportunity.stage) },
        CustomerID: { value: opportunity.accountId },
        CloseDate: { value: opportunity.closeDate },
        Amount: { value: opportunity.amount },
        Probability: { value: opportunity.probability }
    };

    return await createOpportunity(
        baseUrl, 
        token, 
        'CR304000', 
        opportunityData
    );
}

function mapCRMStage(crmStage) {
    const stageMap = {
        'Prospecting': '01',
        'Qualification': '02',
        'Proposal': '03',
        'Negotiation': '04',
        'Closed Won': '05'
    };
    return stageMap[crmStage] || '01';
}

Sales Order Sync

async function createSalesOrderFromOpportunity(opportunity) {
    const products = await getOpportunityProducts(opportunity.id);
    
    const orderData = {
        CustomerID: { value: opportunity.accountId },
        OrderType: { value: 'SO' },
        Description: { value: `Opportunity: ${opportunity.name}` },
        Details: products.map(product => ({
            InventoryCD: { value: product.sku },
            Qty: { value: product.quantity },
            UnitPrice: { value: product.unitPrice }
        }))
    };

    const order = await createSalesOrder(
        baseUrl, 
        token, 
        'SO301000', 
        orderData
    );

    await updateOpportunityField(opportunity.id, 'acumaticaOrder', order.OrderNbr);
}

Webhooks

// Handle CRM webhook events
app.post('/webhooks/crm', async (req, res) => {
    const event = req.body;
    
    switch (event.type) {
        case 'contact.created':
        case 'contact.updated':
            await syncContactToAcumatica(event.data);
            break;
            
        case 'opportunity.stage_changed':
            await updateOpportunityStage(event.data);
            break;
            
        case 'opportunity.closed_won':
            await createSalesOrderFromOpportunity(event.data);
            break;
    }
    
    res.status(200).send('OK');
});

Complete Integration Class

class AcumaticaCRMIntegration {
    constructor(acumaticaConfig, crmConfig) {
        this.acumatica = acumaticaConfig;
        this.crm = crmConfig;
    }

    async syncAllData() {
        await this.syncContacts();
        await this.syncOpportunities();
        await this.syncSalesOrders();
    }

    async syncContacts() {
        const contacts = await this.crm.getContacts();
        
        for (const contact of contacts) {
            await this.syncContactToAcumatica(contact);
        }
    }

    async handleWebhook(event) {
        const handlers = {
            'contact.created': this.syncContactToAcumatica,
            'opportunity.closed_won': this.createSalesOrderFromOpportunity,
            'account.updated': this.syncAccountToAcumatica
        };

        const handler = handlers[event.type];
        if (handler) {
            await handler.call(this, event.data);
        }
    }
}

Summary

Integrating Acumatica with CRM systems creates a seamless flow of customer and sales data between platforms. By implementing the patterns in this guide, you can synchronize contacts, opportunities, and sales orders automatically.

For more information, check out our other tutorials on Payment Gateway Integration and Shopify Integration.