Skip to content

Commit 4efb400

Browse files
committed
[ADD] #792 extra crm features
[RFR] make work days calculation accessible to other modules
1 parent 0c6551c commit 4efb400

File tree

8 files changed

+166
-53
lines changed

8 files changed

+166
-53
lines changed

ps_crm/models/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from . import crm_lead
2+
from . import crm_lead_employee
23
from . import crm_monthly_revenue
34
from . import crm_monthly_revenue_split
45
from . import crm_stage

ps_crm/models/crm_lead.py

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
from odoo import _, api, fields, models
99
from odoo.exceptions import ValidationError
1010

11+
from odoo.addons.ps_planning.models.ps_contracted_line import _get_work_days_dates
12+
1113

1214
class Lead(models.Model):
1315
_inherit = "crm.lead"
@@ -38,6 +40,12 @@ class Lead(models.Model):
3840
"lead_id",
3941
string="Revenue split",
4042
)
43+
user_name = fields.Char(related="user_id.name")
44+
lead_employee_ids = fields.One2many(
45+
"crm.lead.employee", "lead_id", string="Employees"
46+
)
47+
first_employee_name = fields.Char(compute="_compute_first_employee_name")
48+
docs_link = fields.Char("Link to documentation")
4149

4250
@api.depends("monthly_revenue_ids.date")
4351
def _compute_latest_revenue_date(self):
@@ -60,13 +68,25 @@ def _compute_show_recalculate_total_button(self):
6068
this.expected_revenue != this.sum_monthly_revenue
6169
)
6270

71+
@api.depends("lead_employee_ids")
72+
def _compute_first_employee_name(self):
73+
for this in self:
74+
this.first_employee_name = this.lead_employee_ids[:1].employee_id.name
75+
6376
@api.model
6477
def default_get(self, fields):
6578
res = super().default_get(fields)
6679
user = self.env.user
6780
res.update({"operating_unit_id": user.default_operating_unit_id.id})
6881
return res
6982

83+
@api.model_create_multi
84+
def create(self, vals_list):
85+
result = super().create(vals_list)
86+
for this in result:
87+
this.update_monthly_revenue()
88+
return result
89+
7090
def _get_split_operating_units(self):
7191
return self.env["operating.unit"].search(
7292
[
@@ -98,22 +118,24 @@ def update_monthly_revenue(self):
98118
)
99119
)
100120
total_expected_revenue -= line.expected_revenue
101-
manual_days += (line.month.date_end - line.month.date_start).days + 1
121+
manual_days += _get_work_days_dates(
122+
line.month.date_start, line.month.date_end
123+
)
102124

103125
month_end_date = (sd + relativedelta(months=1)).replace(day=1) - timedelta(
104126
days=1
105127
)
106128
if month_end_date > ed:
107129
month_end_date = ed
108130
monthly_revenues = []
109-
total_days = (ed - sd).days + 1 - manual_days
131+
total_days = _get_work_days_dates(sd, ed) - manual_days
110132

111133
while True:
112134
if not any(
113135
vals["date"].month == month_end_date.month
114136
for _dummy, _dummy, vals in manual_lines
115137
):
116-
days_per_month = (month_end_date - sd).days + 1
138+
days_per_month = _get_work_days_dates(sd, month_end_date)
117139
expected_revenue_per_month = self.company_currency.round(
118140
total_expected_revenue * days_per_month / total_days
119141
)

ps_crm/models/crm_lead_employee.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from odoo import fields, models
2+
3+
4+
class CrmLeadEmployee(models.Model):
5+
_name = "crm.lead.employee"
6+
_description = "CRM lead employee"
7+
8+
lead_id = fields.Many2one("crm.lead", required=True)
9+
employee_id = fields.Many2one("hr.employee", required=True)
10+
rate = fields.Monetary()
11+
currency_id = fields.Many2one(related="lead_id.company_currency")

ps_crm/models/crm_monthly_revenue.py

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55

66
from dateutil.relativedelta import relativedelta
77

8-
from odoo import api, fields, models
8+
from odoo import _, api, fields, models
9+
from odoo.tools.misc import format_date
10+
11+
from odoo.addons.ps_planning.models.ps_contracted_line import _get_work_days_dates
912

1013

