/var/www/vhosts/m-auto.co/httpdocs/includes
NameSizeModeActions
7-6-2026.zip51450644editdlrm
config.php19370644editdlrm
db.php6940644editdlrm
db_production.php13010644editdlrm
footer.php66480644editdlrm
header.php97570644editdlrm
header.zip26560644editdlrm
odoo_api.php116220644editdlrm
odoo_config.php11500644editdlrm
permissions.php19270644editdlrm
Edit: /var/www/vhosts/m-auto.co/httpdocs/includes/odoo_api.php (11622B)
url = OdooConfig::ODOO_URL; $this->db = OdooConfig::ODOO_DB; $this->username = OdooConfig::ODOO_USERNAME; $this->password = OdooConfig::ODOO_PASSWORD; $this->uid = null; } /** * Create XML-RPC request manually */ private function createXmlRpcRequest($method, $params) { $xml = '' . "\n"; $xml .= '' . "\n"; $xml .= '' . htmlspecialchars($method) . '' . "\n"; $xml .= '' . "\n"; foreach ($params as $param) { $xml .= '' . $this->encodeValue($param) . '' . "\n"; } $xml .= '' . "\n"; $xml .= '' . "\n"; return $xml; } /** * Encode value for XML-RPC */ private function encodeValue($value) { if (is_string($value)) { return '' . htmlspecialchars($value) . ''; } elseif (is_int($value)) { return '' . $value . ''; } elseif (is_bool($value)) { return '' . ($value ? '1' : '0') . ''; } elseif (is_array($value)) { if (array_keys($value) === range(0, count($value) - 1)) { // Indexed array $xml = ''; foreach ($value as $item) { $xml .= $this->encodeValue($item); } $xml .= ''; return $xml; } else { // Associative array (struct) $xml = ''; foreach ($value as $key => $val) { $xml .= ''; $xml .= '' . htmlspecialchars($key) . ''; $xml .= $this->encodeValue($val); $xml .= ''; } $xml .= ''; return $xml; } } elseif (is_null($value) || $value === false) { return '0'; } else { return '' . htmlspecialchars((string)$value) . ''; } } /** * Parse XML-RPC response */ private function parseXmlRpcResponse($xml) { $doc = new DOMDocument(); $doc->loadXML($xml); $fault = $doc->getElementsByTagName('fault'); if ($fault->length > 0) { throw new Exception('XML-RPC Fault'); } $params = $doc->getElementsByTagName('param'); if ($params->length > 0) { return $this->decodeValue($params->item(0)->firstChild); } return false; } /** * Decode XML-RPC value */ private function decodeValue($node) { if (!$node) return null; $value = $node->firstChild; if (!$value) return null; switch ($value->nodeName) { case 'string': return $value->nodeValue; case 'int': case 'i4': return (int)$value->nodeValue; case 'boolean': return (bool)$value->nodeValue; case 'array': $result = []; $data = $value->getElementsByTagName('value'); foreach ($data as $item) { $result[] = $this->decodeValue($item); } return $result; case 'struct': $result = []; $members = $value->getElementsByTagName('member'); foreach ($members as $member) { $name = $member->getElementsByTagName('name')->item(0)->nodeValue; $val = $member->getElementsByTagName('value')->item(0); $result[$name] = $this->decodeValue($val); } return $result; default: return $value->nodeValue; } } /** * Authenticate with Odoo */ private function authenticate() { if ($this->uid !== null) { return $this->uid; } try { $xml = $this->createXmlRpcRequest('authenticate', [ $this->db, $this->username, $this->password, [] ]); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $this->url . OdooConfig::XMLRPC_COMMON); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: text/xml']); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode !== 200) { throw new Exception('HTTP Error: ' . $httpCode); } $this->uid = $this->parseXmlRpcResponse($response); if (!$this->uid || $this->uid === false) { throw new Exception('Authentication failed'); } return $this->uid; } catch (Exception $e) { error_log('Odoo Authentication Error: ' . $e->getMessage()); return false; } } /** * Execute Odoo method */ private function execute($model, $method, $args = [], $kwargs = []) { $uid = $this->authenticate(); if (!$uid) { return false; } try { $xml = $this->createXmlRpcRequest('execute_kw', [ $this->db, $uid, $this->password, $model, $method, $args, $kwargs ]); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $this->url . OdooConfig::XMLRPC_OBJECT); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: text/xml']); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode !== 200) { throw new Exception('HTTP Error: ' . $httpCode); } return $this->parseXmlRpcResponse($response); } catch (Exception $e) { error_log('Odoo API Error: ' . $e->getMessage()); return false; } } /** * Create a new lead in CRM */ public function createLead($data) { $leadData = [ 'name' => $data['name'] ?? 'New Lead', 'contact_name' => $data['contact_name'] ?? '', 'phone' => $data['phone'] ?? '', 'email_from' => $data['email'] ?? '', 'description' => $data['description'] ?? '', 'source_id' => $this->getSourceId($data['source'] ?? ''), 'stage_id' => OdooConfig::LEAD_STAGE_NEW, 'country_id' => OdooConfig::DEFAULT_COUNTRY_ID, 'company_id' => OdooConfig::DEFAULT_COMPANY_ID, 'user_id' => false, // Unassigned initially ]; // Add custom fields if provided if (isset($data['branch_name'])) { $leadData['x_branch'] = $data['branch_name']; } if (isset($data['service_type'])) { $leadData['x_service_type'] = $data['service_type']; } if (isset($data['car_info'])) { $leadData['x_car_info'] = $data['car_info']; } if (isset($data['visit_date'])) { $leadData['x_visit_date'] = $data['visit_date']; } if (isset($data['reservation_date'])) { $leadData['x_reservation_date'] = $data['reservation_date']; } return $this->execute('crm.lead', 'create', [$leadData]); } /** * Get or create source ID */ private function getSourceId($sourceName) { if (empty($sourceName)) { return false; } // Search for existing source $sourceIds = $this->execute('utm.source', 'search', [['name', '=', $sourceName]]); if ($sourceIds && count($sourceIds) > 0) { return $sourceIds[0]; } // Create new source if not found $sourceId = $this->execute('utm.source', 'create', [['name' => $sourceName]]); return $sourceId; } /** * Create partner (customer) record */ public function createPartner($data) { $partnerData = [ 'name' => $data['name'] ?? '', 'phone' => $data['phone'] ?? '', 'email' => $data['email'] ?? '', 'is_company' => false, 'customer_rank' => 1, 'country_id' => OdooConfig::DEFAULT_COUNTRY_ID, ]; return $this->execute('res.partner', 'create', [$partnerData]); } /** * Search for existing partner by phone or email */ public function findPartner($phone = '', $email = '') { $domain = []; if (!empty($phone)) { $domain[] = ['phone', '=', $phone]; } if (!empty($email)) { if (!empty($domain)) { $domain = ['|'] + $domain + [['email', '=', $email]]; } else { $domain[] = ['email', '=', $email]; } } if (empty($domain)) { return false; } $partnerIds = $this->execute('res.partner', 'search', [$domain], ['limit' => 1]); return $partnerIds && count($partnerIds) > 0 ? $partnerIds[0] : false; } /** * Create activity/task for follow-up */ public function createActivity($leadId, $activityType, $summary, $note = '') { $activityData = [ 'res_model' => 'crm.lead', 'res_id' => $leadId, 'activity_type_id' => $activityType, 'summary' => $summary, 'note' => $note, 'date_deadline' => date('Y-m-d', strtotime('+1 day')), ]; return $this->execute('mail.activity', 'create', [$activityData]); } /** * Test connection to Odoo */ public function testConnection() { try { $uid = $this->authenticate(); if ($uid) { // Try to read user info $userInfo = $this->execute('res.users', 'read', [$uid], ['fields' => ['name', 'login']]); return $userInfo !== false; } return false; } catch (Exception $e) { error_log('Odoo Connection Test Error: ' . $e->getMessage()); return false; } } } ?>