[ADD] reveal_service : allow user to generate leads based on filters
Purpose : Allow the user to generate a certain number of leads based on certain criteria like localization, technologies used, or size. Available filters are : - company size - localization (country and states) - industries - technologies The user can also ask for a few contacts that can be filtered based on their role or seniority. Each company found generates a new lead/opportunity for which the sales team, salesperson and tags can be preset from the lead mining request. This commit includes the followings changes : - New module crm_iap_lead - New model crm.iap.lead.helpers which contains helper methods used by both modules crm_iap_lead and crm_iap_lead_website - New model crm.iap.lead.mining.request that holds the data of a lead mining request - An option in the CRM settings to install this feature - New button 'Generate Leads' in the leads/opportunity ListView and KanbanView that opens a modal allowing to create a lead mining request - New section 'Lead Generation' in menuitem 'Configuration' of CRM TaskID : 1902172 closes odoo/odoo#30189
This commit is contained in:
committed by
Louis Baudoux
parent
6703840062
commit
7410de111f
@@ -11,7 +11,9 @@ class ResConfigSettings(models.TransientModel):
|
||||
generate_lead_from_alias = fields.Boolean('Manual Assignation of Emails', config_parameter='crm.generate_lead_from_alias')
|
||||
group_use_lead = fields.Boolean(string="Leads", implied_group='crm.group_use_lead')
|
||||
module_crm_phone_validation = fields.Boolean("Phone Formatting")
|
||||
module_crm_iap_lead = fields.Boolean("Generate new leads based on their country, technologies, size, etc.")
|
||||
module_crm_iap_lead_website = fields.Boolean("Create Leads/Opportunities from your website's traffic")
|
||||
lead_mining_in_pipeline = fields.Boolean("Create a lead mining request directly from the opportunity pipeline.", config_parameter='crm.lead_mining_in_pipeline')
|
||||
|
||||
def _find_default_lead_alias_id(self):
|
||||
alias = self.env.ref('crm.mail_alias_lead_info', False)
|
||||
|
||||
@@ -52,21 +52,35 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h2>Lead Generation</h2>
|
||||
<div class="row mt16 o_settings_container">
|
||||
<div class="col-lg-6 o_setting_box">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="module_crm_iap_lead_website"/>
|
||||
</div>
|
||||
|
||||
<div class="o_setting_right_pane crm_reveal_settings">
|
||||
<label string="Website Lead Generation" for="module_crm_reveal"/>
|
||||
<div class="o_setting_right_pane" id="crm_iap_lead_website_settings">
|
||||
<label string="Website Lead Generation" for="module_crm_iap_lead_website"/>
|
||||
<div class="text-muted">
|
||||
Convert visitors of your website into leads and perform data enrichment based on their IP address.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt16 o_settings_container">
|
||||
<div class="col-lg-6 o_setting_box">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="module_crm_iap_lead"/>
|
||||
</div>
|
||||
|
||||
<div class="o_setting_right_pane" id="crm_iap_lead_settings">
|
||||
<label string="Lead Mining" for="module_crm_iap_lead"/>
|
||||
<div class="text-muted">
|
||||
Generate new leads based on their country, technologies, size, etc.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h2>Contacts</h2>
|
||||
<div class="row mt16 o_settings_container">
|
||||
<div class="col-lg-6 o_setting_box">
|
||||
|
||||
@@ -10,8 +10,17 @@
|
||||
'data/crm.iap.lead.industry.csv',
|
||||
'data/crm.iap.lead.role.csv',
|
||||
'data/crm.iap.lead.seniority.csv',
|
||||
'data/crm.iap.lead.technology.csv',
|
||||
'data/message_template.xml',
|
||||
'data/crm_iap_lead_data.xml',
|
||||
'data/ir_sequence_data.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'views/crm_lead_view.xml',
|
||||
'views/crm_iap_lead_views.xml',
|
||||
'views/res_config_settings_views.xml',
|
||||
'views/crm_iap_lead_templates.xml',
|
||||
],
|
||||
'qweb': [
|
||||
'static/src/xml/leads_tree_generate_leads_views.xml',
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,348 @@
|
||||
id,name,tech_tag
|
||||
crm_iap_lead_technology_1,1&1 Hosting,1_and_1_hosting
|
||||
crm_iap_lead_technology_2,3d Cart,3d_cart
|
||||
crm_iap_lead_technology_3,Acquia,acquia
|
||||
crm_iap_lead_technology_4,Acquisio,acquisio
|
||||
crm_iap_lead_technology_5,Act On,act_on
|
||||
crm_iap_lead_technology_6,Action Network,action_network
|
||||
crm_iap_lead_technology_7,Active Demand,active_demand
|
||||
crm_iap_lead_technology_8,Activecampaign,activecampaign
|
||||
crm_iap_lead_technology_9,Add To Any,add_to_any
|
||||
crm_iap_lead_technology_10,Adform Advertiser,adform_advertiser
|
||||
crm_iap_lead_technology_11,Adobe Business Catalyst,adobe_business_catalyst
|
||||
crm_iap_lead_technology_12,Adobe Connect,adobe_connect
|
||||
crm_iap_lead_technology_13,Adobe Dynamic Tag Management,adobe_dynamic_tag_management
|
||||
crm_iap_lead_technology_14,Adobe Experience Manager,adobe_experience_manager
|
||||
crm_iap_lead_technology_15,AdRoll,adroll
|
||||
crm_iap_lead_technology_16,Airbrake,airbrake
|
||||
crm_iap_lead_technology_17,Akamai,akamai
|
||||
crm_iap_lead_technology_18,Akamai DNS,akamai_dns
|
||||
crm_iap_lead_technology_19,Alexa,alexa
|
||||
crm_iap_lead_technology_20,Altocloud,altocloud
|
||||
crm_iap_lead_technology_21,Amazon Associates,amazon_associates
|
||||
crm_iap_lead_technology_22,Amazon Payments,amazon_payments
|
||||
crm_iap_lead_technology_23,Amazon S3,amazon_s3
|
||||
crm_iap_lead_technology_24,Amazon Simple Email Service,amazon_ses
|
||||
crm_iap_lead_technology_25,Amazon Web Services,aws_ec2
|
||||
crm_iap_lead_technology_26,amCharts,amcharts
|
||||
crm_iap_lead_technology_27,Amplitude,amplitude
|
||||
crm_iap_lead_technology_28,Android,android
|
||||
crm_iap_lead_technology_29,Apache,apache
|
||||
crm_iap_lead_technology_30,App Nexus,app_nexus
|
||||
crm_iap_lead_technology_31,Appboy,appboy
|
||||
crm_iap_lead_technology_32,Appcues,appcues
|
||||
crm_iap_lead_technology_33,AppDynamics,appdynamics
|
||||
crm_iap_lead_technology_34,Apteligent,apteligent
|
||||
crm_iap_lead_technology_35,ASP.Net,asp_net
|
||||
crm_iap_lead_technology_36,Attribution,attribution
|
||||
crm_iap_lead_technology_37,Authorizenet,authorizenet
|
||||
crm_iap_lead_technology_38,Autopilot,autopilot
|
||||
crm_iap_lead_technology_39,Aweber,aweber
|
||||
crm_iap_lead_technology_40,Bazaarvoice,bazaarvoice
|
||||
crm_iap_lead_technology_41,Benchmarkemail,benchmarkemail
|
||||
crm_iap_lead_technology_42,Big Cartel,big_cartel
|
||||
crm_iap_lead_technology_43,Bigcommerce,bigcommerce
|
||||
crm_iap_lead_technology_44,Bing Ads,bing_ads
|
||||
crm_iap_lead_technology_45,Bing Advertiser,bing_advertiser
|
||||
crm_iap_lead_technology_46,Bing Maps,bing_maps
|
||||
crm_iap_lead_technology_47,Bloomreach,bloomreach
|
||||
crm_iap_lead_technology_48,Bluehost Hosting,bluehost_hosting
|
||||
crm_iap_lead_technology_49,Braintree,braintree
|
||||
crm_iap_lead_technology_50,Branch,branch
|
||||
crm_iap_lead_technology_51,Brightcove,brightcove
|
||||
crm_iap_lead_technology_52,Bronto,bronto
|
||||
crm_iap_lead_technology_53,Bug Herd,bug_herd
|
||||
crm_iap_lead_technology_54,Bugsnag,bugsnag
|
||||
crm_iap_lead_technology_55,C3 Metrics,c3_metrics
|
||||
crm_iap_lead_technology_56,Calq,calq
|
||||
crm_iap_lead_technology_57,Campaignmonitor,campaignmonitor
|
||||
crm_iap_lead_technology_58,Castle,castle
|
||||
crm_iap_lead_technology_59,CentOS,centos
|
||||
crm_iap_lead_technology_60,Chargify,chargify
|
||||
crm_iap_lead_technology_61,Chart Beat,chart_beat
|
||||
crm_iap_lead_technology_62,Chartio,chartio
|
||||
crm_iap_lead_technology_63,Chatlio,chatlio
|
||||
crm_iap_lead_technology_64,Chownow,chownow
|
||||
crm_iap_lead_technology_65,ClickFunnels,clickfunnels
|
||||
crm_iap_lead_technology_66,Clicktale,clicktale
|
||||
crm_iap_lead_technology_67,Clicky,clicky
|
||||
crm_iap_lead_technology_68,Cloud Flare,cloud_flare
|
||||
crm_iap_lead_technology_69,Cloudinary,cloudinary
|
||||
crm_iap_lead_technology_70,Commerce Sciences,commerce_sciences
|
||||
crm_iap_lead_technology_71,Constant Contact,constant_contact
|
||||
crm_iap_lead_technology_72,Contently,contently
|
||||
crm_iap_lead_technology_73,Convert Kit,convert_kit
|
||||
crm_iap_lead_technology_74,Convertro,convertro
|
||||
crm_iap_lead_technology_75,Crazy Egg,crazy_egg
|
||||
crm_iap_lead_technology_76,Criteo,criteo
|
||||
crm_iap_lead_technology_77,Crowdskout,crowdskout
|
||||
crm_iap_lead_technology_78,Customer.io,customer_io
|
||||
crm_iap_lead_technology_79,Dailymotion,dailymotion
|
||||
crm_iap_lead_technology_80,Debian,debian
|
||||
crm_iap_lead_technology_81,Demandbase,demandbase
|
||||
crm_iap_lead_technology_82,Demandware,demandware
|
||||
crm_iap_lead_technology_83,Digital Ocean,digital_ocean
|
||||
crm_iap_lead_technology_84,Disqus,disqus
|
||||
crm_iap_lead_technology_85,Django,django
|
||||
crm_iap_lead_technology_86,DNS Made Easy,dns_made_easy
|
||||
crm_iap_lead_technology_87,DoubleClick Ads,double_click
|
||||
crm_iap_lead_technology_88,DoubleClick Advertiser,double_click_advertiser
|
||||
crm_iap_lead_technology_89,DreamHost Hosting,dreamhost_hosting
|
||||
crm_iap_lead_technology_90,Drift,drift
|
||||
crm_iap_lead_technology_91,Drip,drip
|
||||
crm_iap_lead_technology_92,Drupal,drupal
|
||||
crm_iap_lead_technology_93,Dwolla,dwolla
|
||||
crm_iap_lead_technology_94,Dyn DNS,dyn_dns
|
||||
crm_iap_lead_technology_95,Dynamic Yield,dynamic_yield
|
||||
crm_iap_lead_technology_96,Ecwid,ecwid
|
||||
crm_iap_lead_technology_97,ElasticEmail,elasticemail
|
||||
crm_iap_lead_technology_98,Elevio,elevio
|
||||
crm_iap_lead_technology_99,Eloqua,eloqua
|
||||
crm_iap_lead_technology_100,Emma,emma
|
||||
crm_iap_lead_technology_101,Engagio,engagio
|
||||
crm_iap_lead_technology_102,Errorception,errorception
|
||||
crm_iap_lead_technology_103,Express,express
|
||||
crm_iap_lead_technology_104,Facebook Advertiser,facebook_advertiser
|
||||
crm_iap_lead_technology_105,Facebook Beacon,facebook_beacon
|
||||
crm_iap_lead_technology_106,Facebook Comments,facebook_comments
|
||||
crm_iap_lead_technology_107,Facebook Connect,facebook_connect
|
||||
crm_iap_lead_technology_108,Facebook Like Button,facebook_like_button
|
||||
crm_iap_lead_technology_109,Facebook Social Plugins,facebook_social_plugins
|
||||
crm_iap_lead_technology_110,Fedora,fedora
|
||||
crm_iap_lead_technology_111,Flowplayer,flowplayer
|
||||
crm_iap_lead_technology_112,Formstack,formstack
|
||||
crm_iap_lead_technology_113,FreeBSD,freebsd
|
||||
crm_iap_lead_technology_114,Freshdesk,freshdesk
|
||||
crm_iap_lead_technology_115,Fullcontact,fullcontact
|
||||
crm_iap_lead_technology_116,Fullstory,fullstory
|
||||
crm_iap_lead_technology_117,FusionCharts,fusioncharts
|
||||
crm_iap_lead_technology_118,Gauges,gauges
|
||||
crm_iap_lead_technology_119,Get Response,get_response
|
||||
crm_iap_lead_technology_120,Get Satisfaction,get_satisfaction
|
||||
crm_iap_lead_technology_121,Go Squared,go_squared
|
||||
crm_iap_lead_technology_122,Gocardless,gocardless
|
||||
crm_iap_lead_technology_123,GoDaddy Hosting,godaddy_hosting
|
||||
crm_iap_lead_technology_124,Godaddy Nameserver,godaddy_nameserver
|
||||
crm_iap_lead_technology_125,Google Adsense,google_adsense
|
||||
crm_iap_lead_technology_126,Google Adwords,google_adwords
|
||||
crm_iap_lead_technology_127,Google Affiliate Network,google_affiliate_network
|
||||
crm_iap_lead_technology_128,Google Analytics,google_analytics
|
||||
crm_iap_lead_technology_129,Google Apps,google_apps
|
||||
crm_iap_lead_technology_130,Google Charts,google_charts
|
||||
crm_iap_lead_technology_131,Google Cloud,google_cloud
|
||||
crm_iap_lead_technology_132,Google Forms,google_forms
|
||||
crm_iap_lead_technology_133,Google Maps,google_maps
|
||||
crm_iap_lead_technology_134,Google Tag Manager,google_tag_manager
|
||||
crm_iap_lead_technology_135,Google Website Optimizer,google_website_optimizer
|
||||
crm_iap_lead_technology_136,Google Widgets,google_widgets
|
||||
crm_iap_lead_technology_137,GraphIQ,graphiq
|
||||
crm_iap_lead_technology_138,Gravity Forms,gravity_forms
|
||||
crm_iap_lead_technology_139,Greenhouse,greenhouse
|
||||
crm_iap_lead_technology_140,Heap,heap
|
||||
crm_iap_lead_technology_141,Hello Bar,hello_bar
|
||||
crm_iap_lead_technology_142,Help Scout,help_scout
|
||||
crm_iap_lead_technology_143,Heroku,heroku
|
||||
crm_iap_lead_technology_144,Highcharts,highcharts
|
||||
crm_iap_lead_technology_145,Hotjar,hotjar
|
||||
crm_iap_lead_technology_146,Hoverowl,hoverowl
|
||||
crm_iap_lead_technology_147,HubSpot,hubspot
|
||||
crm_iap_lead_technology_148,Icims,icims
|
||||
crm_iap_lead_technology_149,Indicative,indicative
|
||||
crm_iap_lead_technology_150,Infusionsoft,infusionsoft
|
||||
crm_iap_lead_technology_151,Inside Sales,inside_sales
|
||||
crm_iap_lead_technology_152,Inspectlet,inspectlet
|
||||
crm_iap_lead_technology_153,Instagram,instagram
|
||||
crm_iap_lead_technology_154,Instagram Links,instagram_links
|
||||
crm_iap_lead_technology_155,Instart Logic,instart_logic
|
||||
crm_iap_lead_technology_156,Intense Debate,intense_debate
|
||||
crm_iap_lead_technology_157,Intercom,intercom
|
||||
crm_iap_lead_technology_158,ios,ios
|
||||
crm_iap_lead_technology_159,Iterable,iterable
|
||||
crm_iap_lead_technology_160,Java,java
|
||||
crm_iap_lead_technology_161,Jobvite,jobvite
|
||||
crm_iap_lead_technology_162,Joomla,joomla
|
||||
crm_iap_lead_technology_163,Jw Player,jw_player
|
||||
crm_iap_lead_technology_164,Kaltura,kaltura
|
||||
crm_iap_lead_technology_165,Kapost,kapost
|
||||
crm_iap_lead_technology_166,Keen IO,keen_io
|
||||
crm_iap_lead_technology_167,Kissmetrics,kiss_metrics
|
||||
crm_iap_lead_technology_168,Klaviyo,klaviyo
|
||||
crm_iap_lead_technology_169,Knowtify,knowtify
|
||||
crm_iap_lead_technology_170,Lead Dyno,lead_dyno
|
||||
crm_iap_lead_technology_171,Lever,lever
|
||||
crm_iap_lead_technology_172,Lightspeed,lightspeed
|
||||
crm_iap_lead_technology_173,LinkedIn Advertiser,linked_in_advertiser
|
||||
crm_iap_lead_technology_174,Linkwithin,linkwithin
|
||||
crm_iap_lead_technology_175,Linode Hosting,linode_hosting
|
||||
crm_iap_lead_technology_176,Live Chat,live_chat
|
||||
crm_iap_lead_technology_177,Livefyre,livefyre
|
||||
crm_iap_lead_technology_178,Liveramp,liveramp
|
||||
crm_iap_lead_technology_179,LKQD,lkqd
|
||||
crm_iap_lead_technology_180,Localytics,localytics
|
||||
crm_iap_lead_technology_181,Looker,looker
|
||||
crm_iap_lead_technology_182,Lucky Orange,lucky_orange
|
||||
crm_iap_lead_technology_183,Mad Kudu,mad_kudu
|
||||
crm_iap_lead_technology_184,Magento,magento
|
||||
crm_iap_lead_technology_185,Magento Enterprise,magento_enterprise
|
||||
crm_iap_lead_technology_186,Magento V1,magento_v1
|
||||
crm_iap_lead_technology_187,Magento V2,magento_v2
|
||||
crm_iap_lead_technology_188,Mailchimp,mailchimp
|
||||
crm_iap_lead_technology_189,Mailgun,mailgun
|
||||
crm_iap_lead_technology_190,Mailjet,mailjet
|
||||
crm_iap_lead_technology_191,Mandrill,mandrill
|
||||
crm_iap_lead_technology_192,Marin,marin
|
||||
crm_iap_lead_technology_193,Marketo,marketo
|
||||
crm_iap_lead_technology_194,Maxmind,maxmind
|
||||
crm_iap_lead_technology_195,Microsoft Azure,microsoft_azure
|
||||
crm_iap_lead_technology_196,Microsoft Exchange Online,microsoft_exchange_online
|
||||
crm_iap_lead_technology_197,Microsoft Office 365,microsoft_office_365
|
||||
crm_iap_lead_technology_198,Mindbody,mindbody
|
||||
crm_iap_lead_technology_199,Mixpanel,mixpanel
|
||||
crm_iap_lead_technology_200,Mode,mode
|
||||
crm_iap_lead_technology_201,Mouseflow,mouseflow
|
||||
crm_iap_lead_technology_202,Mousestats,mousestats
|
||||
crm_iap_lead_technology_203,My Site Auditor,my_site_auditor
|
||||
crm_iap_lead_technology_204,Namecheap Dns,namecheap_dns
|
||||
crm_iap_lead_technology_205,NationBuilder,nation_builder
|
||||
crm_iap_lead_technology_206,Neustar Ad Advisor,neustar_ad_advisor
|
||||
crm_iap_lead_technology_207,New Relic,new_relic
|
||||
crm_iap_lead_technology_208,Nextable,nextable
|
||||
crm_iap_lead_technology_209,Nginx,nginx
|
||||
crm_iap_lead_technology_210,Nosto,nosto
|
||||
crm_iap_lead_technology_211,Ns1,ns1
|
||||
crm_iap_lead_technology_212,Olark,olark
|
||||
crm_iap_lead_technology_213,Omniconvert,omniconvert
|
||||
crm_iap_lead_technology_214,Omniture (Adobe Analytics),omniture_adobe_analytics
|
||||
crm_iap_lead_technology_215,Ooyala,ooyala
|
||||
crm_iap_lead_technology_216,Open Table,open_table
|
||||
crm_iap_lead_technology_217,Optimizely,optimizely
|
||||
crm_iap_lead_technology_218,Optimonk,optimonk
|
||||
crm_iap_lead_technology_219,Oscommerce,oscommerce
|
||||
crm_iap_lead_technology_220,Outbound,outbound
|
||||
crm_iap_lead_technology_221,Outbrain Ads,outbrain_ads
|
||||
crm_iap_lead_technology_222,Outlook,outlook
|
||||
crm_iap_lead_technology_223,ownerIQ,owneriq
|
||||
crm_iap_lead_technology_224,Pardot,pardot
|
||||
crm_iap_lead_technology_225,PayPal,paypal
|
||||
crm_iap_lead_technology_226,Payza,payza
|
||||
crm_iap_lead_technology_227,Percolate,percolate
|
||||
crm_iap_lead_technology_228,Perfect Audience,perfect_audience
|
||||
crm_iap_lead_technology_229,Periscope Data,periscope_data
|
||||
crm_iap_lead_technology_230,Picreel,picreel
|
||||
crm_iap_lead_technology_231,Pingdom,pingdom
|
||||
crm_iap_lead_technology_232,Pinterest,pinterest
|
||||
crm_iap_lead_technology_233,Pipedrive,pipedrive
|
||||
crm_iap_lead_technology_234,Piwik,piwik
|
||||
crm_iap_lead_technology_235,Playwire,playwire
|
||||
crm_iap_lead_technology_236,Postmark,postmark
|
||||
crm_iap_lead_technology_237,PowerReviews,powerreviews
|
||||
crm_iap_lead_technology_238,Presta Shop,presta_shop
|
||||
crm_iap_lead_technology_239,Privy,privy
|
||||
crm_iap_lead_technology_240,Qbrick,qbrick
|
||||
crm_iap_lead_technology_241,Qualaroo,qualaroo
|
||||
crm_iap_lead_technology_242,Qualtrics,qualtrics
|
||||
crm_iap_lead_technology_243,Quantcast,quantcast
|
||||
crm_iap_lead_technology_244,Qubit,qubit
|
||||
crm_iap_lead_technology_245,Rackspace,rackspace
|
||||
crm_iap_lead_technology_246,Rackspace Email,rackspace_email
|
||||
crm_iap_lead_technology_247,Recaptcha,recaptcha
|
||||
crm_iap_lead_technology_248,Recruiterbox,recruiterbox
|
||||
crm_iap_lead_technology_249,Recurly,recurly
|
||||
crm_iap_lead_technology_250,Red Hat,red_hat
|
||||
crm_iap_lead_technology_251,ReSRCit,resrcit
|
||||
crm_iap_lead_technology_252,Resumator,resumator
|
||||
crm_iap_lead_technology_253,RetailRocket,retailrocket
|
||||
crm_iap_lead_technology_254,Rezdy,rezdy
|
||||
crm_iap_lead_technology_255,Rezgo,rezgo
|
||||
crm_iap_lead_technology_256,Robly,robly
|
||||
crm_iap_lead_technology_257,Rollbar,rollbar
|
||||
crm_iap_lead_technology_258,Route 53,aws_route_53
|
||||
crm_iap_lead_technology_259,Ruby On Rails,ruby_on_rails
|
||||
crm_iap_lead_technology_260,Salesforce,salesforce
|
||||
crm_iap_lead_technology_261,Salesmachine,salesmachine
|
||||
crm_iap_lead_technology_262,Salsa,salsa
|
||||
crm_iap_lead_technology_263,Satismeter,satismeter
|
||||
crm_iap_lead_technology_264,Segment,segment
|
||||
crm_iap_lead_technology_265,Sendgrid,sendgrid
|
||||
crm_iap_lead_technology_266,Sentry,sentry
|
||||
crm_iap_lead_technology_267,Sessioncam,sessioncam
|
||||
crm_iap_lead_technology_268,Sharepoint,sharepoint
|
||||
crm_iap_lead_technology_269,Sharp Spring,sharp_spring
|
||||
crm_iap_lead_technology_270,Shopify,shopify
|
||||
crm_iap_lead_technology_271,Shopify Plus,shopify_plus
|
||||
crm_iap_lead_technology_272,Shopware,shopware
|
||||
crm_iap_lead_technology_273,Sidecar,sidecar
|
||||
crm_iap_lead_technology_274,Silkroad,silkroad
|
||||
crm_iap_lead_technology_275,Simplicant,simplicant
|
||||
crm_iap_lead_technology_276,Slack,slack
|
||||
crm_iap_lead_technology_277,Smartlook,smartlook
|
||||
crm_iap_lead_technology_278,Snowplow Analytics,snowplow_analytics
|
||||
crm_iap_lead_technology_279,Sociomantic,sociomantic
|
||||
crm_iap_lead_technology_280,Socket.io,socket_io
|
||||
crm_iap_lead_technology_281,Softlayer Hosting,softlayer_hosting
|
||||
crm_iap_lead_technology_282,Squarespace,squarespace
|
||||
crm_iap_lead_technology_283,SteelHouse,steel_house
|
||||
crm_iap_lead_technology_284,Stripe,stripe
|
||||
crm_iap_lead_technology_285,Success Factors,success_factors
|
||||
crm_iap_lead_technology_286,Sumo,sumo
|
||||
crm_iap_lead_technology_287,Survey Monkey,survey_monkey
|
||||
crm_iap_lead_technology_288,Tableau,tableau
|
||||
crm_iap_lead_technology_289,Taboola Ads,taboola_ads
|
||||
crm_iap_lead_technology_290,Taleo,taleo
|
||||
crm_iap_lead_technology_291,Talkable,talkable
|
||||
crm_iap_lead_technology_292,Tawk,tawk
|
||||
crm_iap_lead_technology_293,Tealium,tealium
|
||||
crm_iap_lead_technology_294,Terminus,terminus
|
||||
crm_iap_lead_technology_295,Top Producer,top_producer
|
||||
crm_iap_lead_technology_296,Totango,totango
|
||||
crm_iap_lead_technology_297,Tout,tout
|
||||
crm_iap_lead_technology_298,Toutapp,toutapp
|
||||
crm_iap_lead_technology_299,TowerData,towerdata
|
||||
crm_iap_lead_technology_300,Track JS,track_js
|
||||
crm_iap_lead_technology_301,Trustpilot,trustpilot
|
||||
crm_iap_lead_technology_302,Twitter Advertiser,twitter_advertiser
|
||||
crm_iap_lead_technology_303,Twitter Badge,twitter_badge
|
||||
crm_iap_lead_technology_304,Twitter Button,twitter_button
|
||||
crm_iap_lead_technology_305,Typeform,typeform
|
||||
crm_iap_lead_technology_306,Typekit By Adobe,typekit_by_adobe
|
||||
crm_iap_lead_technology_307,Uber Cart,uber_cart
|
||||
crm_iap_lead_technology_308,Ubuntu,ubuntu
|
||||
crm_iap_lead_technology_309,Ultipro,ultipro
|
||||
crm_iap_lead_technology_310,Unix,unix
|
||||
crm_iap_lead_technology_311,UserVoice,user_voice
|
||||
crm_iap_lead_technology_312,Vero,vero
|
||||
crm_iap_lead_technology_313,Verticalresponse,verticalresponse
|
||||
crm_iap_lead_technology_314,Video.js,videojs
|
||||
crm_iap_lead_technology_315,Vidyard,vidyard
|
||||
crm_iap_lead_technology_316,Vimeo,vimeo
|
||||
crm_iap_lead_technology_317,Virtue Mart,virtue_mart
|
||||
crm_iap_lead_technology_318,Visual IQ,visual_iq
|
||||
crm_iap_lead_technology_319,Visual Website Optimizer,visual_website_optimizer
|
||||
crm_iap_lead_technology_320,Volusion,volusion
|
||||
crm_iap_lead_technology_321,Vzaar,vzaar
|
||||
crm_iap_lead_technology_322,WebEngage,webengage
|
||||
crm_iap_lead_technology_323,Weebly,weebly
|
||||
crm_iap_lead_technology_324,Wistia,wistia
|
||||
crm_iap_lead_technology_325,Wix Stores,wix_stores
|
||||
crm_iap_lead_technology_326,Woo Commerce,woo_commerce
|
||||
crm_iap_lead_technology_327,Woopra,woopra
|
||||
crm_iap_lead_technology_328,Wootric,wootric
|
||||
crm_iap_lead_technology_329,Wordpress,wordpress
|
||||
crm_iap_lead_technology_330,Workable,workable
|
||||
crm_iap_lead_technology_331,Wp Engine,wp_engine
|
||||
crm_iap_lead_technology_332,Wufoo,wufoo
|
||||
crm_iap_lead_technology_333,xt:Commerce,xt_commerce
|
||||
crm_iap_lead_technology_334,Yahoo Stores,yahoo_stores
|
||||
crm_iap_lead_technology_335,Yandex Metrica,yandex_metrica
|
||||
crm_iap_lead_technology_336,Yelp Seatme,yelp_seatme
|
||||
crm_iap_lead_technology_337,Yesware,yesware
|
||||
crm_iap_lead_technology_338,Yieldify,yieldify
|
||||
crm_iap_lead_technology_339,Yotpo,yotpo
|
||||
crm_iap_lead_technology_340,Youtube,youtube
|
||||
crm_iap_lead_technology_341,Zeit Now,zeit_now
|
||||
crm_iap_lead_technology_342,Zen Cart,zen_cart
|
||||
crm_iap_lead_technology_343,Zendesk,zendesk
|
||||
crm_iap_lead_technology_344,Zenreach,zenreach
|
||||
crm_iap_lead_technology_345,Zopim,zopim
|
||||
crm_iap_lead_technology_346,Zuora,zuora
|
||||
crm_iap_lead_technology_347,Zype,zype
|
||||
|
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
<!-- Sequences for lead mining requests -->
|
||||
<record id="seq_crm_iap_lead_mining_request" model="ir.sequence">
|
||||
<field name="name">Lead Mining Request</field>
|
||||
<field name="code">crm.iap.lead.mining.request</field>
|
||||
<field name="prefix">LMR</field>
|
||||
<field name="padding">3</field>
|
||||
<field name="company_id" eval="False"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -2,3 +2,5 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from . import crm_lead
|
||||
from . import crm_iap_lead
|
||||
from . import crm_iap_lead_helpers
|
||||
from . import crm_iap_lead_mining_request
|
||||
|
||||
@@ -48,3 +48,16 @@ class PeopleSeniority(models.Model):
|
||||
@api.depends('name')
|
||||
def name_get(self):
|
||||
return [(seniority.id, seniority.name.replace('_', ' ').title()) for seniority in self]
|
||||
|
||||
|
||||
class TechnologyTag(models.Model):
|
||||
""" Technology Tags of Clearbit """
|
||||
_name = 'crm.iap.lead.technology'
|
||||
_description = 'Technology Tag'
|
||||
|
||||
name = fields.Char(string='Name', required=True, translate=True)
|
||||
tech_tag = fields.Char(string="Tech Tag", required=True)
|
||||
|
||||
_sql_constraints = [
|
||||
('name_uniq', 'unique (name)', 'Technology tag name already exists!'),
|
||||
]
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
from math import floor, log10
|
||||
from odoo import api, models
|
||||
|
||||
|
||||
class CRMHelpers(models.Model):
|
||||
_name = 'crm.iap.lead.helpers'
|
||||
_description = 'Helper methods for crm_iap_lead modules'
|
||||
|
||||
@api.model
|
||||
def notify_no_more_credit(self, service_name, model_name, notification_parameter):
|
||||
"""
|
||||
Notify about the number of credit.
|
||||
In order to avoid to spam people each hour, an ir.config_parameter is set
|
||||
"""
|
||||
already_notified = self.env['ir.config_parameter'].sudo().get_param(notification_parameter, False)
|
||||
if already_notified:
|
||||
return
|
||||
mail_template = self.env.ref('crm_iap_lead.lead_generation_no_credits')
|
||||
iap_account = self.env['iap.account'].search([('service_name', '=', service_name)], limit=1)
|
||||
# Get the email address of the creators of the records
|
||||
res = self.env[model_name].search_read([], ['create_uid'])
|
||||
uids = set(r['create_uid'][0] for r in res if r.get('create_uid'))
|
||||
res = self.env['res.users'].search_read([('id', 'in', list(uids))], ['email'])
|
||||
emails = set(r['email'] for r in res if r.get('email'))
|
||||
|
||||
mail_values = mail_template.generate_email(iap_account.id)
|
||||
mail_values['email_to'] = ','.join(emails)
|
||||
mail = self.env['mail.mail'].create(mail_values)
|
||||
mail.send()
|
||||
self.env['ir.config_parameter'].sudo().set_param(notification_parameter, True)
|
||||
|
||||
@api.model
|
||||
def lead_vals_from_response(self, lead_type, team_id, tag_ids, user_id, company_data, people_data):
|
||||
country_id = self.env['res.country'].search([('code', '=', company_data['country_code'])]).id
|
||||
website_url = 'https://www.%s' % company_data['domain'] if company_data['domain'] else False
|
||||
lead_vals = {
|
||||
# Lead vals from record itself
|
||||
'type': lead_type,
|
||||
'team_id': team_id,
|
||||
'tag_ids': [(6, 0, tag_ids)],
|
||||
'user_id': user_id,
|
||||
'reveal_id': company_data['clearbit_id'],
|
||||
# Lead vals from data
|
||||
'name': company_data['name'],
|
||||
'partner_name': company_data['legal_name'] or company_data['name'],
|
||||
'email_from': ",".join(company_data['email'] or []),
|
||||
'phone': company_data['phone'] or (company_data['phone_numbers'] and company_data['phone_numbers'][0]) or '',
|
||||
'website': website_url,
|
||||
'street': company_data['location'],
|
||||
'city': company_data['city'],
|
||||
'zip': company_data['postal_code'],
|
||||
'country_id': country_id,
|
||||
'state_id': self._find_state_id(company_data['state_code'], country_id),
|
||||
'description': self._prepare_lead_description(company_data),
|
||||
}
|
||||
|
||||
# If type is people then add first contact in lead data
|
||||
if people_data:
|
||||
lead_vals.update({
|
||||
'contact_name': people_data[0]['full_name'],
|
||||
'email_from': people_data[0]['email'],
|
||||
'function': people_data[0]['title'],
|
||||
})
|
||||
return lead_vals
|
||||
|
||||
@api.model
|
||||
def _find_state_id(self, state_code, country_id):
|
||||
state_id = self.env['res.country.state'].search([('code', '=', state_code), ('country_id', '=', country_id)])
|
||||
if state_id:
|
||||
return state_id.id
|
||||
return False
|
||||
|
||||
@api.model
|
||||
def _prepare_lead_description(self, reveal_data):
|
||||
description = ''
|
||||
if reveal_data['sector']:
|
||||
description += reveal_data['sector']
|
||||
if reveal_data['website_title']:
|
||||
description += '\n' + reveal_data['website_title']
|
||||
if reveal_data['twitter_bio']:
|
||||
description += '\n' + "Twitter Bio: " + reveal_data['twitter_bio']
|
||||
if reveal_data['twitter_followers']:
|
||||
description += ('\nTwitter %s followers, %s \n') % (reveal_data['twitter_followers'], reveal_data['twitter_location'] or '')
|
||||
|
||||
numbers = ['raised', 'market_cap', 'employees', 'estimated_annual_revenue']
|
||||
millnames = ['', ' K', ' M', ' B', 'T']
|
||||
|
||||
def millify(n):
|
||||
try:
|
||||
n = float(n)
|
||||
millidx = max(0, min(len(millnames) - 1, int(floor(0 if n == 0 else log10(abs(n)) / 3))))
|
||||
return '{:.0f}{}'.format(n / 10**(3 * millidx), millnames[millidx])
|
||||
except Exception:
|
||||
return n
|
||||
|
||||
for key in numbers:
|
||||
if reveal_data.get(key):
|
||||
description += ' %s : %s,' % (key.replace('_', ' ').title(), millify(reveal_data[key]))
|
||||
return description
|
||||
|
||||
@api.model
|
||||
def format_data_for_message_post(self, company_data, people_data):
|
||||
log_data = {
|
||||
'twitter': company_data['twitter'],
|
||||
'description': company_data['description'],
|
||||
'logo': company_data['logo'],
|
||||
'name': company_data['name'],
|
||||
'phone_numbers': company_data['phone_numbers'],
|
||||
'facebook': company_data['facebook'],
|
||||
'linkedin': company_data['linkedin'],
|
||||
'crunchbase': company_data['crunchbase'],
|
||||
'tech': [t.replace('_', ' ').title() for t in company_data['tech']],
|
||||
'people_data': people_data,
|
||||
}
|
||||
timezone = company_data['timezone']
|
||||
if timezone:
|
||||
log_data.update({
|
||||
'timezone': timezone.replace('_', ' ').title(),
|
||||
'timezone_url': company_data['timezone_url'],
|
||||
})
|
||||
return log_data
|
||||
@@ -0,0 +1,233 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import logging
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.addons.iap import jsonrpc, InsufficientCreditError
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
DEFAULT_ENDPOINT = 'https://iap-services.odoo.com'
|
||||
|
||||
MAX_LEAD = 200
|
||||
MAX_CONTACT = 5
|
||||
|
||||
CREDIT_PER_COMPANY = 1
|
||||
CREDIT_PER_CONTACT = 1
|
||||
|
||||
|
||||
class CRMLeadMiningRequest(models.Model):
|
||||
_name = 'crm.iap.lead.mining.request'
|
||||
_description = 'CRM Lead Mining Request'
|
||||
|
||||
def _default_lead_type(self):
|
||||
if self.env.user.has_group('crm.group_use_lead'):
|
||||
return 'lead'
|
||||
else:
|
||||
return 'opportunity'
|
||||
|
||||
name = fields.Char(string='Request Number', required=True, readonly=True, default=lambda self: _('New'), copy=False)
|
||||
state = fields.Selection([('draft', 'Draft'), ('done', 'Done'), ('error', 'Error')], string='Status', required=True, default='draft')
|
||||
|
||||
# Request Data
|
||||
lead_number = fields.Integer(string='Number of Leads', required=True, default=10)
|
||||
search_type = fields.Selection([('companies', 'Companies'), ('people', 'Companies and their Contacts')], string='Target', required=True, default='companies')
|
||||
error = fields.Text(string='Error', readonly=True)
|
||||
|
||||
# Lead / Opportunity Data
|
||||
lead_type = fields.Selection([('lead', 'Lead'), ('opportunity', 'Opportunity')], string='Type', required=True, default=_default_lead_type)
|
||||
team_id = fields.Many2one('crm.team', string='Sales Team', domain="[('use_opportunities', '=', True)]")
|
||||
user_id = fields.Many2one('res.users', string='Salesperson')
|
||||
tag_ids = fields.Many2many('crm.lead.tag', string='Tags')
|
||||
lead_ids = fields.One2many('crm.lead', 'lead_mining_request_id', string='Generated Lead / Opportunity')
|
||||
leads_count = fields.Integer(compute='_compute_leads_count', string='Number of Generated Leads')
|
||||
|
||||
# Company Criteria Filter
|
||||
filter_on_size = fields.Boolean(string='Filter on Size', default=False)
|
||||
company_size_min = fields.Integer(string='Size', default=1)
|
||||
company_size_max = fields.Integer(default=1000)
|
||||
country_ids = fields.Many2many('res.country', string='Countries')
|
||||
state_ids = fields.Many2many('res.country.state', string='States')
|
||||
industry_ids = fields.Many2many('crm.iap.lead.industry', string='Industries')
|
||||
technology_ids = fields.Many2many('crm.iap.lead.technology', string='Technologies')
|
||||
|
||||
# Contact Generation Filter
|
||||
contact_number = fields.Integer(string='Number of Contacts', default=1)
|
||||
contact_filter_type = fields.Selection([('role', 'Role'), ('seniority', 'Seniority')], string='Filter on', default='role')
|
||||
preferred_role_id = fields.Many2one('crm.iap.lead.role', string='Preferred Role')
|
||||
role_ids = fields.Many2many('crm.iap.lead.role', string='Other Roles')
|
||||
seniority_id = fields.Many2one('crm.iap.lead.seniority', string='Seniority')
|
||||
|
||||
# Fields for the blue tooltip
|
||||
lead_number_info = fields.Integer(string='Number of Leads ', related='lead_number', readonly=True)
|
||||
lead_total_credit = fields.Integer(compute='_compute_lead_total_credit')
|
||||
contact_credit_per_company = fields.Integer(compute='_compute_contact_credit_per_company')
|
||||
contact_total_credit = fields.Integer(compute='_compute_contact_total_credit')
|
||||
|
||||
@api.depends('lead_number')
|
||||
def _compute_lead_total_credit(self):
|
||||
for req in self:
|
||||
req.lead_total_credit = CREDIT_PER_COMPANY * req.lead_number
|
||||
|
||||
@api.depends('contact_number')
|
||||
def _compute_contact_credit_per_company(self):
|
||||
for req in self:
|
||||
req.contact_credit_per_company = CREDIT_PER_CONTACT * req.contact_number
|
||||
|
||||
@api.depends('contact_number', 'lead_number')
|
||||
def _compute_contact_total_credit(self):
|
||||
for req in self:
|
||||
req.contact_total_credit = CREDIT_PER_CONTACT * req.contact_number * req.lead_number
|
||||
|
||||
@api.depends('lead_ids')
|
||||
def _compute_leads_count(self):
|
||||
for req in self:
|
||||
req.leads_count = len(req.lead_ids)
|
||||
|
||||
@api.onchange('lead_number')
|
||||
def _onchange_lead_number(self):
|
||||
if self.lead_number <= 0:
|
||||
self.lead_number = 1
|
||||
elif self.lead_number > MAX_LEAD:
|
||||
self.lead_number = MAX_LEAD
|
||||
|
||||
@api.onchange('contact_number')
|
||||
def _onchange_contact_number(self):
|
||||
if self.contact_number <= 0:
|
||||
self.contact_number = 1
|
||||
elif self.contact_number > MAX_CONTACT:
|
||||
self.contact_number = MAX_CONTACT
|
||||
|
||||
@api.onchange('country_ids')
|
||||
def _onchange_country_ids(self):
|
||||
self.state_ids = []
|
||||
|
||||
@api.onchange('company_size_min')
|
||||
def _onchange_company_size_min(self):
|
||||
if self.company_size_min <= 0:
|
||||
self.company_size_min = 1
|
||||
elif self.company_size_min > self.company_size_max:
|
||||
self.company_size_min = self.company_size_max
|
||||
|
||||
@api.onchange('company_size_max')
|
||||
def _onchange_company_size_max(self):
|
||||
if self.company_size_max < self.company_size_min:
|
||||
self.company_size_max = self.company_size_min
|
||||
|
||||
def _prepare_iap_payload(self):
|
||||
"""
|
||||
This will prepare the data to send to the server
|
||||
"""
|
||||
self.ensure_one()
|
||||
payload = {'lead_number': self.lead_number,
|
||||
'search_type': self.search_type,
|
||||
'countries': self.country_ids.mapped('code')}
|
||||
if self.state_ids:
|
||||
payload['states'] = self.state_ids.mapped('code')
|
||||
if self.filter_on_size:
|
||||
payload.update({'company_size_min': self.company_size_min,
|
||||
'company_size_max': self.company_size_max})
|
||||
if self.technology_ids:
|
||||
payload['technology_tags'] = self.technology_ids.mapped('tech_tag')
|
||||
if self.search_type == 'people':
|
||||
payload.update({'contact_number': self.contact_number,
|
||||
'contact_filter_type': self.contact_filter_type})
|
||||
if self.contact_filter_type == 'role':
|
||||
payload.update({'preferred_role': self.preferred_role_id.reveal_id,
|
||||
'other_roles': self.role_ids.mapped('reveal_id')})
|
||||
elif self.contact_filter_type == 'seniority':
|
||||
payload['seniority'] = self.seniority_id.reveal_id
|
||||
return payload
|
||||
|
||||
def _perform_request(self):
|
||||
"""
|
||||
This will perform the request and create the corresponding leads.
|
||||
The user will be notified if he hasn't enough credits.
|
||||
"""
|
||||
server_payload = self._prepare_iap_payload()
|
||||
reveal_account = self.env['iap.account'].get('reveal')
|
||||
dbuuid = self.env['ir.config_parameter'].sudo().get_param('database.uuid')
|
||||
endpoint = self.env['ir.config_parameter'].sudo().get_param('reveal.endpoint', DEFAULT_ENDPOINT) + '/iap/clearbit/1/lead_mining_request'
|
||||
params = {
|
||||
'account_token': reveal_account.account_token,
|
||||
'dbuuid': dbuuid,
|
||||
'data': server_payload
|
||||
}
|
||||
try:
|
||||
response = jsonrpc(endpoint, params=params, timeout=300)
|
||||
return response['data']
|
||||
except InsufficientCreditError as e:
|
||||
self.error = 'Insufficient credits. Recharge your account and retry.'
|
||||
self.state = 'error'
|
||||
self._cr.commit()
|
||||
raise e
|
||||
|
||||
@api.multi
|
||||
def _create_leads_from_response(self, result):
|
||||
""" This method will get the response from the service and create the leads accordingly """
|
||||
self.ensure_one()
|
||||
lead_vals = []
|
||||
messages_to_post = {}
|
||||
for data in result:
|
||||
lead_vals.append(self._lead_vals_from_response(data))
|
||||
messages_to_post[data['company_data']['clearbit_id']] = self.env['crm.iap.lead.helpers'].format_data_for_message_post(data['company_data'], data.get('people_data'))
|
||||
leads = self.env['crm.lead'].create(lead_vals)
|
||||
for lead in leads:
|
||||
if messages_to_post.get(lead.reveal_id):
|
||||
lead.message_post_with_view('crm_iap_lead.lead_message_template', values=messages_to_post[lead.reveal_id], subtype_id=self.env.ref('mail.mt_note').id)
|
||||
|
||||
# Methods responsible for format response data into valid odoo lead data
|
||||
@api.model
|
||||
def _lead_vals_from_response(self, data):
|
||||
self.ensure_one()
|
||||
company_data = data.get('company_data')
|
||||
people_data = data.get('people_data')
|
||||
lead_vals = self.env['crm.iap.lead.helpers'].lead_vals_from_response(self.lead_type, self.team_id.id, self.tag_ids.ids, self.user_id.id, company_data, people_data)
|
||||
lead_vals['lead_mining_request_id'] = self.id
|
||||
return lead_vals
|
||||
|
||||
@api.multi
|
||||
def action_draft(self):
|
||||
self.ensure_one()
|
||||
self.name = _('New')
|
||||
self.state = 'draft'
|
||||
|
||||
@api.multi
|
||||
def action_submit(self):
|
||||
self.ensure_one()
|
||||
if self.name == _('New'):
|
||||
self.name = self.env['ir.sequence'].next_by_code('crm.iap.lead.mining.request') or _('New')
|
||||
results = self._perform_request()
|
||||
if results:
|
||||
self._create_leads_from_response(results)
|
||||
self.state = 'done'
|
||||
if self.lead_type == 'lead':
|
||||
return self.action_get_lead_action()
|
||||
elif self.lead_type == 'opportunity':
|
||||
return self.action_get_opportunity_action()
|
||||
|
||||
@api.multi
|
||||
def action_get_lead_action(self):
|
||||
self.ensure_one()
|
||||
action = self.env.ref('crm.crm_lead_all_leads').read()[0]
|
||||
action['domain'] = [('id', 'in', self.lead_ids.ids), ('type', '=', 'lead')]
|
||||
action['help'] = _("""<p class="o_view_nocontent_empty_folder">
|
||||
No leads found
|
||||
</p><p>
|
||||
No leads could be generated according to your search criteria
|
||||
</p>""")
|
||||
return action
|
||||
|
||||
@api.multi
|
||||
def action_get_opportunity_action(self):
|
||||
self.ensure_one()
|
||||
action = self.env.ref('crm.crm_lead_opportunities').read()[0]
|
||||
action['domain'] = [('id', 'in', self.lead_ids.ids), ('type', '=', 'opportunity')]
|
||||
action['help'] = _("""<p class="o_view_nocontent_empty_folder">
|
||||
No opportunities found
|
||||
</p><p>
|
||||
No opportunities could be generated according to your search criteria
|
||||
</p>""")
|
||||
return action
|
||||
@@ -8,3 +8,4 @@ class Lead(models.Model):
|
||||
_inherit = 'crm.lead'
|
||||
|
||||
reveal_id = fields.Char(string='Reveal ID', index=True)
|
||||
lead_mining_request_id = fields.Many2one('crm.iap.lead.mining.request', string='Lead Mining Request', index=True)
|
||||
|
||||
@@ -3,4 +3,5 @@ access_crm_iap_lead_industry,access_crm_iap_lead_industry,model_crm_iap_lead_ind
|
||||
access_crm_iap_lead_role,access_crm_iap_lead_role,model_crm_iap_lead_role,sales_team.group_sale_manager,1,1,1,1
|
||||
access_crm_iap_lead_seniority,access_crm_iap_lead_seniority,model_crm_iap_lead_seniority,sales_team.group_sale_manager,1,1,1,1
|
||||
access_crm_iap_lead_technology,access_crm_iap_lead_technology,model_crm_iap_lead_technology,sales_team.group_sale_manager,1,1,1,1
|
||||
access_crm_iap_lead_request,access_crm_iap_lead_request,model_crm_iap_lead_request,sales_team.group_sale_manager,1,1,1,1
|
||||
access_crm_iap_lead_mining_request,access_crm_iap_lead_mining_request,model_crm_iap_lead_mining_request,sales_team.group_sale_manager,1,1,1,1
|
||||
access_crm_iap_lead_helpers,access_crm_iap_lead_helpers,model_crm_iap_lead_helpers,,0,0,0,0
|
||||
|
||||
|
@@ -0,0 +1,76 @@
|
||||
odoo.define('crm.leads.tree', function (require) {
|
||||
"use strict";
|
||||
var ListController = require('web.ListController');
|
||||
var ListView = require('web.ListView');
|
||||
|
||||
var KanbanController = require('web.KanbanController');
|
||||
var KanbanView = require('web.KanbanView');
|
||||
|
||||
var viewRegistry = require('web.view_registry');
|
||||
|
||||
function renderGenerateLeadsButton() {
|
||||
if (this.$buttons) {
|
||||
var self = this;
|
||||
var lead_type = self.initialState.getContext()['default_type'];
|
||||
this.$buttons.on('click', '.o_button_generate_leads', function () {
|
||||
self.do_action({
|
||||
name: 'Generate Leads',
|
||||
type: 'ir.actions.act_window',
|
||||
res_model: 'crm.iap.lead.mining.request',
|
||||
target: 'new',
|
||||
views: [[false, 'form']],
|
||||
context: {'is_modal': true, 'default_lead_type': lead_type},
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var LeadMiningRequestListController = ListController.extend({
|
||||
willStart: function() {
|
||||
var self = this;
|
||||
var ready = this.getSession().user_has_group('sales_team.group_sale_manager')
|
||||
.then(function (is_sale_manager) {
|
||||
if (is_sale_manager) {
|
||||
self.buttons_template = 'LeadMiningRequestListView.buttons';
|
||||
}
|
||||
});
|
||||
return $.when(this._super.apply(this, arguments), ready);
|
||||
},
|
||||
renderButtons: function () {
|
||||
this._super.apply(this, arguments);
|
||||
renderGenerateLeadsButton.apply(this, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
var LeadMiningRequestListView = ListView.extend({
|
||||
config: _.extend({}, ListView.prototype.config, {
|
||||
Controller: LeadMiningRequestListController,
|
||||
}),
|
||||
});
|
||||
|
||||
var LeadMiningRequestKanbanController = KanbanController.extend({
|
||||
willStart: function() {
|
||||
var self = this;
|
||||
var ready = this.getSession().user_has_group('sales_team.group_sale_manager')
|
||||
.then(function (is_sale_manager) {
|
||||
if (is_sale_manager) {
|
||||
self.buttons_template = 'LeadMiningRequestKanbanView.buttons';
|
||||
}
|
||||
});
|
||||
return $.when(this._super.apply(this, arguments), ready);
|
||||
},
|
||||
renderButtons: function () {
|
||||
this._super.apply(this, arguments);
|
||||
renderGenerateLeadsButton.apply(this, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
var LeadMiningRequestKanbanView = KanbanView.extend({
|
||||
config: _.extend({}, KanbanView.prototype.config, {
|
||||
Controller: LeadMiningRequestKanbanController,
|
||||
}),
|
||||
});
|
||||
|
||||
viewRegistry.add('crm_iap_lead_mining_request_tree', LeadMiningRequestListView);
|
||||
viewRegistry.add('crm_iap_lead_mining_request_kanban', LeadMiningRequestKanbanView);
|
||||
});
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<templates>
|
||||
<t t-name="LeadMiningRequest.generate_leads_button">
|
||||
<button type="button" class="btn btn-secondary o_button_generate_leads">
|
||||
Generate Leads
|
||||
</button>
|
||||
</t>
|
||||
|
||||
<t t-extend="ListView.buttons" t-name="LeadMiningRequestListView.buttons">
|
||||
<t t-jquery="button.o_list_button_add" t-operation="after">
|
||||
<t t-call="LeadMiningRequest.generate_leads_button"/>
|
||||
<t t-js="ctx">
|
||||
if (window.odoo._modules.indexOf("base_import") >= 0) {
|
||||
r.push(context.engine.tools.call(context, 'ImportView.import_button', dict));
|
||||
};
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
<t t-extend="KanbanView.buttons" t-name="LeadMiningRequestKanbanView.buttons">
|
||||
<t t-jquery="button" t-operation="after">
|
||||
<t t-call="LeadMiningRequest.generate_leads_button"/>
|
||||
<t t-js="ctx">
|
||||
if (window.odoo._modules.indexOf("base_import") >= 0) {
|
||||
r.push(context.engine.tools.call(context, 'ImportView.import_button', dict));
|
||||
};
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</templates>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="assets_backend" name="crm_iap_lead assets" inherit_id="web.assets_backend">
|
||||
<xpath expr="." position="inside">
|
||||
<script type="text/javascript" src="/crm_iap_lead/static/src/js/leads_tree_generate_leads.js"/>
|
||||
</xpath>
|
||||
</template>
|
||||
</odoo>
|
||||
@@ -0,0 +1,183 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="crm_iap_lead_mining_request_form" model="ir.ui.view">
|
||||
<field name="name">crm.iap.lead.mining.request.form</field>
|
||||
<field name="model">crm.iap.lead.mining.request</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<header>
|
||||
<button name="action_submit" type="object"
|
||||
string="Submit" states="draft"
|
||||
class="oe_highlight" invisible="context.get('is_modal')"/>
|
||||
<button name="action_submit" type="object"
|
||||
string="Retry" states="error"
|
||||
class="oe_highlight"/>
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,done" invisible="context.get('is_modal')"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="action_get_opportunity_action" class="oe_stat_button" type="object" icon="fa-handshake-o"
|
||||
attrs="{'invisible': ['|', '|', ('lead_type', '!=', 'opportunity'), ('state', '!=' , 'done')]}">
|
||||
<div class="o_stat_info">
|
||||
<field name="leads_count"/>
|
||||
<span class="o_stat_text">Opportunities</span>
|
||||
</div>
|
||||
</button>
|
||||
<button name="action_get_lead_action" class="oe_stat_button" type="object" icon="fa-handshake-o" groups="crm.group_use_lead"
|
||||
attrs="{'invisible': ['|', '|', ('lead_type', '!=', 'lead'), ('state', '!=' , 'done')]}">
|
||||
<div class="o_stat_info">
|
||||
<field name="leads_count"/>
|
||||
<span class="o_stat_text">Leads</span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<span invisible="context.get('is_modal')">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="oe_title">
|
||||
<h1>
|
||||
<field name="name"/>
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
<group>
|
||||
<group string="Request">
|
||||
<field name="lead_number" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="search_type" widget="radio" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="error" attrs="{'invisible': [('state', '!=', 'error')]}"/>
|
||||
</group>
|
||||
<group string="Lead Information">
|
||||
<field name="lead_type" groups="crm.group_use_lead" invisible="context.get('is_modal')" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="team_id" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="user_id" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="tag_ids" widget="many2many_tags" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<group string="Companies">
|
||||
<field name="filter_on_size" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<label for="company_size_min" attrs="{'invisible': [('filter_on_size', '=', False)]}"/>
|
||||
<div attrs="{'invisible': [('filter_on_size', '=', False)]}">
|
||||
From
|
||||
<field name="company_size_min" class="oe_inline col-sm-3" attrs="{'required': [('filter_on_size', '=', True)], 'readonly': [('state', '!=', 'draft')]}"/>
|
||||
to
|
||||
<field name="company_size_max" class="oe_inline col-sm-3" attrs="{'required': [('filter_on_size', '=', True)], 'readonly': [('state', '!=', 'draft')]}"/>
|
||||
employees
|
||||
</div>
|
||||
<field name="country_ids" widget="many2many_tags" attrs="{'readonly': [('state', '!=', 'draft')]}" required="True" options="{'no_create': True, 'no_open': True}"/>
|
||||
<field name="state_ids" widget="many2many_tags" attrs="{'invisible': [('country_ids', '=', [])], 'readonly': [('state', '!=', 'draft')]}" domain="[('country_id', 'in', country_ids)]" options="{'no_create': True, 'no_open': True}"/>
|
||||
<field name="technology_ids" widget="many2many_tags" attrs="{'readonly': [('state', '!=', 'draft')]}" options="{'no_create': True, 'no_open': True}"/>
|
||||
</group>
|
||||
<group string="Contacts" attrs="{'invisible': [('search_type', '!=', 'people')]}">
|
||||
<field name="contact_number" attrs="{'readonly': [('state', '!=', 'draft')], 'required': [('search_type', '=', 'people')]}"/>
|
||||
<field name="contact_filter_type" widget="radio" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="preferred_role_id"
|
||||
options="{'no_create_edit': True, 'no_quick_create': True}"
|
||||
attrs="{'invisible': [('contact_filter_type','!=', 'role')], 'required': [('search_type', '=', 'people'), ('contact_filter_type', '=', 'role')], 'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="role_ids" widget="many2many_tags"
|
||||
options="{'color_field': 'color', 'no_create_edit': True, 'no_quick_create': True}"
|
||||
attrs="{'invisible': ['|', ('preferred_role_id','=', False), ('contact_filter_type','!=', 'role')], 'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="seniority_id" options="{'no_create_edit': True, 'no_quick_create': True}"
|
||||
attrs="{'invisible': [('contact_filter_type', '!=', 'seniority')], 'required': [('search_type', '=', 'people'), ('contact_filter_type', '=', 'seniority')], 'readonly': [('state', '!=', 'draft')]}"/>
|
||||
</group>
|
||||
</group>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="alert alert-info" role="alert">
|
||||
Up to
|
||||
<field name="lead_total_credit" class="mb0"/>
|
||||
credits will be consumed to find
|
||||
<field name="lead_number_info" class="mb0"/>
|
||||
companies.
|
||||
<br/>
|
||||
<span attrs="{'invisible': [('search_type', '!=', 'people')]}">
|
||||
Up to
|
||||
<field name="contact_credit_per_company" class="mb0"/>
|
||||
additional credits will be consumed per company to identify contacts.
|
||||
(<field name="contact_total_credit" class="mb0"/>)
|
||||
<br/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="alert alert-info" role="alert"
|
||||
attrs="{'invisible': [('search_type', '!=', 'people')]}">
|
||||
Make sure you know if you have to be GDPR compliant for storing personal data.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
<button string="Submit" name="action_submit" type="object" default_focus="1" class="btn-primary" invisible="not context.get('is_modal')"/>
|
||||
<button string="Cancel" class="btn-secondary" special="cancel" invisible="not context.get('is_modal')"/>
|
||||
</footer>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="crm_iap_lead_mining_request_tree" model="ir.ui.view">
|
||||
<field name="name">crm.iap.lead.mining.request.tree</field>
|
||||
<field name="model">crm.iap.lead.mining.request</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
<field name="lead_number"/>
|
||||
<field name="lead_type"/>
|
||||
<field name="search_type"/>
|
||||
<field name="country_ids" widget="many2many_tags"/>
|
||||
<field name="team_id"/>
|
||||
<field name="user_id"/>
|
||||
<field name="tag_ids" widget="many2many_tags"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="crm_iap_lead_mining_request_search" model="ir.ui.view">
|
||||
<field name="name">crm.iap.lead.mining.request.search</field>
|
||||
<field name="model">crm.iap.lead.mining.request</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Lead Mining Request">
|
||||
<field name="name"/>
|
||||
<field name="team_id"/>
|
||||
<field name="user_id"/>
|
||||
<field name="tag_ids"/>
|
||||
<filter name="state_is_draft" string="Draft" domain="[('state', '=', 'draft')]"/>
|
||||
<filter name="state_is_done" string="Done" domain="[('state', '=', 'done')]"/>
|
||||
<filter name="state_is_error" string="Error" domain="[('state', '=', 'error')]"/>
|
||||
<separator/>
|
||||
<filter name="type_is_lead" string="Leads" domain="[('lead_type', '=', 'lead')]"/>
|
||||
<filter name="type_is_opportunity" string="Opportunities" domain="[('lead_type', '=', 'opportunity')]"/>
|
||||
<group expand="0" string="Group By">
|
||||
<filter string="Type" name="groupby_lead_type" domain="[]" context="{'group_by':'lead_type'}"/>
|
||||
<filter string="Sales Team" name="groupby_team_id" domain="[]" context="{'group_by':'team_id'}"/>
|
||||
<filter string="Salesperson" name="groupby_user_id" domain="[]" context="{'group_by':'user_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="crm_iap_lead_mining_request_action" model="ir.actions.act_window">
|
||||
<field name="name">Lead Mining Requests</field>
|
||||
<field name="res_model">crm.iap.lead.mining.request</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
|
||||
<!-- This menu is display in CRM app when crm_iap_lead is installed-->
|
||||
<menuitem
|
||||
id="crm_menu_lead_generation"
|
||||
name="Lead Generation"
|
||||
parent="crm.crm_menu_config"
|
||||
sequence="20"/>
|
||||
|
||||
<menuitem
|
||||
id="crm_iap_lead_mining_request_menu_action"
|
||||
name="Lead Mining"
|
||||
action="crm_iap_lead_mining_request_action"
|
||||
parent="crm_menu_lead_generation"
|
||||
sequence="0"/>
|
||||
|
||||
</odoo>
|
||||
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<odoo>
|
||||
<record id="crm_iap_opportunity_tree" model="ir.ui.view">
|
||||
<field name="name">crm.opportunity.inherited.tree</field>
|
||||
<field name="model">crm.lead</field>
|
||||
<field name="inherit_id" ref="crm.crm_case_tree_view_oppor" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//tree" position="attributes">
|
||||
<attribute name="js_class">crm_iap_lead_mining_request_tree</attribute>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="crm_iap_opportunity_kanban" model="ir.ui.view">
|
||||
<field name="name">crm.opportunity.inherited.kanban</field>
|
||||
<field name="model">crm.lead</field>
|
||||
<field name="inherit_id" ref="crm.crm_case_kanban_view_leads" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//kanban" position="attributes">
|
||||
<attribute name="js_class">crm_iap_lead_mining_request_kanban</attribute>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="crm_iap_lead_tree" model="ir.ui.view">
|
||||
<field name="name">crm.lead.inherited.tree</field>
|
||||
<field name="model">crm.lead</field>
|
||||
<field name="inherit_id" ref="crm.crm_case_tree_view_leads" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//tree" position="attributes">
|
||||
<attribute name="js_class">crm_iap_lead_mining_request_tree</attribute>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="crm_iap_lead_kanban" model="ir.ui.view">
|
||||
<field name="name">crm.lead.inherited.kanban</field>
|
||||
<field name="model">crm.lead</field>
|
||||
<field name="inherit_id" ref="crm.view_crm_lead_kanban" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//kanban" position="attributes">
|
||||
<attribute name="js_class">crm_iap_lead_mining_request_kanban</attribute>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="res_config_settings_view_form" model="ir.ui.view">
|
||||
<field name="name">res.config.settings.view.form.inherit.crm.iap.lead</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="inherit_id" ref="crm.res_config_settings_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<div id="crm_iap_lead_settings" position="inside">
|
||||
<widget name="iap_buy_more_credits" service_name="reveal"/>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -6,7 +6,6 @@ import itertools
|
||||
import logging
|
||||
import re
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from math import floor, log10
|
||||
|
||||
from odoo import api, fields, models, tools, _
|
||||
from odoo.addons.iap import jsonrpc
|
||||
@@ -316,35 +315,12 @@ class CRMRevealRule(models.Model):
|
||||
'reveal_state': 'not_found'
|
||||
})
|
||||
if result.get('credit_error'):
|
||||
self._notify_no_more_credit()
|
||||
self.env['crm.iap.lead.helpers'].notify_no_more_credit('reveal', self._name, 'reveal.already_notified')
|
||||
return False
|
||||
else:
|
||||
self.env['ir.config_parameter'].sudo().set_param('reveal.already_notified', False)
|
||||
return True
|
||||
|
||||
def _notify_no_more_credit(self):
|
||||
"""
|
||||
Notify about the number of credit.
|
||||
In order to avoid to spam people each hour, an ir.config_parameter is set
|
||||
"""
|
||||
already_notified = self.env['ir.config_parameter'].sudo().get_param('reveal.already_notified', False)
|
||||
if already_notified:
|
||||
return
|
||||
mail_template = self.env.ref('crm_iap_lead.lead_generation_no_credits')
|
||||
iap_account = self.env['iap.account'].search([('service_name', '=', 'reveal')], limit=1)
|
||||
# Get the email address of the creators of the Lead Generation Rules
|
||||
res = self.env['crm.reveal.rule'].search_read([], ['create_uid'])
|
||||
uids = set(r['create_uid'][0] for r in res if r.get('create_uid'))
|
||||
res = self.env['res.users'].search_read([('id', 'in', list(uids))], ['email'])
|
||||
emails = set(r['email'] for r in res if r.get('email'))
|
||||
|
||||
mail_values = mail_template.generate_email(iap_account.id)
|
||||
mail_values['email_to'] = ','.join(emails)
|
||||
mail = self.env['mail.mail'].create(mail_values)
|
||||
mail.send()
|
||||
self.env['ir.config_parameter'].sudo().set_param('reveal.already_notified', True)
|
||||
|
||||
|
||||
def _create_lead_from_response(self, result):
|
||||
""" This method will get response from service and create the lead accordingly """
|
||||
if result['rule_id']:
|
||||
@@ -365,7 +341,7 @@ class CRMRevealRule(models.Model):
|
||||
lead = self.env['crm.lead'].create(lead_vals)
|
||||
lead.message_post_with_view(
|
||||
'crm_iap_lead.lead_message_template',
|
||||
values=self._format_data_for_message_post(result),
|
||||
values=self.env['crm.iap.lead.helpers'].format_data_for_message_post(result['reveal_data'], result.get('people_data')),
|
||||
subtype_id=self.env.ref('mail.mt_note').id
|
||||
)
|
||||
return lead
|
||||
@@ -373,100 +349,19 @@ class CRMRevealRule(models.Model):
|
||||
# Methods responsible for format response data in to valid odoo lead data
|
||||
def _lead_vals_from_response(self, result):
|
||||
self.ensure_one()
|
||||
reveal_data = result['reveal_data']
|
||||
company_data = result['reveal_data']
|
||||
people_data = result.get('people_data')
|
||||
country_id = self.env['res.country'].search([('code', '=', reveal_data['country_code'])]).id
|
||||
website_url = 'https://www.%s' % reveal_data['domain'] if reveal_data['domain'] else False
|
||||
lead_vals = {
|
||||
# Lead vals from rule itself
|
||||
'type': self.lead_type,
|
||||
'team_id': self.team_id.id,
|
||||
'tag_ids': [(6, 0, self.tag_ids.ids)],
|
||||
lead_vals = self.env['crm.iap.lead.helpers'].lead_vals_from_response(self.lead_type, self.team_id.id, self.tag_ids.ids, self.user_id.id, company_data, people_data)
|
||||
|
||||
lead_vals.update({
|
||||
'priority': self.priority,
|
||||
'user_id': self.user_id.id,
|
||||
'reveal_ip': result['ip'],
|
||||
'reveal_rule_id': self.id,
|
||||
'reveal_id': result['clearbit_id'],
|
||||
'referred': 'Website Visitor',
|
||||
# Lead vals from response
|
||||
'name': reveal_data['name'],
|
||||
'reveal_iap_credits': result['credit'],
|
||||
'partner_name': reveal_data['legal_name'] or reveal_data['name'],
|
||||
'email_from': ",".join(reveal_data['email'] or []),
|
||||
'phone': reveal_data['phone'] or (reveal_data['phone_numbers'] and reveal_data['phone_numbers'][0]) or '',
|
||||
'website': website_url,
|
||||
'street': reveal_data['location'],
|
||||
'city': reveal_data['city'],
|
||||
'zip': reveal_data['postal_code'],
|
||||
'country_id': country_id,
|
||||
'state_id': self._find_state_id(reveal_data['state_name'], reveal_data['state_code'], country_id),
|
||||
'description': self._prepare_lead_description(reveal_data),
|
||||
}
|
||||
})
|
||||
|
||||
if self.suffix:
|
||||
lead_vals['name'] = '%s - %s' % (lead_vals['name'], self.suffix)
|
||||
|
||||
# If type is people then add first contact in lead data
|
||||
if people_data:
|
||||
lead_vals.update({
|
||||
'contact_name': people_data[0]['full_name'],
|
||||
'email_from': people_data[0]['email'],
|
||||
'function': people_data[0]['title'],
|
||||
})
|
||||
return lead_vals
|
||||
|
||||
def _find_state_id(self, state_code, state_name, country_id):
|
||||
state_id = self.env['res.country.state'].search([('code', '=', state_code), ('country_id', '=', country_id)])
|
||||
if state_id:
|
||||
return state_id.id
|
||||
return False
|
||||
|
||||
def _prepare_lead_description(self, reveal_data):
|
||||
description = ''
|
||||
if reveal_data['sector']:
|
||||
description += reveal_data['sector']
|
||||
if reveal_data['website_title']:
|
||||
description += '\n' + reveal_data['website_title']
|
||||
if reveal_data['twitter_bio']:
|
||||
description += '\n' + "Twitter Bio: " + reveal_data['twitter_bio']
|
||||
if reveal_data['twitter_followers']:
|
||||
description += ('\nTwitter %s followers, %s \n') % (reveal_data['twitter_followers'], reveal_data['twitter_location'] or '')
|
||||
|
||||
numbers = ['raised', 'market_cap', 'employees', 'estimated_annual_revenue']
|
||||
millnames = ['', ' K', ' M', ' B', 'T']
|
||||
|
||||
def millify(n):
|
||||
try:
|
||||
n = float(n)
|
||||
millidx = max(0, min(len(millnames) - 1, int(floor(0 if n == 0 else log10(abs(n)) / 3))))
|
||||
return '{:.0f}{}'.format(n / 10**(3 * millidx), millnames[millidx])
|
||||
except Exception:
|
||||
return n
|
||||
|
||||
for key in numbers:
|
||||
if reveal_data.get(key):
|
||||
description += ' %s : %s,' % (key.replace('_', ' ').title(), millify(reveal_data[key]))
|
||||
return description
|
||||
|
||||
def _format_data_for_message_post(self, result):
|
||||
reveal_data = result['reveal_data']
|
||||
people_data = result.get('people_data')
|
||||
log_data = {
|
||||
'twitter': reveal_data['twitter'],
|
||||
'description': reveal_data['description'],
|
||||
'logo': reveal_data['logo'],
|
||||
'name': reveal_data['name'],
|
||||
'phone_numbers': reveal_data['phone_numbers'],
|
||||
'facebook': reveal_data['facebook'],
|
||||
'linkedin': reveal_data['linkedin'],
|
||||
'crunchbase': reveal_data['crunchbase'],
|
||||
'tech': [t.replace('_', ' ').title() for t in reveal_data['tech']],
|
||||
'people_data': people_data,
|
||||
}
|
||||
timezone = result['ip_time_zone'] or reveal_data['timezone']
|
||||
if timezone:
|
||||
log_data.update({
|
||||
'timezone': timezone.replace('_', ' ').title(),
|
||||
'timezone_url': reveal_data['timezone_url'],
|
||||
})
|
||||
return log_data
|
||||
|
||||
@@ -157,7 +157,9 @@
|
||||
<menuitem
|
||||
id="crm_reveal_rule_menu_action"
|
||||
action="crm_reveal_rule_action"
|
||||
parent="crm.crm_menu_config" name="Visits to Leads"/>
|
||||
parent="crm_iap_lead.crm_menu_lead_generation"
|
||||
name="Visits to Leads"
|
||||
sequence="5"/>
|
||||
|
||||
<menuitem
|
||||
id="crm_reveal_view_menu_action"
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="res_config_settings_view_form" model="ir.ui.view">
|
||||
<field name="name">res.config.settings.view.form.inherit.crm.reveal</field>
|
||||
<field name="name">res.config.settings.view.form.inherit.crm.iap.lead.website</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="inherit_id" ref="crm.res_config_settings_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<div id="crm_reveal_settings" position="inside">
|
||||
<div id="crm_iap_lead_website_settings" position="inside">
|
||||
<widget name="iap_buy_more_credits" service_name="reveal"/>
|
||||
</div>
|
||||
</field>
|
||||
|
||||
@@ -68,7 +68,7 @@ def jsonrpc(url, method='call', params=None, timeout=15):
|
||||
raise e
|
||||
return response.get('result')
|
||||
except (ValueError, requests.exceptions.ConnectionError, requests.exceptions.MissingSchema, requests.exceptions.Timeout, requests.exceptions.HTTPError) as e:
|
||||
raise exceptions.AccessError('The url that this service requested returned an error. Please contact the author the app. The url it tried to contact was ' + url)
|
||||
raise exceptions.AccessError('The url that this service requested returned an error. Please contact the author of the app. The url it tried to contact was ' + url)
|
||||
|
||||
#----------------------------------------------------------
|
||||
# Helpers for proxy
|
||||
|
||||
Reference in New Issue
Block a user