1114
class CrmMonthlyRevenue(models.Model):
@@ -96,29 +99,6 @@ def onchange_editable_fields(self):
9699
def _compute_date_fields(self):
97100
date_range = self.env["date.range"]
98101
for this in self:
99-
date = this.date
100-
101-
if date and this.latest_revenue_date:
102-
lrd = this.latest_revenue_date
103-
if date < lrd or (date.month == lrd.month and date.year == lrd.year):
104-
date = date = (lrd + relativedelta(months=2)).replace(
105-
day=1
106-
) - timedelta(days=1)
107-
108-
if not date:
109-
continue
110-
111-
days = " days (" if date.day > 1 else " day ("
112-
this.no_of_days = (
113-
str(date.day)
114-
+ days
115-
+ str(1)
116-
+ "-"
117-
+ str(date.day)
118-
+ " "
119-
+ str(date.strftime("%B"))
120-
+ ")"
121-
)
122102
company_id = this.lead_id.company_id.id or this.env.user.company_id.id
123103
common_domain = [
124104
("date_start", "<=", this.date),
@@ -133,3 +113,10 @@ def _compute_date_fields(self):
133113
common_domain + [("type_id.fiscal_year", "=", True)]
134114
)
135115
this.year = year.id
116+
117+
days = _get_work_days_dates(this.date.replace(day=1), this.date)
118+
this.no_of_days = _("%d days (1 - %s %s)") % (
119+
days,
120+
this.date.day,
121+
format_date(self.env, this.date, date_format="MMMM"),
122+
)

ps_crm/models/crm_stage.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@
88
class CRMStage(models.Model):
99
_inherit = "crm.stage"
1010

11+
active = fields.Boolean(default=True)
1112
popup_requirements = fields.Boolean("Show when changing")

ps_crm/security/ir.model.access.csv

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,6 @@ access_account_tax_group_sale_manager_mgs,account.tax.group sale manager,account
3030
access_crm_monthly_revenue_reg_usr,crm.monthly.revenue.manager,model_crm_monthly_revenue,ps_crm.group_sale_regular_user,1,1,1,1
3131
access_crm_monthly_revenue_split_reg_usr,crm.revenue.split,model_crm_monthly_revenue_split,ps_crm.group_sale_regular_user,1,1,1,1
3232
access_crm_lead_mgs,sale.order,crm.model_crm_lead,ps_crm.group_sale_regular_user,1,1,1,1
33+
34+
access_crm_lead_employee_user,access_crm_lead_employee,model_crm_lead_employee,group_sale_regular_user,1,1,1,1
35+
access_crm_lead_employee_salesman,access_crm_lead_employee,model_crm_lead_employee,sales_team.group_sale_salesman,1,1,1,1

ps_crm/views/crm_lead.xml

