Skip to content

Commit 3242e70

Browse files
committed
[FIX] project: allow partner_id on new project created from template
Before this commit, when creating a new project from a template, the 'partner_id' field was being removed from the values given to 'action_create_from_template()', even if it was explicitly set in the 'values' parameters we want the new project to have. For instance when specifying the 'Customer' field from the project creation from template wizard, it was not being taken into account, and the new project was created without a partner. Same when a product is configured to generate a project from a template, the partner was not set on the new project. We adapt the copy method of project to do so. We also make projects billable by default and remove some 'default_allow_billable' contexts as it's not useful anymore, and we adapt tests accordingly.
1 parent ecd2f8f commit 3242e70

11 files changed

+27
-30
lines changed

addons/project/models/project_project.py

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -473,22 +473,20 @@ def map_tasks(self, new_project_id):
473473
return True
474474

475475
def copy_data(self, default=None):
476+
default = dict(default or {})
476477
vals_list = super().copy_data(default=default)
477-
if default and 'name' in default:
478-
return vals_list
479478
copy_from_template = self.env.context.get('copy_from_template')
480479
for project, vals in zip(self, vals_list):
481480
if project.is_template and not copy_from_template:
482481
vals['is_template'] = True
483482
if copy_from_template:
484-
# We can make last_update_status as None because it is a required field
485-
vals.pop("last_update_status", None)
486-
for field in set(self._get_template_field_blacklist()) & set(vals.keys()):
487-
del vals[field]
488-
vals["name"] = project.name
483+
for field in self._get_template_field_blacklist():
484+
if field in vals and field not in default:
485+
del vals[field]
486+
if copy_from_template or (not project.is_template and vals.get('is_template')):
487+
vals['name'] = default.get('name', project.name)
489488
else:
490-
if project.is_template or not vals.get("is_template"):
491-
vals["name"] = self.env._("%s (copy)", project.name)
489+
vals['name'] = default.get('name', self.env._('%s (copy)', project.name))
492490
return vals_list
493491

494492
def copy(self, default=None):
@@ -1292,10 +1290,7 @@ def action_create_from_template(self, values=None, role_to_users_mapping=None):
12921290
key.removeprefix('default_'): value
12931291
for key, value in self.env.context.items()
12941292
if key.startswith('default_') and key.removeprefix('default_') in self._get_template_default_context_whitelist()
1295-
} | values | {
1296-
field: False
1297-
for field in self._get_template_field_blacklist()
1298-
}
1293+
} | values
12991294
project = self.with_context(copy_from_template=True).copy(default=default)
13001295
project.message_post(body=self.env._("Project created from template %(name)s.", name=self.name))
13011296

addons/project/views/project_project_views.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,7 @@
728728
<kanban position="attributes">
729729
<attribute name="js_class"></attribute>
730730
</kanban>
731+
<span name="partner_name" position="replace"/>
731732
</field>
732733
</record>
733734

addons/project/wizard/project_template_create_wizard.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,14 @@ def _default_role_to_users_ids(self):
1717
date = fields.Date(string='Expiration Date')
1818
alias_name = fields.Char(string="Alias Name")
1919
alias_domain_id = fields.Many2one("mail.alias.domain", string="Alias Domain")
20-
partner_id = fields.Many2one("res.partner")
2120
template_id = fields.Many2one("project.project", default=lambda self: self._context.get('template_id'))
2221
role_to_users_ids = fields.One2many('project.template.role.to.users.map', 'wizard_id', default=_default_role_to_users_ids)
2322

2423
def _get_template_whitelist_fields(self):
2524
"""
2625
Whitelist of fields of this wizard that will be used when creating a project from a template.
2726
"""
28-
return ["name", "date_start", "date", "alias_name", "alias_domain_id", "partner_id"]
27+
return ["name", "date_start", "date", "alias_name", "alias_domain_id"]
2928

3029
def _create_project_from_template(self):
3130
# Dictionary with all whitelist fields and their values

addons/sale_project/models/project_project.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def _domain_sale_line_id(self):
2424
])
2525
return domain
2626

27-
allow_billable = fields.Boolean("Billable")
27+
allow_billable = fields.Boolean("Billable", default=True)
2828
sale_line_id = fields.Many2one(
2929
'sale.order.line', 'Sales Order Item', copy=False,
3030
compute="_compute_sale_line_id", store=True, readonly=False, index='btree_not_null',

addons/sale_project/models/sale_order.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,6 @@ def action_create_project(self):
227227
'default_sale_line_id': default_sale_line.id,
228228
'default_partner_id': self.partner_id.id,
229229
'default_user_ids': [self.env.uid],
230-
'default_allow_billable': 1,
231230
'hide_allow_billable': True,
232231
'default_company_id': self.company_id.id,
233232
'generate_milestone': default_sale_line.product_id.service_policy == 'delivered_milestones',
@@ -254,7 +253,6 @@ def action_view_project_ids(self):
254253
**self._context,
255254
'default_partner_id': self.partner_id.id,
256255
'default_sale_line_id': default_sale_line.id,
257-
'default_allow_billable': 1,
258256
}
259257
}
260258
if len(self.with_context(active_test=False).project_ids) == 1:

