summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiqdad <ahmadmiqdad27@gmail.com>2025-06-09 17:35:22 +0700
committerMiqdad <ahmadmiqdad27@gmail.com>2025-06-09 17:35:22 +0700
commit5f5753dbec8af518dd34821820462cd6340a2a08 (patch)
tree09c2bd8a52124700e74a4b512267d215c2e23421
parent1bd3a91889f8616d7042c0d15315c2f25c974ed3 (diff)
<miqdad> wati leads
-rw-r--r--indoteknik_api/controllers/api_v1/wati.py171
-rw-r--r--indoteknik_custom/models/wati.py166
2 files changed, 332 insertions, 5 deletions
diff --git a/indoteknik_api/controllers/api_v1/wati.py b/indoteknik_api/controllers/api_v1/wati.py
index 68ff1640..d60cd160 100644
--- a/indoteknik_api/controllers/api_v1/wati.py
+++ b/indoteknik_api/controllers/api_v1/wati.py
@@ -2,19 +2,182 @@ from .. import controller
from odoo import http
from odoo.http import request
import json
+import logging
+_logger = logging.getLogger(__name__)
-class Wati(controller.Controller):
+
+# class Wati(controller.Controller):
+# prefix = '/api/v1/'
+#
+# @http.route(prefix + 'wati/notification', auth='none', type='json', csrf=False, cors='*', methods=['POST', 'OPTIONS'])
+# def notification(self, **kw):
+# json_raw = json.loads(request.httprequest.data)
+# json_dump = json.dumps(json_raw, indent=4, sort_keys=True)
+#
+# request.env['wati.notification'].create([{
+# 'json_raw': json_dump,
+# 'is_lead': False
+# }])
+#
+# return
+
+# REPLACE webhook controller yang sudah ada dengan ini:
+
+class Wati(http.Controller):
prefix = '/api/v1/'
- @http.route(prefix + 'wati/notification', auth='none', type='json', csrf=False, cors='*', methods=['POST', 'OPTIONS'])
+ @http.route(prefix + 'wati/notification', auth='none', type='json', csrf=False, cors='*',
+ methods=['POST', 'OPTIONS'])
def notification(self, **kw):
json_raw = json.loads(request.httprequest.data)
json_dump = json.dumps(json_raw, indent=4, sort_keys=True)
- request.env['wati.notification'].create([{
+ # Create notification record (existing)
+ notification = request.env['wati.notification'].create([{
'json_raw': json_dump,
'is_lead': False
}])
- return
+ # NEW: Immediate tags check
+ phone = json_raw.get('waId') or json_raw.get('from')
+
+ if phone:
+ lead_id = self._check_tags_immediate(phone, notification[0])
+
+ if lead_id:
+ notification.write({'is_lead': True, 'lead_id': lead_id})
+ _logger.info('🚀 Lead created immediately via webhook: %s' % lead_id)
+
+ return {'status': 'success'}
+
+ def _check_tags_immediate(self, phone, notification):
+ """Check tags untuk specific phone - immediate"""
+ try:
+ _logger.info('📱 Immediate tags check for: %s' % phone)
+
+ # Get contact dari WATI untuk phone ini
+ wati_api = request.env['wati.api']
+
+ params = {
+ 'pageSize': 1,
+ 'pageNumber': 1,
+ 'attribute': json.dumps([
+ {'name': "phone", 'operator': "contain", 'value': phone}
+ ]),
+ }
+
+ result = wati_api.http_get('/api/v1/getContacts', params)
+
+ if isinstance(result, dict) and result.get('result') == 'success':
+ contact_list = result.get('contact_list', [])
+
+ if contact_list:
+ contact = contact_list[0]
+
+ # Check if has tags=leads
+ if self._contact_has_tags_leads(contact):
+ # Check existing lead
+ existing_lead = request.env['crm.lead'].search([('phone', '=', phone)], limit=1)
+
+ if existing_lead:
+ _logger.info('✅ Lead already exists for %s' % phone)
+ return existing_lead.id
+
+ # Create new lead
+ lead_id = self._create_lead_from_webhook(contact)
+ if lead_id:
+ _logger.info('🎯 Created new lead %s from webhook tags' % lead_id)
+ return lead_id
+
+ return None
+
+ except Exception as e:
+ _logger.error('❌ Error in immediate tags check: %s' % str(e))
+ return None
+
+ def _contact_has_tags_leads(self, contact):
+ """Check if contact has tags=leads"""
+ custom_params = contact.get('customParams', [])
+
+ for param in custom_params:
+ if (param.get('name', '').lower() == 'tags' and
+ param.get('value', '').lower() == 'leads'):
+ return True
+
+ return False
+
+ def _create_lead_from_webhook(self, contact):
+ """Create lead dari webhook data"""
+ try:
+ phone = contact.get('phone', '')
+
+ # Extract data dari customParams
+ custom_params = contact.get('customParams', [])
+ contact_data = {}
+
+ for param in custom_params:
+ param_name = param.get('name', '').lower()
+ param_value = param.get('value', '').strip()
+
+ if param_name == 'perusahaan':
+ contact_data['perusahaan'] = param_value
+ elif param_name == 'name':
+ contact_data['name'] = param_value
+ elif param_name == 'email':
+ contact_data['email'] = param_value
+ elif param_name == 'sales':
+ contact_data['sales'] = param_value
+ elif param_name == 'notes':
+ contact_data['notes'] = param_value
+
+ # Generate lead name
+ company_name = contact_data.get('perusahaan', '')
+ contact_name = contact_data.get('name', '') or contact.get('name', '')
+
+ if company_name:
+ lead_name = 'WATI Lead (Webhook) - %s' % company_name
+ elif contact_name:
+ lead_name = 'WATI Lead (Webhook) - %s' % contact_name
+ else:
+ lead_name = 'WATI Lead (Webhook) - %s' % phone
+
+ # Get salesperson
+ sales_name = contact_data.get('sales', '')
+ user_id = 2 # Default
+
+ if sales_name:
+ user = request.env['res.users'].search([('name', 'ilike', sales_name)], limit=1)
+ if user:
+ user_id = user.id
+
+ # Create lead
+ lead_vals = {
+ 'name': lead_name,
+ 'phone': phone,
+ 'contact_name': contact_name,
+ 'partner_name': company_name,
+ 'email_from': contact_data.get('email', ''),
+ 'description': contact_data.get('notes', 'Lead created from WATI webhook (real-time)'),
+ 'type': 'lead',
+ 'user_id': user_id,
+ }
+
+ new_lead = request.env['crm.lead'].create(lead_vals)
+
+ # Create activity untuk follow up
+ request.env['mail.activity'].create({
+ 'activity_type_id': request.env.ref('mail.mail_activity_data_todo').id,
+ 'summary': '🚨 URGENT: New WATI Lead (Real-time)',
+ 'note': 'Lead created instantly from WATI webhook when tags=leads was added. Immediate follow up required!',
+ 'res_id': new_lead.id,
+ 'res_model_id': request.env.ref('crm.model_crm_lead').id,
+ 'user_id': user_id,
+ 'date_deadline': fields.Date.today(),
+ })
+
+ return new_lead.id
+
+ except Exception as e:
+ _logger.error('❌ Error creating lead from webhook: %s' % str(e))
+ return None \ No newline at end of file
diff --git a/indoteknik_custom/models/wati.py b/indoteknik_custom/models/wati.py
index a0619f83..18517502 100644
--- a/indoteknik_custom/models/wati.py
+++ b/indoteknik_custom/models/wati.py
@@ -201,6 +201,170 @@ class WatiNotification(models.Model):
wati.is_lead = True
wati.lead_id = current_lead.id
+ # FINAL CODE - Sesuai dengan mapping table Anda
+
+ def check_wati_tags_leads(self):
+ """Check tags 'leads' di WATI dan create leads di Odoo - Final Version"""
+ _logger.info('=== Starting WATI Tags Check (Final) ===')
+
+ wati_api = self.env['wati.api']
+ total_leads_created = 0
+
+ try:
+ # Get WATI contacts
+ wati_contacts = wati_api.http_get('/api/v1/getContacts', {'pageSize': 100, 'pageNumber': 1})
+
+ if isinstance(wati_contacts, dict) and wati_contacts.get('result') == 'success':
+ contact_list = wati_contacts.get('contact_list', [])
+
+ for contact in contact_list:
+ if self._create_lead_if_tagged(contact):
+ total_leads_created += 1
+
+ _logger.info('WATI check completed: %s leads created' % total_leads_created)
+ return {'leads_created': total_leads_created}
+
+ except Exception as e:
+ _logger.error('Error in WATI tags check: %s' % str(e))
+ return {'leads_created': 0, 'error': str(e)}
+
+ def _create_lead_if_tagged(self, contact):
+ """Create lead jika contact punya tags=leads - Sesuai Mapping Table"""
+ try:
+ # Check tags leads
+ if not self._has_tags_leads(contact):
+ return False
+
+ phone = contact.get('phone', '')
+ if not phone:
+ return False
+
+ # Check existing lead by phone
+ existing_lead = self.env['crm.lead'].search([('phone', '=', phone)], limit=1)
+ if existing_lead:
+ _logger.info('Lead already exists for phone %s' % phone)
+ return False
+
+ # Extract data dari customParams sesuai mapping table
+ custom_params = contact.get('customParams', [])
+ contact_data = self._extract_contact_data(custom_params)
+
+ # Create lead dengan field mapping yang sesuai
+ lead_vals = {
+ 'name': self._generate_lead_name(contact_data, contact),
+ 'phone': phone, # Phone Number → Mobile
+ 'contact_name': contact_data.get('name', ''), # Name → Contact Name
+ 'partner_name': contact_data.get('perusahaan', ''), # Perusahaan → Company Name
+ 'email_from': contact_data.get('email', ''), # Email → Email
+ 'description': contact_data.get('notes', ''), # Notes → Internal Notes
+ 'type': 'lead',
+ 'user_id': self._get_salesperson_id(contact_data.get('sales', '')), # Sales → Salesperson
+ }
+
+ new_lead = self.env['crm.lead'].create(lead_vals)
+ _logger.info('Created WATI lead %s for %s (%s)' % (new_lead.id, contact_data.get('name', 'Unknown'), phone))
+ return True
+
+ except Exception as e:
+ _logger.error('Error creating lead: %s' % str(e))
+ return False
+
+ def _extract_contact_data(self, custom_params):
+ """Extract data dari customParams sesuai mapping table"""
+ contact_data = {}
+
+ for param in custom_params:
+ param_name = param.get('name', '').lower()
+ param_value = param.get('value', '').strip()
+
+ # Mapping sesuai table:
+ if param_name == 'perusahaan': # Perusahaan → Company Name
+ contact_data['perusahaan'] = param_value
+ elif param_name == 'name': # Name → Contact Name
+ contact_data['name'] = param_value
+ elif param_name == 'email': # Email → Email
+ contact_data['email'] = param_value
+ elif param_name == 'sales': # Sales → Salesperson
+ contact_data['sales'] = param_value
+ elif param_name == 'notes': # Notes → Internal Notes
+ contact_data['notes'] = param_value
+ # Phone Number sudah diambil dari contact.phone
+
+ return contact_data
+
+ def _generate_lead_name(self, contact_data, contact):
+ """Generate lead name sesuai mapping: Judul Leads berdasarkan company/contact"""
+ company_name = contact_data.get('perusahaan', '')
+ contact_name = contact_data.get('name', '') or contact.get('name', '')
+
+ if company_name:
+ return 'WATI Lead - %s' % company_name
+ elif contact_name:
+ return 'WATI Lead - %s' % contact_name
+ else:
+ return 'WATI Lead - %s' % contact.get('phone', 'Unknown')
+
+ def _get_salesperson_id(self, sales_name):
+ """Get salesperson ID dari nama - Sales → Salesperson"""
+ if not sales_name:
+ return 2 # Default Sales (ID 2)
+
+ # Try find user by name
+ user = self.env['res.users'].search([
+ ('name', 'ilike', sales_name)
+ ], limit=1)
+
+ if user:
+ return user.id
+ else:
+ # Fallback ke default Sales
+ return 2
+
+ def _has_tags_leads(self, contact):
+ """Check apakah ada tags untuk tajik ke odoo => Leads"""
+ custom_params = contact.get('customParams', [])
+
+ for param in custom_params:
+ param_name = param.get('name', '').lower()
+ param_value = param.get('value', '').lower()
+
+ # Check: "Judul Tags untuk tajik ke odoo => Leads"
+ if param_name == 'tags' and param_value == 'leads':
+ return True
+
+ return False
+
+ def manual_check_tags(self):
+ """Manual trigger untuk testing"""
+ result = self.check_wati_tags_leads()
+
+ message = 'WATI Tags Check Completed!\n\n'
+ message += 'Leads Created: %s\n\n' % result.get('leads_created', 0)
+ message += 'Field Mapping:\n'
+ message += '• Perusahaan → Company Name\n'
+ message += '• Name → Contact Name\n'
+ message += '• Email → Email\n'
+ message += '• Sales → Salesperson\n'
+ message += '• Phone Number → Mobile\n'
+ message += '• Notes → Internal Notes\n'
+ message += '• Tags=leads → Trigger Lead Creation'
+
+ if result.get('error'):
+ message += '\n\nError: %s' % result['error']
+ message_type = 'warning'
+ else:
+ message_type = 'success'
+
+ return {
+ 'type': 'ir.actions.client',
+ 'tag': 'display_notification',
+ 'params': {
+ 'title': 'WATI Tags Check',
+ 'message': message,
+ 'type': message_type,
+ 'sticky': True,
+ }
+ }
class WatiHistory(models.Model):
_name = 'wati.history'
@@ -319,4 +483,4 @@ class WatiHistoryLine(models.Model):
ticket_id = fields.Char(string='Ticket ID')
type = fields.Char(string='Type')
wa_id = fields.Char(string='WA ID')
- date_wati = fields.Datetime(string='Date WATI')
+ date_wati = fields.Datetime(string='Date WATI') \ No newline at end of file