Lines changed: 88 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55
<field name="inherit_id" ref="crm.crm_lead_view_form" />
66
<field name="arch" type="xml">
77
<xpath expr="//group[1]" position="before">
8-
<div colspan="2">
9-
<field name="contract_signed" />
8+
<div>
9+
<field name="contract_signed" nolabel="1" />
1010
<label for="contract_signed" />
11+
<br class="oe_edit_only" />
12+
<label for="docs_link" class="ml-4" />
13+
<field name="docs_link" widget="url" />
1114
</div>
1215
<field name="show_recalculate_total_button" invisible="1" />
1316
<button
@@ -57,6 +60,15 @@
5760
</tree>
5861
</field>
5962
</div>
63+
<group string="Tariffs">
64+
<field name="lead_employee_ids" nolabel="1">
65+
<tree editable="bottom">
66+
<field name="employee_id" />
67+
<field name="rate" />
68+
<field name="currency_id" invisible="1" />
69+
</tree>
70+
</field>
71+
</group>
6072
</xpath>
6173
<xpath expr="//field[@name='date_deadline']" position="after">
6274
<field name="project_id" />
@@ -223,18 +235,90 @@
223235
<field name="model">crm.lead</field>
224236
<field name="inherit_id" ref="crm.quick_create_opportunity_form" />
225237
<field name="arch" type="xml">
238+
<field name="partner_id" position="before">
239+
<field name="name" position="move" />
240+
</field>
241+
<field name="partner_id" position="attributes">
242+
<attribute name="string">Customer</attribute>
243+
</field>
244+
<field name="name" position="after">
245+
<field name="start_date" />
246+
<field name="end_date" />
247+
</field>
226248
<xpath expr="//field[@name='partner_id']" position="after">
227249
<field name="operating_unit_id" />
228250
<field name="department_id" />
229-
<field name="tag_ids" string="Proposition" widget="many2many_tags" />
230-
<field name="date_deadline" string="Expected Closing Date" />
251+
<field name="date_deadline" string="Deadline submission" />
231252
</xpath>
232253
<label for="expected_revenue" position="attributes">
233254
<attribute name="string">Expected Revenue + Probability</attribute>
234255
</label>
235256
<xpath expr="//field[@name='expected_revenue']" position="after">
236257
<field name="probability" />
237258
</xpath>
259+
<field name="email_from" position="attributes">
260+
<attribute name="invisible">True</attribute>
261+
</field>
262+
<field name="phone" position="attributes">
263+
<attribute name="invisible">True</attribute>
264+
</field>
265+
<xpath
266+
expr="//field[@name='priority' and @widget='priority']"
267+
position="attributes"
268+
>
269+
<attribute name="invisible">True</attribute>
270+
</xpath>
271+
</field>
272+
</record>
273+
<record model="ir.ui.view" id="crm_case_kanban_view_leads">
274+
<field name="model">crm.lead</field>
275+
<field name="inherit_id" ref="crm.crm_case_kanban_view_leads" />
276+
<field name="arch" type="xml">
277+
<field name="user_id" position="before">
278+
<field name="user_name" />
279+
<field name="date_deadline" />
280+
<field name="first_employee_name" />
281+
</field>
282+
<xpath
283+
expr="//div[hasclass('o_kanban_record_title')]//field"
284+
position="before"
285+
>
286+
<xpath
287+
expr="//div/span[@t-if='record.partner_id.value']"
288+
position="move"
289+
/>
290+
</xpath>
291+
<xpath
292+
expr="//div[hasclass('o_kanban_record_title')]//field"
293+
position="attributes"
294+
>
295+
<attribute name="t-if">!record.partner_id.value</attribute>
296+
</xpath>
297+
<xpath expr="//div[hasclass('o_kanban_record_title')]" position="after">
298+
<div t-if="record.partner_id.value">
299+
<field name="name" />
300+
</div>
301+
<div>
302+
<field name="user_name" />
303+
</div>
304+
</xpath>
305+
<xpath expr="//field[@name='tag_ids']/.." position="before">
306+
<div t-if="record.date_deadline and record.date_deadline.value">
307+
<field name="date_deadline" />
308+
</div>
309+
<div
310+
t-if="record.first_employee_name and record.first_employee_name.value"
311+
>
312+
Proposed
313+
<field name="first_employee_name" />
314+
</div>
315+
</xpath>
316+
<xpath
317+
expr="//field[@name='priority' and @widget='priority']"
318+
position="attributes"
319+
>
320+
<attribute name="invisible">True</attribute>
321+
</xpath>
238322
</field>
239323
</record>
240324
<record id="crm.crm_lead_all_leads" model="ir.actions.act_window">

ps_planning/models/ps_contracted_line.py

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,31 @@
88
from odoo.exceptions import UserError, ValidationError
99

1010

11+
def _get_work_days_dates(date_start, date_end):
12+
start_weekday = date_start.weekday()
13+
end_weekday = date_end.weekday()
14+
weeks = (
15+
(
16+
(date_end + relativedelta(weekday=SU))
17+
- (
18+
date_start
19+
+ (
20+
relativedelta(weekday=SA)
21+
if start_weekday != 6
22+
else relativedelta(days=-1)
23+
)
24+
)
25+
).days
26+
- 1
27+
) / 7
28+
days = weeks * 5
29+
if start_weekday < 5:
30+
days += 5 - start_weekday
31+
if end_weekday < 4:
32+
days -= 4 - end_weekday
33+
return days
34+
35+
1136
class PsContractedLine(models.Model):
1237
_name = "ps.contracted.line"
1338
_inherit = "ps.planning.department.mixin"
@@ -222,25 +247,4 @@ def _get_work_days(self, period):
222247
return self._get_work_days_dates(period.date_start, period.date_end)
223248

224249
def _get_work_days_dates(self, date_start, date_end):
225-
start_weekday = date_start.weekday()
226-
end_weekday = date_end.weekday()
227-
weeks = (
228-
(
229-
(date_end + relativedelta(weekday=SU))
230-
- (
231-
date_start
232-
+ (
233-
relativedelta(weekday=SA)
234-
if start_weekday != 6
235-
else relativedelta(days=-1)
236-
)
237-
)
238-
).days
239-
- 1
240-
) / 7
241-
days = weeks * 5
242-
if start_weekday < 5:
243-
days += 5 - start_weekday
244-
if end_weekday < 4:
245-
days -= 4 - end_weekday
246-
return days
250+
return _get_work_days_dates(date_start, date_end)

0 commit comments

Comments
 (0)