addons/sale_project/tests/test_child_tasks.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ def test_write_partner_id_on_parent_write_on_child(self):
113113
'name': 'child',
114114
'partner_id': False,
115115
'parent_id': parent.id,
116-
'project_id': self.env['project.project'].create({'name': 'proute'}).id,
116+
'project_id': self.env['project.project'].create({'name': 'proute', 'allow_billable': False}).id,
117117
})
118118
self.assertFalse(child.partner_id)
119119
parent.write({'partner_id': self.user.partner_id.id})

addons/sale_project/views/product_views.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@
1616
<div class="o_td_label d-inline-flex" invisible="service_tracking != 'task_global_project'">
1717
<label for='project_id'/>
1818
</div>
19-
<field name="project_id" context="{'default_allow_billable': True}" invisible="service_tracking != 'task_global_project'" nolabel="1" placeholder="Defined on quotation"/>
19+
<field name="project_id" invisible="service_tracking != 'task_global_project'" nolabel="1" placeholder="Defined on quotation"/>
2020
<div class="o_td_label d-inline-flex" invisible="service_tracking not in ['task_in_project', 'project_only']">
2121
<label for='project_template_id'/>
2222
</div>
23-
<field name="project_template_id" context="{'active_test': False, 'default_allow_billable': True, 'default_is_template': True}" invisible="service_tracking not in ['task_in_project', 'project_only']" nolabel="1" placeholder="Empty project"/>
23+
<field name="project_template_id" context="{'active_test': False, 'default_is_template': True}" invisible="service_tracking not in ['task_in_project', 'project_only']" nolabel="1" placeholder="Empty project"/>
2424
<field name="service_policy"
2525
string="Invoicing Policy"
2626
invisible="type != 'service' or sale_ok == False"

addons/sale_project/views/project_task_views.xml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@
147147
<field name="inherit_id" ref="project.quick_create_task_form"/>
148148
<field name="arch" type="xml">
149149
<xpath expr="//field[@name='project_id']" position="attributes">
150-
<attribute name="context">{'default_allow_billable': True, 'default_type_ids': [(4, context.get('default_stage_id', False))]}
150+
<attribute name="context">{'default_type_ids': [(4, context.get('default_stage_id', False))]}
151151
</attribute>
152152
</xpath>
153153
</field>
@@ -238,9 +238,6 @@
238238
<attribute name="column_invisible">not parent.allow_billable</attribute>
239239
<attribute name="invisible">not allow_billable</attribute>
240240
</xpath>
241-
<field name="project_id" position="attributes">
242-
<attribute name="context">{'default_allow_billable': True}</attribute>
243-
</field>
244241
</field>
245242
</record>
246243

addons/sale_project/views/project_views.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,16 +87,16 @@
8787
</record>
8888

8989
<record id="project.open_view_project_all_config" model="ir.actions.act_window">
90-
<field name="context">{'default_allow_billable': True, 'sale_show_partner_name': True, 'display_milestone_deadline': True}</field>
90+
<field name="context">{'sale_show_partner_name': True, 'display_milestone_deadline': True}</field>
9191
</record>
9292
<record id="project.open_view_project_all_config_group_stage" model="ir.actions.act_window">
93-
<field name="context">{'default_allow_billable': True, 'sale_show_partner_name': True}</field>
93+
<field name="context">{'sale_show_partner_name': True}</field>
9494
</record>
9595
<record id="project.open_view_project_all" model="ir.actions.act_window">
96-
<field name="context">{'default_allow_billable': True, 'sale_show_partner_name': True, 'display_milestone_deadline': True}</field>
96+
<field name="context">{'sale_show_partner_name': True, 'display_milestone_deadline': True}</field>
9797
</record>
9898
<record id="project.open_view_project_all_group_stage" model="ir.actions.act_window">
99-
<field name="context">{'default_allow_billable': True, 'sale_show_partner_name': True}</field>
99+
<field name="context">{'sale_show_partner_name': True}</field>
100100
</record>
101101

102102
<record id="project_templates_view_list" model="ir.ui.view">

addons/sale_project/views/sale_order_views.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
</button>
4848
<field name="journal_id" position="before">
4949
<field name="project_id" groups="project.group_project_user"
50-
context="{'default_allow_billable': True, 'default_partner_id': partner_id, 'order_id': id, 'order_state' : state}"/>
50+
context="{'default_partner_id': partner_id, 'order_id': id, 'order_state' : state}"/>
5151
</field>
5252
</field>
5353
</record>

addons/sale_project/wizard/project_template_create_wizard.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,11 @@
44
class ProjectTemplateCreateWizard(models.TransientModel):
55
_inherit = 'project.template.create.wizard'
66

7+
partner_id = fields.Many2one("res.partner")
78
allow_billable = fields.Boolean(related="template_id.allow_billable")
9+
10+
def _get_template_whitelist_fields(self):
11+
res = super()._get_template_whitelist_fields()
12+
if self.allow_billable:
13+
res.append("partner_id")
14+
return res

0 commit comments

Comments
 (0)