[IMP] crm, website_crm: replace support of activities
crm.lead model now supports activities. Filters have been added to ease their management. Mail activities replace the old crm.activity model. All code related to crm.activity is then removed, including views and custom widget. Standard activities feature is now used widely in Odoo addons and replace those custom activities. A small update is required in website_crm_partner_assign. Now the portal user can only update or create its own activities aka assigned to him. If he has an activity assigned to him it is displayed in the opportunity website view. If not editing the opportunity will create a new activity assigned to him.
This commit is contained in:
committed by
Thibault Delavallée
parent
4aa3f3f94e
commit
87e457158e
@@ -41,7 +41,6 @@ Dashboard for CRM will include:
|
||||
'web_tour',
|
||||
],
|
||||
'data': [
|
||||
'data/crm_activity_data.xml',
|
||||
'data/crm_data.xml',
|
||||
'data/crm_stage_data.xml',
|
||||
'data/sales_config_settings_data.xml',
|
||||
@@ -53,7 +52,6 @@ Dashboard for CRM will include:
|
||||
'security/ir.model.access.csv',
|
||||
|
||||
'wizard/base_partner_merge_views.xml',
|
||||
'wizard/crm_activity_log_views.xml',
|
||||
'wizard/crm_lead_lost_views.xml',
|
||||
'wizard/crm_lead_to_opportunity_views.xml',
|
||||
'wizard/crm_merge_opportunities_views.xml',
|
||||
@@ -64,7 +62,6 @@ Dashboard for CRM will include:
|
||||
|
||||
'views/crm_templates.xml',
|
||||
'views/crm_views.xml',
|
||||
'views/crm_activity_views.xml',
|
||||
'views/crm_stage_views.xml',
|
||||
'views/crm_lead_views.xml',
|
||||
'views/calendar_views.xml',
|
||||
@@ -74,8 +71,8 @@ Dashboard for CRM will include:
|
||||
],
|
||||
'demo': [
|
||||
'data/crm_demo.xml',
|
||||
'data/mail_activity_demo.xml',
|
||||
'data/crm_lead_demo.xml',
|
||||
'data/crm_activity_demo.xml',
|
||||
'data/base_action_rule_demo.xml',
|
||||
],
|
||||
'css': ['static/src/css/crm.css'],
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="0">
|
||||
|
||||
<record id="crm_activity_data_email" model="crm.activity">
|
||||
<field name="name">Email</field>
|
||||
</record>
|
||||
<record id="crm_activity_data_call" model="crm.activity">
|
||||
<field name="name">Call</field>
|
||||
</record>
|
||||
<record id="crm_activity_data_meeting" model="crm.activity">
|
||||
<field name="name">Task</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -1,37 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
|
||||
<record id="crm_activity_demo_followup_quote" model="crm.activity">
|
||||
<field name="name">Follow-up Quote</field>
|
||||
<field name="description">Follow-up quote</field>
|
||||
<field name="days">30</field>
|
||||
</record>
|
||||
|
||||
<record id="crm_activity_demo_make_quote" model="crm.activity">
|
||||
<field name="name">Make Quote</field>
|
||||
<field name="description">Send a quotation</field>
|
||||
<field name="days">15</field>
|
||||
<field name="recommended_activity_ids" eval="[(6,0, [ref('crm.crm_activity_demo_followup_quote')])]"/>
|
||||
</record>
|
||||
|
||||
<record id="crm_activity_demo_call_demo" model="crm.activity">
|
||||
<field name="name">Call for Demo</field>
|
||||
<field name="days">10</field>
|
||||
<field name="description">Call for a demo</field>
|
||||
<field name="recommended_activity_ids" eval="[(6, 0, [ref('crm.crm_activity_demo_make_quote')])]"/>
|
||||
</record>
|
||||
|
||||
<record id="crm_activity_data_call" model="crm.activity">
|
||||
<field name="days">5</field>
|
||||
<field name="recommended_activity_ids" eval="[(6, 0, [ref('crm.crm_activity_data_email')])]"/>
|
||||
</record>
|
||||
|
||||
<record id="crm_activity_data_meeting" model="crm.activity">
|
||||
<field name="recommended_activity_ids" eval="[(6, 0, [ref('crm_activity_data_call'), ref('crm_activity_data_email')])]"/>
|
||||
<field name="days">15</field>
|
||||
</record>
|
||||
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -374,9 +374,6 @@ Andrew</p>]]></field>
|
||||
<field name="tag_ids" eval="[(6, 0, [categ_oppor1])]"/>
|
||||
<field name="priority">1</field>
|
||||
<field name="date_deadline" eval="(DateTime.today() + relativedelta(weeks=2)).strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="next_activity_id" ref="crm_activity_data_meeting"/>
|
||||
<field name="date_action" eval="(DateTime.today() + relativedelta(days=3)).strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="title_action">Meeting to go over pricing information.</field>
|
||||
<field name="team_id" ref="sales_team.team_sales_department"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="stage_id" ref="crm.stage_lead1"/>
|
||||
@@ -402,9 +399,6 @@ Andrew</p>]]></field>
|
||||
<field name="tag_ids" eval="[(6, 0, [categ_oppor2])]"/>
|
||||
<field name="priority">2</field>
|
||||
<field name="date_deadline" eval="(DateTime.today() + relativedelta(weeks=2)).strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="next_activity_id" ref="crm_activity_data_email"/>
|
||||
<field name="date_action" eval="(DateTime.today() + relativedelta(days=3)).strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="title_action">Send Catalog by Email</field>
|
||||
<field name="team_id" ref="sales_team.crm_team_1"/>
|
||||
<field name="user_id" ref="base.user_demo"/>
|
||||
<field name="stage_id" ref="crm.stage_lead1"/>
|
||||
@@ -427,9 +421,6 @@ Andrew</p>]]></field>
|
||||
<field name="tag_ids" eval="[(6, 0, [categ_oppor1])]"/>
|
||||
<field name="priority">1</field>
|
||||
<field name="date_deadline" eval="(DateTime.today() + relativedelta(weeks=1)).strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="next_activity_id" ref="crm_activity_data_call"/>
|
||||
<field name="date_action" eval="(DateTime.today() + relativedelta(days=1)).strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="title_action">Call to get system requirements</field>
|
||||
<field name="team_id" ref="sales_team.team_sales_department"/>
|
||||
<field name="user_id" ref="base.user_demo"/>
|
||||
<field name="stage_id" ref="crm.stage_lead2"/>
|
||||
@@ -516,9 +507,6 @@ Andrew</p>]]></field>
|
||||
<field name="tag_ids" eval="[(6, 0, [categ_oppor5])]"/>
|
||||
<field name="priority">2</field>
|
||||
<field name="date_deadline" eval="(DateTime.today() + relativedelta(weeks=1)).strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="next_activity_id" ref="crm_activity_data_meeting"/>
|
||||
<field name="date_action" eval="(DateTime.today() + relativedelta(days=2)).strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="title_action">Convert to quote</field>
|
||||
<field name="team_id" ref="sales_team.team_sales_department"/>
|
||||
<field name="user_id" ref="base.user_demo"/>
|
||||
<field name="stage_id" ref="crm.stage_lead2"/>
|
||||
@@ -542,9 +530,6 @@ Andrew</p>]]></field>
|
||||
<field name="tag_ids" eval="[(6, 0, [categ_oppor3,categ_oppor4])]"/>
|
||||
<field name="priority">1</field>
|
||||
<field name="date_deadline" eval="(DateTime.today() + relativedelta(days=3)).strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="next_activity_id" ref="crm_activity_data_email"/>
|
||||
<field name="date_action" eval="(DateTime.today() + relativedelta(days=-1)).strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="title_action">Send our service pricelist</field>
|
||||
<field name="team_id" ref="sales_team.crm_team_1"/>
|
||||
<field name="user_id" ref="base.user_demo"/>
|
||||
<field name="stage_id" ref="crm.stage_lead2"/>
|
||||
@@ -577,9 +562,6 @@ Andrew</p>]]></field>
|
||||
<field name="tag_ids" eval="[(6, 0, [categ_oppor4,categ_oppor6])]"/>
|
||||
<field name="priority">1</field>
|
||||
<field name="date_deadline" eval="(DateTime.today() + relativedelta(weeks=3)).strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="next_activity_id" ref="crm_activity_data_call"/>
|
||||
<field name="date_action" eval="(DateTime.today() + relativedelta(days=1)).strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="title_action">Call to get training needs</field>
|
||||
<field name="team_id" ref="sales_team.crm_team_1"/>
|
||||
<field name="user_id" ref="base.user_demo"/>
|
||||
<field name="stage_id" ref="crm.stage_lead2"/>
|
||||
@@ -628,9 +610,6 @@ Andrew</p>]]></field>
|
||||
<field name="tag_ids" eval="[(6, 0, [categ_oppor1])]"/>
|
||||
<field name="priority">1</field>
|
||||
<field name="date_deadline" eval="(DateTime.today() + relativedelta(weeks=1)).strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="next_activity_id" ref="crm_activity_data_call"/>
|
||||
<field name="date_action" eval="(DateTime.today() + relativedelta(days=-2)).strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="title_action">Followup on the proposal</field>
|
||||
<field name="team_id" ref="sales_team.team_sales_department"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="stage_id" ref="crm.stage_lead3"/>
|
||||
@@ -653,7 +632,6 @@ Andrew</p>]]></field>
|
||||
<field name="phone">+1 312 349 2324</field>
|
||||
<field name="tag_ids" eval="[(6, 0, [categ_oppor4,categ_oppor8])]"/>
|
||||
<field name="priority">2</field>
|
||||
<field name="next_activity_id" ref="crm_activity_data_call"/>
|
||||
<field name="team_id" ref="sales_team.team_sales_department"/>
|
||||
<field name="user_id" ref="base.user_demo"/>
|
||||
<field name="stage_id" ref="crm.stage_lead3"/>
|
||||
@@ -672,7 +650,6 @@ Andrew</p>]]></field>
|
||||
<field name="street">Cannon Hill Park</field>
|
||||
<field name="tag_ids" eval="[(6, 0, [categ_oppor7])]"/>
|
||||
<field name="priority">2</field>
|
||||
<field name="next_activity_id" ref="crm_activity_data_meeting"/>
|
||||
<field name="team_id" ref="sales_team.team_sales_department"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="stage_id" ref="crm.stage_lead3"/>
|
||||
@@ -691,7 +668,6 @@ Andrew</p>]]></field>
|
||||
<field name="partner_id" ref="base.res_partner_12"/>
|
||||
<field name="tag_ids" eval="[(6, 0, [categ_oppor3])]"/>
|
||||
<field name="priority">1</field>
|
||||
<field name="next_activity_id" ref="crm_activity_data_email"/>
|
||||
<field name="team_id" ref="sales_team.crm_team_1"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="stage_id" ref="crm.stage_lead3"/>
|
||||
@@ -708,8 +684,6 @@ Andrew</p>]]></field>
|
||||
<field name="partner_id" ref="base.res_partner_18"/>
|
||||
<field name="priority">0</field>
|
||||
<field name="tag_ids" eval="[(6, 0, [categ_oppor3])]"/>
|
||||
<field name="next_activity_id" ref="crm_activity_data_email"/>
|
||||
<field name="date_action" eval="(DateTime.today() + relativedelta(days=1)).strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="team_id" ref="sales_team.crm_team_1"/>
|
||||
<field name="user_id" ref="base.user_demo"/>
|
||||
<field name="stage_id" ref="crm.stage_lead3"/>
|
||||
@@ -728,8 +702,6 @@ Andrew</p>]]></field>
|
||||
<field name="city">Lima</field>
|
||||
<field name="priority">0</field>
|
||||
<field name="tag_ids" eval="[(6, 0, [categ_oppor7])]"/>
|
||||
<field name="next_activity_id" ref="crm_activity_data_email"/>
|
||||
<field name="date_action" eval="(DateTime.today() + relativedelta(days=2)).strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="team_id" ref="sales_team.crm_team_1"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="stage_id" ref="crm.stage_lead3"/>
|
||||
@@ -753,9 +725,6 @@ Andrew</p>]]></field>
|
||||
<field name="street2">C1414CMS Capital Federal</field>
|
||||
<field name="priority">2</field>
|
||||
<field name="tag_ids" eval="[(6, 0, [categ_oppor4])]"/>
|
||||
<field name="next_activity_id" ref="crm_activity_data_call"/>
|
||||
<field name="date_action" eval="(DateTime.today() + relativedelta(days=0)).strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="title_action">Conf call with technical service</field>
|
||||
<field name="team_id" ref="sales_team.team_sales_department"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="stage_id" ref="crm.stage_lead3"/>
|
||||
@@ -778,9 +747,6 @@ Andrew</p>]]></field>
|
||||
<field name="priority">2</field>
|
||||
<field name="tag_ids" eval="[(6, 0, [categ_oppor2])]"/>
|
||||
<field name="date_deadline" eval="(DateTime.today() + relativedelta(days=6)).strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="next_activity_id" ref="crm_activity_data_email"/>
|
||||
<field name="date_action" eval="(DateTime.today() + relativedelta(days=0)).strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="title_action">Send Catalog by Email</field>
|
||||
<field name="team_id" ref="sales_team.crm_team_1"/>
|
||||
<field name="user_id" ref="base.user_demo"/>
|
||||
<field name="stage_id" ref="crm.stage_lead3"/>
|
||||
@@ -804,9 +770,6 @@ Andrew</p>]]></field>
|
||||
<field name="priority">2</field>
|
||||
<field name="tag_ids" eval="[(6, 0, [categ_oppor2])]"/>
|
||||
<field name="date_deadline" eval="(DateTime.today() + relativedelta(days=6)).strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="next_activity_id" ref="crm_activity_data_email"/>
|
||||
<field name="date_action" eval="(DateTime.today() + relativedelta(days=0)).strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="title_action">Send Catalog by Email</field>
|
||||
<field name="team_id" ref="sales_team.team_sales_department"/>
|
||||
<field name="user_id" ref="base.user_demo"/>
|
||||
<field name="stage_id" ref="crm.stage_lead3"/>
|
||||
@@ -817,5 +780,100 @@ Andrew</p>]]></field>
|
||||
eval="[ref('crm_case_20'), ref('crm_case_23'), ref('crm_case_27')],
|
||||
{'install_mode': True}"/>
|
||||
|
||||
<!-- Activities -->
|
||||
<record id="activity_1" model="mail.activity">
|
||||
<field name="res_id" ref="crm.crm_case_13" />
|
||||
<field name="res_model_id" ref="crm.model_crm_lead"/>
|
||||
<field name="activity_type_id" ref="mail.mail_activity_data_call" />
|
||||
<field name="summary">Meeting to go over pricing information.</field>
|
||||
<field name="date_deadline" eval="(DateTime.today() + relativedelta(days=3)).strftime('%Y-%m-%d %H:%M')"/>
|
||||
</record>
|
||||
<record id="activity_2" model="mail.activity">
|
||||
<field name="res_id" ref="crm.crm_case_14" />
|
||||
<field name="res_model_id" ref="crm.model_crm_lead"/>
|
||||
<field name="activity_type_id" ref="mail.mail_activity_data_email"/>
|
||||
<field name="date_deadline" eval="(DateTime.today() + relativedelta(days=3)).strftime('%Y-%m-%d %H:%M')" />
|
||||
<field name="summary">Send Catalog by Email</field>
|
||||
</record>
|
||||
<record id="activity_3" model="mail.activity">
|
||||
<field name="res_id" ref="crm.crm_case_15" />
|
||||
<field name="res_model_id" ref="crm.model_crm_lead"/>
|
||||
<field name="activity_type_id" ref="mail.mail_activity_data_call"/>
|
||||
<field name="date_deadline" eval="(DateTime.today() + relativedelta(days=1)).strftime('%Y-%m-%d %H:%M')" />
|
||||
<field name="summary">Call to get system requirements</field>
|
||||
</record>
|
||||
<record id="activity_4" model="mail.activity">
|
||||
<field name="res_id" ref="crm.crm_case_16" />
|
||||
<field name="res_model_id" ref="crm.model_crm_lead"/>
|
||||
<field name="activity_type_id" ref="mail.mail_activity_data_call"/>
|
||||
<field name="date_deadline" eval="(DateTime.today() + relativedelta(days=2)).strftime('%Y-%m-%d %H:%M')" />
|
||||
<field name="summary">Convert to quote</field>
|
||||
</record>
|
||||
<record id="activity_5" model="mail.activity">
|
||||
<field name="res_id" ref="crm.crm_case_17" />
|
||||
<field name="res_model_id" ref="crm.model_crm_lead"/>
|
||||
<field name="activity_type_id" ref="mail.mail_activity_data_email"/>
|
||||
<field name="date_deadline" eval="(DateTime.today() + relativedelta(days=-1)).strftime('%Y-%m-%d %H:%M')" />
|
||||
<field name="summary">Send our service pricelist</field>
|
||||
</record>
|
||||
<record id="activity_6" model="mail.activity">
|
||||
<field name="res_id" ref="crm.crm_case_18" />
|
||||
<field name="res_model_id" ref="crm.model_crm_lead"/>
|
||||
<field name="activity_type_id" ref="mail.mail_activity_data_call"/>
|
||||
<field name="date_deadline" eval="(DateTime.today() + relativedelta(days=1)).strftime('%Y-%m-%d %H:%M')" />
|
||||
<field name="summary">Call to get training needs</field>
|
||||
</record>
|
||||
<record id="activity_7" model="mail.activity">
|
||||
<field name="res_id" ref="crm.crm_case_19" />
|
||||
<field name="res_model_id" ref="crm.model_crm_lead"/>
|
||||
<field name="activity_type_id" ref="mail.mail_activity_data_call"/>
|
||||
<field name="date_deadline" eval="(DateTime.today() + relativedelta(days=-2)).strftime('%Y-%m-%d %H:%M')" />
|
||||
<field name="summary">Followup on the proposal</field>
|
||||
</record>
|
||||
<record id="activity_8" model="mail.activity">
|
||||
<field name="res_id" ref="crm.crm_case_20" />
|
||||
<field name="res_model_id" ref="crm.model_crm_lead"/>
|
||||
<field name="activity_type_id" ref="mail.mail_activity_data_call"/>
|
||||
<field name="date_deadline" eval="(DateTime.today() + relativedelta(days=1)).strftime('%Y-%m-%d %H:%M')" />
|
||||
</record>
|
||||
<record id="activity_9" model="mail.activity">
|
||||
<field name="res_id" ref="crm.crm_case_21" />
|
||||
<field name="res_model_id" ref="crm.model_crm_lead"/>
|
||||
<field name="activity_type_id" ref="mail.mail_activity_data_call"/>
|
||||
<field name="date_deadline" eval="(DateTime.today() + relativedelta(days=-1)).strftime('%Y-%m-%d %H:%M')" />
|
||||
</record>
|
||||
<record id="activity_10" model="mail.activity">
|
||||
<field name="res_id" ref="crm.crm_case_22" />
|
||||
<field name="res_model_id" ref="crm.model_crm_lead"/>
|
||||
<field name="activity_type_id" ref="mail.mail_activity_data_email"/>
|
||||
<field name="date_deadline" eval="(DateTime.today() + relativedelta(days=-2)).strftime('%Y-%m-%d %H:%M')" />
|
||||
</record>
|
||||
<record id="activity_11" model="mail.activity">
|
||||
<field name="res_id" ref="crm.crm_case_23" />
|
||||
<field name="res_model_id" ref="crm.model_crm_lead"/>
|
||||
<field name="activity_type_id" ref="mail.mail_activity_data_email"/>
|
||||
<field name="date_deadline" eval="(DateTime.today() + relativedelta(days=1)).strftime('%Y-%m-%d %H:%M')" />
|
||||
</record>
|
||||
<record id="activity_12" model="mail.activity">
|
||||
<field name="res_id" ref="crm.crm_case_24" />
|
||||
<field name="res_model_id" ref="crm.model_crm_lead"/>
|
||||
<field name="activity_type_id" ref="mail.mail_activity_data_email"/>
|
||||
<field name="date_deadline" eval="(DateTime.today() + relativedelta(days=2)).strftime('%Y-%m-%d %H:%M')" />
|
||||
</record>
|
||||
<record id="activity_13" model="mail.activity">
|
||||
<field name="res_id" ref="crm.crm_case_25" />
|
||||
<field name="res_model_id" ref="crm.model_crm_lead"/>
|
||||
<field name="activity_type_id" ref="mail.mail_activity_data_call"/>
|
||||
<field name="date_deadline" eval="(DateTime.today() + relativedelta(days=0)).strftime('%Y-%m-%d %H:%M')" />
|
||||
<field name="summary">Conf call with technical service</field>
|
||||
</record>
|
||||
<record id="activity_14" model="mail.activity">
|
||||
<field name="res_id" ref="crm.crm_case_26" />
|
||||
<field name="res_model_id" ref="crm.model_crm_lead"/>
|
||||
<field name="activity_type_id" ref="mail.mail_activity_data_email"/>
|
||||
<field name="date_deadline" eval="(DateTime.today() + relativedelta(days=0)).strftime('%Y-%m-%d %H:%M')" />
|
||||
<field name="summary">Send Catalog by Email</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0"?>
|
||||
<odoo>
|
||||
<record id="mail_activity_demo_followup_quote" model="mail.activity.type">
|
||||
<field name="name">Follow-up Quote</field>
|
||||
<field name="icon">fa-file-text-o</field>
|
||||
<field name="res_model_id" ref="crm.model_crm_lead"/>
|
||||
<field name="summary">Follow-up quote</field>
|
||||
<field name="days">30</field>
|
||||
</record>
|
||||
<record id="mail_activity_demo_make_quote" model="mail.activity.type">
|
||||
<field name="name">Make Quote</field>
|
||||
<field name="icon">fa-file-text-o</field>
|
||||
<field name="res_model_id" ref="crm.model_crm_lead"/>
|
||||
<field name="summary">Send a quotation</field>
|
||||
<field name="days">15</field>
|
||||
</record>
|
||||
<record id="mail_activity_demo_call_demo" model="mail.activity.type">
|
||||
<field name="name">Call for Demo</field>
|
||||
<field name="icon">fa-phone</field>
|
||||
<field name="res_model_id" ref="crm.model_crm_lead"/>
|
||||
<field name="days">10</field>
|
||||
<field name="summary">Call for a demo</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
import res_users
|
||||
import calendar
|
||||
import crm_activity
|
||||
import crm_lead
|
||||
import crm_stage
|
||||
import crm_team
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class CrmActivity(models.Model):
|
||||
''' CrmActivity is a model introduced in Odoo v9 that models activities
|
||||
performed in CRM, like phone calls, sending emails, making demonstrations,
|
||||
... Users are able to configure their custom activities.
|
||||
|
||||
Each activity can configure recommended next activities. This allows to model
|
||||
light custom workflows. This way sales manager can configure their crm
|
||||
workflow that salepersons will use in their daily job.
|
||||
|
||||
CrmActivity inherits from mail.message.subtype. This allows users to follow
|
||||
some activities through subtypes. Each activity will generate messages with
|
||||
the matching subtypes, allowing reporting and statistics computation based
|
||||
on mail.message.subtype model. '''
|
||||
|
||||
_name = 'crm.activity'
|
||||
_description = 'CRM Activity'
|
||||
_inherits = {'mail.message.subtype': 'subtype_id'}
|
||||
_rec_name = 'name'
|
||||
_order = "sequence"
|
||||
|
||||
days = fields.Integer('Number of days', default=0,
|
||||
help='Number of days before executing the action, allowing you to plan the date of the action.')
|
||||
sequence = fields.Integer('Sequence', default=0)
|
||||
team_id = fields.Many2one('crm.team', string='Sales Team')
|
||||
subtype_id = fields.Many2one('mail.message.subtype', string='Message Subtype', required=True, ondelete='cascade')
|
||||
recommended_activity_ids = fields.Many2many(
|
||||
'crm.activity', 'crm_activity_rel', 'activity_id', 'recommended_id',
|
||||
string='Recommended Next Activities')
|
||||
preceding_activity_ids = fields.Many2many(
|
||||
'crm.activity', 'crm_activity_rel', 'recommended_id', 'activity_id',
|
||||
string='Preceding Activities')
|
||||
|
||||
# setting a default value on inherited fields is a bit involved
|
||||
res_model = fields.Char('Model', related='subtype_id.res_model', inherited=True, default='crm.lead')
|
||||
internal = fields.Boolean('Internal Only', related='subtype_id.internal', inherited=True, default=True)
|
||||
default = fields.Boolean('Default', related='subtype_id.default', inherited=True, default=False)
|
||||
|
||||
@api.multi
|
||||
def unlink(self):
|
||||
activities = self.search([('subtype_id', '=', self.subtype_id.id)])
|
||||
# to ensure that the subtype is only linked the current activity
|
||||
if len(activities) == 1:
|
||||
self.subtype_id.unlink()
|
||||
return super(CrmActivity, self).unlink()
|
||||
@@ -52,11 +52,10 @@ CRM_LEAD_FIELDS_TO_MERGE = [
|
||||
|
||||
|
||||
class Lead(FormatAddress, models.Model):
|
||||
|
||||
_name = "crm.lead"
|
||||
_description = "Lead/Opportunity"
|
||||
_order = "priority desc,date_action,id desc"
|
||||
_inherit = ['mail.thread', 'utm.mixin']
|
||||
_order = "priority desc,activity_date_deadline,id desc"
|
||||
_inherit = ['mail.thread', 'mail.activity.mixin', 'utm.mixin']
|
||||
_mail_mass_mailing = _('Leads / Opportunities')
|
||||
|
||||
def _default_probability(self):
|
||||
@@ -116,12 +115,6 @@ class Lead(FormatAddress, models.Model):
|
||||
probability = fields.Float('Probability', group_operator="avg", default=lambda self: self._default_probability())
|
||||
planned_revenue = fields.Float('Expected Revenue', track_visibility='always')
|
||||
date_deadline = fields.Date('Expected Closing', help="Estimate of the date on which the opportunity will be won.")
|
||||
|
||||
# CRM Actions
|
||||
next_activity_id = fields.Many2one("crm.activity", string="Next Activity", index=True)
|
||||
date_action = fields.Date('Next Activity Date', index=True)
|
||||
title_action = fields.Char('Next Activity Summary')
|
||||
|
||||
color = fields.Integer('Color Index', default=0)
|
||||
partner_address_name = fields.Char('Partner Contact Name', related='partner_id.name', readonly=True)
|
||||
partner_address_email = fields.Char('Partner Contact Email', related='partner_id.email', readonly=True)
|
||||
@@ -170,8 +163,8 @@ class Lead(FormatAddress, models.Model):
|
||||
today = date.today()
|
||||
for lead in self:
|
||||
kanban_state = 'grey'
|
||||
if lead.date_action:
|
||||
lead_date = fields.Date.from_string(lead.date_action)
|
||||
if lead.activity_date_deadline:
|
||||
lead_date = fields.Date.from_string(lead.activity_date_deadline)
|
||||
if lead_date >= today:
|
||||
kanban_state = 'green'
|
||||
else:
|
||||
@@ -270,18 +263,6 @@ class Lead(FormatAddress, models.Model):
|
||||
if self.state_id:
|
||||
self.country_id = self.state_id.country_id.id
|
||||
|
||||
@api.onchange('next_activity_id')
|
||||
def _onchange_next_activity_id(self):
|
||||
values = {
|
||||
'title_action': False,
|
||||
'date_action': False,
|
||||
}
|
||||
if self.next_activity_id:
|
||||
values['title_action'] = self.next_activity_id.description
|
||||
if self.next_activity_id.days:
|
||||
values['date_action'] = fields.Datetime.to_string(datetime.now() + timedelta(days=self.next_activity_id.days))
|
||||
self.update(values)
|
||||
|
||||
# ----------------------------------------
|
||||
# ORM override (CRUD, fields_view_get, ...)
|
||||
# ----------------------------------------
|
||||
@@ -934,13 +915,13 @@ class Lead(FormatAddress, models.Model):
|
||||
if date_deadline < date.today():
|
||||
result['closing']['overdue'] += 1
|
||||
# Next activities
|
||||
if opp.next_activity_id and opp.date_action:
|
||||
date_action = fields.Date.from_string(opp.date_action)
|
||||
if date_action == date.today():
|
||||
for activity in opp.activity_ids:
|
||||
date_deadline = fields.Date.from_string(activity.date_deadline)
|
||||
if date_deadline == date.today():
|
||||
result['activity']['today'] += 1
|
||||
if date.today() <= date_action <= date.today() + timedelta(days=7):
|
||||
if date.today() <= date_deadline <= date.today() + timedelta(days=7):
|
||||
result['activity']['next_7_days'] += 1
|
||||
if date_action < date.today():
|
||||
if date_deadline < date.today():
|
||||
result['activity']['overdue'] += 1
|
||||
# Won in Opportunities
|
||||
if opp.date_closed:
|
||||
@@ -957,19 +938,19 @@ class Lead(FormatAddress, models.Model):
|
||||
# crm.activity is a very messy model so we need to do that in order to retrieve the actions done.
|
||||
self._cr.execute("""
|
||||
SELECT
|
||||
m.id,
|
||||
m.subtype_id,
|
||||
m.date,
|
||||
l.user_id,
|
||||
l.type
|
||||
FROM mail_message M
|
||||
LEFT JOIN crm_lead L ON (M.res_id = L.id)
|
||||
INNER JOIN crm_activity A ON (M.subtype_id = A.subtype_id)
|
||||
mail_message.id,
|
||||
mail_message.subtype_id,
|
||||
mail_message.mail_activity_type_id,
|
||||
mail_message.date,
|
||||
crm_lead.user_id,
|
||||
crm_lead.type
|
||||
FROM mail_message
|
||||
LEFT JOIN crm_lead ON (mail_message.res_id = crm_lead.id)
|
||||
INNER JOIN mail_activity_type activity_type ON (mail_message.mail_activity_type_id = activity_type.id)
|
||||
WHERE
|
||||
(M.model = 'crm.lead') AND (L.user_id = %s) AND (L.type = 'opportunity')
|
||||
(mail_message.model = 'crm.lead') AND (crm_lead.user_id = %s) AND (crm_lead.type = 'opportunity')
|
||||
""", (self._uid,))
|
||||
activites_done = self._cr.dictfetchall()
|
||||
|
||||
for activity in activites_done:
|
||||
if activity['date']:
|
||||
date_act = fields.Date.from_string(activity['date'])
|
||||
|
||||
@@ -18,7 +18,8 @@ class ActivityReport(models.Model):
|
||||
team_id = fields.Many2one('crm.team', 'Sales Team', readonly=True)
|
||||
lead_id = fields.Many2one('crm.lead', "Lead", readonly=True)
|
||||
subject = fields.Char('Summary', readonly=True)
|
||||
subtype_id = fields.Many2one('mail.message.subtype', 'Activity', readonly=True)
|
||||
subtype_id = fields.Many2one('mail.message.subtype', 'Subtype', readonly=True)
|
||||
mail_activity_type_id = fields.Many2one('mail.activity.type', 'Activity Type', readonly=True)
|
||||
country_id = fields.Many2one('res.country', 'Country', readonly=True)
|
||||
company_id = fields.Many2one('res.company', 'Company', readonly=True)
|
||||
stage_id = fields.Many2one('crm.stage', 'Stage', readonly=True)
|
||||
@@ -37,6 +38,7 @@ class ActivityReport(models.Model):
|
||||
select
|
||||
m.id,
|
||||
m.subtype_id,
|
||||
m.mail_activity_type_id,
|
||||
m.author_id,
|
||||
m.date,
|
||||
m.subject,
|
||||
@@ -57,5 +59,5 @@ class ActivityReport(models.Model):
|
||||
on
|
||||
(m.res_id = l.id)
|
||||
WHERE
|
||||
(m.model = 'crm.lead')
|
||||
(m.model = 'crm.lead' AND m.mail_activity_type_id IS NOT NULL)
|
||||
)""")
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<field name="model">crm.activity.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph string="Activities Analysis" stacked="True">
|
||||
<field name="subtype_id" type="col"/>
|
||||
<field name="mail_activity_type_id" type="col"/>
|
||||
<field name="date" interval="month" type="row"/>
|
||||
</graph>
|
||||
</field>
|
||||
@@ -17,7 +17,7 @@
|
||||
<field name="model">crm.activity.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<pivot string="Activities Analysis" disable_linking="True">
|
||||
<field name="subtype_id" type="col"/>
|
||||
<field name="mail_activity_type_id" type="col"/>
|
||||
<field name="date" interval="month" type="row"/>
|
||||
</pivot>
|
||||
</field>
|
||||
@@ -28,7 +28,7 @@
|
||||
<field name="model">crm.activity.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Activities Analysis">
|
||||
<filter string="My Activities" name="my_activity" domain="[('user_id', '=', uid)]"/>
|
||||
<filter string="My Activities" name="activities_my" domain="[('user_id', '=', uid)]"/>
|
||||
<separator/>
|
||||
<filter name="lead" string="Leads" domain="[('lead_type','=', 'lead')]" help="Show only lead"/>
|
||||
<filter name="opportunity" string="Opportunities" domain="[('lead_type','=','opportunity')]" help="Show only opportunity"/>
|
||||
@@ -58,7 +58,7 @@
|
||||
<field name="res_model">crm.activity.report</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">pivot,graph</field>
|
||||
<field name="context">{'search_default_my_activity': True}</field>
|
||||
<field name="context">{'search_default_activities_my': True}</field>
|
||||
<field name="domain">[]</field>
|
||||
</record>
|
||||
|
||||
|
||||
@@ -18,9 +18,6 @@ access_crm_lead_tag_manager,crm_lead_tag manager,model_crm_lead_tag,sales_team.g
|
||||
access_crm_lost_reason_manager,crm.lost.reason.manager,model_crm_lost_reason,sales_team.group_sale_manager,1,1,1,1
|
||||
access_crm_lost_reason_salesman,crm.lost.reason.salesman,model_crm_lost_reason,sales_team.group_sale_salesman,1,0,0,0
|
||||
access_crm_lost_reason_user,crm.lost.reason.user,model_crm_lost_reason,base.group_user,1,0,0,0
|
||||
access_crm_activity_user,crm.activity.user,model_crm_activity,base.group_user,1,1,1,0
|
||||
access_crm_activity_manager,crm.activity.manager,model_crm_activity,sales_team.group_sale_manager,1,1,1,1
|
||||
access_crm_activity_salesman,crm.activity.salesman,model_crm_activity,sales_team.group_sale_salesman,1,1,1,0
|
||||
access_crm_activity_report_user,crm.activity.report.user,model_crm_activity_report,base.group_user,1,0,0,0
|
||||
access_calendar_event_manager,calendar.event.manager,calendar.model_calendar_event,sales_team.group_sale_manager,1,1,1,1
|
||||
access_calendar_event,calendar.event,calendar.model_calendar_event,sales_team.group_sale_salesman,1,1,1,0
|
||||
|
||||
|
@@ -35,18 +35,22 @@ tour.register('crm_tour', {
|
||||
position: "right",
|
||||
run: "drag_and_drop .o_opportunity_kanban .o_kanban_group:eq(2) ",
|
||||
}, {
|
||||
trigger: ".o_kanban_record:not(.o_updating) .oe_kanban_status_grey",
|
||||
trigger: ".o_kanban_record:not(.o_updating) .o_activity_color_default",
|
||||
extra_trigger: ".o_opportunity_kanban",
|
||||
content: _t("This opportunity has <b>no next activity scheduled</b>. <i>Click to set one.</i>"),
|
||||
content: _t("This opportunity has <b>no activity planned</b>. <i>Click to check them.</i>"),
|
||||
position: "bottom"
|
||||
}, {
|
||||
trigger: ".o_recommended_activity .o_radio_item",
|
||||
trigger: ".o_schedule_activity",
|
||||
extra_trigger: ".o_opportunity_kanban",
|
||||
content: _t("Schedule an activity by clicking here"),
|
||||
position: "bottom"
|
||||
}, {
|
||||
trigger: ".modal-body .o_form_field_many2one",
|
||||
extra_trigger: ".o_opportunity_kanban",
|
||||
content: _t("<p>You will be able to customize your followup activities. Examples:</p><ol><li>introductory email</li><li>call 10 days after</li><li>second call 3 days after, ...</li></ol><p class='mb0'><i>Select a standard activity for now on.</i></p>"),
|
||||
position: "left",
|
||||
position: "bottom",
|
||||
run: function (actions) {
|
||||
actions.auto(this.$anchor.children("input").first());
|
||||
actions.auto(".modal-footer .btn-primary");
|
||||
actions.auto(".modal-footer .btn-default");
|
||||
},
|
||||
}, {
|
||||
trigger: ".o_kanban_record",
|
||||
|
||||
@@ -3,52 +3,47 @@
|
||||
|
||||
from .common import TestCrmCases
|
||||
from odoo import fields
|
||||
from datetime import date
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
|
||||
class TestCrmActivity(TestCrmCases):
|
||||
class TestCrmMailActivity(TestCrmCases):
|
||||
|
||||
def setUp(self):
|
||||
super(TestCrmActivity, self).setUp()
|
||||
super(TestCrmMailActivity, self).setUp()
|
||||
# Set up activities
|
||||
Activity = self.env['crm.activity']
|
||||
self.activity3 = Activity.create({
|
||||
lead_model_id = self.env['ir.model'].search([('model', '=', 'crm.lead')]).id
|
||||
ActivityType = self.env['mail.activity.type']
|
||||
self.activity3 = ActivityType.create({
|
||||
'name': 'Celebrate the sale',
|
||||
'days': 3,
|
||||
'description': 'ACT 3 : Beers for everyone because I am a good salesman !',
|
||||
'internal': True,
|
||||
'res_model': 'crm.lead',
|
||||
'summary': 'ACT 3 : Beers for everyone because I am a good salesman !',
|
||||
'res_model_id': lead_model_id,
|
||||
})
|
||||
self.activity2 = Activity.create({
|
||||
self.activity2 = ActivityType.create({
|
||||
'name': 'Call for Demo',
|
||||
'days': 6,
|
||||
'description': 'ACT 2 : I want to show you my ERP !',
|
||||
'internal': True,
|
||||
'res_model': 'crm.lead',
|
||||
'recommended_activity_ids': [(6, 0, [self.activity3.id])],
|
||||
'summary': 'ACT 2 : I want to show you my ERP !',
|
||||
'res_model_id': lead_model_id,
|
||||
})
|
||||
self.activity1 = Activity.create({
|
||||
self.activity1 = ActivityType.create({
|
||||
'name': 'Initial Contact',
|
||||
'days': 5,
|
||||
'description': 'ACT 1 : Presentation, barbecue, ... ',
|
||||
'internal': True,
|
||||
'res_model': 'crm.lead',
|
||||
'recommended_activity_ids': [(6, 0, [self.activity2.id])],
|
||||
'summary': 'ACT 1 : Presentation, barbecue, ... ',
|
||||
'res_model_id': lead_model_id,
|
||||
})
|
||||
|
||||
# I create an opportunity, as salesman
|
||||
self.partner_client = self.env.ref("base.res_partner_1")
|
||||
Lead = self.env['crm.lead'].sudo(self.crm_salesman.id)
|
||||
self.lead = Lead.create({
|
||||
self.lead = self.env['crm.lead'].sudo(self.crm_salesman.id).create({
|
||||
'name': 'Test Opp',
|
||||
'type': 'opportunity',
|
||||
'name': 'Test Opportunity Activity Log',
|
||||
'partner_id': self.partner_client.id,
|
||||
'team_id': self.env.ref("sales_team.team_sales_department").id,
|
||||
'user_id': self.crm_salesman.id,
|
||||
})
|
||||
|
||||
def test_crm_activity_recipients(self):
|
||||
""" This test case check :
|
||||
""" This test case checks
|
||||
- no internal subtype followed by client
|
||||
- activity subtype are not default ones
|
||||
- only activity followers are recipients when this kind of activity is logged
|
||||
@@ -60,73 +55,60 @@ class TestCrmActivity(TestCrmCases):
|
||||
self.lead.message_subscribe([self.partner_client.id])
|
||||
|
||||
# Check the client is not follower of any internal subtype
|
||||
is_internal_subtype_for_client = self.lead.message_follower_ids.filtered(lambda fol: fol.partner_id.id == self.partner_client.id).mapped('subtype_ids.internal')
|
||||
self.assertFalse(any(is_internal_subtype_for_client), 'Partner client is following an internal subtype')
|
||||
internal_subtypes = self.lead.message_follower_ids.filtered(lambda fol: fol.partner_id == self.partner_client).mapped('subtype_ids').filtered(lambda subtype: subtype.internal)
|
||||
self.assertFalse(internal_subtypes)
|
||||
|
||||
# Add sale manager as follower of default subtypes
|
||||
self.lead.message_subscribe([self.crm_salemanager.partner_id.id])
|
||||
# Make the sale manager follower of the activity subtype
|
||||
manager_follower = self.env['mail.followers'].sudo().search([('res_model', '=', 'crm.lead'), ('res_id', '=', self.lead.id), ('partner_id', '=', self.crm_salemanager.partner_id.id)])
|
||||
manager_follower.write({
|
||||
'subtype_ids': [(4, activity.subtype_id.id)]
|
||||
})
|
||||
|
||||
# Instanciate wizard, trigger onchange lead and set the next activity
|
||||
ActivityLogWizard = self.env['crm.activity.log'].sudo(self.crm_salesman.id)
|
||||
wizard = ActivityLogWizard.create({
|
||||
activity = self.env['mail.activity'].sudo(self.crm_salesman.id).create({
|
||||
'activity_type_id': self.activity1.id,
|
||||
'note': 'Content of the activity to log',
|
||||
'lead_id': self.lead.id,
|
||||
'res_id': self.lead.id,
|
||||
'res_model_id': self.env.ref('crm.model_crm_lead').id,
|
||||
})
|
||||
wizard.onchange_lead_id()
|
||||
wizard.write({
|
||||
'next_activity_id': activity.id,
|
||||
})
|
||||
wizard.action_log()
|
||||
activity._onchange_activity_type_id()
|
||||
self.assertEqual(self.lead.activity_type_id, self.activity1)
|
||||
self.assertEqual(self.lead.activity_summary, self.activity1.summary)
|
||||
# self.assertEqual(self.lead.activity_date_deadline, self.activity1.summary)
|
||||
|
||||
# Check message recipients
|
||||
# mark as done, check lead and posted message
|
||||
activity.action_done()
|
||||
self.assertFalse(self.lead.activity_type_id.id)
|
||||
self.assertFalse(self.lead.activity_ids)
|
||||
activity_message = self.lead.message_ids[0]
|
||||
self.assertEqual(activity_message.needaction_partner_ids, self.crm_salemanager.partner_id, 'Only the crm manager should be notified by the activity')
|
||||
self.assertEqual(self.lead.next_activity_id.id, False, 'When logging activity, the next activity planned is erased')
|
||||
self.assertEqual(activity_message.needaction_partner_ids, self.crm_salemanager.partner_id)
|
||||
self.assertEqual(activity_message.subtype_id, self.env.ref('mail.mt_activities'))
|
||||
|
||||
def test_crm_activity_next_action(self):
|
||||
""" This test case set the next activity on a lead, log another, and schedule a third. """
|
||||
# Add the next activity (like we set it from a form view)
|
||||
self.lead.write({
|
||||
'next_activity_id': self.activity1.id
|
||||
lead_model_id = self.env['ir.model'].search([('model', '=', 'crm.lead')]).id
|
||||
activity = self.env['mail.activity'].sudo(self.crm_salesman.id).create({
|
||||
'activity_type_id': self.activity1.id,
|
||||
'summary': 'My Own Summary',
|
||||
'res_id': self.lead.id,
|
||||
'res_model_id': lead_model_id,
|
||||
})
|
||||
self.lead._onchange_next_activity_id()
|
||||
activity._onchange_activity_type_id()
|
||||
|
||||
# Check the next activity is correct
|
||||
self.assertEqual(self.lead.title_action, self.activity1.description, 'Activity title should be the same on the lead and on the chosen activity')
|
||||
self.assertEqual(self.lead.activity_summary, activity.summary)
|
||||
self.assertEqual(self.lead.activity_type_id, activity.activity_type_id)
|
||||
# self.assertEqual(fields.Datetime.from_string(self.lead.activity_date_deadline), datetime.now() + timedelta(days=activity.activity_type_id.days))
|
||||
|
||||
# Instanciate the wizard to schedule the next activity
|
||||
wizard = self.env['crm.activity.log'].sudo(self.crm_salesman.id).create({
|
||||
activity.write({
|
||||
'activity_type_id': self.activity2.id,
|
||||
'summary': '',
|
||||
'note': 'Content of the activity to log',
|
||||
'lead_id': self.lead.id,
|
||||
})
|
||||
wizard.onchange_lead_id()
|
||||
wizard.write({
|
||||
'next_activity_id': self.activity2.id,
|
||||
})
|
||||
wizard.action_log()
|
||||
activity._onchange_activity_type_id()
|
||||
|
||||
self.assertEqual(self.lead.activity_summary, activity.activity_type_id.summary)
|
||||
self.assertEqual(self.lead.activity_type_id, activity.activity_type_id)
|
||||
# self.assertEqual(fields.Datetime.from_string(self.lead.activity_date_deadline), datetime.now() + timedelta(days=activity.activity_type_id.days))
|
||||
|
||||
activity.action_done()
|
||||
|
||||
# Check the next activity on the lead has been removed
|
||||
self.assertFalse(self.lead.next_activity_id.id, 'No next activity should be set on lead, since we jsut log another activity')
|
||||
|
||||
# Instanciate the wizard to schedule the next activity
|
||||
self.env['crm.activity.log'].sudo(self.crm_salesman.id).create({
|
||||
'next_activity_id': self.activity3.id,
|
||||
'note': 'Content of the activity to log',
|
||||
'lead_id': self.lead.id,
|
||||
})
|
||||
wizard.onchange_lead_id()
|
||||
wizard.write({
|
||||
'next_activity_id': self.activity3.id,
|
||||
})
|
||||
wizard.onchange_next_activity_id()
|
||||
wizard.action_schedule()
|
||||
|
||||
# Check the activity is well scheldule on lead
|
||||
delta_days = (fields.Date.from_string(self.lead.date_action) - date.today()).days
|
||||
self.assertEqual(self.activity3.days, delta_days, 'The action date should be in the number of days set up on the activity 3')
|
||||
self.assertEqual(self.lead.title_action, self.activity3.description, 'Activity title should be the same on the lead and on the activity 3')
|
||||
self.assertFalse(self.lead.activity_type_id)
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<odoo>
|
||||
|
||||
<record id="crm_activity_view_search" model="ir.ui.view">
|
||||
<field name="name">crm.activity.search</field>
|
||||
<field name="model">crm.activity</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Action Search">
|
||||
<field name="name"/>
|
||||
<field name="team_id"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="crm_activity_view_form" model="ir.ui.view">
|
||||
<field name="name">crm.activity.form</field>
|
||||
<field name="model">crm.activity</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Activities">
|
||||
<div class="oe_title">
|
||||
<label for="name" class="oe_edit_only"/>
|
||||
<h1><field name="name"/></h1>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="team_id"/>
|
||||
<field name="description"/>
|
||||
<field name="days"/>
|
||||
<field name="default"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="recommended_activity_ids" widget="many2many_tags"/>
|
||||
</group>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="crm_activity_view_tree" model="ir.ui.view">
|
||||
<field name="name">crm.activity.tree</field>
|
||||
<field name="model">crm.activity</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Activities">
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="name"/>
|
||||
<field name="days"/>
|
||||
<field name="team_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="crm_activity_action" model="ir.actions.act_window">
|
||||
<field name="name">Activities</field>
|
||||
<field name="res_model">crm.activity</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">Click to create a new activity.</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
id="crm_activity_menu"
|
||||
name="Activities"
|
||||
action="crm_activity_action"
|
||||
parent="menu_crm_config_lead"/>
|
||||
</odoo>
|
||||
@@ -186,7 +186,7 @@
|
||||
<field name="model">crm.lead</field>
|
||||
<field name="priority" eval="2"/>
|
||||
<field name="arch" type="xml">
|
||||
<calendar string="Leads Generation" date_start="date_action" color="user_id">
|
||||
<calendar string="Leads Generation" date_start="activity_date_deadline" color="user_id">
|
||||
<field name="name"/>
|
||||
<field name="partner_name"/>
|
||||
</calendar>
|
||||
@@ -240,16 +240,18 @@
|
||||
<field name="priority"/>
|
||||
<field name="planned_revenue"/>
|
||||
<field name="kanban_state"/>
|
||||
<field name="date_action"/>
|
||||
<field name="activity_date_deadline"/>
|
||||
<field name="user_email"/>
|
||||
<field name="user_id"/>
|
||||
<field name="partner_address_email"/>
|
||||
<field name="message_needaction_counter"/>
|
||||
<field name="tag_ids"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="title_action"/>
|
||||
<field name="activity_summary"/>
|
||||
<field name="active"/>
|
||||
<field name="company_currency"/>
|
||||
<field name="activity_state" />
|
||||
<field name="activity_ids" />
|
||||
<templates>
|
||||
<field name="date_deadline"/>
|
||||
<t t-name="kanban-box">
|
||||
@@ -284,16 +286,10 @@
|
||||
<span class='oe_kanban_mail_new' title='Unread Messages'><i class='fa fa-comments'/><t t-raw="record.message_needaction_counter.raw_value"/></span>
|
||||
</t>
|
||||
<div>
|
||||
<a name="%(crm.crm_activity_log_action)d" type="action" t-if="record.kanban_state.raw_value!='grey'">
|
||||
<span
|
||||
t-att-title="record.date_action.value + ': '+ record.title_action.value"
|
||||
t-attf-class="oe_kanban_status oe_kanban_status_#{record.kanban_state.raw_value}"/>
|
||||
</a>
|
||||
<a name="%(crm.crm_activity_schedule_action)d" type="action" t-if="record.kanban_state.raw_value=='grey'">
|
||||
<span
|
||||
class="oe_kanban_status oe_kanban_status_grey"/>
|
||||
</a>
|
||||
<img t-att-src="kanban_image('res.users', 'image_small', record.user_id.raw_value)" t-att-title="record.user_id.value" width="24" height="24" class="oe_kanban_avatar pull-right"/>
|
||||
<div class="o_kanban_inline_block">
|
||||
<field name="activity_ids" widget="kanban_activity"/>
|
||||
</div>
|
||||
<img t-att-src="kanban_image('res.users', 'image_small', record.user_id.raw_value)" t-att-title="record.user_id.value" width="24" height="24" class="oe_kanban_avatar"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -332,6 +328,18 @@
|
||||
<filter string="Exclude Opt Out"
|
||||
name='not_opt_out' domain="[('opt_out', '=', False)]"
|
||||
help="Leads that did not ask not to be included in mass mailing campaigns"/>
|
||||
<separator/>
|
||||
<filter string="My Activities" name="activities_my"
|
||||
domain="[('activity_ids.user_id', '=', uid)]"/>
|
||||
<filter string="Today Activities" name="activities_today"
|
||||
domain="[('activity_ids.date_deadline', '=', context_today().strftime('%Y-%m-%d'))]"/>
|
||||
<filter string="Upcoming Activities (7 days)" name="activities_week"
|
||||
domain="['&', ('activity_ids.date_deadline', '>=', context_today().strftime('%Y-%m-%d')),
|
||||
('activity_ids.date_deadline', '<=', (context_today()+datetime.timedelta(days=7)).strftime('%Y-%m-%d'))
|
||||
]"/>
|
||||
<filter string="Overdue Activities" name="activities_overdue"
|
||||
domain="[('activity_ids.date_deadline', '<', context_today().strftime('%Y-%m-%d'))]"
|
||||
help="Show all records which has next action date is before today"/>
|
||||
<group expand="0" string="Group By">
|
||||
<filter string="Salesperson" name="groupby_salesperson" domain="[]" context="{'group_by':'user_id'}"/>
|
||||
<filter string="Sales Team" name="groupby_team" domain="[]" context="{'group_by':'team_id'}"/>
|
||||
@@ -362,8 +370,6 @@
|
||||
type="action" class="oe_highlight"
|
||||
context="{'default_lead_id': active_id}"
|
||||
attrs="{'invisible': [('active', '=', False),('probability', '<', 100)]}"/>
|
||||
<button name="%(crm.crm_activity_log_action)d" string="Log Activity" type="action" class="btn-link"
|
||||
attrs="{'invisible': [('active', '=', False)]}"/>
|
||||
<field name="stage_id" widget="statusbar" clickable="True"
|
||||
options="{'fold_field': 'fold'}"
|
||||
domain="['|', ('team_id', '=', team_id), ('team_id', '=', False)]"
|
||||
@@ -425,21 +431,6 @@
|
||||
</group>
|
||||
|
||||
<group>
|
||||
<label for="next_activity_id"/>
|
||||
<div>
|
||||
<div class="o_row mr16">
|
||||
<field name="next_activity_id"
|
||||
options="{'no_create': True, 'no_open': True}"
|
||||
domain="['|',('team_id','=',False),('team_id','=',team_id)]"/>
|
||||
<span class="oe_form_field"
|
||||
attrs="{'invisible': ['|', ('next_activity_id', '=', False), ('date_action', '=', False)]}"> on </span>
|
||||
<field name="date_action" attrs="{'invisible': [('next_activity_id', '=', False)]}" placeholder="Choose a date..."/>
|
||||
</div>
|
||||
<div>
|
||||
<field name="title_action" placeholder="e.g. Discuss proposal"
|
||||
attrs="{'invisible': [('next_activity_id', '=', False)]}"/>
|
||||
</div>
|
||||
</div>
|
||||
<field name="date_deadline"/>
|
||||
</group>
|
||||
|
||||
@@ -503,6 +494,7 @@
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
<field name="message_follower_ids" widget="mail_followers"/>
|
||||
<field name="activity_ids" widget="mail_activity"/>
|
||||
<field name="message_ids" widget="mail_thread"/>
|
||||
</div>
|
||||
</form>
|
||||
@@ -513,14 +505,14 @@
|
||||
<field name="name">crm.lead.tree.opportunity</field>
|
||||
<field name="model">crm.lead</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Opportunities" decoration-bf="message_needaction==True" decoration-muted="probability == 100" decoration-danger="date_action and (date_action < current_date)">
|
||||
<tree string="Opportunities" decoration-bf="message_needaction==True" decoration-muted="probability == 100" decoration-danger="activity_date_deadline and (activity_date_deadline < current_date)">
|
||||
<field name="date_deadline" invisible="1"/>
|
||||
<field name="create_date"/>
|
||||
<field name="name" string="Opportunity"/>
|
||||
<field name="partner_id" string="Customer"/>
|
||||
<field name="country_id"/>
|
||||
<field name="date_action"/>
|
||||
<field name="title_action"/>
|
||||
<field name="activity_date_deadline"/>
|
||||
<field name="activity_summary"/>
|
||||
<field name="medium_id" invisible="1"/>
|
||||
<field name="campaign_id" invisible="1"/>
|
||||
<field name="source_id" invisible="1"/>
|
||||
@@ -542,12 +534,12 @@
|
||||
<field name="name">crm.lead.tree.opportunity.next.activity</field>
|
||||
<field name="model">crm.lead</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Next Activity" decoration-danger="date_action and (date_action < current_date)" default_order="date_action">
|
||||
<tree string="Next Activities" decoration-danger="activity_date_deadline and (activity_date_deadline < current_date)" default_order="activity_date_deadline">
|
||||
<field name="name"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="date_action"/>
|
||||
<field name="next_activity_id"/>
|
||||
<field name="title_action"/>
|
||||
<field name="activity_date_deadline"/>
|
||||
<field name="activity_type_id"/>
|
||||
<field name="activity_summary"/>
|
||||
<field name="stage_id"/>
|
||||
<field name="planned_revenue"/>
|
||||
<field name="date_deadline"/>
|
||||
@@ -566,8 +558,8 @@
|
||||
<field name="user_id"/>
|
||||
<field name="partner_id" operator="child_of" string="Customer"/>
|
||||
<field name="stage_id" domain="[]"/>
|
||||
<field name="next_activity_id"/>
|
||||
<field name="title_action"/>
|
||||
<field name="activity_type_id"/>
|
||||
<field name="activity_summary"/>
|
||||
<field name="probability"/>
|
||||
<field name="lost_reason"/>
|
||||
<separator/>
|
||||
@@ -580,14 +572,16 @@
|
||||
<filter string="Unassigned" name="unassigned"
|
||||
domain="[('user_id','=', False)]" help="No salesperson"/>
|
||||
<separator/>
|
||||
<filter string="Today Activities" name="today"
|
||||
domain="[('date_action', '=', context_today().strftime('%Y-%m-%d'))]"/>
|
||||
<filter string="This Week Activities" name="this_week"
|
||||
domain="['&', ('date_action', '>=', context_today().strftime('%Y-%m-%d')),
|
||||
('date_action', '<=', (context_today()+datetime.timedelta(days=7)).strftime('%Y-%m-%d'))
|
||||
<filter string="My Activities" name="activities_my"
|
||||
domain="[('activity_ids.user_id', '=', uid)]"/>
|
||||
<filter string="Today Activities" name="activities_today"
|
||||
domain="[('activity_ids.date_deadline', '=', context_today().strftime('%Y-%m-%d'))]"/>
|
||||
<filter string="Upcoming Activities (7 days)" name="activities_week"
|
||||
domain="['&', ('activity_ids.date_deadline', '>=', context_today().strftime('%Y-%m-%d')),
|
||||
('activity_ids.date_deadline', '<=', (context_today()+datetime.timedelta(days=7)).strftime('%Y-%m-%d'))
|
||||
]"/>
|
||||
<filter string="Overdue Activities" name="overdue"
|
||||
domain="[('date_action', '<', context_today().strftime('%Y-%m-%d'))]"
|
||||
<filter string="Overdue Activities" name="activities_overdue"
|
||||
domain="[('activity_ids.date_deadline', '<', context_today().strftime('%Y-%m-%d'))]"
|
||||
help="Show all opportunities for which the next action date is before today"/>
|
||||
<separator/>
|
||||
<filter string="Unread Messages" name="message_needaction" domain="[('message_needaction','=',True)]"/>
|
||||
@@ -831,7 +825,7 @@ if record:
|
||||
eval="[(5, 0, 0), (0, 0, {'view_mode': 'tree', 'view_id': ref('crm_lead_view_tree_activity')}),
|
||||
(0, 0, {'view_mode': 'form', 'view_id': ref('crm_case_form_view_oppor')}),
|
||||
(0, 0, {'view_mode': 'kanban'}), (0, 0, {'view_mode': 'calendar'}), (0, 0, {'view_mode': 'pivot'}), (0, 0, {'view_mode': 'graph'})]"/>
|
||||
<field name="domain">[('type','=','opportunity'), ('date_action', '!=', False)]</field>
|
||||
<field name="domain">[('type','=','opportunity'), ('activity_date_deadline', '!=', False)]</field>
|
||||
<field name="context">{
|
||||
'default_type': 'opportunity',
|
||||
'default_user_id': uid,
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import base_partner_merge
|
||||
import crm_activity_log
|
||||
import crm_lead_lost
|
||||
import crm_partner_binding
|
||||
import crm_lead_to_opportunity
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from odoo import api, fields, models, tools, _
|
||||
|
||||
|
||||
class ActivityLog(models.TransientModel):
|
||||
|
||||
_name = "crm.activity.log"
|
||||
_description = "Log an Activity"
|
||||
_rec_name = 'title_action'
|
||||
|
||||
@api.model
|
||||
def _default_lead_id(self):
|
||||
if 'default_lead_id' in self._context:
|
||||
return self._context['default_lead_id']
|
||||
if self._context.get('active_model') == 'crm.lead':
|
||||
return self._context.get('active_id')
|
||||
return False
|
||||
|
||||
next_activity_id = fields.Many2one('crm.activity', 'Activity')
|
||||
last_activity_id = fields.Many2one('crm.activity', 'Previous Activity', default=False)
|
||||
recommended_activity_id = fields.Many2one("crm.activity", "Recommended Activities")
|
||||
title_action = fields.Char('Summary')
|
||||
note = fields.Html('Note')
|
||||
date_action = fields.Date('Next Activity Date')
|
||||
lead_id = fields.Many2one('crm.lead', 'Lead', required=True, default=_default_lead_id)
|
||||
team_id = fields.Many2one('crm.team', 'Sales Team')
|
||||
date_deadline = fields.Date('Expected Closing')
|
||||
planned_revenue = fields.Float('Expected Revenue')
|
||||
|
||||
@api.onchange('lead_id')
|
||||
def onchange_lead_id(self):
|
||||
self.next_activity_id = self.lead_id.next_activity_id
|
||||
self.date_deadline = self.lead_id.date_deadline
|
||||
self.team_id = self.lead_id.team_id
|
||||
self.planned_revenue = self.lead_id.planned_revenue
|
||||
self.title_action = self.lead_id.title_action
|
||||
|
||||
@api.onchange('next_activity_id')
|
||||
def onchange_next_activity_id(self):
|
||||
if not self.title_action:
|
||||
self.title_action = self.next_activity_id.description
|
||||
date_action = False
|
||||
if self.next_activity_id and self.next_activity_id.days:
|
||||
date_action = (datetime.now() + timedelta(days=self.next_activity_id.days)).strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)
|
||||
self.date_action = date_action
|
||||
|
||||
@api.onchange('recommended_activity_id')
|
||||
def onchange_recommended_activity_id(self):
|
||||
self.next_activity_id = self.recommended_activity_id
|
||||
|
||||
@api.multi
|
||||
def action_log_and_schedule(self):
|
||||
self.ensure_one()
|
||||
self.action_log()
|
||||
view_id = self.env.ref('crm.crm_activity_log_view_form_schedule')
|
||||
return {
|
||||
'name': _('Next activity'),
|
||||
'res_model': 'crm.activity.log',
|
||||
'context': {
|
||||
'default_last_activity_id': self.next_activity_id.id,
|
||||
'default_lead_id': self.lead_id.id
|
||||
},
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_id': False,
|
||||
'views': [(view_id.id, 'form')],
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
'view_type': 'form',
|
||||
'res_id': False
|
||||
}
|
||||
|
||||
@api.multi
|
||||
def action_log(self):
|
||||
for log in self:
|
||||
body_html = "<div><b>%(title)s</b>: %(next_activity)s</div>%(description)s%(note)s" % {
|
||||
'title': _('Activity Done'),
|
||||
'next_activity': log.next_activity_id.name,
|
||||
'description': log.title_action and '<p><em>%s</em></p>' % log.title_action or '',
|
||||
'note': log.note or '',
|
||||
}
|
||||
log.lead_id.message_post(body_html, subject=log.title_action, subtype_id=log.next_activity_id.subtype_id.id)
|
||||
log.lead_id.write({
|
||||
'date_deadline': log.date_deadline,
|
||||
'planned_revenue': log.planned_revenue,
|
||||
'title_action': False,
|
||||
'date_action': False,
|
||||
'next_activity_id': False,
|
||||
})
|
||||
return True
|
||||
|
||||
@api.multi
|
||||
def action_schedule(self):
|
||||
for log in self:
|
||||
log.lead_id.write({
|
||||
'title_action': log.title_action,
|
||||
'date_action': log.date_action,
|
||||
'next_activity_id': log.next_activity_id.id,
|
||||
})
|
||||
return True
|
||||
@@ -1,85 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<odoo>
|
||||
<record id="crm_activity_log_view_form" model="ir.ui.view">
|
||||
<field name="name">Log an Activity</field>
|
||||
<field name="model">crm.activity.log</field>
|
||||
<field name="priority">20</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Log an Activity">
|
||||
<group>
|
||||
<field name="team_id" invisible="1"/>
|
||||
<field name="lead_id" invisible="1"/>
|
||||
<group>
|
||||
<field name="next_activity_id" required="1"
|
||||
domain="['|', ('team_id', '=', False), ('team_id', '=', team_id)]"
|
||||
options="{'no_create': True, 'no_open': True}"/>
|
||||
<field name="title_action" placeholder="e.g. Discuss proposal"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="planned_revenue"/>
|
||||
<field name="date_deadline"/>
|
||||
</group>
|
||||
</group>
|
||||
<field name="note" placeholder="Log a note..."/>
|
||||
<footer>
|
||||
<button name="action_log_and_schedule" string="Log & Schedule Next" type="object" class="btn btn-primary"/>
|
||||
<button name="action_log" string="Log Only" type="object" class="btn btn-primary"/>
|
||||
<button string="Cancel" class="btn btn-default" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="crm_activity_log_view_form_schedule" model="ir.ui.view">
|
||||
<field name="name">Schedule next Activity</field>
|
||||
<field name="model">crm.activity.log</field>
|
||||
<field name="priority">40</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Schedule Next Activity">
|
||||
<group class="mt0">
|
||||
<field name="team_id" invisible="1"/>
|
||||
<field name="lead_id" invisible="1"/>
|
||||
<field name="last_activity_id" invisible="1"/>
|
||||
<group>
|
||||
<field name="next_activity_id"
|
||||
domain="['|', ('team_id', '=', False), ('team_id', '=', team_id)]"
|
||||
options="{'no_create': True, 'no_open': True}"/>
|
||||
<field name="date_action"/>
|
||||
<field name="title_action" placeholder="e.g. Discuss proposal"/>
|
||||
</group>
|
||||
<group>
|
||||
<div>
|
||||
<p><strong>Recommended activities:</strong></p>
|
||||
<field name="recommended_activity_id" widget="radio" class="o_recommended_activity"
|
||||
domain="[('preceding_activity_ids', '=', last_activity_id)]"/>
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="action_schedule" string="Schedule Activity" type="object" class="btn btn-primary"/>
|
||||
<button string="No activity" class="btn btn-default" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="crm_activity_log_action" model="ir.actions.act_window">
|
||||
<field name="name">Log an Activity</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">crm.activity.log</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="crm_activity_log_view_form"/>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="crm_activity_schedule_action" model="ir.actions.act_window">
|
||||
<field name="name">Schedule an Activity</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">crm.activity.log</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="crm_activity_log_view_form_schedule"/>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
@@ -124,7 +124,7 @@ class Lead2OpportunityPartner(models.TransientModel):
|
||||
if self.name == 'merge':
|
||||
leads = self.with_context(active_test=False).opportunity_ids.merge_opportunity()
|
||||
if not leads.active:
|
||||
leads.write({'active': True, 'next_activity_id': False, 'lost_reason': False})
|
||||
leads.write({'active': True, 'activity_type_id': False, 'lost_reason': False})
|
||||
if leads.type == "lead":
|
||||
values.update({'lead_ids': leads.ids, 'user_ids': [self.user_id.id]})
|
||||
self.with_context(active_ids=leads.ids)._convert_opportunity(values)
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
odoo.define('mail.activity.log', function (require) {
|
||||
"use strict";
|
||||
|
||||
var Model = require("web.Model");
|
||||
|
||||
|
||||
var AbstractActivity = {
|
||||
init: function(res_id, res_model){
|
||||
this.res_id = res_id;
|
||||
this.res_model = res_model;
|
||||
this.limit = 10; // TODO Add pager
|
||||
this.Activity = new Model("mail.activity");
|
||||
},
|
||||
remove_activity_log: function (activity_id) {
|
||||
return this.Activity.call("unlink", [activity_id]);
|
||||
},
|
||||
mark_as_done: function (activity_id) {
|
||||
return this.Activity.call("mark_as_done", [activity_id]);
|
||||
},
|
||||
get_create_activity_action : function(activity_id){
|
||||
var context = activity_id ? {'mark_done': true} : {}
|
||||
return {
|
||||
type: 'ir.actions.act_window',
|
||||
res_model: 'mail.activity',
|
||||
view_mode: 'form',
|
||||
view_type: 'form',
|
||||
views: [
|
||||
[false, 'form']
|
||||
],
|
||||
target: 'new',
|
||||
context: _.extend({
|
||||
default_res_id: this.res_id,
|
||||
default_res_model: this.res_model,
|
||||
}, context, this.context),
|
||||
res_id: activity_id,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
return {
|
||||
AbstractActivity: AbstractActivity,
|
||||
};
|
||||
});
|
||||
@@ -27,7 +27,7 @@
|
||||
</a>
|
||||
</td>
|
||||
<td class="o_main" title="To Activities">
|
||||
<a href="#" class="o_dashboard_action" name="crm.crm_lead_action_activities" data-context="{'search_default_today':'1'}">
|
||||
<a href="#" class="o_dashboard_action" name="crm.crm_lead_action_activities" data-context="{'search_default_activities_today':'1'}">
|
||||
<span class="o_highlight">
|
||||
<t t-if="!show_demo">
|
||||
<t t-esc="values['activity']['today']"/>
|
||||
@@ -59,7 +59,7 @@
|
||||
</a>
|
||||
</td>
|
||||
<td class="o_main" title="To Activities">
|
||||
<a href="#" class="o_dashboard_action" name="crm.crm_lead_action_activities" data-context="{'search_default_this_week':'1'}">
|
||||
<a href="#" class="o_dashboard_action" name="crm.crm_lead_action_activities" data-context="{'search_default_activities_week':'1'}">
|
||||
<t t-if="!show_demo">
|
||||
<t t-esc="values['activity']['next_7_days']"/>
|
||||
</t>
|
||||
@@ -74,7 +74,7 @@
|
||||
<td></td>
|
||||
<!-- Hide overdue when there is none -->
|
||||
<td t-if="show_demo or (values and values['activity']['overdue'] != 0)" class="o_warning" title="To Activities">
|
||||
<a href="#" class="o_dashboard_action" name="crm.crm_lead_action_activities" data-context="{'search_default_overdue':'1'}">
|
||||
<a href="#" class="o_dashboard_action" name="crm.crm_lead_action_activities" data-context="{'search_default_activities_overdue':'1'}">
|
||||
<t t-if="!show_demo">
|
||||
<t t-esc="values['activity']['overdue']"/> overdue
|
||||
</t>
|
||||
@@ -84,7 +84,7 @@
|
||||
</a>
|
||||
</td>
|
||||
<td t-if="show_demo or (values and values['closing']['overdue'] != 0)" class="o_warning" title="To Opportunities">
|
||||
<a href="#" class="o_dashboard_action" name="crm.action_your_pipeline" data-context="{'search_default_overdue':'1'}">
|
||||
<a href="#" class="o_dashboard_action" name="crm.action_your_pipeline" data-context="{'search_default_activities_overdue':'1'}">
|
||||
<t t-if="!show_demo">
|
||||
<t t-esc="values['closing']['overdue']"/> exp. closing
|
||||
</t>
|
||||
|
||||
@@ -94,10 +94,10 @@ class WebsiteAccount(website_account):
|
||||
|
||||
searchbar_filters = {
|
||||
'all': {'label': _('All'), 'domain': []},
|
||||
'today': {'label': _('Today Activities'), 'domain': [('date_action', '=', today)]},
|
||||
'today': {'label': _('Today Activities'), 'domain': [('activity_date_deadline', '=', today)]},
|
||||
'week': {'label': _('This Week Activities'),
|
||||
'domain': [('date_action', '>=', today), ('date_action', '<=', this_week_end_date)]},
|
||||
'overdue': {'label': _('Overdue Activities'), 'domain': [('date_action', '<', today)]},
|
||||
'domain': [('activity_date_deadline', '>=', today), ('activity_date_deadline', '<=', this_week_end_date)]},
|
||||
'overdue': {'label': _('Overdue Activities'), 'domain': [('activity_date_deadline', '<', today)]},
|
||||
'won': {'label': _('Won'), 'domain': [('stage_id.probability', '=', 100), ('stage_id.fold', '=', True)]},
|
||||
'lost': {'label': _('Lost'), 'domain': [('active', '=', False)]},
|
||||
}
|
||||
@@ -158,8 +158,9 @@ class WebsiteAccount(website_account):
|
||||
return request.render(
|
||||
"website_crm_partner_assign.portal_my_opportunity", {
|
||||
'opportunity': lead,
|
||||
'user_activity': lead.activity_ids.filtered(lambda activity: activity.user_id == request.env.user)[:1],
|
||||
'stages': request.env['crm.stage'].search([('probability', '!=', '100')], order='sequence desc'),
|
||||
'activities': request.env['crm.activity'].sudo().search([], order='sequence desc'),
|
||||
'activity_types': request.env['mail.activity.type'].sudo().search([]),
|
||||
'states': request.env['res.country.state'].sudo().search([]),
|
||||
'countries': request.env['res.country'].sudo().search([]),
|
||||
})
|
||||
|
||||
@@ -226,30 +226,33 @@ class CrmLead(models.Model):
|
||||
@api.multi
|
||||
def update_lead_portal(self, values):
|
||||
self.check_access_rights('write')
|
||||
|
||||
for lead in self:
|
||||
if values['date_action'] == '':
|
||||
values['date_action'] = False
|
||||
if lead.next_activity_id.id != values['activity_id'] or lead.title_action != values['title_action']\
|
||||
or lead.date_action != values['date_action']:
|
||||
activity = lead.sudo().next_activity_id
|
||||
body_html = "<div><b>%(title)s</b>: %(next_activity)s</div>%(description)s" % {
|
||||
'title': _('Activity Done'),
|
||||
'next_activity': activity.name,
|
||||
'description': lead.title_action and '<p><em>%s</em></p>' % lead.title_action or '',
|
||||
}
|
||||
lead.message_post(
|
||||
body=body_html,
|
||||
subject=lead.title_action,
|
||||
subtype="mail.mt_note")
|
||||
lead.write({
|
||||
lead_values = {
|
||||
'planned_revenue': values['planned_revenue'],
|
||||
'probability': values['probability'],
|
||||
'next_activity_id': values['activity_id'],
|
||||
'title_action': values['title_action'],
|
||||
'date_action': values['date_action'] if values['date_action'] else False,
|
||||
'priority': values['priority'],
|
||||
'date_deadline': values['date_deadline'] if values['date_deadline'] else False,
|
||||
})
|
||||
}
|
||||
# As activities may belong to several users, only the current portal user activity
|
||||
# will be modified by the portal form. If no activity exist we create a new one instead
|
||||
# that we assign to the portal user.
|
||||
user_activity = lead.activity_ids.filtered(lambda activity: activity.user_id == self.env.user)[:1]
|
||||
if user_activity:
|
||||
user_activity.sudo().write({
|
||||
'activity_type_id': values['activity_type_id'],
|
||||
'summary': values['activity_summary'],
|
||||
'date_deadline': values['activity_date_deadline'],
|
||||
})
|
||||
else:
|
||||
self.env['mail.activity'].sudo().create({
|
||||
'res_model_id': self.env.ref('crm.model_crm_lead').id,
|
||||
'res_id': lead.id,
|
||||
'user_id': self.env.user.id,
|
||||
'activity_type_id': values['activity_type_id'],
|
||||
'summary': values['activity_summary'],
|
||||
'date_deadline': values['activity_date_deadline'],
|
||||
})
|
||||
lead.write(lead_values)
|
||||
|
||||
@api.model
|
||||
def create_opp_portal(self, values):
|
||||
@@ -276,4 +279,4 @@ class CrmLead(models.Model):
|
||||
lead.convert_opportunity(lead.partner_id.id)
|
||||
return {
|
||||
'id': lead.id
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,5 +13,4 @@ partner_access_crm_lead,crm.lead,crm.model_crm_lead,base.group_portal,1,1,0,0
|
||||
access_res_partner_grade_invoicing_payment,res.partner.grade,model_res_partner_grade,account.group_account_invoice,1,0,0,0
|
||||
access_res_partner_grade_portal,res.partner.grade,model_res_partner_grade,base.group_portal,1,0,0,0
|
||||
crm_lead_portal_access,crm.lead.portal,crm.model_crm_lead,base.group_portal,1,1,0,0
|
||||
crm_activity_portal_access,crm.activity.portal,crm.model_crm_activity,base.group_portal,1,1,1,0
|
||||
mail_message_subtype_portal_access,mail.message.subtype.portal,mail.model_mail_message_subtype,base.group_portal,1,1,1,0
|
||||
|
@@ -124,12 +124,11 @@ $('.edit_opp_confirm').on('click',function(){
|
||||
$btn.prop('disabled', true);
|
||||
new Model('crm.lead')
|
||||
.call("update_lead_portal", [[parseInt($('.edit_opp_form .opportunity_id').val())],{
|
||||
activity_id: parseInt($('.edit_opp_form .next_activity').find(":selected").attr('data')),
|
||||
planned_revenue: parseFloat($('.edit_opp_form .planned_revenue').val()),
|
||||
probability: parseFloat($('.edit_opp_form .probability').val()),
|
||||
date_deadline: $('.edit_opp_form .date_deadline').val(),
|
||||
title_action: $('.edit_opp_form .title_action').val(),
|
||||
date_action: $('.edit_opp_form .date_action').val(),
|
||||
activity_type_id: parseInt($('.edit_opp_form .next_activity').find(":selected").attr('data')),
|
||||
activity_summary: $('.edit_opp_form .activity_summary').val(),
|
||||
activity_date_deadline: $('.edit_opp_form .activity_date_deadline').val(),
|
||||
priority: $('input[name="PriorityRadioOptions"]:checked').val(),
|
||||
}])
|
||||
.fail(function() {
|
||||
@@ -143,14 +142,14 @@ $('.edit_opp_confirm').on('click',function(){
|
||||
|
||||
$('.edit_opp_form .next_activity').on('change', function(){
|
||||
var selected = $('.edit_opp_form .next_activity').find(":selected");
|
||||
if(selected.attr('description')){
|
||||
$('.edit_opp_form .title_action').val(selected.attr('description'));
|
||||
if(selected.attr('activity_summary')){
|
||||
$('.edit_opp_form .activity_summary').val(selected.attr('activity_summary'));
|
||||
}
|
||||
if(selected.attr('days')){
|
||||
var date_now = moment();
|
||||
var days = parseInt(selected.attr('days'));
|
||||
var date = date_now.add(days, 'days');
|
||||
$('.edit_opp_form .date_action').val(date.format('YYYY-MM-DD'));
|
||||
$('.edit_opp_form .activity_date_deadline').val(date.format('YYYY-MM-DD'));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -757,19 +757,19 @@
|
||||
<div class="form-group">
|
||||
<label class="control-label" for="next_activity">Next Activity</label>
|
||||
<select class="form-control next_activity" name="next_activity">
|
||||
<t t-foreach="activities" t-as="activity">
|
||||
<option t-att-data="activity.id" t-att-selected="activity.id == opportunity.next_activity_id.id" t-att-name="activity.name" t-att-days="activity.days" t-att-description="activity.description"><t t-esc="activity.name"/></option>
|
||||
<t t-foreach="activity_types" t-as="activity_type">
|
||||
<option t-att-data="activity_type.id" t-att-selected="activity_type.id == user_activity.activity_type_id.id" t-att-name="activity_type.name" t-att-days="activity_type.days" t-att-summary="activity_type.summary"><t t-esc="activity_type.name"/></option>
|
||||
</t>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label" for="title_action">Details Next Activity</label>
|
||||
<textarea row="3" name="title_action" class="form-control title_action"><t t-esc="opportunity.title_action"/></textarea>
|
||||
<label class="control-label" for="activity_summary">Details Next Activity</label>
|
||||
<textarea row="3" name="activity_summary" class="form-control activity_summary"><t t-esc="user_activity.summary"/></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label" for="date_action">Next Activity Date</label>
|
||||
<label class="control-label" for="activity_date_deadline">Next Activity Date</label>
|
||||
<div class='input-group date'>
|
||||
<input type="text" name="date_action" t-att-value="opportunity.date_action" class="form-control date_action" data-date-format="YYYY-MM-DD" t-att-name="prefix" placeholder="YYYY-MM-DD" />
|
||||
<input type="text" name="activity_date_deadline" t-att-value="user_activity.date_deadline" class="form-control activity_date_deadline" data-date-format="YYYY-MM-DD" t-att-name="prefix" placeholder="YYYY-MM-DD" />
|
||||
<span class="input-group-addon"><span class="fa fa-calendar"></span></span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -782,16 +782,16 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="row" t-if="user_activity">
|
||||
<label class="col-xs-4">Next Activity</label>
|
||||
<span class="col-xs-8">
|
||||
<span t-field="opportunity.next_activity_id"/>
|
||||
<span t-if="opportunity.date_action"> on </span>
|
||||
<span t-field="opportunity.date_action"/>
|
||||
<span t-field="user_activity.activity_type_id"/>
|
||||
<span t-if="user_activity.date_deadline"> on </span>
|
||||
<span t-field="user_activity.date_deadline"/>
|
||||
</span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="col-xs-8 col-xs-offset-4" t-field="opportunity.title_action"/>
|
||||
<div class="row" t-if="user_activity">
|
||||
<span class="col-xs-8 col-xs-offset-4" t-field="user_activity.summary"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user