// Data mapping/transformation utilities for Zoho integration class ZohoMapper { // Map Zoho CRM Lead to standardized format static mapLead(zohoLead) { return { id: zohoLead.id, name: zohoLead.Full_Name || zohoLead.Lead_Name, email: zohoLead.Email, phone: zohoLead.Phone, company: zohoLead.Company, status: zohoLead.Lead_Status, source: zohoLead.Lead_Source, createdTime: zohoLead.Created_Time, modifiedTime: zohoLead.Modified_Time, owner: zohoLead.Owner?.name, // Map custom fields if they exist customFields: this.mapCustomFields(zohoLead) }; } // Map Zoho CRM Contact to standardized format static mapContact(zohoContact) { return { id: zohoContact.id, firstName: zohoContact.First_Name, lastName: zohoContact.Last_Name, email: zohoContact.Email, phone: zohoContact.Phone, account: zohoContact.Account_Name, title: zohoContact.Title, department: zohoContact.Department, createdTime: zohoContact.Created_Time, modifiedTime: zohoContact.Modified_Time, owner: zohoContact.Owner?.name, customFields: this.mapCustomFields(zohoContact) }; } // Map Zoho CRM Deal to standardized format static mapDeal(zohoDeal) { return { id: zohoDeal.id, name: zohoDeal.Deal_Name, amount: zohoDeal.Amount, stage: zohoDeal.Stage, probability: zohoDeal.Probability, closeDate: zohoDeal.Closing_Date, account: zohoDeal.Account_Name, contact: zohoDeal.Contact_Name, createdTime: zohoDeal.Created_Time, modifiedTime: zohoDeal.Modified_Time, owner: zohoDeal.Owner?.name, customFields: this.mapCustomFields(zohoDeal) }; } // Map Zoho Sales Order to standardized format (handles both CRM and Books) static mapSalesOrder(zohoSalesOrder) { return { id: zohoSalesOrder.id || zohoSalesOrder.salesorder_id, subject: zohoSalesOrder.Subject || zohoSalesOrder.subject, orderNumber: zohoSalesOrder.SO_Number || zohoSalesOrder.salesorder_number, account: zohoSalesOrder.Account_Name || zohoSalesOrder.customer_name, contact: zohoSalesOrder.Contact_Name || zohoSalesOrder.contact_name, deal: zohoSalesOrder.Deal_Name, grandTotal: zohoSalesOrder.Grand_Total || zohoSalesOrder.total, status: zohoSalesOrder.Status || zohoSalesOrder.status, orderDate: zohoSalesOrder.Order_Date || zohoSalesOrder.date, dueDate: zohoSalesOrder.Due_Date || zohoSalesOrder.due_date, createdTime: zohoSalesOrder.Created_Time || zohoSalesOrder.created_time, modifiedTime: zohoSalesOrder.Modified_Time || zohoSalesOrder.last_modified_time, owner: zohoSalesOrder.Owner?.name || zohoSalesOrder.owner?.name, customFields: this.mapCustomFields(zohoSalesOrder) }; } // Map Zoho Purchase Order to standardized format (handles both CRM and Books) static mapPurchaseOrder(zohoPurchaseOrder) { return { id: zohoPurchaseOrder.id || zohoPurchaseOrder.purchaseorder_id, subject: zohoPurchaseOrder.Subject || zohoPurchaseOrder.subject, orderNumber: zohoPurchaseOrder.PO_Number || zohoPurchaseOrder.purchaseorder_number, vendor: zohoPurchaseOrder.Vendor_Name || zohoPurchaseOrder.vendor_name, account: zohoPurchaseOrder.Account_Name || zohoPurchaseOrder.customer_name, grandTotal: zohoPurchaseOrder.Grand_Total || zohoPurchaseOrder.total, status: zohoPurchaseOrder.Status || zohoPurchaseOrder.status, orderDate: zohoPurchaseOrder.PO_Date || zohoPurchaseOrder.date, dueDate: zohoPurchaseOrder.Expected_Delivery_Date || zohoPurchaseOrder.due_date, createdTime: zohoPurchaseOrder.Created_Time || zohoPurchaseOrder.created_time, modifiedTime: zohoPurchaseOrder.Modified_Time || zohoPurchaseOrder.last_modified_time, owner: zohoPurchaseOrder.Owner?.name || zohoPurchaseOrder.owner?.name, customFields: this.mapCustomFields(zohoPurchaseOrder) }; } // Map Zoho Invoice to standardized format (handles both CRM and Books) static mapInvoice(zohoInvoice) { return { id: zohoInvoice.id || zohoInvoice.invoice_id, subject: zohoInvoice.Subject || zohoInvoice.subject, invoiceNumber: zohoInvoice.Invoice_Number || zohoInvoice.invoice_number, account: zohoInvoice.Account_Name || zohoInvoice.customer_name, contact: zohoInvoice.Contact_Name || zohoInvoice.contact_name, deal: zohoInvoice.Deal_Name, grandTotal: zohoInvoice.Grand_Total || zohoInvoice.total, status: zohoInvoice.Status || zohoInvoice.status, invoiceDate: zohoInvoice.Invoice_Date || zohoInvoice.date, dueDate: zohoInvoice.Due_Date || zohoInvoice.due_date, createdTime: zohoInvoice.Created_Time || zohoInvoice.created_time, modifiedTime: zohoInvoice.Modified_Time || zohoInvoice.last_modified_time, owner: zohoInvoice.Owner?.name || zohoInvoice.owner?.name, customFields: this.mapCustomFields(zohoInvoice) }; } // Map Zoho People Employee to standardized format static mapEmployee(zohoEmployee) { return { id: zohoEmployee.id, employeeId: zohoEmployee.employeeId, firstName: zohoEmployee.firstName, lastName: zohoEmployee.lastName, email: zohoEmployee.email, phone: zohoEmployee.phone, department: zohoEmployee.department, designation: zohoEmployee.designation, reportingTo: zohoEmployee.reportingTo, joiningDate: zohoEmployee.joiningDate, status: zohoEmployee.status, customFields: this.mapCustomFields(zohoEmployee) }; } // Map Zoho People Department to standardized format static mapDepartment(zohoDepartment) { return { id: zohoDepartment.id, name: zohoDepartment.name, description: zohoDepartment.description, head: zohoDepartment.head, employeeCount: zohoDepartment.employeeCount, customFields: this.mapCustomFields(zohoDepartment) }; } // Map Zoho People Timesheet to standardized format static mapTimesheet(zohoTimesheet) { return { id: zohoTimesheet.id, employeeId: zohoTimesheet.employeeId, projectId: zohoTimesheet.projectId, taskId: zohoTimesheet.taskId, date: zohoTimesheet.date, hours: zohoTimesheet.hours, description: zohoTimesheet.description, status: zohoTimesheet.status, customFields: this.mapCustomFields(zohoTimesheet) }; } // Map Zoho People Leave Request to standardized format static mapLeaveRequest(zohoLeaveRequest) { return { id: zohoLeaveRequest.id, employeeId: zohoLeaveRequest.employeeId, leaveType: zohoLeaveRequest.leaveType, startDate: zohoLeaveRequest.startDate, endDate: zohoLeaveRequest.endDate, days: zohoLeaveRequest.days, reason: zohoLeaveRequest.reason, status: zohoLeaveRequest.status, customFields: this.mapCustomFields(zohoLeaveRequest) }; } // Map Zoho People Attendance to standardized format static mapAttendance(zohoAttendance) { return { id: zohoAttendance.id, employeeId: zohoAttendance.employeeId, date: zohoAttendance.date, checkIn: zohoAttendance.checkIn, checkOut: zohoAttendance.checkOut, hoursWorked: zohoAttendance.hoursWorked, status: zohoAttendance.status, customFields: this.mapCustomFields(zohoAttendance) }; } // Map Zoho People Employee Forms to standardized format static mapEmployeeForm(zohoEmployeeForm) { return { id: zohoEmployeeForm.id, employeeId: zohoEmployeeForm.employeeId, firstName: zohoEmployeeForm.firstName, lastName: zohoEmployeeForm.lastName, email: zohoEmployeeForm.email, phone: zohoEmployeeForm.phone, department: zohoEmployeeForm.department, designation: zohoEmployeeForm.designation, joiningDate: zohoEmployeeForm.joiningDate, status: zohoEmployeeForm.status, customFields: this.mapCustomFields(zohoEmployeeForm) }; } // Map Zoho People Attendance Entries to standardized format static mapAttendanceEntry(zohoAttendanceEntry) { return { id: zohoAttendanceEntry.id, employeeId: zohoAttendanceEntry.empId, emailId: zohoAttendanceEntry.emailId, date: zohoAttendanceEntry.date, checkIn: zohoAttendanceEntry.checkIn, checkOut: zohoAttendanceEntry.checkOut, hoursWorked: zohoAttendanceEntry.hoursWorked, status: zohoAttendanceEntry.status, customFields: this.mapCustomFields(zohoAttendanceEntry) }; } // Map Zoho People Shift Configuration to standardized format static mapShiftConfiguration(zohoShiftConfig) { return { id: zohoShiftConfig.id, employeeId: zohoShiftConfig.empId, shiftName: zohoShiftConfig.shiftName, startTime: zohoShiftConfig.startTime, endTime: zohoShiftConfig.endTime, breakDuration: zohoShiftConfig.breakDuration, workingDays: zohoShiftConfig.workingDays, customFields: this.mapCustomFields(zohoShiftConfig) }; } // Map Zoho People Leave Data to standardized format static mapLeaveData(zohoLeaveData) { return { id: zohoLeaveData.id, employeeId: zohoLeaveData.employeeId, leaveType: zohoLeaveData.leaveType, startDate: zohoLeaveData.startDate, endDate: zohoLeaveData.endDate, days: zohoLeaveData.days, reason: zohoLeaveData.reason, status: zohoLeaveData.status, customFields: this.mapCustomFields(zohoLeaveData) }; } // Map Zoho People Goals Data to standardized format static mapGoalsData(zohoGoalsData) { return { id: zohoGoalsData.id, employeeId: zohoGoalsData.employeeId, goalTitle: zohoGoalsData.goalTitle, description: zohoGoalsData.description, targetValue: zohoGoalsData.targetValue, currentValue: zohoGoalsData.currentValue, startDate: zohoGoalsData.startDate, endDate: zohoGoalsData.endDate, status: zohoGoalsData.status, customFields: this.mapCustomFields(zohoGoalsData) }; } // Map Zoho People Performance Data to standardized format static mapPerformanceData(zohoPerformanceData) { return { id: zohoPerformanceData.id, employeeId: zohoPerformanceData.employeeId, reviewPeriod: zohoPerformanceData.reviewPeriod, rating: zohoPerformanceData.rating, comments: zohoPerformanceData.comments, reviewer: zohoPerformanceData.reviewer, reviewDate: zohoPerformanceData.reviewDate, status: zohoPerformanceData.status, customFields: this.mapCustomFields(zohoPerformanceData) }; } // Map Zoho Books Organization to standardized format static mapOrganization(zohoOrganization) { return { id: zohoOrganization.organization_id, name: zohoOrganization.organization_name, currency: zohoOrganization.currency_code, timezone: zohoOrganization.time_zone, fiscalYearStart: zohoOrganization.fiscal_year_start_month, accountCreatedDate: zohoOrganization.account_created_date, customFields: this.mapCustomFields(zohoOrganization) }; } // Map Zoho Books Customer to standardized format static mapCustomer(zohoCustomer) { return { id: zohoCustomer.contact_id, name: zohoCustomer.contact_name, email: zohoCustomer.contact_persons?.[0]?.email, phone: zohoCustomer.contact_persons?.[0]?.phone, company: zohoCustomer.company_name, billingAddress: zohoCustomer.billing_address, shippingAddress: zohoCustomer.shipping_address, currency: zohoCustomer.currency_code, paymentTerms: zohoCustomer.payment_terms, customFields: this.mapCustomFields(zohoCustomer) }; } // Map Zoho Books Vendor to standardized format static mapVendor(zohoVendor) { return { id: zohoVendor.contact_id, name: zohoVendor.contact_name, email: zohoVendor.contact_persons?.[0]?.email, phone: zohoVendor.contact_persons?.[0]?.phone, company: zohoVendor.company_name, billingAddress: zohoVendor.billing_address, shippingAddress: zohoVendor.shipping_address, currency: zohoVendor.currency_code, paymentTerms: zohoVendor.payment_terms, customFields: this.mapCustomFields(zohoVendor) }; } // Map Zoho Books Item to standardized format static mapItem(zohoItem) { return { id: zohoItem.item_id, name: zohoItem.name, description: zohoItem.description, sku: zohoItem.sku, unit: zohoItem.unit, rate: zohoItem.rate, purchaseRate: zohoItem.purchase_rate, salesRate: zohoItem.sales_rate, itemType: zohoItem.item_type, status: zohoItem.status, customFields: this.mapCustomFields(zohoItem) }; } // Map Zoho Books Invoice to standardized format static mapBooksInvoice(zohoInvoice) { return { id: zohoInvoice.invoice_id, invoiceNumber: zohoInvoice.invoice_number, customerId: zohoInvoice.customer_id, customerName: zohoInvoice.customer_name, date: zohoInvoice.date, dueDate: zohoInvoice.due_date, total: zohoInvoice.total, balance: zohoInvoice.balance, status: zohoInvoice.status, currency: zohoInvoice.currency_code, customFields: this.mapCustomFields(zohoInvoice) }; } // Map Zoho Books Estimate to standardized format static mapEstimate(zohoEstimate) { return { id: zohoEstimate.estimate_id, estimateNumber: zohoEstimate.estimate_number, customerId: zohoEstimate.customer_id, customerName: zohoEstimate.customer_name, date: zohoEstimate.date, expiryDate: zohoEstimate.expiry_date, total: zohoEstimate.total, status: zohoEstimate.status, currency: zohoEstimate.currency_code, customFields: this.mapCustomFields(zohoEstimate) }; } // Map Zoho Books Bill to standardized format static mapBill(zohoBill) { return { id: zohoBill.bill_id, billNumber: zohoBill.bill_number, vendorId: zohoBill.vendor_id, vendorName: zohoBill.vendor_name, date: zohoBill.date, dueDate: zohoBill.due_date, total: zohoBill.total, balance: zohoBill.balance, status: zohoBill.status, currency: zohoBill.currency_code, customFields: this.mapCustomFields(zohoBill) }; } // Map Zoho CRM Estimate to standardized format (handles both CRM and Books) static mapEstimate(zohoEstimate) { return { id: zohoEstimate.id || zohoEstimate.estimate_id, subject: zohoEstimate.Subject || zohoEstimate.subject, estimateNumber: zohoEstimate.Estimate_Number || zohoEstimate.estimate_number, account: zohoEstimate.Account_Name || zohoEstimate.customer_name, contact: zohoEstimate.Contact_Name || zohoEstimate.contact_name, deal: zohoEstimate.Deal_Name, grandTotal: zohoEstimate.Grand_Total || zohoEstimate.total, status: zohoEstimate.Status || zohoEstimate.status, estimateDate: zohoEstimate.Estimate_Date || zohoEstimate.date, expiryDate: zohoEstimate.Expiry_Date || zohoEstimate.expiry_date, createdTime: zohoEstimate.Created_Time || zohoEstimate.created_time, modifiedTime: zohoEstimate.Modified_Time || zohoEstimate.last_modified_time, owner: zohoEstimate.Owner?.name || zohoEstimate.owner?.name, customFields: this.mapCustomFields(zohoEstimate) }; } // Map Zoho CRM Bill to standardized format (handles both CRM and Books) static mapBill(zohoBill) { return { id: zohoBill.id || zohoBill.bill_id, subject: zohoBill.Subject || zohoBill.subject, billNumber: zohoBill.Bill_Number || zohoBill.bill_number, vendor: zohoBill.Vendor_Name || zohoBill.vendor_name, account: zohoBill.Account_Name || zohoBill.customer_name, grandTotal: zohoBill.Grand_Total || zohoBill.total, status: zohoBill.Status || zohoBill.status, billDate: zohoBill.Bill_Date || zohoBill.date, dueDate: zohoBill.Due_Date || zohoBill.due_date, createdTime: zohoBill.Created_Time || zohoBill.created_time, modifiedTime: zohoBill.Modified_Time || zohoBill.last_modified_time, owner: zohoBill.Owner?.name || zohoBill.owner?.name, customFields: this.mapCustomFields(zohoBill) }; } // Map Zoho CRM Expense to standardized format (handles both CRM and Books) static mapExpense(zohoExpense) { return { id: zohoExpense.id || zohoExpense.expense_id, subject: zohoExpense.Subject || zohoExpense.subject, expenseNumber: zohoExpense.Expense_Number || zohoExpense.expense_number, account: zohoExpense.Account_Name || zohoExpense.account_name, amount: zohoExpense.Amount || zohoExpense.amount, description: zohoExpense.Description || zohoExpense.description, status: zohoExpense.Status || zohoExpense.status, expenseDate: zohoExpense.Expense_Date || zohoExpense.date, createdTime: zohoExpense.Created_Time || zohoExpense.created_time, modifiedTime: zohoExpense.Modified_Time || zohoExpense.last_modified_time, owner: zohoExpense.Owner?.name || zohoExpense.owner?.name, customFields: this.mapCustomFields(zohoExpense) }; } // Map Zoho Books Bank Account to standardized format static mapBankAccount(zohoBankAccount) { return { id: zohoBankAccount.account_id, accountName: zohoBankAccount.account_name, accountNumber: zohoBankAccount.account_number, bankName: zohoBankAccount.bank_name, accountType: zohoBankAccount.account_type, balance: zohoBankAccount.balance, currency: zohoBankAccount.currency_code, customFields: this.mapCustomFields(zohoBankAccount) }; } // Map Zoho Books Bank Transaction to standardized format static mapBankTransaction(zohoBankTransaction) { return { id: zohoBankTransaction.transaction_id, accountId: zohoBankTransaction.account_id, date: zohoBankTransaction.date, amount: zohoBankTransaction.amount, description: zohoBankTransaction.description, type: zohoBankTransaction.type, status: zohoBankTransaction.status, customFields: this.mapCustomFields(zohoBankTransaction) }; } // Map Zoho Projects Project to standardized format static mapProject(zohoProject) { return { id: zohoProject.id, name: zohoProject.name, description: zohoProject.description, status: zohoProject.status, startDate: zohoProject.start_date, endDate: zohoProject.end_date, owner: zohoProject.owner?.name, createdTime: zohoProject.created_time, customFields: this.mapCustomFields(zohoProject) }; } // Map Zoho Projects Task to standardized format static mapTask(zohoTask) { return { id: zohoTask.id, name: zohoTask.name, description: zohoTask.description, status: zohoTask.status, priority: zohoTask.priority, startDate: zohoTask.start_date, endDate: zohoTask.end_date, assignee: zohoTask.assignee?.name, project: zohoTask.project?.name, customFields: this.mapCustomFields(zohoTask) }; } // Map custom fields from Zoho response static mapCustomFields(zohoRecord) { const customFields = {}; if (zohoRecord.Custom_Fields) { zohoRecord.Custom_Fields.forEach(field => { customFields[field.api_name] = field.value; }); } return customFields; } // Map multiple records using appropriate mapper static mapRecords(records, recordType) { const mapperMap = { // CRM 'leads': this.mapLead, 'contacts': this.mapContact, 'deals': this.mapDeal, 'sales_orders': this.mapSalesOrder, 'purchase_orders': this.mapPurchaseOrder, 'invoices': this.mapInvoice, // People 'employees': this.mapEmployee, 'departments': this.mapDepartment, 'timesheets': this.mapTimesheet, 'leave_requests': this.mapLeaveRequest, 'attendance': this.mapAttendance, 'employee_forms': this.mapEmployeeForm, 'attendance_entries': this.mapAttendanceEntry, 'shift_configuration': this.mapShiftConfiguration, 'leave_data': this.mapLeaveData, 'goals_data': this.mapGoalsData, 'performance_data': this.mapPerformanceData, // Books 'organizations': this.mapOrganization, 'customers': this.mapCustomer, 'vendors': this.mapVendor, 'items': this.mapItem, 'invoices': this.mapBooksInvoice, 'estimates': this.mapEstimate, 'bills': this.mapBill, 'expenses': this.mapExpense, 'bank_accounts': this.mapBankAccount, 'bank_transactions': this.mapBankTransaction, // Projects 'projects': this.mapProject, 'tasks': this.mapTask }; const mapper = mapperMap[recordType]; if (!mapper) { throw new Error(`No mapper found for record type: ${recordType}`); } return records.map(record => mapper(record)); } // Map Zoho API response to standardized format static mapApiResponse(zohoResponse, recordType) { let records = []; let pageInfo = {}; // Handle different response structures based on record type switch (recordType) { case 'projects': // Projects response is directly an array records = zohoResponse || []; pageInfo = { count: records.length, moreRecords: false, page: 1 }; break; case 'tasks': // Tasks response has tasklists array and page_info records = zohoResponse.tasks || []; pageInfo = { count: zohoResponse.page_info?.per_page || records.length, moreRecords: zohoResponse.page_info?.has_next_page || false, page: zohoResponse.page_info?.page || 1, pageCount: zohoResponse.page_info?.page_count || 1 }; break; case 'phases': // Tasks response has tasklists array and page_info records = zohoResponse.milestones || []; pageInfo = { count: zohoResponse.page_info?.per_page || records.length, moreRecords: zohoResponse.page_info?.has_next_page || false, page: zohoResponse.page_info?.page || 1, pageCount: zohoResponse.page_info?.page_count || 1 }; break; case 'tasklists': // Tasks response has tasklists array and page_info records = zohoResponse.tasklists || []; pageInfo = { count: zohoResponse.page_info?.per_page || records.length, moreRecords: zohoResponse.page_info?.has_next_page || false, page: zohoResponse.page_info?.page || 1, pageCount: zohoResponse.page_info?.page_count || 1 }; break; case 'portals': // Portals response is directly an array records = zohoResponse || []; pageInfo = { count: records.length, moreRecords: false, page: 1 }; break; case 'issues': // Issues response structure (assuming similar to tasks with page_info) records = zohoResponse.issues || zohoResponse.data || []; pageInfo = { count: zohoResponse.page_info?.per_page || records.length, moreRecords: zohoResponse.page_info?.has_next_page || false, page: zohoResponse.page_info?.page || 1, pageCount: zohoResponse.page_info?.page_count || 1 }; break; case 'tasklists': // Task lists response structure (assuming similar to tasks with page_info) records = zohoResponse.tasklists || zohoResponse.data || []; pageInfo = { count: zohoResponse.page_info?.per_page || records.length, moreRecords: zohoResponse.page_info?.has_next_page || false, page: zohoResponse.page_info?.page || 1, pageCount: zohoResponse.page_info?.page_count || 1 }; break; case 'phases': // Phases response structure (assuming similar to tasks with page_info) records = zohoResponse.phases || zohoResponse.data || []; pageInfo = { count: zohoResponse.page_info?.per_page || records.length, moreRecords: zohoResponse.page_info?.has_next_page || false, page: zohoResponse.page_info?.page || 1, pageCount: zohoResponse.page_info?.page_count || 1 }; break; case 'invoices': // Handle both CRM and Books invoices - check response structure if (zohoResponse.data && zohoResponse.info) { // Books response structure records = zohoResponse.data || []; pageInfo = { count: zohoResponse.info?.count || records.length, moreRecords: zohoResponse.info?.more_records || false, page: zohoResponse.info?.page || 1 }; } else { // CRM response structure records = zohoResponse.invoices || []; pageInfo = { count: zohoResponse.page_context?.count || records.length, moreRecords: zohoResponse.page_context?.more_records || false, page: zohoResponse.page_context?.page || 1 }; } break; case 'contacts': // Books response structure for contacts if (zohoResponse.data && zohoResponse.info) { // Books response structure records = zohoResponse.data || []; pageInfo = { count: zohoResponse.info?.count || records.length, moreRecords: zohoResponse.info?.more_records || false, page: zohoResponse.info?.page || 1 }; } else { records = zohoResponse.contacts || []; pageInfo = { count: zohoResponse.page_context?.count || records.length, moreRecords: zohoResponse.page_context?.more_records || false, page: zohoResponse.page_context?.page || 1 }; } break; case 'vendors': // Books response structure for vendors (filtered contacts) records = zohoResponse.contacts || []; pageInfo = { count: zohoResponse.page_context?.count || records.length, moreRecords: zohoResponse.page_context?.more_records || false, page: zohoResponse.page_context?.page || 1 }; break; case 'sales_orders': // Handle both CRM and Books sales orders - check response structure if (zohoResponse.data && zohoResponse.info) { // Books response structure records = zohoResponse.data || []; pageInfo = { count: zohoResponse.info?.count || records.length, moreRecords: zohoResponse.info?.more_records || false, page: zohoResponse.info?.page || 1 }; } else { // CRM response structure records = zohoResponse.salesorders || []; pageInfo = { count: zohoResponse.page_context?.count || records.length, moreRecords: zohoResponse.page_context?.more_records || false, page: zohoResponse.page_context?.page || 1 }; } break; case 'purchase_orders': // Handle both CRM and Books purchase orders - check response structure if (zohoResponse.data && zohoResponse.info) { // Books response structure records = zohoResponse.data || []; pageInfo = { count: zohoResponse.info?.count || records.length, moreRecords: zohoResponse.info?.more_records || false, page: zohoResponse.info?.page || 1 }; } else { // CRM response structure records = zohoResponse.purchaseorders || []; pageInfo = { count: zohoResponse.page_context?.count || records.length, moreRecords: zohoResponse.page_context?.more_records || false, page: zohoResponse.page_context?.page || 1 }; } break; case 'employee_forms': // Handle both CRM and Books sales orders - check response structure // Books response structure records = zohoResponse.response.result || []; pageInfo = { count: zohoResponse.response.result?.count || records.length, moreRecords: zohoResponse.response.result?.more_records || false, page: zohoResponse.response.result?.page || 1 }; break; case 'departments': case 'timesheets': case 'leave_requests': case 'attendance': // People response structure records = zohoResponse.data || []; pageInfo = { count: zohoResponse.info?.count || records.length, moreRecords: zohoResponse.info?.more_records || false, page: zohoResponse.info?.page || 1 }; break; case 'employee_forms': case 'attendance_entries': case 'shift_configuration': case 'leave_data': case 'goals_data': case 'performance_data': // People Forms API response structure records = zohoResponse.data || []; pageInfo = { count: zohoResponse.info?.count || records.length, moreRecords: zohoResponse.info?.more_records || false, page: zohoResponse.info?.page || 1 }; break; case 'employee_detail': // Single employee detail response records = zohoResponse.data ? [zohoResponse.data] : []; pageInfo = { count: records.length, moreRecords: false, page: 1 }; break; case 'estimates': // Handle both CRM and Books estimates - check response structure if (zohoResponse.data && zohoResponse.info) { // Books response structure records = zohoResponse.data || []; pageInfo = { count: zohoResponse.info?.count || records.length, moreRecords: zohoResponse.info?.more_records || false, page: zohoResponse.info?.page || 1 }; } else { // CRM response structure records = zohoResponse.estimates || []; pageInfo = { count: zohoResponse.page_context?.count || records.length, moreRecords: zohoResponse.page_context?.more_records || false, page: zohoResponse.page_context?.page || 1 }; } break; case 'bills': // Handle both CRM and Books bills - check response structure if (zohoResponse.data && zohoResponse.info) { // Books response structure records = zohoResponse.data || []; pageInfo = { count: zohoResponse.info?.count || records.length, moreRecords: zohoResponse.info?.more_records || false, page: zohoResponse.info?.page || 1 }; } else { // CRM response structure records = zohoResponse.bills || []; pageInfo = { count: zohoResponse.page_context?.count || records.length, moreRecords: zohoResponse.page_context?.more_records || false, page: zohoResponse.page_context?.page || 1 }; } break; case 'expenses': // Handle both CRM and Books expenses - check response structure if (zohoResponse.data && zohoResponse.info) { // Books response structure records = zohoResponse.data || []; pageInfo = { count: zohoResponse.info?.count || records.length, moreRecords: zohoResponse.info?.more_records || false, page: zohoResponse.info?.page || 1 }; } else { // CRM response structure records = zohoResponse.expenses || []; pageInfo = { count: zohoResponse.page_context?.count || records.length, moreRecords: zohoResponse.page_context?.more_records || false, page: zohoResponse.page_context?.page || 1 }; } break; case 'organizations': case 'customers': case 'items': case 'bank_accounts': case 'bank_transactions': case 'reports': // Books response structure records = zohoResponse.data || []; pageInfo = { count: zohoResponse.info?.count || records.length, moreRecords: zohoResponse.info?.more_records || false, page: zohoResponse.info?.page || 1 }; break; default: // Default CRM response structure (leads, contacts, deals, employees) records = zohoResponse.data || []; pageInfo = { count: zohoResponse.info?.count || records.length, moreRecords: zohoResponse.info?.more_records || false, page: zohoResponse.info?.page || 1 }; break; } return { data: records, info: pageInfo }; } } module.exports = ZohoMapper;