invoices purchase order sales order added for crm
This commit is contained in:
parent
3df5c84d3a
commit
8ac686c13e
@ -203,4 +203,79 @@ async function getAllProjectPhases(req, res) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { getData, getServices, getResources, getPortals, getAllProjects, getAllProjectTasks, getAllProjectTaskLists, getAllProjectIssues, getAllProjectPhases };
|
async function getSalesOrders(req, res) {
|
||||||
|
try {
|
||||||
|
const { provider, page, limit, filters } = req.query;
|
||||||
|
|
||||||
|
if (provider !== 'zoho') {
|
||||||
|
return res.status(400).json(failure('Sales Orders are only available for Zoho provider', 'INVALID_PROVIDER'));
|
||||||
|
}
|
||||||
|
|
||||||
|
const integrationService = new IntegrationService(req.user.id);
|
||||||
|
const params = { page, limit };
|
||||||
|
if (filters) {
|
||||||
|
try {
|
||||||
|
params.filters = JSON.parse(filters);
|
||||||
|
} catch (e) {
|
||||||
|
return res.status(400).json(failure('Invalid filters format', 'INVALID_FILTERS'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const salesOrders = await integrationService.getSalesOrders(provider, params);
|
||||||
|
res.json(success('Zoho Sales Orders retrieved successfully', salesOrders));
|
||||||
|
} catch (error) {
|
||||||
|
res.status(400).json(failure(error.message, 'INTEGRATION_ERROR'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getPurchaseOrders(req, res) {
|
||||||
|
try {
|
||||||
|
const { provider, page, limit, filters } = req.query;
|
||||||
|
|
||||||
|
if (provider !== 'zoho') {
|
||||||
|
return res.status(400).json(failure('Purchase Orders are only available for Zoho provider', 'INVALID_PROVIDER'));
|
||||||
|
}
|
||||||
|
|
||||||
|
const integrationService = new IntegrationService(req.user.id);
|
||||||
|
const params = { page, limit };
|
||||||
|
if (filters) {
|
||||||
|
try {
|
||||||
|
params.filters = JSON.parse(filters);
|
||||||
|
} catch (e) {
|
||||||
|
return res.status(400).json(failure('Invalid filters format', 'INVALID_FILTERS'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const purchaseOrders = await integrationService.getPurchaseOrders(provider, params);
|
||||||
|
res.json(success('Zoho Purchase Orders retrieved successfully', purchaseOrders));
|
||||||
|
} catch (error) {
|
||||||
|
res.status(400).json(failure(error.message, 'INTEGRATION_ERROR'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getInvoices(req, res) {
|
||||||
|
try {
|
||||||
|
const { provider, page, limit, filters } = req.query;
|
||||||
|
|
||||||
|
if (provider !== 'zoho') {
|
||||||
|
return res.status(400).json(failure('Invoices are only available for Zoho provider', 'INVALID_PROVIDER'));
|
||||||
|
}
|
||||||
|
|
||||||
|
const integrationService = new IntegrationService(req.user.id);
|
||||||
|
const params = { page, limit };
|
||||||
|
if (filters) {
|
||||||
|
try {
|
||||||
|
params.filters = JSON.parse(filters);
|
||||||
|
} catch (e) {
|
||||||
|
return res.status(400).json(failure('Invalid filters format', 'INVALID_FILTERS'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const invoices = await integrationService.getInvoices(provider, params);
|
||||||
|
res.json(success('Zoho Invoices retrieved successfully', invoices));
|
||||||
|
} catch (error) {
|
||||||
|
res.status(400).json(failure(error.message, 'INTEGRATION_ERROR'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { getData, getServices, getResources, getPortals, getAllProjects, getAllProjectTasks, getAllProjectTaskLists, getAllProjectIssues, getAllProjectPhases, getSalesOrders, getPurchaseOrders, getInvoices };
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const Joi = require('joi');
|
const Joi = require('joi');
|
||||||
const { getData, getServices, getResources, getPortals, getAllProjects, getAllProjectTasks, getAllProjectTaskLists, getAllProjectIssues, getAllProjectPhases } = require('../controllers/integrationController');
|
const { getData, getServices, getResources, getPortals, getAllProjects, getAllProjectTasks, getAllProjectTaskLists, getAllProjectIssues, getAllProjectPhases, getSalesOrders, getPurchaseOrders, getInvoices } = require('../controllers/integrationController');
|
||||||
const auth = require('../middlewares/auth');
|
const auth = require('../middlewares/auth');
|
||||||
const ZohoHandler = require('../../integrations/zoho/handler');
|
const ZohoHandler = require('../../integrations/zoho/handler');
|
||||||
|
|
||||||
@ -116,6 +116,36 @@ const allProjectPhasesSchema = Joi.object({
|
|||||||
|
|
||||||
router.get('/all-project-phases', auth, validate(allProjectPhasesSchema), getAllProjectPhases);
|
router.get('/all-project-phases', auth, validate(allProjectPhasesSchema), getAllProjectPhases);
|
||||||
|
|
||||||
|
// Get Zoho Sales Orders
|
||||||
|
const salesOrdersSchema = Joi.object({
|
||||||
|
provider: Joi.string().valid('zoho').required(),
|
||||||
|
page: Joi.number().min(1).default(1),
|
||||||
|
limit: Joi.number().min(1).max(100).default(20),
|
||||||
|
filters: Joi.string().optional()
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get('/sales-orders', auth, validate(salesOrdersSchema), getSalesOrders);
|
||||||
|
|
||||||
|
// Get Zoho Purchase Orders
|
||||||
|
const purchaseOrdersSchema = Joi.object({
|
||||||
|
provider: Joi.string().valid('zoho').required(),
|
||||||
|
page: Joi.number().min(1).default(1),
|
||||||
|
limit: Joi.number().min(1).max(100).default(20),
|
||||||
|
filters: Joi.string().optional()
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get('/purchase-orders', auth, validate(purchaseOrdersSchema), getPurchaseOrders);
|
||||||
|
|
||||||
|
// Get Zoho Invoices
|
||||||
|
const invoicesSchema = Joi.object({
|
||||||
|
provider: Joi.string().valid('zoho').required(),
|
||||||
|
page: Joi.number().min(1).default(1),
|
||||||
|
limit: Joi.number().min(1).max(100).default(20),
|
||||||
|
filters: Joi.string().optional()
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get('/invoices', auth, validate(invoicesSchema), getInvoices);
|
||||||
|
|
||||||
// Webhook endpoints (no auth required - uses signature verification)
|
// Webhook endpoints (no auth required - uses signature verification)
|
||||||
const zohoHandler = new ZohoHandler();
|
const zohoHandler = new ZohoHandler();
|
||||||
router.post('/webhooks/zoho/crm', zohoHandler.handleCrmWebhook.bind(zohoHandler));
|
router.post('/webhooks/zoho/crm', zohoHandler.handleCrmWebhook.bind(zohoHandler));
|
||||||
|
|||||||
@ -112,6 +112,21 @@ class ZohoClient {
|
|||||||
return ZohoMapper.mapApiResponse(response, 'tasks');
|
return ZohoMapper.mapApiResponse(response, 'tasks');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getSalesOrders(params = {}) {
|
||||||
|
const response = await this.makeRequest('/crm/v2/Sales_Orders', { params });
|
||||||
|
return ZohoMapper.mapApiResponse(response, 'sales_orders');
|
||||||
|
}
|
||||||
|
|
||||||
|
async getPurchaseOrders(params = {}) {
|
||||||
|
const response = await this.makeRequest('/crm/v2/Purchase_Orders', { params });
|
||||||
|
return ZohoMapper.mapApiResponse(response, 'purchase_orders');
|
||||||
|
}
|
||||||
|
|
||||||
|
async getInvoices(params = {}) {
|
||||||
|
const response = await this.makeRequest('/crm/v2/Invoices', { params });
|
||||||
|
return ZohoMapper.mapApiResponse(response, 'invoices');
|
||||||
|
}
|
||||||
|
|
||||||
// Zoho People methods
|
// Zoho People methods
|
||||||
async getEmployees(params = {}) {
|
async getEmployees(params = {}) {
|
||||||
const response = await this.makeRequest('/people/api/v1/employees', { params }, 'people');
|
const response = await this.makeRequest('/people/api/v1/employees', { params }, 'people');
|
||||||
@ -201,7 +216,7 @@ class ZohoClient {
|
|||||||
|
|
||||||
getAvailableResources(service) {
|
getAvailableResources(service) {
|
||||||
const resources = {
|
const resources = {
|
||||||
'crm': ['leads', 'contacts', 'deals', 'tasks'],
|
'crm': ['leads', 'contacts', 'deals', 'tasks', 'sales_orders', 'purchase_orders', 'invoices'],
|
||||||
'people': ['employees', 'departments'],
|
'people': ['employees', 'departments'],
|
||||||
'projects': ['projects', 'tasks', 'timesheets']
|
'projects': ['projects', 'tasks', 'timesheets']
|
||||||
};
|
};
|
||||||
|
|||||||
@ -54,6 +54,65 @@ class ZohoMapper {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Map Zoho CRM Sales Order to standardized format
|
||||||
|
static mapSalesOrder(zohoSalesOrder) {
|
||||||
|
return {
|
||||||
|
id: zohoSalesOrder.id,
|
||||||
|
subject: zohoSalesOrder.Subject,
|
||||||
|
orderNumber: zohoSalesOrder.SO_Number,
|
||||||
|
account: zohoSalesOrder.Account_Name,
|
||||||
|
contact: zohoSalesOrder.Contact_Name,
|
||||||
|
deal: zohoSalesOrder.Deal_Name,
|
||||||
|
grandTotal: zohoSalesOrder.Grand_Total,
|
||||||
|
status: zohoSalesOrder.Status,
|
||||||
|
orderDate: zohoSalesOrder.Order_Date,
|
||||||
|
dueDate: zohoSalesOrder.Due_Date,
|
||||||
|
createdTime: zohoSalesOrder.Created_Time,
|
||||||
|
modifiedTime: zohoSalesOrder.Modified_Time,
|
||||||
|
owner: zohoSalesOrder.Owner?.name,
|
||||||
|
customFields: this.mapCustomFields(zohoSalesOrder)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map Zoho CRM Purchase Order to standardized format
|
||||||
|
static mapPurchaseOrder(zohoPurchaseOrder) {
|
||||||
|
return {
|
||||||
|
id: zohoPurchaseOrder.id,
|
||||||
|
subject: zohoPurchaseOrder.Subject,
|
||||||
|
orderNumber: zohoPurchaseOrder.PO_Number,
|
||||||
|
vendor: zohoPurchaseOrder.Vendor_Name,
|
||||||
|
account: zohoPurchaseOrder.Account_Name,
|
||||||
|
grandTotal: zohoPurchaseOrder.Grand_Total,
|
||||||
|
status: zohoPurchaseOrder.Status,
|
||||||
|
orderDate: zohoPurchaseOrder.PO_Date,
|
||||||
|
dueDate: zohoPurchaseOrder.Expected_Delivery_Date,
|
||||||
|
createdTime: zohoPurchaseOrder.Created_Time,
|
||||||
|
modifiedTime: zohoPurchaseOrder.Modified_Time,
|
||||||
|
owner: zohoPurchaseOrder.Owner?.name,
|
||||||
|
customFields: this.mapCustomFields(zohoPurchaseOrder)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map Zoho CRM Invoice to standardized format
|
||||||
|
static mapInvoice(zohoInvoice) {
|
||||||
|
return {
|
||||||
|
id: zohoInvoice.id,
|
||||||
|
subject: zohoInvoice.Subject,
|
||||||
|
invoiceNumber: zohoInvoice.Invoice_Number,
|
||||||
|
account: zohoInvoice.Account_Name,
|
||||||
|
contact: zohoInvoice.Contact_Name,
|
||||||
|
deal: zohoInvoice.Deal_Name,
|
||||||
|
grandTotal: zohoInvoice.Grand_Total,
|
||||||
|
status: zohoInvoice.Status,
|
||||||
|
invoiceDate: zohoInvoice.Invoice_Date,
|
||||||
|
dueDate: zohoInvoice.Due_Date,
|
||||||
|
createdTime: zohoInvoice.Created_Time,
|
||||||
|
modifiedTime: zohoInvoice.Modified_Time,
|
||||||
|
owner: zohoInvoice.Owner?.name,
|
||||||
|
customFields: this.mapCustomFields(zohoInvoice)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Map Zoho People Employee to standardized format
|
// Map Zoho People Employee to standardized format
|
||||||
static mapEmployee(zohoEmployee) {
|
static mapEmployee(zohoEmployee) {
|
||||||
return {
|
return {
|
||||||
@ -120,6 +179,9 @@ class ZohoMapper {
|
|||||||
'leads': this.mapLead,
|
'leads': this.mapLead,
|
||||||
'contacts': this.mapContact,
|
'contacts': this.mapContact,
|
||||||
'deals': this.mapDeal,
|
'deals': this.mapDeal,
|
||||||
|
'sales_orders': this.mapSalesOrder,
|
||||||
|
'purchase_orders': this.mapPurchaseOrder,
|
||||||
|
'invoices': this.mapInvoice,
|
||||||
'employees': this.mapEmployee,
|
'employees': this.mapEmployee,
|
||||||
'projects': this.mapProject,
|
'projects': this.mapProject,
|
||||||
'tasks': this.mapTask
|
'tasks': this.mapTask
|
||||||
@ -226,6 +288,18 @@ class ZohoMapper {
|
|||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'sales_orders':
|
||||||
|
case 'purchase_orders':
|
||||||
|
case 'invoices':
|
||||||
|
// CRM response structure for sales orders, purchase orders, and invoices
|
||||||
|
records = zohoResponse.data || [];
|
||||||
|
pageInfo = {
|
||||||
|
count: zohoResponse.info?.count || records.length,
|
||||||
|
moreRecords: zohoResponse.info?.more_records || false,
|
||||||
|
page: zohoResponse.info?.page || 1
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Default CRM response structure (leads, contacts, deals, employees)
|
// Default CRM response structure (leads, contacts, deals, employees)
|
||||||
records = zohoResponse.data || [];
|
records = zohoResponse.data || [];
|
||||||
|
|||||||
@ -134,6 +134,39 @@ class IntegrationService {
|
|||||||
}
|
}
|
||||||
return await client.getAllProjectPhases(portalId, params);
|
return await client.getAllProjectPhases(portalId, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getSalesOrders(provider, params = {}) {
|
||||||
|
const client = this.clients[provider];
|
||||||
|
if (!client) {
|
||||||
|
throw new Error(`Provider ${provider} not supported`);
|
||||||
|
}
|
||||||
|
if (provider !== 'zoho') {
|
||||||
|
throw new Error('Sales Orders are only available for Zoho provider');
|
||||||
|
}
|
||||||
|
return await client.getSalesOrders(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getPurchaseOrders(provider, params = {}) {
|
||||||
|
const client = this.clients[provider];
|
||||||
|
if (!client) {
|
||||||
|
throw new Error(`Provider ${provider} not supported`);
|
||||||
|
}
|
||||||
|
if (provider !== 'zoho') {
|
||||||
|
throw new Error('Purchase Orders are only available for Zoho provider');
|
||||||
|
}
|
||||||
|
return await client.getPurchaseOrders(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getInvoices(provider, params = {}) {
|
||||||
|
const client = this.clients[provider];
|
||||||
|
if (!client) {
|
||||||
|
throw new Error(`Provider ${provider} not supported`);
|
||||||
|
}
|
||||||
|
if (provider !== 'zoho') {
|
||||||
|
throw new Error('Invoices are only available for Zoho provider');
|
||||||
|
}
|
||||||
|
return await client.getInvoices(params);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = IntegrationService;
|
module.exports = IntegrationService;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user