diff --git a/README.md b/README.md
index fc0d1cb..8f2931d 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,15 @@
-# website_crm
+Your Contact Form
+-----------------
+
+### Integrate contact forms with your leads
+
+This simple application integrates a contact form in your "Contact us" page.
+Forms submissions create leads automatically in Odoo CRM.
+
+Easy Contact Page
+-----------------
+
+Get your leads filled up automatically with your contact form integration. This
+application allows a better qualification of the lead which is perfect to link
+them to marketing campaigns.
diff --git a/__init__.py b/__init__.py
new file mode 100644
index 0000000..7d34c7c
--- /dev/null
+++ b/__init__.py
@@ -0,0 +1,5 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import controllers
+from . import models
diff --git a/__manifest__.py b/__manifest__.py
new file mode 100644
index 0000000..6e503b4
--- /dev/null
+++ b/__manifest__.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+{
+ 'name': 'Contact Form',
+ 'category': 'Website/Website',
+ 'sequence': 54,
+ 'summary': 'Generate leads from a contact form',
+ 'version': '2.1',
+ 'description': """
+Add capability to your website forms to generate leads or opportunities in the CRM app.
+Forms has to be customized inside the *Website Builder* in order to generate leads.
+
+This module includes contact phone and mobile numbers validation.""",
+ 'depends': ['website', 'crm'],
+ 'data': [
+ 'security/ir.model.access.csv',
+ 'data/crm_lead_merge_template.xml',
+ 'data/ir_actions_data.xml',
+ 'data/ir_model_data.xml',
+ 'views/crm_lead_views.xml',
+ 'views/website_visitor_views.xml',
+ 'views/website_templates_contactus.xml',
+ ],
+ 'installable': True,
+ 'auto_install': True,
+ 'assets': {
+ 'website.assets_wysiwyg': [
+ 'website_crm/static/src/js/website_crm_editor.js',
+ ],
+ 'web.assets_tests': [
+ 'website_crm/static/tests/**/*',
+ ],
+ },
+ 'license': 'LGPL-3',
+}
diff --git a/controllers/__init__.py b/controllers/__init__.py
new file mode 100644
index 0000000..25803fb
--- /dev/null
+++ b/controllers/__init__.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import website_form
diff --git a/controllers/website_form.py b/controllers/website_form.py
new file mode 100644
index 0000000..6b8fd7f
--- /dev/null
+++ b/controllers/website_form.py
@@ -0,0 +1,92 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import tools
+from odoo.addons.phone_validation.tools import phone_validation
+from odoo.addons.website.controllers import form
+from odoo.http import request
+
+
+class WebsiteForm(form.WebsiteForm):
+
+ def _get_country(self):
+ visitor_partner = request.env['website.visitor']._get_visitor_from_request().partner_id
+ if visitor_partner:
+ # match same behaviour as in partner._phone_format()
+ country = visitor_partner.country_id or request.env.company.country_id
+ if country:
+ return country
+ country_code = request.geoip.country_code
+ if country_code:
+ return request.env['res.country'].sudo().search([('code', '=', country_code)], limit=1)
+ return request.env['res.country']
+
+ # Check and insert values from the form on the model + validation phone fields
+ def _handle_website_form(self, model_name, **kwargs):
+ model_record = request.env['ir.model'].sudo().search([('model', '=', model_name), ('website_form_access', '=', True)])
+ if model_record:
+ try:
+ data = self.extract_data(model_record, request.params)
+ except:
+ # no specific management, super will do it
+ pass
+ else:
+ record = data.get('record', {})
+ phone_fields = request.env[model_name]._phone_get_number_fields()
+ country = request.env['res.country'].browse(record.get('country_id'))
+ contact_country = country if country.exists() else self._get_country()
+ for phone_field in phone_fields:
+ if not record.get(phone_field):
+ continue
+ number = record[phone_field]
+ fmt_number = phone_validation.phone_format(
+ number, contact_country.code if contact_country else None,
+ contact_country.phone_code if contact_country else None,
+ force_format='INTERNATIONAL',
+ raise_exception=False
+ )
+ request.params.update({phone_field: fmt_number})
+
+ if model_name == 'crm.lead' and not request.params.get('state_id'):
+ geoip_country_code = request.geoip.country_code
+ geoip_state_code = request.geoip.subdivisions[0].iso_code if request.geoip.subdivisions else None
+ if geoip_country_code and geoip_state_code:
+ state = request.env['res.country.state'].search([('code', '=', geoip_state_code), ('country_id.code', '=', geoip_country_code)])
+ if state:
+ request.params['state_id'] = state.id
+ return super(WebsiteForm, self)._handle_website_form(model_name, **kwargs)
+
+ def insert_record(self, request, model, values, custom, meta=None):
+ is_lead_model = model.model == 'crm.lead'
+ if is_lead_model:
+ values_email_normalized = tools.email_normalize(values.get('email_from'))
+ visitor_sudo = request.env['website.visitor']._get_visitor_from_request()
+ visitor_partner = visitor_sudo.partner_id
+ if values_email_normalized and visitor_partner and visitor_partner.email_normalized == values_email_normalized:
+ # Here, 'phone' in values has already been formatted, see _handle_website_form.
+ values_phone = values.get('phone')
+ # We write partner id on crm only if no phone exists on partner or in input,
+ # or if both numbers (after formating) are the same. This way we get additional phone
+ # if possible, without modifying an existing one. (see inverse function on model crm.lead)
+ if values_phone and visitor_partner.phone:
+ if values_phone == visitor_partner.phone:
+ values['partner_id'] = visitor_partner.id
+ elif (visitor_partner._phone_format('phone') or visitor_partner.phone) == values_phone:
+ values['partner_id'] = visitor_partner.id
+ else:
+ values['partner_id'] = visitor_partner.id
+ if 'company_id' not in values:
+ values['company_id'] = request.website.company_id.id
+ lang = request.context.get('lang', False)
+ values['lang_id'] = values.get('lang_id') or request.env['res.lang']._lang_get_id(lang)
+
+ result = super(WebsiteForm, self).insert_record(request, model, values, custom, meta=meta)
+
+ if is_lead_model and visitor_sudo and result:
+ lead_sudo = request.env['crm.lead'].browse(result).sudo()
+ if lead_sudo.exists():
+ vals = {'lead_ids': [(4, result)]}
+ if not visitor_sudo.lead_ids and not visitor_sudo.partner_id:
+ vals['name'] = lead_sudo.contact_name
+ visitor_sudo.write(vals)
+ return result
diff --git a/data/crm_lead_merge_template.xml b/data/crm_lead_merge_template.xml
new file mode 100644
index 0000000..c75bc3a
--- /dev/null
+++ b/data/crm_lead_merge_template.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+ lead.campaign_id or lead.medium_id or lead.source_id or lead.visitor_ids
+
+
+
+