[REM] core: remove name_get API
Rationale ========= Since v8, the `display_name` field is present on all models. By default, `display_name` uses `name_get` which has pretty much the same purpose (return record name used by the web client). Gradually, many (backend) developers (and the ORM: https://github.com/odoo/odoo/commit/6da1c3ac4c036eac289597602976538e243cb939) started using `display_name` (more convenient than `record.name_get()[0][1]`) but it still had the `name_get` override. It becomes more complex than necessary and poeple start to misunderstand the two (and sometimes override both, leading to inconstiencies between `display_name`/`name_get`). To simplify the ORM and the API, we decided to keep only one of them, the `display_name` field: - It is much more convenient from a backend point of view (`record.name_get()[0][1]` vs `record.display_name`) - It is cached during the same transaction (and invalidated if its dependencies change) - It can be overridden like any other compute field (override `_compute_display_name` with any extra dependencies) - `name_get` is replaced by `read(['display_name'])` (API perceptive), which can actually be more efficient (if `display_name`'s depends are correct, the ORM will only fetch the fields it needs instead of every prefetchable field) Changes ======= - Deprecates `name_get` for the v17 and based the method on `display_name` (the opposite of before) - Converts all usage of `name_get` - Overrides of `name_get` are now overrides of `_compute_display_name` - For `res.partner`, rename the field store `display_name` into `complete_name` because `display_name` context-dependent and it makes no sense to have a compute store that is context-dependent. - Previously, it was possible to return multiple names for the same record with `name_get`, but it was tricky and most of the usage of this `name_get` didn't take this into account. The only example of this is the `name_get` of `product.product` (now use `", ".join(<names>)`). Part-of: odoo/odoo#122085
This commit is contained in:
@@ -597,12 +597,9 @@ class AccountAccount(models.Model):
|
||||
self.name = name
|
||||
self.code = code
|
||||
|
||||
def name_get(self):
|
||||
result = []
|
||||
def _compute_display_name(self):
|
||||
for account in self:
|
||||
name = account.code + ' ' + account.name
|
||||
result.append((account.id, name))
|
||||
return result
|
||||
account.display_name = f"{account.code} {account.name}"
|
||||
|
||||
@api.returns('self', lambda value: value.id)
|
||||
def copy(self, default=None):
|
||||
@@ -701,7 +698,8 @@ class AccountAccount(models.Model):
|
||||
"""
|
||||
if 'import_file' in self.env.context:
|
||||
code, name = self._split_code_name(name)
|
||||
return self.create({'code': code, 'name': name}).name_get()[0]
|
||||
record = self.create({'code': code, 'name': name})
|
||||
return record.id, record.display_name
|
||||
raise ValidationError(_("Please create new accounts from the Chart of Accounts menu."))
|
||||
|
||||
@api.model_create_multi
|
||||
@@ -828,15 +826,14 @@ class AccountGroup(models.Model):
|
||||
if not group.code_prefix_start or group.code_prefix_start > group.code_prefix_end:
|
||||
group.code_prefix_start = group.code_prefix_end
|
||||
|
||||
def name_get(self):
|
||||
result = []
|
||||
def _compute_display_name(self):
|
||||
for group in self:
|
||||
prefix = group.code_prefix_start and str(group.code_prefix_start)
|
||||
if prefix and group.code_prefix_end != group.code_prefix_start:
|
||||
prefix += '-' + str(group.code_prefix_end)
|
||||
name = (prefix and (prefix + ' ') or '') + group.name
|
||||
result.append((group.id, name))
|
||||
return result
|
||||
group.display_name = name
|
||||
|
||||
|
||||
@api.model
|
||||
def _name_search(self, name, domain=None, operator='ilike', limit=None, order=None):
|
||||
|
||||
@@ -14,18 +14,15 @@ class AccountAccountTag(models.Model):
|
||||
tax_negate = fields.Boolean(string="Negate Tax Balance", help="Check this box to negate the absolute value of the balance of the lines associated with this tag in tax report computation.")
|
||||
country_id = fields.Many2one(string="Country", comodel_name='res.country', help="Country for which this tag is available, when applied on taxes.")
|
||||
|
||||
def name_get(self):
|
||||
def _compute_display_name(self):
|
||||
if not self.env.company.multi_vat_foreign_country_ids:
|
||||
return super().name_get()
|
||||
return super()._compute_display_name()
|
||||
|
||||
res = []
|
||||
for tag in self:
|
||||
name = tag.name
|
||||
if tag.applicability == "taxes" and tag.country_id and tag.country_id != self.env.company.account_fiscal_country_id:
|
||||
name = _("%s (%s)", tag.name, tag.country_id.code)
|
||||
res.append((tag.id, name,))
|
||||
|
||||
return res
|
||||
tag.display_name = name
|
||||
|
||||
@api.model
|
||||
def _get_tax_tags(self, tag_name, country_id):
|
||||
|
||||
@@ -18,6 +18,6 @@ class AccountIncoterms(models.Model):
|
||||
'Active', default=True,
|
||||
help="By unchecking the active field, you may hide an INCOTERM you will not use.")
|
||||
|
||||
def name_get(self):
|
||||
return [(incoterm.id, '%s%s' % (incoterm.code and '[%s] ' % incoterm.code or '', incoterm.name))
|
||||
for incoterm in self]
|
||||
def _compute_display_name(self):
|
||||
for incoterm in self:
|
||||
incoterm.display_name = '%s%s' % (incoterm.code and '[%s] ' % incoterm.code or '', incoterm.name)
|
||||
|
||||
@@ -696,14 +696,12 @@ class AccountJournal(models.Model):
|
||||
'journal_id': self,
|
||||
}).id
|
||||
|
||||
def name_get(self):
|
||||
res = []
|
||||
def _compute_display_name(self):
|
||||
for journal in self:
|
||||
name = journal.name
|
||||
if journal.currency_id and journal.currency_id != journal.company_id.currency_id:
|
||||
name = "%s (%s)" % (name, journal.currency_id.name)
|
||||
res += [(journal.id, name)]
|
||||
return res
|
||||
name = f"{name} ({journal.currency_id.name})"
|
||||
journal.display_name = name
|
||||
|
||||
def action_configure_bank_journal(self):
|
||||
""" This function is called by the "configure" button of bank journals,
|
||||
|
||||
@@ -2387,11 +2387,9 @@ class AccountMove(models.Model):
|
||||
self.line_ids.unlink()
|
||||
return super().unlink()
|
||||
|
||||
def name_get(self):
|
||||
result = []
|
||||
def _compute_display_name(self):
|
||||
for move in self:
|
||||
result.append((move.id, move._get_move_display_name(show_ref=True)))
|
||||
return result
|
||||
move.display_name = move._get_move_display_name(show_ref=True)
|
||||
|
||||
def onchange(self, values, field_name, field_onchange):
|
||||
if field_name in ('line_ids', 'invoice_line_ids'):
|
||||
|
||||
@@ -1525,14 +1525,15 @@ class AccountMoveLine(models.Model):
|
||||
|
||||
return res
|
||||
|
||||
def name_get(self):
|
||||
return [(line.id, " ".join(
|
||||
element for element in (
|
||||
line.move_id.name,
|
||||
line.ref and f"({line.ref})",
|
||||
line.name or line.product_id.display_name,
|
||||
) if element
|
||||
)) for line in self]
|
||||
def _compute_display_name(self):
|
||||
for line in self:
|
||||
line.display_name = " ".join(
|
||||
element for element in (
|
||||
line.move_id.name,
|
||||
line.ref and f"({line.ref})",
|
||||
line.name or line.product_id.display_name,
|
||||
) if element
|
||||
)
|
||||
|
||||
def copy_data(self, default=None):
|
||||
data_list = super().copy_data(default=default)
|
||||
|
||||
@@ -740,8 +740,9 @@ class AccountPayment(models.Model):
|
||||
return res
|
||||
|
||||
@api.depends('move_id.name')
|
||||
def name_get(self):
|
||||
return [(payment.id, payment.move_id.name != '/' and payment.move_id.name or _('Draft Payment')) for payment in self]
|
||||
def _compute_display_name(self):
|
||||
for payment in self:
|
||||
payment.display_name = payment.move_id.name if payment.move_id.name != '/' else _('Draft Payment')
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# SYNCHRONIZATION account.payment <-> account.move
|
||||
|
||||
@@ -119,10 +119,11 @@ class AccountPaymentMethodLine(models.Model):
|
||||
company_id = fields.Many2one(related='journal_id.company_id')
|
||||
available_payment_method_ids = fields.Many2many(related='journal_id.available_payment_method_ids')
|
||||
|
||||
def name_get(self):
|
||||
if self.env.context.get('show_payment_journal_id'):
|
||||
return [(method.id, "%s (%s)" % (method.name, method.journal_id.name)) for method in self]
|
||||
return super().name_get()
|
||||
def _compute_display_name(self):
|
||||
if not self.env.context.get('show_payment_journal_id'):
|
||||
return super()._compute_display_name()
|
||||
for method in self:
|
||||
method.display_name = f"{method.name} ({method.journal_id.name})"
|
||||
|
||||
@api.depends('payment_method_id.name')
|
||||
def _compute_name(self):
|
||||
|
||||
@@ -203,11 +203,9 @@ class AccountReport(models.Model):
|
||||
return name
|
||||
|
||||
@api.depends('name', 'country_id')
|
||||
def name_get(self):
|
||||
result = []
|
||||
def _compute_display_name(self):
|
||||
for report in self:
|
||||
result.append((report.id, report.name + (f' ({report.country_id.code})' if report.country_id else '')))
|
||||
return result
|
||||
report.display_name = report.name + (f' ({report.country_id.code})' if report.country_id else '')
|
||||
|
||||
|
||||
class AccountReportLine(models.Model):
|
||||
@@ -561,8 +559,10 @@ class AccountReportExpression(models.Model):
|
||||
tags_to_archive.active = False
|
||||
tags_to_unlink.unlink()
|
||||
|
||||
def name_get(self):
|
||||
return [(expr.id, f'{expr.report_line_name} [{expr.label}]') for expr in self]
|
||||
def _compute_display_name(self):
|
||||
for expr in self:
|
||||
expr.display_name = f'{expr.report_line_name} [{expr.label}]'
|
||||
|
||||
|
||||
def _expand_aggregations(self):
|
||||
"""Return self and its full aggregation expression dependency"""
|
||||
|
||||
@@ -362,8 +362,7 @@ class AccountTax(models.Model):
|
||||
default['name'] = _("%s (Copy)") % self.name
|
||||
return super(AccountTax, self).copy(default=default)
|
||||
|
||||
def name_get(self):
|
||||
name_list = []
|
||||
def _compute_display_name(self):
|
||||
type_tax_use = dict(self._fields['type_tax_use']._description_selection(self.env))
|
||||
tax_scope = dict(self._fields['tax_scope']._description_selection(self.env))
|
||||
for record in self:
|
||||
@@ -372,8 +371,7 @@ class AccountTax(models.Model):
|
||||
name += ' (%s)' % type_tax_use.get(record.type_tax_use)
|
||||
if record.tax_scope:
|
||||
name += ' (%s)' % tax_scope.get(record.tax_scope)
|
||||
name_list += [(record.id, name)]
|
||||
return name_list
|
||||
record.display_name = name
|
||||
|
||||
@api.onchange('amount')
|
||||
def onchange_amount(self):
|
||||
|
||||
@@ -307,15 +307,13 @@ class ResPartnerBank(models.Model):
|
||||
account.partner_id._message_log(body=msg)
|
||||
return super().unlink()
|
||||
|
||||
def name_get(self):
|
||||
res = super().name_get()
|
||||
def _compute_display_name(self):
|
||||
super()._compute_display_name()
|
||||
if self.env.context.get('display_account_trust'):
|
||||
res = []
|
||||
for acc in self:
|
||||
trusted_label = _('trusted') if acc.allow_out_payment else _('untrusted')
|
||||
if acc.bank_id:
|
||||
name = '{} - {} ({})'.format(acc.acc_number, acc.bank_id.name, trusted_label)
|
||||
name = f'{acc.acc_number} - {acc.bank_id.name} ({trusted_label})'
|
||||
else:
|
||||
name = '{} ({})'.format(acc.acc_number, trusted_label)
|
||||
res.append((acc.id, name))
|
||||
return res
|
||||
name = f'{acc.acc_number} ({trusted_label})'
|
||||
acc.display_name = name
|
||||
|
||||
@@ -115,16 +115,14 @@ class AccountAnalyticAccount(models.Model):
|
||||
if self._cr.fetchone():
|
||||
raise UserError(_("You can't set a different company on your analytic account since there are some analytic items linked to it."))
|
||||
|
||||
def name_get(self):
|
||||
res = []
|
||||
def _compute_display_name(self):
|
||||
for analytic in self:
|
||||
name = analytic.name
|
||||
if analytic.code:
|
||||
name = f'[{analytic.code}] {name}'
|
||||
if analytic.partner_id.commercial_partner_id.name:
|
||||
name = f'{name} - {analytic.partner_id.commercial_partner_id.name}'
|
||||
res.append((analytic.id, name))
|
||||
return res
|
||||
analytic.display_name = name
|
||||
|
||||
def copy_data(self, default=None):
|
||||
default = dict(default or {})
|
||||
|
||||
@@ -15,9 +15,7 @@ class City(models.Model):
|
||||
country_id = fields.Many2one(comodel_name='res.country', string='Country', required=True)
|
||||
state_id = fields.Many2one(comodel_name='res.country.state', string='State', domain="[('country_id', '=', country_id)]")
|
||||
|
||||
def name_get(self):
|
||||
res = []
|
||||
def _compute_display_name(self):
|
||||
for city in self:
|
||||
name = city.name if not city.zipcode else '%s (%s)' % (city.name, city.zipcode)
|
||||
res.append((city.id, name))
|
||||
return res
|
||||
name = city.name if not city.zipcode else f'{city.name} ({city.zipcode})'
|
||||
city.display_name = name
|
||||
|
||||
@@ -59,7 +59,7 @@ def _compute_sparse(self, records):
|
||||
def _inverse_sparse(self, records):
|
||||
for record in records:
|
||||
values = record[self.sparse]
|
||||
value = self.convert_to_read(record[self.name], record, use_name_get=False)
|
||||
value = self.convert_to_read(record[self.name], record, use_display_name=False)
|
||||
if value:
|
||||
if values.get(self.name) != value:
|
||||
values[self.name] = value
|
||||
|
||||
@@ -645,7 +645,7 @@ class Meeting(models.Model):
|
||||
|
||||
return True
|
||||
|
||||
def name_get(self):
|
||||
def _compute_display_name(self):
|
||||
""" Hide private events' name for events which don't belong to the current user
|
||||
"""
|
||||
hidden = self.filtered(
|
||||
@@ -654,11 +654,8 @@ class Meeting(models.Model):
|
||||
evt.user_id.id != self.env.uid and
|
||||
self.env.user.partner_id not in evt.partner_ids
|
||||
)
|
||||
|
||||
shown = self - hidden
|
||||
shown_names = super(Meeting, shown).name_get()
|
||||
obfuscated_names = [(eid, _('Busy')) for eid in hidden.ids]
|
||||
return shown_names + obfuscated_names
|
||||
hidden.display_name = _('Busy')
|
||||
super(Meeting, self - hidden)._compute_display_name()
|
||||
|
||||
@api.model
|
||||
def read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True):
|
||||
|
||||
@@ -18,8 +18,9 @@ class PeopleRole(models.Model):
|
||||
]
|
||||
|
||||
@api.depends('name')
|
||||
def name_get(self):
|
||||
return [(role.id, role.name.replace('_', ' ').title()) for role in self]
|
||||
def _compute_display_name(self):
|
||||
for role in self:
|
||||
role.display_name = role.name.replace('_', ' ').title()
|
||||
|
||||
|
||||
class PeopleSeniority(models.Model):
|
||||
@@ -35,5 +36,6 @@ class PeopleSeniority(models.Model):
|
||||
]
|
||||
|
||||
@api.depends('name')
|
||||
def name_get(self):
|
||||
return [(seniority.id, seniority.name.replace('_', ' ').title()) for seniority in self]
|
||||
def _compute_display_name(self):
|
||||
for seniority in self:
|
||||
seniority.display_name = seniority.name.replace('_', ' ').title()
|
||||
|
||||
@@ -17,5 +17,6 @@ class PeopleSeniority(models.Model):
|
||||
]
|
||||
|
||||
@api.depends('name')
|
||||
def name_get(self):
|
||||
return [(seniority.id, seniority.name.replace('_', ' ').title()) for seniority in self]
|
||||
def _compute_display_name(self):
|
||||
for seniority in self:
|
||||
seniority.display_name = seniority.name.replace('_', ' ').title()
|
||||
|
||||
@@ -589,11 +589,10 @@ class EventEvent(models.Model):
|
||||
self.message_subscribe([vals['organizer_id']])
|
||||
return res
|
||||
|
||||
def name_get(self):
|
||||
def _compute_display_name(self):
|
||||
"""Adds ticket seats availability if requested by context."""
|
||||
if not self.env.context.get('name_with_seats_availability'):
|
||||
return super().name_get()
|
||||
res = []
|
||||
return super()._compute_display_name()
|
||||
for event in self:
|
||||
# event or its tickets are sold out
|
||||
if event.event_registrations_sold_out:
|
||||
@@ -606,8 +605,7 @@ class EventEvent(models.Model):
|
||||
)
|
||||
else:
|
||||
name = event.name
|
||||
res.append((event.id, name))
|
||||
return res
|
||||
event.display_name = name
|
||||
|
||||
@api.returns('self', lambda value: value.id)
|
||||
def copy(self, default=None):
|
||||
|
||||
@@ -162,10 +162,11 @@ class EventRegistration(models.Model):
|
||||
|
||||
return ret
|
||||
|
||||
def name_get(self):
|
||||
""" Custom name_get in case a registration is nott linked to an attendee
|
||||
def _compute_display_name(self):
|
||||
""" Custom display_name in case a registration is nott linked to an attendee
|
||||
"""
|
||||
return [(registration.id, registration.name or f"#{registration.id}") for registration in self]
|
||||
for registration in self:
|
||||
registration.display_name = registration.name or f"#{registration.id}"
|
||||
|
||||
def toggle_active(self):
|
||||
pre_inactive = self - self.filtered(self._active_name)
|
||||
|
||||
@@ -163,11 +163,10 @@ class EventTicket(models.Model):
|
||||
raise ValidationError(_('There are not enough seats available for:')
|
||||
+ '\n%s\n' % '\n'.join(sold_out_tickets))
|
||||
|
||||
def name_get(self):
|
||||
def _compute_display_name(self):
|
||||
"""Adds ticket seats availability if requested by context."""
|
||||
if not self.env.context.get('name_with_seats_availability'):
|
||||
return super().name_get()
|
||||
res = []
|
||||
return super()._compute_display_name()
|
||||
for ticket in self:
|
||||
if not ticket.seats_max:
|
||||
name = ticket.name
|
||||
@@ -179,8 +178,7 @@ class EventTicket(models.Model):
|
||||
ticket_name=ticket.name,
|
||||
count=formatLang(self.env, ticket.seats_available, digits=0),
|
||||
)
|
||||
res.append((ticket.id, name))
|
||||
return res
|
||||
ticket.display_name = name
|
||||
|
||||
def _get_ticket_multiline_description(self):
|
||||
""" Compute a multiline description of this ticket. It is used when ticket
|
||||
|
||||
@@ -14,5 +14,6 @@ class FleetVehicleAssignationLog(models.Model):
|
||||
date_start = fields.Date(string="Start Date")
|
||||
date_end = fields.Date(string="End Date")
|
||||
|
||||
def name_get(self):
|
||||
return [(rec.id, f'{rec.vehicle_id.name} - {rec.driver_id.name}') for rec in self]
|
||||
def _compute_display_name(self):
|
||||
for rec in self:
|
||||
rec.display_name = f'{rec.vehicle_id.name} - {rec.driver_id.name}'
|
||||
|
||||
@@ -53,14 +53,12 @@ class FleetVehicleModel(models.Model):
|
||||
domain = expression.AND([name_domain, domain])
|
||||
return self._search(domain, limit=limit, order=order)
|
||||
|
||||
def name_get(self):
|
||||
res = []
|
||||
def _compute_display_name(self):
|
||||
for record in self:
|
||||
name = record.name
|
||||
if record.brand_id.name:
|
||||
name = record.brand_id.name + '/' + name
|
||||
res.append((record.id, name))
|
||||
return res
|
||||
name = f"{record.brand_id.name}/{name}"
|
||||
record.display_name = name
|
||||
|
||||
def _compute_vehicle_count(self):
|
||||
group = self.env['fleet.vehicle']._read_group(
|
||||
|
||||
@@ -698,11 +698,10 @@ class Challenge(models.Model):
|
||||
message_body = _("The challenge %s is finished.", challenge.name)
|
||||
|
||||
if rewarded_users:
|
||||
user_names = rewarded_users.name_get()
|
||||
message_body += Markup("<br/>") + _(
|
||||
"Reward (badge %(badge_name)s) for every succeeding user was sent to %(users)s.",
|
||||
badge_name=challenge.reward_id.name,
|
||||
users=", ".join(name for (user_id, name) in user_names)
|
||||
users=", ".join(rewarded_users.mapped('display_name'))
|
||||
)
|
||||
else:
|
||||
message_body += Markup("<br/>") + _("Nobody has succeeded to reach every goal, no badge is rewarded for this challenge.")
|
||||
|
||||
@@ -31,14 +31,16 @@ class Department(models.Model):
|
||||
master_department_id = fields.Many2one(
|
||||
'hr.department', 'Master Department', compute='_compute_master_department_id', store=True)
|
||||
|
||||
def name_get(self):
|
||||
if not self.env.context.get('hierarchical_naming', True):
|
||||
return [(record.id, record.name) for record in self]
|
||||
return super(Department, self).name_get()
|
||||
def _compute_display_name(self):
|
||||
if self.env.context.get('hierarchical_naming', True):
|
||||
return super()._compute_display_name()
|
||||
for record in self:
|
||||
record.display_name = record.name
|
||||
|
||||
@api.model
|
||||
def name_create(self, name):
|
||||
return self.create({'name': name}).name_get()[0]
|
||||
record = self.create({'name': name})
|
||||
return record.id, record.display_name
|
||||
|
||||
@api.depends('name', 'parent_id.complete_name')
|
||||
def _compute_complete_name(self):
|
||||
|
||||
@@ -191,10 +191,11 @@ class HrEmployeePrivate(models.Model):
|
||||
})
|
||||
}
|
||||
|
||||
def name_get(self):
|
||||
def _compute_display_name(self):
|
||||
if self.check_access_rights('read', raise_exception=False):
|
||||
return super(HrEmployeePrivate, self).name_get()
|
||||
return self.env['hr.employee.public'].browse(self.ids).name_get()
|
||||
return super()._compute_display_name()
|
||||
for employee_private, employee_public in zip(self, self.env['hr.employee.public'].browse(self.ids)):
|
||||
employee_private.display_name = employee_public.display_name
|
||||
|
||||
def search_fetch(self, domain, field_names, offset=0, limit=None, order=None):
|
||||
if self.check_access_rights('read', raise_exception=False):
|
||||
|
||||
@@ -13,17 +13,17 @@ class Partner(models.Model):
|
||||
help="Related employees based on their private address")
|
||||
employees_count = fields.Integer(compute='_compute_employees_count', groups="hr.group_hr_user")
|
||||
|
||||
def name_get(self):
|
||||
def _compute_display_name(self):
|
||||
""" Override to allow an employee to see its private address in his profile.
|
||||
This avoids to relax access rules on `res.parter` and to add an `ir.rule`.
|
||||
(advantage in both security and performance).
|
||||
Use a try/except instead of systematically checking to minimize the impact on performance.
|
||||
"""
|
||||
try:
|
||||
return super(Partner, self).name_get()
|
||||
super()._compute_display_name()
|
||||
except AccessError as e:
|
||||
if len(self) == 1 and self in self.env.user.employee_ids.mapped('address_home_id'):
|
||||
return super(Partner, self.sudo()).name_get()
|
||||
super(Partner, self.sudo())._compute_display_name()
|
||||
raise e
|
||||
|
||||
def _compute_employees_count(self):
|
||||
|
||||
@@ -31,21 +31,21 @@ class HrAttendance(models.Model):
|
||||
check_out = fields.Datetime(string="Check Out")
|
||||
worked_hours = fields.Float(string='Worked Hours', compute='_compute_worked_hours', store=True, readonly=True)
|
||||
|
||||
def name_get(self):
|
||||
result = []
|
||||
def _compute_display_name(self):
|
||||
for attendance in self:
|
||||
if not attendance.check_out:
|
||||
result.append((attendance.id, _("%(empl_name)s from %(check_in)s") % {
|
||||
'empl_name': attendance.employee_id.name,
|
||||
'check_in': format_datetime(self.env, attendance.check_in, dt_format=False),
|
||||
}))
|
||||
attendance.display_name = _(
|
||||
"%s from %s",
|
||||
attendance.employee_id.name,
|
||||
format_datetime(self.env, attendance.check_in, dt_format=False)
|
||||
)
|
||||
else:
|
||||
result.append((attendance.id, _("%(empl_name)s from %(check_in)s to %(check_out)s") % {
|
||||
'empl_name': attendance.employee_id.name,
|
||||
'check_in': format_datetime(self.env, attendance.check_in, dt_format=False),
|
||||
'check_out': format_datetime(self.env, attendance.check_out, dt_format=False),
|
||||
}))
|
||||
return result
|
||||
attendance.display_name = _(
|
||||
"%s from %s to %s",
|
||||
attendance.employee_id.name,
|
||||
format_datetime(self.env, attendance.check_in, dt_format=False),
|
||||
format_datetime(self.env, attendance.check_out, dt_format=False),
|
||||
)
|
||||
|
||||
def _get_employee_calendar(self):
|
||||
self.ensure_one()
|
||||
|
||||
@@ -17,7 +17,6 @@ class ContractHistory(models.Model):
|
||||
# to the employee. That's why we will use this id (employee_id) as the id of the hr.contract.history.
|
||||
contract_id = fields.Many2one('hr.contract', readonly=True)
|
||||
|
||||
display_name = fields.Char(compute='_compute_display_name')
|
||||
name = fields.Char('Contract Name', readonly=True)
|
||||
date_hired = fields.Date('Hire Date', readonly=True)
|
||||
date_start = fields.Date('Start Date', readonly=True)
|
||||
|
||||
@@ -61,7 +61,7 @@ class Department(models.Model):
|
||||
**self._get_action_context(),
|
||||
'search_default_active_time_off': 3,
|
||||
'hide_employee_name': 1,
|
||||
'holiday_status_name_get': False
|
||||
'holiday_status_display_name': False
|
||||
}
|
||||
return action
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ class HolidaysRequest(models.Model):
|
||||
defaults = super(HolidaysRequest, self).default_get(fields_list)
|
||||
defaults = self._default_get_request_parameters(defaults)
|
||||
|
||||
if self.env.context.get('holiday_status_name_get', True) and 'holiday_status_id' in fields_list and not defaults.get('holiday_status_id'):
|
||||
if self.env.context.get('holiday_status_display_name', True) and 'holiday_status_id' in fields_list and not defaults.get('holiday_status_id'):
|
||||
lt = self.env['hr.leave.type'].search(['|', ('requires_allocation', '=', 'no'), ('has_valid_allocation', '=', True)], limit=1, order='sequence')
|
||||
|
||||
if lt:
|
||||
@@ -774,19 +774,6 @@ class HolidaysRequest(models.Model):
|
||||
|
||||
@api.depends('employee_id', 'holiday_status_id')
|
||||
def _compute_display_name(self):
|
||||
super()._compute_display_name()
|
||||
|
||||
def onchange(self, values, field_name, field_onchange):
|
||||
# Try to force the leave_type name_get when creating new records
|
||||
# This is called right after pressing create and returns the name_get for
|
||||
# most fields in the view.
|
||||
if field_onchange.get('employee_id') and 'employee_id' not in self._context and values:
|
||||
employee_id = get_employee_from_context(values, self._context, self.env.user.employee_id.id)
|
||||
self = self.with_context(employee_id=employee_id)
|
||||
return super().onchange(values, field_name, field_onchange)
|
||||
|
||||
def name_get(self):
|
||||
res = []
|
||||
for leave in self:
|
||||
user_tz = timezone(leave.tz)
|
||||
date_from_utc = leave.date_from and leave.date_from.astimezone(user_tz).date()
|
||||
@@ -795,13 +782,9 @@ class HolidaysRequest(models.Model):
|
||||
if self.env.context.get('short_name'):
|
||||
short_leave_name = leave.name or time_off_type_display or _('Time Off')
|
||||
if leave.leave_type_request_unit == 'hour':
|
||||
res.append((
|
||||
leave.id,
|
||||
_("%s: %.2f hours") % (short_leave_name, leave.number_of_hours_display)))
|
||||
leave.display_name = _("%s: %.2f hours", short_leave_name, leave.number_of_hours_display)
|
||||
else:
|
||||
res.append((
|
||||
leave.id,
|
||||
_("%s: %.2f days") % (short_leave_name, leave.number_of_days)))
|
||||
leave.display_name = _("%s: %.2f days", short_leave_name, leave.number_of_days)
|
||||
else:
|
||||
if leave.holiday_type == 'company':
|
||||
target = leave.mode_company_id.name
|
||||
@@ -816,65 +799,55 @@ class HolidaysRequest(models.Model):
|
||||
display_date = format_date(self.env, date_from_utc) or ""
|
||||
if leave.leave_type_request_unit == 'hour':
|
||||
if self.env.context.get('hide_employee_name') and 'employee_id' in self.env.context.get('group_by', []):
|
||||
res.append((
|
||||
leave.id,
|
||||
_("%(leave_type)s: %(duration).2f hours on %(date)s",
|
||||
leave_type=time_off_type_display,
|
||||
duration=leave.number_of_hours_display,
|
||||
date=fields.Date.to_string(date_from_utc) or "",
|
||||
)
|
||||
))
|
||||
leave.display_name = _("%(leave_type)s: %(duration).2f hours on %(date)s",
|
||||
leave_type=time_off_type_display,
|
||||
duration=leave.number_of_hours_display,
|
||||
date=fields.Date.to_string(date_from_utc) or "",
|
||||
)
|
||||
elif not time_off_type_display:
|
||||
res.append((
|
||||
leave.id,
|
||||
_("%(person)s: %(duration).2f hours on %(date)s",
|
||||
person=target,
|
||||
duration=leave.number_of_hours_display,
|
||||
date=display_date,
|
||||
)
|
||||
))
|
||||
leave.display_name = _("%(person)s: %(duration).2f hours on %(date)s",
|
||||
person=target,
|
||||
duration=leave.number_of_hours_display,
|
||||
date=display_date,
|
||||
)
|
||||
else:
|
||||
res.append((
|
||||
leave.id,
|
||||
_("%(person)s on %(leave_type)s: %(duration).2f hours on %(date)s",
|
||||
person=target,
|
||||
leave_type=time_off_type_display,
|
||||
duration=leave.number_of_hours_display,
|
||||
date=display_date,
|
||||
)
|
||||
))
|
||||
leave.display_name = _("%(person)s on %(leave_type)s: %(duration).2f hours on %(date)s",
|
||||
person=target,
|
||||
leave_type=time_off_type_display,
|
||||
duration=leave.number_of_hours_display,
|
||||
date=display_date,
|
||||
)
|
||||
else:
|
||||
if leave.number_of_days > 1 and date_from_utc and date_to_utc:
|
||||
display_date += ' / %s' % format_date(self.env, date_to_utc) or ""
|
||||
if not target or self.env.context.get('hide_employee_name') and 'employee_id' in self.env.context.get('group_by', []):
|
||||
res.append((
|
||||
leave.id,
|
||||
_("%(leave_type)s: %(duration).2f days (%(start)s)",
|
||||
leave_type=time_off_type_display,
|
||||
duration=leave.number_of_days,
|
||||
start=display_date,
|
||||
)
|
||||
))
|
||||
leave.display_name = _("%(leave_type)s: %(duration).2f days (%(start)s)",
|
||||
leave_type=time_off_type_display,
|
||||
duration=leave.number_of_days,
|
||||
start=display_date,
|
||||
)
|
||||
elif not time_off_type_display:
|
||||
res.append((
|
||||
leave.id,
|
||||
_("%(person)s: %(duration).2f days (%(start)s)",
|
||||
person=target,
|
||||
duration=leave.number_of_days,
|
||||
start=display_date,
|
||||
)
|
||||
))
|
||||
leave.display_name = _("%(person)s: %(duration).2f days (%(start)s)",
|
||||
person=target,
|
||||
duration=leave.number_of_days,
|
||||
start=display_date,
|
||||
)
|
||||
else:
|
||||
res.append((
|
||||
leave.id,
|
||||
_("%(person)s on %(leave_type)s: %(duration).2f days (%(start)s)",
|
||||
person=target,
|
||||
leave_type=time_off_type_display,
|
||||
duration=leave.number_of_days,
|
||||
start=display_date,
|
||||
)
|
||||
))
|
||||
return res
|
||||
leave.display_name = _("%(person)s on %(leave_type)s: %(duration).2f days (%(start)s)",
|
||||
person=target,
|
||||
leave_type=time_off_type_display,
|
||||
duration=leave.number_of_days,
|
||||
start=display_date,
|
||||
)
|
||||
|
||||
def onchange(self, values, field_name, field_onchange):
|
||||
# Try to force the leave_type display_name when creating new records
|
||||
# This is called right after pressing create and returns the display_name for
|
||||
# most fields in the view.
|
||||
if field_onchange.get('employee_id') and 'employee_id' not in self._context and values:
|
||||
employee_id = get_employee_from_context(values, self._context, self.env.user.employee_id.id)
|
||||
self = self.with_context(employee_id=employee_id)
|
||||
return super().onchange(values, field_name, field_onchange)
|
||||
|
||||
def add_follower(self, employee_id):
|
||||
employee = self.env['hr.employee'].browse(employee_id)
|
||||
@@ -1373,18 +1346,16 @@ class HolidaysRequest(models.Model):
|
||||
|
||||
def _notify_manager(self):
|
||||
leaves = self.filtered(lambda hol: (hol.validation_type == 'both' and hol.state in ['validate1', 'validate']) or (hol.validation_type == 'manager' and hol.state == 'validate'))
|
||||
holiday_names = self.name_get()
|
||||
for holiday in leaves:
|
||||
responsible = holiday.employee_id.leave_manager_id.partner_id.ids
|
||||
if responsible:
|
||||
holiday_name = list(filter(lambda h: holiday.id in h, holiday_names))[0][1]
|
||||
self.env['mail.thread'].sudo().message_notify(
|
||||
partner_ids=responsible,
|
||||
model_description='Time Off',
|
||||
subject=_('Refused Time Off'),
|
||||
body=_(
|
||||
'%(holiday_name)s has been refused.',
|
||||
holiday_name=holiday_name,
|
||||
holiday_name=holiday.display_name,
|
||||
),
|
||||
email_layout_xmlid='mail.mail_notification_light',
|
||||
)
|
||||
@@ -1397,7 +1368,6 @@ class HolidaysRequest(models.Model):
|
||||
self._force_cancel(reason, 'mail.mt_note')
|
||||
|
||||
def _force_cancel(self, reason, msg_subtype='mail.mt_comment'):
|
||||
leave_names = self.name_get()
|
||||
recs = self.browse() if self.env.context.get(MODULE_UNINSTALL_FLAG) else self
|
||||
for leave in recs:
|
||||
leave.message_post(
|
||||
@@ -1418,14 +1388,13 @@ class HolidaysRequest(models.Model):
|
||||
responsibles |= leave.holiday_status_id.responsible_ids.partner_id
|
||||
|
||||
if responsibles:
|
||||
leave_name = list(filter(lambda h: leave.id in h, leave_names))[0][1]
|
||||
self.env['mail.thread'].sudo().message_notify(
|
||||
partner_ids=responsibles.ids,
|
||||
model_description='Time Off',
|
||||
subject=_('Canceled Time Off'),
|
||||
body=_(
|
||||
"%(leave_name)s has been cancelled with the justification: <br/> %(reason)s.",
|
||||
leave_name=leave_name,
|
||||
leave_name=leave.display_name,
|
||||
reason=reason
|
||||
),
|
||||
email_layout_xmlid='mail.mail_notification_light',
|
||||
|
||||
@@ -520,16 +520,15 @@ class HolidaysAllocation(models.Model):
|
||||
####################################################
|
||||
|
||||
def onchange(self, values, field_name, field_onchange):
|
||||
# Try to force the leave_type name_get when creating new records
|
||||
# This is called right after pressing create and returns the name_get for
|
||||
# Try to force the leave_type display_name when creating new records
|
||||
# This is called right after pressing create and returns the display_name for
|
||||
# most fields in the view.
|
||||
if field_onchange.get('employee_id') and 'employee_id' not in self._context and values:
|
||||
employee_id = get_employee_from_context(values, self._context, self.env.user.employee_id.id)
|
||||
self = self.with_context(employee_id=employee_id)
|
||||
return super().onchange(values, field_name, field_onchange)
|
||||
|
||||
def name_get(self):
|
||||
res = []
|
||||
def _compute_display_name(self):
|
||||
for allocation in self:
|
||||
if allocation.holiday_type == 'company':
|
||||
target = allocation.mode_company_id.name
|
||||
@@ -542,16 +541,12 @@ class HolidaysAllocation(models.Model):
|
||||
else:
|
||||
target = ', '.join(allocation.employee_ids.sudo().mapped('name'))
|
||||
|
||||
res.append(
|
||||
(allocation.id,
|
||||
_("Allocation of %(allocation_name)s: %(duration).2f %(duration_type)s to %(person)s",
|
||||
allocation_name=allocation.holiday_status_id.sudo().name,
|
||||
duration=allocation.number_of_hours_display if allocation.type_request_unit == 'hour' else allocation.number_of_days,
|
||||
duration_type=_('hours') if allocation.type_request_unit == 'hour' else _('days'),
|
||||
person=target
|
||||
))
|
||||
allocation.display_name = _("Allocation of %s: %.2f %s to %s",
|
||||
allocation.holiday_status_id.sudo().name,
|
||||
allocation.number_of_hours_display if allocation.type_request_unit == 'hour' else allocation.number_of_days,
|
||||
_('hours') if allocation.type_request_unit == 'hour' else _('days'),
|
||||
target,
|
||||
)
|
||||
return res
|
||||
|
||||
def add_follower(self, employee_id):
|
||||
employee = self.env['hr.employee'].browse(employee_id)
|
||||
|
||||
@@ -537,26 +537,26 @@ class HolidaysType(models.Model):
|
||||
if leave_type.employee_requests == 'no':
|
||||
leave_type.allocation_validation_type = 'officer'
|
||||
|
||||
def requested_name_get(self):
|
||||
return self._context.get('holiday_status_name_get', True) and self._context.get('employee_id')
|
||||
def requested_display_name(self):
|
||||
return self._context.get('holiday_status_display_name', True) and self._context.get('employee_id')
|
||||
|
||||
def name_get(self):
|
||||
if not self.requested_name_get():
|
||||
@api.depends('requires_allocation', 'virtual_remaining_leaves', 'max_leaves', 'request_unit')
|
||||
@api.depends_context('holiday_status_display_name', 'employee_id', 'from_manager_leave_form')
|
||||
def _compute_display_name(self):
|
||||
if not self.requested_display_name():
|
||||
# leave counts is based on employee_id, would be inaccurate if not based on correct employee
|
||||
return super(HolidaysType, self).name_get()
|
||||
res = []
|
||||
return super()._compute_display_name()
|
||||
for record in self:
|
||||
name = record.name
|
||||
if record.requires_allocation == "yes" and not self._context.get('from_manager_leave_form'):
|
||||
name = "%(name)s (%(count)s)" % {
|
||||
'name': name,
|
||||
'count': _('%g remaining out of %g') % (
|
||||
name = "{name} ({count})".format(
|
||||
name=name,
|
||||
count=_('%g remaining out of %g') % (
|
||||
float_round(record.virtual_remaining_leaves, precision_digits=2) or 0.0,
|
||||
float_round(record.max_leaves, precision_digits=2) or 0.0,
|
||||
) + (_(' hours') if record.request_unit == 'hour' else _(' days'))
|
||||
}
|
||||
res.append((record.id, name))
|
||||
return res
|
||||
) + (_(' hours') if record.request_unit == 'hour' else _(' days')),
|
||||
)
|
||||
record.display_name = name
|
||||
|
||||
@api.model
|
||||
def _search(self, domain, offset=0, limit=None, order=None, access_rights_uid=None):
|
||||
|
||||
@@ -679,7 +679,7 @@
|
||||
'search_default_active_employee': 3,
|
||||
'search_default_active_time_off': 4,
|
||||
'hide_employee_name': 1,
|
||||
'holiday_status_name_get': False}
|
||||
'holiday_status_display_name': False}
|
||||
</field>
|
||||
<field name="domain">['|', ('employee_id.company_id', 'in', allowed_company_ids),
|
||||
'&', ('multi_employee', '=', True),
|
||||
@@ -701,7 +701,7 @@
|
||||
<field name="search_view_id" ref="hr_holidays.hr_leave_view_search_manager"/>
|
||||
<field name="context">{
|
||||
'hide_employee_name': 1,
|
||||
'holiday_status_name_get': False}
|
||||
'holiday_status_display_name': False}
|
||||
</field>
|
||||
<field name="domain">[('holiday_allocation_id', '=', active_id)]</field>
|
||||
<field name="help" type="html">
|
||||
|
||||
@@ -13,27 +13,24 @@ class HRLeaveType(models.Model):
|
||||
"Deduct Extra Hours", default=False,
|
||||
help="Once a time off of this type is approved, extra hours in attendances will be deducted.")
|
||||
|
||||
def name_get(self):
|
||||
@api.depends_context('request_type', 'leave', 'holiday_status_display_name', 'employee_id')
|
||||
def _compute_display_name(self):
|
||||
# Exclude hours available in allocation contexts, it might be confusing otherwise
|
||||
if not self.requested_name_get() or self._context.get('request_type', 'leave') == 'allocation':
|
||||
return super().name_get()
|
||||
employee_id = False
|
||||
overtime_leaves = self.env['hr.leave.type']
|
||||
res = []
|
||||
for leave_type in self:
|
||||
if leave_type.overtime_deductible and leave_type.requires_allocation == 'no':
|
||||
if not employee_id:
|
||||
employee_id = self.env['hr.employee'].browse(self._context.get('employee_id')).sudo()
|
||||
if employee_id.total_overtime > 0:
|
||||
overtime_leaves |= leave_type
|
||||
name = "%(name)s (%(count)s)" % {
|
||||
'name': leave_type.name,
|
||||
'count': _('%s hours available',
|
||||
format_duration(employee_id.total_overtime)),
|
||||
}
|
||||
res.append((leave_type.id, name))
|
||||
res += super(HRLeaveType, self - overtime_leaves).name_get()
|
||||
return res
|
||||
if not self.requested_display_name() or self._context.get('request_type', 'leave') == 'allocation':
|
||||
return super()._compute_display_name()
|
||||
|
||||
employee = self.env['hr.employee'].browse(self._context.get('employee_id')).sudo()
|
||||
if employee.total_overtime <= 0:
|
||||
return super()._compute_display_name()
|
||||
|
||||
overtime_leaves = self.filtered(lambda l_type: l_type.overtime_deductible and l_type.requires_allocation == 'no')
|
||||
for leave_type in overtime_leaves:
|
||||
leave_type.display_name = "%(name)s (%(count)s)" % {
|
||||
'name': leave_type.name,
|
||||
'count': _('%s hours available',
|
||||
format_duration(employee.total_overtime)),
|
||||
}
|
||||
super(HRLeaveType, self - overtime_leaves)._compute_display_name()
|
||||
|
||||
def get_employees_days(self, employee_ids, date=None):
|
||||
res = super().get_employees_days(employee_ids, date)
|
||||
|
||||
@@ -505,13 +505,11 @@ class Applicant(models.Model):
|
||||
applicant._message_add_suggested_recipient(recipients, email=email_from, reason=_('Contact Email'))
|
||||
return recipients
|
||||
|
||||
def name_get(self):
|
||||
if self.env.context.get('show_partner_name'):
|
||||
return [
|
||||
(applicant.id, applicant.partner_name or applicant.name)
|
||||
for applicant in self
|
||||
]
|
||||
return super().name_get()
|
||||
def _compute_display_name(self):
|
||||
if not self.env.context.get('show_partner_name'):
|
||||
return super()._compute_display_name()
|
||||
for applicant in self:
|
||||
applicant.display_name = applicant.partner_name or applicant.name
|
||||
|
||||
@api.model
|
||||
def message_new(self, msg, custom_values=None):
|
||||
|
||||
@@ -13,7 +13,8 @@ class Skill(models.Model):
|
||||
sequence = fields.Integer(default=10)
|
||||
skill_type_id = fields.Many2one('hr.skill.type', required=True, ondelete='cascade')
|
||||
|
||||
def name_get(self):
|
||||
def _compute_display_name(self):
|
||||
if not self._context.get('from_skill_dropdown'):
|
||||
return super().name_get()
|
||||
return [(record.id, f"{record.name} ({record.skill_type_id.name})") for record in self]
|
||||
return super()._compute_display_name()
|
||||
for record in self:
|
||||
record.display_name = f"{record.name} ({record.skill_type_id.name})"
|
||||
|
||||
@@ -19,10 +19,11 @@ class SkillLevel(models.Model):
|
||||
('check_level_progress', 'CHECK(level_progress BETWEEN 0 AND 100)', "Progress should be a number between 0 and 100."),
|
||||
]
|
||||
|
||||
def name_get(self):
|
||||
def _compute_display_name(self):
|
||||
if not self._context.get('from_skill_level_dropdown'):
|
||||
return super().name_get()
|
||||
return [(record.id, f"{record.name} ({record.level_progress}%)") for record in self]
|
||||
return super()._compute_display_name()
|
||||
for record in self:
|
||||
record.display_name = f"{record.name} ({record.level_progress}%)"
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
|
||||
@@ -23,13 +23,12 @@ class HrEmployee(models.Model):
|
||||
for employee in self:
|
||||
employee.has_timesheet = result.get(employee.id, False)
|
||||
|
||||
def name_get(self):
|
||||
res = super().name_get()
|
||||
def _compute_display_name(self):
|
||||
super()._compute_display_name()
|
||||
allowed_company_ids = self.env.context.get('allowed_company_ids', [])
|
||||
if len(allowed_company_ids) <= 1:
|
||||
return res
|
||||
return
|
||||
|
||||
name_mapping = dict(res)
|
||||
employees_count_per_user = {
|
||||
user.id: count
|
||||
for user, count in self.env['hr.employee'].sudo()._read_group(
|
||||
@@ -40,8 +39,7 @@ class HrEmployee(models.Model):
|
||||
}
|
||||
for employee in self:
|
||||
if employees_count_per_user.get(employee.user_id.id, 0) > 1:
|
||||
name_mapping[employee.id] = f'{name_mapping[employee.id]} - {employee.company_id.name}'
|
||||
return list(name_mapping.items())
|
||||
employee.display_name = f'{employee.display_name} - {employee.company_id.name}'
|
||||
|
||||
def action_unlink_wizard(self):
|
||||
wizard = self.env['hr.employee.delete.wizard'].create({
|
||||
|
||||
@@ -65,23 +65,14 @@ class AccountAnalyticLine(models.Model):
|
||||
partner_id = fields.Many2one(compute='_compute_partner_id', store=True, readonly=False)
|
||||
readonly_timesheet = fields.Boolean(string="Readonly Timesheet", compute="_compute_readonly_timesheet")
|
||||
|
||||
def name_get(self):
|
||||
result = super().name_get()
|
||||
timesheets_read = self.env[self._name].search_read([('project_id', '!=', False), ('id', 'in', self.ids)], ['id', 'project_id', 'task_id'])
|
||||
if not timesheets_read:
|
||||
return result
|
||||
def _get_display_name(project_id, task_id):
|
||||
""" Get the display name of the timesheet based on the project and task
|
||||
:param project_id: tuple containing the id and the display name of the project
|
||||
:param task_id: tuple containing the id and the display name of the task if a task exists in the timesheet
|
||||
otherwise False.
|
||||
:returns: the display name of the timesheet
|
||||
"""
|
||||
if task_id:
|
||||
return '%s - %s' % (project_id[1], task_id[1])
|
||||
return project_id[1]
|
||||
timesheet_dict = {res['id']: _get_display_name(res['project_id'], res['task_id']) for res in timesheets_read}
|
||||
return list({**dict(result), **timesheet_dict}.items())
|
||||
def _compute_display_name(self):
|
||||
analytic_line_with_project = self.filtered('project_id')
|
||||
super(AccountAnalyticLine, self - analytic_line_with_project)._compute_display_name()
|
||||
for analytic_line in analytic_line_with_project:
|
||||
if analytic_line.task_id:
|
||||
analytic_line.display_name = f"{analytic_line.project_id.display_name} - {analytic_line.task_id.display_name}"
|
||||
else:
|
||||
analytic_line.display_name = analytic_line.project_id.display_name
|
||||
|
||||
def _is_readonly(self):
|
||||
self.ensure_one()
|
||||
|
||||
@@ -164,15 +164,14 @@ class Project(models.Model):
|
||||
project._create_analytic_account()
|
||||
return super(Project, self).write(values)
|
||||
|
||||
def name_get(self):
|
||||
res = super().name_get()
|
||||
def _compute_display_name(self):
|
||||
super()._compute_display_name()
|
||||
if len(self.env.context.get('allowed_company_ids', [])) <= 1:
|
||||
return res
|
||||
name_mapping = dict(res)
|
||||
return
|
||||
|
||||
for project in self:
|
||||
if project.is_internal_project:
|
||||
name_mapping[project.id] = f'{name_mapping[project.id]} - {project.company_id.name}'
|
||||
return list(name_mapping.items())
|
||||
project.display_name = f'{project.display_name} - {project.company_id.name}'
|
||||
|
||||
@api.model
|
||||
def _init_data_analytic_account(self):
|
||||
|
||||
@@ -181,13 +181,13 @@ class Task(models.Model):
|
||||
|
||||
return res
|
||||
|
||||
def name_get(self):
|
||||
def _compute_display_name(self):
|
||||
super()._compute_display_name()
|
||||
if self.env.context.get('hr_timesheet_display_remaining_hours'):
|
||||
name_mapping = dict(super().name_get())
|
||||
for task in self:
|
||||
if task.allow_timesheets and task.planned_hours > 0 and task.encode_uom_in_days:
|
||||
days_left = _("(%s days remaining)") % task._convert_hours_to_days(task.remaining_hours)
|
||||
name_mapping[task.id] = name_mapping.get(task.id, '') + u"\u00A0" + days_left
|
||||
task.display_name = task.display_name + "\u00A0" + days_left
|
||||
elif task.allow_timesheets and task.planned_hours > 0:
|
||||
hours, mins = (str(int(duration)).rjust(2, '0') for duration in divmod(abs(task.remaining_hours) * 60, 60))
|
||||
hours_left = _(
|
||||
@@ -196,9 +196,7 @@ class Task(models.Model):
|
||||
hours=hours,
|
||||
minutes=mins,
|
||||
)
|
||||
name_mapping[task.id] = name_mapping.get(task.id, '') + u"\u00A0" + hours_left
|
||||
return list(name_mapping.items())
|
||||
return super().name_get()
|
||||
task.display_name = task.display_name + "\u00A0" + hours_left
|
||||
|
||||
@api.model
|
||||
def _get_view_cache_key(self, view_id=None, view_type='form', **options):
|
||||
|
||||
@@ -88,7 +88,6 @@ def slug(value):
|
||||
try:
|
||||
if not value.id:
|
||||
raise ValueError("Cannot slug non-existent record %s" % value)
|
||||
# [(id, name)] = value.name_get()
|
||||
identifier, name = value.id, getattr(value, 'seo_name', False) or value.display_name
|
||||
except AttributeError:
|
||||
# assume name_search result tuple
|
||||
|
||||
@@ -21,21 +21,15 @@ class ChatbotScriptAnswer(models.Model):
|
||||
'chatbot.script.step', string='Script Step', required=True, ondelete='cascade')
|
||||
chatbot_script_id = fields.Many2one(related='script_step_id.chatbot_script_id')
|
||||
|
||||
def name_get(self):
|
||||
def _compute_display_name(self):
|
||||
if self._context.get('chatbot_script_answer_display_short_name'):
|
||||
return super().name_get()
|
||||
return super()._compute_display_name()
|
||||
|
||||
result = []
|
||||
for answer in self:
|
||||
answer_message = answer.script_step_id.message.replace('\n', ' ')
|
||||
shortened_message = textwrap.shorten(answer_message, width=26, placeholder=" [...]")
|
||||
|
||||
result.append((
|
||||
answer.id,
|
||||
"%s: %s" % (shortened_message, answer.name)
|
||||
))
|
||||
|
||||
return result
|
||||
answer.display_name = f"{shortened_message}: {answer.name}"
|
||||
|
||||
@api.model
|
||||
def _name_search(self, name, domain=None, operator='ilike', limit=None, order=None):
|
||||
|
||||
@@ -22,11 +22,7 @@ class EWayBillType(models.Model):
|
||||
)
|
||||
active = fields.Boolean("Active", default=True)
|
||||
|
||||
def name_get(self):
|
||||
def _compute_display_name(self):
|
||||
"""Show name and sub_type in name"""
|
||||
result_dict = dict()
|
||||
for ewaybill_type in self:
|
||||
name = ewaybill_type.name
|
||||
name += _(" (Sub-Type: %s)", ewaybill_type.sub_type)
|
||||
result_dict[ewaybill_type.id] = name
|
||||
return list(result_dict.items())
|
||||
ewaybill_type.display_name = _("%s (Sub-Type: %s)", ewaybill_type.name, ewaybill_type.sub_type)
|
||||
|
||||
@@ -11,8 +11,6 @@ class L10nItDdt(models.Model):
|
||||
name = fields.Char(string="Numero DDT", size=20, help="Transport document number", required=True)
|
||||
date = fields.Date(string="Data DDT", help="Transport document date", required=True)
|
||||
|
||||
def name_get(self):
|
||||
res = []
|
||||
def _compute_display_name(self):
|
||||
for ddt in self:
|
||||
res.append((ddt.id, ("%s (%s)") % (ddt.name, ddt.date)))
|
||||
return res
|
||||
ddt.display_name = f"{ddt.name} ({ddt.date})"
|
||||
|
||||
@@ -16,7 +16,7 @@ class L10nLatamIdentificationType(models.Model):
|
||||
is_vat = fields.Boolean()
|
||||
country_id = fields.Many2one('res.country')
|
||||
|
||||
def name_get(self):
|
||||
def _compute_display_name(self):
|
||||
multi_localization = len(self.search([]).mapped('country_id')) > 1
|
||||
return [(rec.id, '%s%s' % (
|
||||
rec.name, multi_localization and rec.country_id and ' (%s)' % rec.country_id.code or '')) for rec in self]
|
||||
for rec in self:
|
||||
rec.display_name = '{}{}'.format(rec.name, multi_localization and rec.country_id and ' (%s)' % rec.country_id.code or '')
|
||||
|
||||
@@ -283,13 +283,12 @@ class AccountPayment(models.Model):
|
||||
})
|
||||
return res
|
||||
|
||||
def name_get(self):
|
||||
def _compute_display_name(self):
|
||||
""" Add check number to display_name on check_id m2o field """
|
||||
res_names = super().name_get()
|
||||
for i, (res_name, rec) in enumerate(zip(res_names, self)):
|
||||
super()._compute_display_name()
|
||||
for rec in self:
|
||||
if rec.check_number and rec.payment_method_line_id.code == 'new_third_party_checks':
|
||||
res_names[i] = (res_name[0], "%s %s" % (res_name[1], _("(Check %s)", rec.check_number)))
|
||||
return res_names
|
||||
rec.display_name = "{} {}".format(rec.display_name, _("(Check %s)", rec.check_number))
|
||||
|
||||
def button_open_check_operations(self):
|
||||
''' Redirect the user to the invoice(s) paid by this payment.
|
||||
|
||||
@@ -35,11 +35,9 @@ class L10nLatamDocumentType(models.Model):
|
||||
self.ensure_one()
|
||||
return document_number
|
||||
|
||||
def name_get(self):
|
||||
result = []
|
||||
def _compute_display_name(self):
|
||||
for rec in self:
|
||||
name = rec.name
|
||||
if rec.code:
|
||||
name = '(%s) %s' % (rec.code, name)
|
||||
result.append((rec.id, name))
|
||||
return result
|
||||
name = f'({rec.code}) {name}'
|
||||
rec.display_name = name
|
||||
|
||||
@@ -19,8 +19,9 @@ class LoyaltyCard(models.Model):
|
||||
"""
|
||||
return '044' + str(uuid4())[7:-18]
|
||||
|
||||
def name_get(self):
|
||||
return [(card.id, f'{card.program_id.name}: {card.code}') for card in self]
|
||||
def _compute_display_name(self):
|
||||
for card in self:
|
||||
card.display_name = f'{card.program_id.name}: {card.code}'
|
||||
|
||||
program_id = fields.Many2one('loyalty.program', ondelete='restrict', default=lambda self: self.env.context.get('active_id', None))
|
||||
program_type = fields.Selection(related='program_id.program_type')
|
||||
|
||||
@@ -38,8 +38,9 @@ class LoyaltyReward(models.Model):
|
||||
('per_order', _('%s per order', symbol))
|
||||
]
|
||||
|
||||
def name_get(self):
|
||||
return [(reward.id, '%s - %s' % (reward.program_id.name, reward.description)) for reward in self]
|
||||
def _compute_display_name(self):
|
||||
for reward in self:
|
||||
reward.display_name = f'{reward.program_id.name} - {reward.description}'
|
||||
|
||||
active = fields.Boolean(default=True)
|
||||
program_id = fields.Many2one('loyalty.program', required=True, ondelete='cascade')
|
||||
|
||||
@@ -18,8 +18,9 @@ class LunchCashMove(models.Model):
|
||||
amount = fields.Float('Amount', required=True)
|
||||
description = fields.Text('Description')
|
||||
|
||||
def name_get(self):
|
||||
return [(cashmove.id, '%s %s' % (_('Lunch Cashmove'), '#%d' % cashmove.id)) for cashmove in self]
|
||||
def _compute_display_name(self):
|
||||
for cashmove in self:
|
||||
cashmove.display_name = '{} {}'.format(_('Lunch Cashmove'), '#%d' % cashmove.id)
|
||||
|
||||
@api.model
|
||||
def get_wallet_balance(self, user, include_config=True):
|
||||
|
||||
@@ -117,14 +117,12 @@ class LunchSupplier(models.Model):
|
||||
'Automatic Email Sending Time should be between 0 and 12'),
|
||||
]
|
||||
|
||||
def name_get(self):
|
||||
res = []
|
||||
def _compute_display_name(self):
|
||||
for supplier in self:
|
||||
if supplier.phone:
|
||||
res.append((supplier.id, '%s %s' % (supplier.name, supplier.phone)))
|
||||
supplier.display_name = f'{supplier.name} {supplier.phone}'
|
||||
else:
|
||||
res.append((supplier.id, supplier.name))
|
||||
return res
|
||||
supplier.display_name = supplier.name
|
||||
|
||||
def _sync_cron(self):
|
||||
for supplier in self:
|
||||
|
||||
@@ -17,10 +17,8 @@ class LunchTopping(models.Model):
|
||||
supplier_id = fields.Many2one('lunch.supplier', ondelete='cascade')
|
||||
topping_category = fields.Integer('Topping Category', required=True, default=1)
|
||||
|
||||
def name_get(self):
|
||||
def _compute_display_name(self):
|
||||
currency_id = self.env.company.currency_id
|
||||
res = dict(super(LunchTopping, self).name_get())
|
||||
for topping in self:
|
||||
price = formatLang(self.env, topping.price, currency_obj=currency_id)
|
||||
res[topping.id] = '%s %s' % (topping.name, price)
|
||||
return list(res.items())
|
||||
topping.display_name = f'{topping.name} {price}'
|
||||
|
||||
@@ -17,8 +17,9 @@ class CashmoveReport(models.Model):
|
||||
user_id = fields.Many2one('res.users', string='User')
|
||||
description = fields.Text('Description')
|
||||
|
||||
def name_get(self):
|
||||
return [(cashmove.id, '%s %s' % (_('Lunch Cashmove'), '#%d' % cashmove.id)) for cashmove in self]
|
||||
def _compute_display_name(self):
|
||||
for cashmove in self:
|
||||
cashmove.display_name = '{} {}'.format(_('Lunch Cashmove'), '#%d' % cashmove.id)
|
||||
|
||||
def init(self):
|
||||
tools.drop_view_if_exists(self._cr, self._table)
|
||||
|
||||
@@ -59,8 +59,9 @@ class ChannelMember(models.Model):
|
||||
else:
|
||||
self.message_unread_counter = 0
|
||||
|
||||
def name_get(self):
|
||||
return [(record.id, record.partner_id.name or record.guest_id.name) for record in self]
|
||||
def _compute_display_name(self):
|
||||
for record in self:
|
||||
record.display_name = record.partner_id.name or record.guest_id.name
|
||||
|
||||
def init(self):
|
||||
self.env.cr.execute("CREATE UNIQUE INDEX IF NOT EXISTS discuss_channel_member_partner_unique ON %s (channel_id, partner_id) WHERE partner_id IS NOT NULL" % self._table)
|
||||
|
||||
@@ -404,12 +404,10 @@ class MailActivity(models.Model):
|
||||
)
|
||||
return activities._as_query(order)
|
||||
|
||||
def name_get(self):
|
||||
res = []
|
||||
def _compute_display_name(self):
|
||||
for record in self:
|
||||
name = record.summary or record.activity_type_id.display_name
|
||||
res.append((record.id, name))
|
||||
return res
|
||||
record.display_name = name
|
||||
|
||||
# ------------------------------------------------------
|
||||
# Business Methods
|
||||
|
||||
@@ -147,20 +147,18 @@ class Alias(models.Model):
|
||||
vals['alias_name'] = self._clean_and_check_unique([vals.get('alias_name')])[0]
|
||||
return super(Alias, self).write(vals)
|
||||
|
||||
def name_get(self):
|
||||
def _compute_display_name(self):
|
||||
"""Return the mail alias display alias_name, including the implicit
|
||||
mail catchall domain if exists from config otherwise "New Alias".
|
||||
e.g. `jobs@mail.odoo.com` or `jobs` or 'New Alias'
|
||||
"""
|
||||
res = []
|
||||
for record in self:
|
||||
if record.alias_name and record.alias_domain:
|
||||
res.append((record['id'], "%s@%s" % (record.alias_name, record.alias_domain)))
|
||||
record.display_name = f"{record.alias_name}@{record.alias_domain}"
|
||||
elif record.alias_name:
|
||||
res.append((record['id'], "%s" % (record.alias_name)))
|
||||
record.display_name = record.alias_name
|
||||
else:
|
||||
res.append((record['id'], _("Inactive Alias")))
|
||||
return res
|
||||
record.display_name = _("Inactive Alias")
|
||||
|
||||
def _clean_and_check_unique(self, names):
|
||||
"""When an alias name appears to already be an email, we keep the local
|
||||
|
||||
@@ -103,7 +103,7 @@ class Message(models.Model):
|
||||
# related document
|
||||
model = fields.Char('Related Document Model')
|
||||
res_id = fields.Many2oneReference('Related Document ID', model_field='model')
|
||||
record_name = fields.Char('Message Record Name') # name_get() of the related document
|
||||
record_name = fields.Char('Message Record Name') # display_name of the related document
|
||||
link_preview_ids = fields.One2many('mail.link.preview', 'message_id', string='Link Previews', groups="base.group_erp_manager")
|
||||
# characteristics
|
||||
message_type = fields.Selection([
|
||||
@@ -993,7 +993,7 @@ class Message(models.Model):
|
||||
'email_from': 'sacha@pokemon.com' # email address or False
|
||||
'subtype_id': (1, u'Discussions'),
|
||||
'date': '2015-06-30 08:22:33',
|
||||
'partner_ids': [[7, "Sacha Du Bourg-Palette"]], # list of partner name_get
|
||||
'partner_ids': [[7, "Sacha Du Bourg-Palette"]], # list of partner convert_to_read
|
||||
'message_type': u'comment',
|
||||
'id': 59,
|
||||
'subject': False
|
||||
@@ -1194,7 +1194,7 @@ class Message(models.Model):
|
||||
|
||||
@api.model
|
||||
def _get_record_name(self, values):
|
||||
""" Return the related document name, using name_get. It is done using
|
||||
""" Return the related document name, using display_name. It is done using
|
||||
SUPERUSER_ID, to be sure to have the record name correctly stored. """
|
||||
model = values.get('model', self.env.context.get('default_model'))
|
||||
res_id = values.get('res_id', self.env.context.get('default_res_id'))
|
||||
|
||||
@@ -2712,7 +2712,7 @@ class MailThread(models.AbstractModel):
|
||||
|
||||
:return str: default subject """
|
||||
self.ensure_one()
|
||||
return self.name_get()[0][1]
|
||||
return self.display_name
|
||||
|
||||
def _message_create(self, values_list):
|
||||
""" Low-level helper to create mail.message records. It is mainly used
|
||||
|
||||
@@ -78,8 +78,8 @@ class MailTracking(models.Model):
|
||||
values.update({
|
||||
'old_value_integer': initial_value and initial_value.id or 0,
|
||||
'new_value_integer': new_value and new_value.id or 0,
|
||||
'old_value_char': initial_value and initial_value.sudo().name_get()[0][1] or '',
|
||||
'new_value_char': new_value and new_value.sudo().name_get()[0][1] or ''
|
||||
'old_value_char': initial_value and initial_value.sudo().display_name or '',
|
||||
'new_value_char': new_value and new_value.sudo().display_name or ''
|
||||
})
|
||||
elif col_info['type'] in ['many2many', 'one2many']:
|
||||
values.update({
|
||||
|
||||
@@ -22,8 +22,9 @@ class ResUsersSettingsVolumes(models.Model):
|
||||
("partner_or_guest_exists", "CHECK((partner_id IS NOT NULL AND guest_id IS NULL) OR (partner_id IS NULL AND guest_id IS NOT NULL))", "A volume setting must have a partner or a guest."),
|
||||
]
|
||||
|
||||
def name_get(self):
|
||||
return [(rec.id, f'{rec.user_setting_id.user_id.name} - {rec.partner_id.name or rec.guest_id.name}') for rec in self]
|
||||
def _compute_display_name(self):
|
||||
for rec in self:
|
||||
rec.display_name = f'{rec.user_setting_id.user_id.name} - {rec.partner_id.name or rec.guest_id.name}'
|
||||
|
||||
def _discuss_users_settings_volume_format(self):
|
||||
return [{
|
||||
|
||||
@@ -60,7 +60,7 @@ patch(Message.prototype, "mail/core/web", {
|
||||
case "boolean":
|
||||
return trackingValue.value ? _t("Yes") : _t("No");
|
||||
/**
|
||||
* many2one formatter exists but is expecting id/name_get or data
|
||||
* many2one formatter exists but is expecting id/display_name or data
|
||||
* object but only the target record name is known in this context.
|
||||
*
|
||||
* Selection formatter exists but requires knowing all
|
||||
|
||||
@@ -193,7 +193,7 @@ class MailPluginController(http.Controller):
|
||||
if normalized_email:
|
||||
filter_domain = [('email_normalized', 'ilike', search_term)]
|
||||
else:
|
||||
filter_domain = ['|', '|', ('display_name', 'ilike', search_term), ('ref', '=', search_term),
|
||||
filter_domain = ['|', '|', ('complete_name', 'ilike', search_term), ('ref', '=', search_term),
|
||||
('email', 'ilike', search_term)]
|
||||
|
||||
# Search for the partner based on the email.
|
||||
|
||||
@@ -92,14 +92,12 @@ class MaintenanceEquipment(models.Model):
|
||||
return self.env.ref('maintenance.mt_mat_assign')
|
||||
return super(MaintenanceEquipment, self)._track_subtype(init_values)
|
||||
|
||||
def name_get(self):
|
||||
result = []
|
||||
def _compute_display_name(self):
|
||||
for record in self:
|
||||
if record.name and record.serial_no:
|
||||
result.append((record.id, record.name + '/' + record.serial_no))
|
||||
record.display_name = record.name + '/' + record.serial_no
|
||||
if record.name and not record.serial_no:
|
||||
result.append((record.id, record.name))
|
||||
return result
|
||||
record.display_name = record.name
|
||||
|
||||
@api.model
|
||||
def _name_search(self, name, domain=None, operator='ilike', limit=None, order=None):
|
||||
|
||||
@@ -129,13 +129,13 @@ class MassMailingContact(models.Model):
|
||||
def name_create(self, name):
|
||||
name, email = self.get_name_email(name)
|
||||
contact = self.create({'name': name, 'email': email})
|
||||
return contact.name_get()[0]
|
||||
return contact.id, contact.display_name
|
||||
|
||||
@api.model
|
||||
def add_to_list(self, name, list_id):
|
||||
name, email = self.get_name_email(name)
|
||||
contact = self.create({'name': name, 'email': email, 'list_ids': [(4, list_id)]})
|
||||
return contact.name_get()[0]
|
||||
return contact.id, contact.display_name
|
||||
|
||||
def _message_get_default_recipients(self):
|
||||
return {r.id: {
|
||||
|
||||
@@ -120,8 +120,9 @@ class MassMailingList(models.Model):
|
||||
|
||||
return super(MassMailingList, self).write(vals)
|
||||
|
||||
def name_get(self):
|
||||
return [(list.id, "%s (%s)" % (list.name, list.contact_count)) for list in self]
|
||||
def _compute_display_name(self):
|
||||
for mailing_list in self:
|
||||
mailing_list.display_name = f"{mailing_list.name} ({mailing_list.contact_count})"
|
||||
|
||||
def copy(self, default=None):
|
||||
self.ensure_one()
|
||||
|
||||
@@ -52,7 +52,6 @@ class MailingTrace(models.Model):
|
||||
_order = 'create_date DESC'
|
||||
|
||||
trace_type = fields.Selection([('mail', 'Email')], string='Type', default='mail', required=True)
|
||||
display_name = fields.Char(compute='_compute_display_name')
|
||||
# mail data
|
||||
mail_mail_id = fields.Many2one('mail.mail', string='Mail', index='btree_not_null')
|
||||
mail_mail_id_int = fields.Integer(
|
||||
@@ -117,7 +116,7 @@ class MailingTrace(models.Model):
|
||||
@api.depends('trace_type', 'mass_mailing_id')
|
||||
def _compute_display_name(self):
|
||||
for trace in self:
|
||||
trace.display_name = '%s: %s (%s)' % (trace.trace_type, trace.mass_mailing_id.name, trace.id)
|
||||
trace.display_name = f'{trace.trace_type}: {trace.mass_mailing_id.name} ({trace.id})'
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, values_list):
|
||||
|
||||
@@ -253,8 +253,9 @@ class MrpBom(models.Model):
|
||||
self.with_context({'active_test': False}).operation_ids.toggle_active()
|
||||
return super().toggle_active()
|
||||
|
||||
def name_get(self):
|
||||
return [(bom.id, '%s%s' % (bom.code and '%s: ' % bom.code or '', bom.product_tmpl_id.display_name)) for bom in self]
|
||||
def _compute_display_name(self):
|
||||
for bom in self:
|
||||
bom.display_name = f"{bom.code + ': ' if bom.code else ''}{bom.product_tmpl_id.display_name}"
|
||||
|
||||
def action_compute_bom_days(self):
|
||||
company_id = self.env.context.get('default_company_id', self.env.company.id)
|
||||
|
||||
@@ -328,15 +328,13 @@ class MrpWorkcenterProductivityLossType(models.Model):
|
||||
_rec_name = 'loss_type'
|
||||
|
||||
@api.depends('loss_type')
|
||||
def name_get(self):
|
||||
def _compute_display_name(self):
|
||||
""" As 'category' field in form view is a Many2one, its value will be in
|
||||
lower case. In order to display its value capitalized 'name_get' is
|
||||
lower case. In order to display its value capitalized 'display_name' is
|
||||
overrided.
|
||||
"""
|
||||
result = []
|
||||
for rec in self:
|
||||
result.append((rec.id, rec.loss_type.title()))
|
||||
return result
|
||||
rec.display_name = rec.loss_type.title()
|
||||
|
||||
loss_type = fields.Selection([
|
||||
('availability', 'Availability'),
|
||||
|
||||
@@ -272,14 +272,12 @@ class MrpWorkorder(models.Model):
|
||||
if not self._check_m2m_recursion('blocked_by_workorder_ids'):
|
||||
raise ValidationError(_("You cannot create cyclic dependency."))
|
||||
|
||||
def name_get(self):
|
||||
res = []
|
||||
def _compute_display_name(self):
|
||||
for wo in self:
|
||||
if len(wo.production_id.workorder_ids) == 1:
|
||||
res.append((wo.id, "%s - %s - %s" % (wo.production_id.name, wo.product_id.name, wo.name)))
|
||||
wo.display_name = f"{wo.production_id.name} - {wo.product_id.name} - {wo.name}"
|
||||
else:
|
||||
res.append((wo.id, "%s - %s - %s - %s" % (wo.production_id.workorder_ids.ids.index(wo._origin.id) + 1, wo.production_id.name, wo.product_id.name, wo.name)))
|
||||
return res
|
||||
wo.display_name = f"{wo.production_id.workorder_ids.ids.index(wo._origin.id) + 1} - {wo.production_id.name} - {wo.product_id.name} - {wo.name}"
|
||||
|
||||
def unlink(self):
|
||||
# Removes references to workorder to avoid Validation Error
|
||||
|
||||
@@ -21,13 +21,6 @@ class MrpProduction(models.Model):
|
||||
|
||||
incoming_picking = fields.Many2one(related='move_finished_ids.move_dest_ids.picking_id')
|
||||
|
||||
@api.depends('name')
|
||||
def name_get(self):
|
||||
return [
|
||||
(record.id, "%s (%s)" % (record.incoming_picking.name, record.name)) if record.bom_id.type == 'subcontract'
|
||||
else (record.id, record.name) for record in self
|
||||
]
|
||||
|
||||
@api.depends('move_raw_ids.move_line_ids')
|
||||
def _compute_move_line_raw_ids(self):
|
||||
for production in self:
|
||||
|
||||
@@ -65,7 +65,7 @@ class ResCompany(models.Model):
|
||||
company_data = {field: value for field, value in company_data.items()
|
||||
if field in self.partner_id._fields and value and (field == 'image_1920' or not self.partner_id[field])}
|
||||
|
||||
# for company and childs: from state_id / country_id name_get like to IDs
|
||||
# for company and childs: from state_id / country_id display_name like to IDs
|
||||
company_data.update(self._enrich_extract_m2o_id(company_data, ['state_id', 'country_id']))
|
||||
if company_data.get('child_ids'):
|
||||
company_data['child_ids'] = [
|
||||
|
||||
@@ -27,6 +27,12 @@ class PaymentToken(models.Model):
|
||||
verified = fields.Boolean(string="Verified")
|
||||
active = fields.Boolean(string="Active", default=True)
|
||||
|
||||
#=== COMPUTE METHODS ===#
|
||||
|
||||
def _compute_display_name(self):
|
||||
for token in self:
|
||||
token.display_name = token._build_display_name()
|
||||
|
||||
#=== CRUD METHODS ===#
|
||||
|
||||
@api.model_create_multi
|
||||
@@ -91,9 +97,6 @@ class PaymentToken(models.Model):
|
||||
"""
|
||||
return
|
||||
|
||||
def name_get(self):
|
||||
return [(token.id, token._build_display_name()) for token in self]
|
||||
|
||||
#=== BUSINESS METHODS ===#
|
||||
|
||||
def _get_available_tokens(self, providers_ids, partner_id, is_validation=False, **kwargs):
|
||||
|
||||
@@ -100,14 +100,15 @@ class PaymentLinkWizard(models.TransientModel):
|
||||
partner_id = related_document.partner_id
|
||||
currency_id = related_document.currency_id
|
||||
selection.extend(
|
||||
self._get_payment_provider_available(
|
||||
(payment_provider.id, payment_provider.display_name)
|
||||
for payment_provider in self._get_payment_provider_available(
|
||||
res_model=res_model,
|
||||
res_id=res_id,
|
||||
company_id=company_id.id,
|
||||
partner_id=partner_id.id,
|
||||
amount=related_document.amount_total,
|
||||
currency_id=currency_id.id,
|
||||
).name_get()
|
||||
)
|
||||
)
|
||||
return selection
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ class Bill(models.Model):
|
||||
def name_create(self, name):
|
||||
try:
|
||||
value = float(name)
|
||||
except:
|
||||
except ValueError:
|
||||
raise UserError(_("The name of the Coins/Bills must be a number."))
|
||||
result = super().create({"name": name, "value": value})
|
||||
return result.name_get()[0]
|
||||
return result.id, result.display_name
|
||||
|
||||
@@ -32,8 +32,9 @@ class PosCategory(models.Model):
|
||||
self.ensure_one()
|
||||
return (self.parent_id._get_hierarchy() if self.parent_id else []) + [self.name]
|
||||
|
||||
def name_get(self) -> List[Tuple[int, str]]:
|
||||
return [(category.id, " / ".join(category._get_hierarchy())) for category in self if category.name]
|
||||
def _compute_display_name(self):
|
||||
for cat in self:
|
||||
cat.display_name = " / ".join(cat._get_hierarchy())
|
||||
|
||||
@api.ondelete(at_uninstall=False)
|
||||
def _unlink_except_session_open(self):
|
||||
|
||||
@@ -366,15 +366,13 @@ class PosConfig(models.Model):
|
||||
if trusted_config.currency_id != config.currency_id:
|
||||
raise ValidationError(_("You cannot share open orders with configuration that does not use the same currency."))
|
||||
|
||||
def name_get(self):
|
||||
result = []
|
||||
def _compute_display_name(self):
|
||||
for config in self:
|
||||
last_session = self.env['pos.session'].search([('config_id', '=', config.id)], limit=1)
|
||||
if (not last_session) or (last_session.state == 'closed'):
|
||||
result.append((config.id, _("%(pos_name)s (not used)", pos_name=config.name)))
|
||||
config.display_name = _("%(pos_name)s (not used)", pos_name=config.name)
|
||||
else:
|
||||
result.append((config.id, "%s (%s)" % (config.name, last_session.user_id.name)))
|
||||
return result
|
||||
config.display_name = f"{config.name} ({last_session.user_id.name})"
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
|
||||
@@ -33,14 +33,12 @@ class PosPayment(models.Model):
|
||||
is_change = fields.Boolean(string='Is this payment change?', default=False)
|
||||
account_move_id = fields.Many2one('account.move')
|
||||
|
||||
def name_get(self):
|
||||
res = []
|
||||
def _compute_display_name(self):
|
||||
for payment in self:
|
||||
if payment.name:
|
||||
res.append((payment.id, '%s %s' % (payment.name, formatLang(self.env, payment.amount, currency_obj=payment.currency_id))))
|
||||
payment.display_name = f'{payment.name} {formatLang(self.env, payment.amount, currency_obj=payment.currency_id)}'
|
||||
else:
|
||||
res.append((payment.id, formatLang(self.env, payment.amount, currency_obj=payment.currency_id)))
|
||||
return res
|
||||
payment.display_name = formatLang(self.env, payment.amount, currency_obj=payment.currency_id)
|
||||
|
||||
@api.constrains('payment_method_id')
|
||||
def _check_payment_method_id(self):
|
||||
|
||||
@@ -587,7 +587,7 @@ export class TicketScreen extends Component {
|
||||
PARTNER: {
|
||||
repr: (order) => order.get_partner_name(),
|
||||
displayName: this.env._t("Customer"),
|
||||
modelField: "partner_id.display_name",
|
||||
modelField: "partner_id.complete_name",
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
+5
-5
@@ -9,12 +9,12 @@ import { usePos } from "@point_of_sale/app/store/pos_hook";
|
||||
const VALID_SEARCH_TAGS = new Set(["date", "customer", "client", "name", "order"]);
|
||||
const FIELD_MAP = {
|
||||
date: "date_order",
|
||||
customer: "partner_id.display_name",
|
||||
client: "partner_id.display_name",
|
||||
customer: "partner_id.complete_name",
|
||||
client: "partner_id.complete_name",
|
||||
name: "name",
|
||||
order: "name",
|
||||
};
|
||||
const SEARCH_FIELDS = ["name", "partner_id.display_name", "date_order"];
|
||||
const SEARCH_FIELDS = ["name", "partner_id.complete_name", "date_order"];
|
||||
|
||||
/**
|
||||
* @emits search
|
||||
@@ -64,7 +64,7 @@ export class SaleOrderManagementControlPanel extends Component {
|
||||
* '|',
|
||||
* '|',
|
||||
* ['pos_reference', 'ilike', '%Customer 1%'],
|
||||
* ['partner_id.display_name', 'ilike', '%Customer 1%'],
|
||||
* ['partner_id.complete_name', 'ilike', '%Customer 1%'],
|
||||
* ['date_order', 'ilike', '%Customer 1%']
|
||||
* ]
|
||||
* ```
|
||||
@@ -81,7 +81,7 @@ export class SaleOrderManagementControlPanel extends Component {
|
||||
* ```
|
||||
* searchString = 'customer: Steward, date: 2020-05-01'
|
||||
* result = [
|
||||
* ['partner_id.display_name', 'ilike', '%Steward%'],
|
||||
* ['partner_id.complete_name', 'ilike', '%Steward%'],
|
||||
* ['date_order', 'ilike', '%2020-05-01%']
|
||||
* ]
|
||||
* ```
|
||||
|
||||
@@ -27,8 +27,8 @@ class PrivacyLookupWizard(models.TransientModel):
|
||||
for wizard in self:
|
||||
wizard.line_count = len(wizard.line_ids)
|
||||
|
||||
def name_get(self):
|
||||
return [(w.id, _('Privacy Lookup')) for w in self]
|
||||
def _compute_display_name(self):
|
||||
self.display_name = _('Privacy Lookup')
|
||||
|
||||
def _get_query_models_blacklist(self):
|
||||
return [
|
||||
@@ -286,8 +286,8 @@ class PrivacyLookupWizardLine(models.TransientModel):
|
||||
record = self.env[line.res_model].sudo().browse(line.res_id)
|
||||
if not record.exists():
|
||||
continue
|
||||
name = record.name_get()
|
||||
line.res_name = name[0][1] if name else ('%s/%s') % (line.res_model_id.name, line.res_id)
|
||||
name = record.display_name
|
||||
line.res_name = name if name else f'{line.res_model_id.name}/{line.res_id}'
|
||||
|
||||
@api.onchange('is_active')
|
||||
def _onchange_is_active(self):
|
||||
|
||||
@@ -55,7 +55,7 @@ class ProductAttributeValue(models.Model):
|
||||
for pav in self:
|
||||
pav.is_used_on_products = bool(pav.pav_attribute_line_ids)
|
||||
|
||||
def name_get(self):
|
||||
def _compute_display_name(self):
|
||||
"""Override because in general the name of the value is confusing if it
|
||||
is displayed without the name of the corresponding attribute.
|
||||
Eg. on product list & kanban views, on BOM form view
|
||||
@@ -65,8 +65,9 @@ class ProductAttributeValue(models.Model):
|
||||
on every value.
|
||||
"""
|
||||
if not self.env.context.get('show_attribute', True):
|
||||
return super().name_get()
|
||||
return [(value.id, "%s: %s" % (value.attribute_id.name, value.name)) for value in self]
|
||||
return super()._compute_display_name()
|
||||
for value in self:
|
||||
value.display_name = f"{value.attribute_id.name}: {value.name}"
|
||||
|
||||
def write(self, values):
|
||||
if 'attribute_id' in values:
|
||||
|
||||
@@ -48,12 +48,14 @@ class ProductCategory(models.Model):
|
||||
|
||||
@api.model
|
||||
def name_create(self, name):
|
||||
return self.create({'name': name}).name_get()[0]
|
||||
category = self.create({'name': name})
|
||||
return category.id, category.display_name
|
||||
|
||||
def name_get(self):
|
||||
if not self.env.context.get('hierarchical_naming', True):
|
||||
return [(record.id, record.name) for record in self]
|
||||
return super().name_get()
|
||||
def _compute_display_name(self):
|
||||
if self.env.context.get('hierarchical_naming', True):
|
||||
return super()._compute_display_name()
|
||||
for record in self:
|
||||
record.display_name = record.name
|
||||
|
||||
@api.ondelete(at_uninstall=False)
|
||||
def _unlink_except_default_category(self):
|
||||
|
||||
@@ -64,8 +64,9 @@ class Pricelist(models.Model):
|
||||
],
|
||||
copy=True)
|
||||
|
||||
def name_get(self):
|
||||
return [(pricelist.id, '%s (%s)' % (pricelist.name, pricelist.currency_id.name)) for pricelist in self]
|
||||
def _compute_display_name(self):
|
||||
for pricelist in self:
|
||||
pricelist.display_name = f'{pricelist.name} ({pricelist.currency_id.name})'
|
||||
|
||||
def _get_products_price(self, products, *args, **kwargs):
|
||||
"""Compute the pricelist prices for the specified products, quantity & uom.
|
||||
|
||||
@@ -8,6 +8,7 @@ from odoo import api, fields, models, tools, _
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.osv import expression
|
||||
from odoo.tools import float_compare
|
||||
from odoo.tools.misc import unique
|
||||
|
||||
|
||||
class ProductProduct(models.Model):
|
||||
@@ -415,21 +416,13 @@ class ProductProduct(models.Model):
|
||||
domain.append((('categ_id', 'child_of', self._context['search_default_categ_id'])))
|
||||
return super()._search(domain, offset, limit, order, access_rights_uid)
|
||||
|
||||
@api.depends_context('display_default_code', 'seller_id')
|
||||
@api.depends_context('display_default_code', 'seller_id', 'company_id')
|
||||
def _compute_display_name(self):
|
||||
# `display_name` is calling `name_get()`` which is overidden on product
|
||||
# to depend on `display_default_code` and `seller_id`
|
||||
return super()._compute_display_name()
|
||||
|
||||
def name_get(self):
|
||||
# TDE: this could be cleaned a bit I think
|
||||
|
||||
def _name_get(d):
|
||||
name = d.get('name', '')
|
||||
code = self._context.get('display_default_code', True) and d.get('default_code', False) or False
|
||||
if code:
|
||||
name = '[%s] %s' % (code,name)
|
||||
return (d['id'], name)
|
||||
def get_display_name(name, code):
|
||||
if self._context.get('display_default_code', True) and code:
|
||||
return f'[{code}] {name}'
|
||||
return name
|
||||
|
||||
partner_id = self._context.get('partner_id')
|
||||
if partner_id:
|
||||
@@ -443,15 +436,13 @@ class ProductProduct(models.Model):
|
||||
self.check_access_rights("read")
|
||||
self.check_access_rule("read")
|
||||
|
||||
result = []
|
||||
|
||||
# prefetch the fields used by the `name_get`
|
||||
# prefetch the fields used by the `display_name`
|
||||
self.sudo().fetch(['name', 'default_code', 'product_tmpl_id'])
|
||||
|
||||
product_template_ids = self.sudo().product_tmpl_id.ids
|
||||
|
||||
if partner_ids:
|
||||
# prefetch the fields used by the `name_get`
|
||||
# prefetch the fields used by the `display_name`
|
||||
supplier_info = self.env['product.supplierinfo'].sudo().search_fetch(
|
||||
[('product_tmpl_id', 'in', product_template_ids), ('partner_id', 'in', partner_ids)],
|
||||
['product_tmpl_id', 'product_id', 'company_id', 'product_name', 'product_code'],
|
||||
@@ -476,27 +467,18 @@ class ProductProduct(models.Model):
|
||||
if company_id:
|
||||
sellers = [x for x in sellers if x.company_id.id in [company_id, False]]
|
||||
if sellers:
|
||||
temp = []
|
||||
for s in sellers:
|
||||
seller_variant = s.product_name and (
|
||||
variant and "%s (%s)" % (s.product_name, variant) or s.product_name
|
||||
) or False
|
||||
mydict = {
|
||||
'id': product.id,
|
||||
'name': seller_variant or name,
|
||||
'default_code': s.product_code or product.default_code,
|
||||
}
|
||||
temp = _name_get(mydict)
|
||||
if temp not in result:
|
||||
result.append(temp)
|
||||
else:
|
||||
mydict = {
|
||||
'id': product.id,
|
||||
'name': name,
|
||||
'default_code': product.default_code,
|
||||
}
|
||||
result.append(_name_get(mydict))
|
||||
temp.append(get_display_name(seller_variant or name, s.product_code or product.default_code))
|
||||
|
||||
return result
|
||||
# => Feature drop here, one record can only have one display_name now, instead separate with `,`
|
||||
# Remove this comment
|
||||
product.display_name = ", ".join(unique(temp))
|
||||
else:
|
||||
product.display_name = get_display_name(name, product.default_code)
|
||||
|
||||
@api.model
|
||||
def _name_search(self, name, domain=None, operator='ilike', limit=None, order=None):
|
||||
|
||||
@@ -485,11 +485,11 @@ class ProductTemplate(models.Model):
|
||||
default['name'] = _("%s (copy)", self.name)
|
||||
return super(ProductTemplate, self).copy(default=default)
|
||||
|
||||
def name_get(self):
|
||||
# Prefetch the fields used by the `name_get`, so `browse` doesn't fetch other fields
|
||||
def _compute_display_name(self):
|
||||
# Prefetch the fields used by the `display_name`, so `browse` doesn't fetch other fields
|
||||
self.fetch(['name', 'default_code'])
|
||||
return [(template.id, '%s%s' % (template.default_code and '[%s] ' % template.default_code or '', template.name))
|
||||
for template in self]
|
||||
for template in self:
|
||||
template.display_name = '{}{}'.format(template.default_code and '[%s] ' % template.default_code or '', template.name)
|
||||
|
||||
@api.model
|
||||
def _name_search(self, name, domain=None, operator='ilike', limit=None, order=None):
|
||||
@@ -529,7 +529,7 @@ class ProductTemplate(models.Model):
|
||||
domain2 = expression.AND([domain, [('id', 'in', tmpl_without_variant.ids)]])
|
||||
searched_ids |= set(super()._name_search(name, domain2, operator, limit, order))
|
||||
|
||||
# re-apply product.template order + name_get
|
||||
# re-apply product.template order + display_name
|
||||
domain = [('id', 'in', list(searched_ids))]
|
||||
return super()._name_search('', domain, 'ilike', limit, order)
|
||||
|
||||
|
||||
@@ -147,12 +147,13 @@ class ProductTemplateAttributeValue(models.Model):
|
||||
ptav_to_archive.write({'ptav_active': False})
|
||||
return True
|
||||
|
||||
def name_get(self):
|
||||
def _compute_display_name(self):
|
||||
"""Override because in general the name of the value is confusing if it
|
||||
is displayed without the name of the corresponding attribute.
|
||||
Eg. on exclusion rules form
|
||||
"""
|
||||
return [(value.id, "%s: %s" % (value.attribute_id.name, value.name)) for value in self]
|
||||
for value in self:
|
||||
value.display_name = f"{value.attribute_id.name}: {value.name}"
|
||||
|
||||
def _only_active(self):
|
||||
return self.filtered(lambda ptav: ptav.ptav_active)
|
||||
|
||||
@@ -48,26 +48,20 @@ class TestSeller(TransactionCase):
|
||||
(0, 0, {'partner_id': self.asustec.id, 'product_code': 'NO', 'company_id': False}),
|
||||
]})
|
||||
|
||||
names = self.product_consu.with_context(
|
||||
name = self.product_consu.with_context(
|
||||
partner_id=self.asustec.id,
|
||||
).name_get()
|
||||
ref = set([x[1] for x in names])
|
||||
self.assertEqual(len(names), 3, "3 vendor references should have been found")
|
||||
self.assertEqual(ref, {'[A] Boudin', '[B] Boudin', '[NO] Boudin'}, "Incorrect vendor reference list")
|
||||
names = self.product_consu.with_context(
|
||||
).display_name
|
||||
self.assertEqual(name, '[A] Boudin, [B] Boudin, [NO] Boudin', "Incorrect vendor reference list")
|
||||
name = self.product_consu.with_context(
|
||||
partner_id=self.asustec.id,
|
||||
company_id=company_a.id,
|
||||
).name_get()
|
||||
ref = set([x[1] for x in names])
|
||||
self.assertEqual(len(names), 2, "2 vendor references should have been found")
|
||||
self.assertEqual(ref, {'[A] Boudin', '[NO] Boudin'}, "Incorrect vendor reference list")
|
||||
names = self.product_consu.with_context(
|
||||
).display_name
|
||||
self.assertEqual(name, '[A] Boudin, [NO] Boudin', "Incorrect vendor reference list")
|
||||
name = self.product_consu.with_context(
|
||||
partner_id=self.asustec.id,
|
||||
company_id=company_b.id,
|
||||
).name_get()
|
||||
ref = set([x[1] for x in names])
|
||||
self.assertEqual(len(names), 2, "2 vendor references should have been found")
|
||||
self.assertEqual(ref, {'[B] Boudin', '[NO] Boudin'}, "Incorrect vendor reference list")
|
||||
).display_name
|
||||
self.assertEqual(name, '[B] Boudin, [NO] Boudin', "Incorrect vendor reference list")
|
||||
|
||||
def test_30_select_seller(self):
|
||||
self.res_partner_1 = self.asustec
|
||||
|
||||
@@ -16,9 +16,10 @@ class ProjectCollaborator(models.Model):
|
||||
('unique_collaborator', 'UNIQUE(project_id, partner_id)', 'A collaborator cannot be selected more than once in the project sharing access. Please remove duplicate(s) and try again.'),
|
||||
]
|
||||
|
||||
def name_get(self):
|
||||
collaborator_search_read = self.search_read([('id', 'in', self.ids)], ['id', 'project_id', 'partner_id'])
|
||||
return [(collaborator['id'], '%s - %s' % (collaborator['project_id'][1], collaborator['partner_id'][1])) for collaborator in collaborator_search_read]
|
||||
def _compute_display_name(self):
|
||||
self.fetch(['project_id', 'partner_id'])
|
||||
for collaborator in self:
|
||||
collaborator.display_name = f'{collaborator.project_id.display_name} - {collaborator.partner_id.display_name}'
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
|
||||
@@ -121,5 +121,5 @@ class ProjectTags(models.Model):
|
||||
def name_create(self, name):
|
||||
existing_tag = self.search([('name', '=ilike', name.strip())], limit=1)
|
||||
if existing_tag:
|
||||
return existing_tag.name_get()[0]
|
||||
return existing_tag.id, existing_tag.display_name
|
||||
return super().name_create(name)
|
||||
|
||||
@@ -193,16 +193,14 @@ class PurchaseOrder(models.Model):
|
||||
order.date_planned = False
|
||||
|
||||
@api.depends('name', 'partner_ref')
|
||||
def name_get(self):
|
||||
result = []
|
||||
def _compute_display_name(self):
|
||||
for po in self:
|
||||
name = po.name
|
||||
if po.partner_ref:
|
||||
name += ' (' + po.partner_ref + ')'
|
||||
if self.env.context.get('show_total_amount') and po.amount_total:
|
||||
name += ': ' + formatLang(self.env, po.amount_total, currency_obj=po.currency_id)
|
||||
result.append((po.id, name))
|
||||
return result
|
||||
po.display_name = name
|
||||
|
||||
@api.depends('order_line.taxes_id', 'order_line.price_subtotal', 'amount_total', 'amount_untaxed')
|
||||
def _compute_tax_totals(self):
|
||||
|
||||
@@ -40,8 +40,7 @@ class PurchaseBillUnion(models.Model):
|
||||
invoice_status in ('to invoice', 'no')
|
||||
)""")
|
||||
|
||||
def name_get(self):
|
||||
result = []
|
||||
def _compute_display_name(self):
|
||||
for doc in self:
|
||||
name = doc.name or ''
|
||||
if doc.reference:
|
||||
@@ -50,5 +49,4 @@ class PurchaseBillUnion(models.Model):
|
||||
if doc.purchase_order_id and doc.purchase_order_id.invoice_status == 'no':
|
||||
amount = 0.0
|
||||
name += ': ' + formatLang(self.env, amount, monetary=True, currency_obj=doc.currency_id)
|
||||
result.append((doc.id, name))
|
||||
return result
|
||||
doc.display_name = name
|
||||
|
||||
@@ -59,8 +59,8 @@ class Rating(models.Model):
|
||||
@api.depends('res_model', 'res_id')
|
||||
def _compute_res_name(self):
|
||||
for rating in self:
|
||||
name = self.env[rating.res_model].sudo().browse(rating.res_id).name_get()
|
||||
rating.res_name = name and name[0][1] or ('%s/%s') % (rating.res_model, rating.res_id)
|
||||
name = self.env[rating.res_model].sudo().browse(rating.res_id).display_name
|
||||
rating.res_name = name or f'{rating.res_model}/{rating.res_id}'
|
||||
|
||||
@api.depends('res_model', 'res_id')
|
||||
def _compute_resource_ref(self):
|
||||
@@ -83,8 +83,8 @@ class Rating(models.Model):
|
||||
for rating in self:
|
||||
name = False
|
||||
if rating.parent_res_model and rating.parent_res_id:
|
||||
name = self.env[rating.parent_res_model].sudo().browse(rating.parent_res_id).name_get()
|
||||
name = name and name[0][1] or ('%s/%s') % (rating.parent_res_model, rating.parent_res_id)
|
||||
name = self.env[rating.parent_res_model].sudo().browse(rating.parent_res_id).display_name
|
||||
name = name or f'{rating.parent_res_model}/{rating.parent_res_id}'
|
||||
rating.parent_res_name = name
|
||||
|
||||
def _get_rating_image_filename(self):
|
||||
|
||||
@@ -70,7 +70,7 @@ class ResourceCalendarAttendance(models.Model):
|
||||
section_names = {'0': _('First week'), '1': _('Second week')}
|
||||
section_info = {True: _('this week'), False: _('other week')}
|
||||
for record in self.filtered(lambda l: l.display_type == 'line_section'):
|
||||
section_name = "%s (%s)" % (section_names[record.week_type], section_info[this_week_type == record.week_type])
|
||||
section_name = f"{section_names[record.week_type]} ({section_info[this_week_type == record.week_type]})"
|
||||
record.display_name = section_name
|
||||
|
||||
def _copy_attendance_vals(self):
|
||||
|
||||
@@ -295,6 +295,18 @@ class SaleOrder(models.Model):
|
||||
|
||||
#=== COMPUTE METHODS ===#
|
||||
|
||||
|
||||
|
||||
@api.depends_context('sale_show_partner_name')
|
||||
def _compute_display_name(self):
|
||||
if not self._context.get('sale_show_partner_name'):
|
||||
return super()._compute_display_name()
|
||||
for order in self:
|
||||
name = order.name
|
||||
if order.partner_id.name:
|
||||
name = f'{name} - {order.partner_id.name}'
|
||||
order.display_name = name
|
||||
|
||||
@api.depends('company_id')
|
||||
def _compute_require_signature(self):
|
||||
for order in self:
|
||||
@@ -1557,17 +1569,6 @@ class SaleOrder(models.Model):
|
||||
upselling_orders = filtered_self.filtered(lambda so: so.invoice_status == 'upselling')
|
||||
upselling_orders._create_upsell_activity()
|
||||
|
||||
def name_get(self):
|
||||
if self._context.get('sale_show_partner_name'):
|
||||
res = []
|
||||
for order in self:
|
||||
name = order.name
|
||||
if order.partner_id.name:
|
||||
name = f'{name} - {order.partner_id.name}'
|
||||
res.append((order.id, name))
|
||||
return res
|
||||
return super().name_get()
|
||||
|
||||
#=== BUSINESS METHODS ===#
|
||||
|
||||
def _create_upsell_activity(self):
|
||||
|
||||
@@ -263,6 +263,15 @@ class SaleOrderLine(models.Model):
|
||||
|
||||
#=== COMPUTE METHODS ===#
|
||||
|
||||
def _compute_display_name(self):
|
||||
name_per_id = self._additional_name_per_id()
|
||||
for so_line in self.sudo():
|
||||
name = '{} - {}'.format(so_line.order_id.name, so_line.name and so_line.name.split('\n')[0] or so_line.product_id.name)
|
||||
additional_name = name_per_id.get(so_line.id)
|
||||
if additional_name:
|
||||
name = f'{name} {additional_name}'
|
||||
so_line.display_name = name
|
||||
|
||||
@api.depends('product_id')
|
||||
def _compute_product_template_id(self):
|
||||
for line in self:
|
||||
@@ -1157,17 +1166,6 @@ class SaleOrderLine(models.Model):
|
||||
if so_line.order_partner_id.ref or so_line.order_partner_id.name
|
||||
}
|
||||
|
||||
def name_get(self):
|
||||
result = []
|
||||
name_per_id = self._additional_name_per_id()
|
||||
for so_line in self.sudo():
|
||||
name = '%s - %s' % (so_line.order_id.name, so_line.name and so_line.name.split('\n')[0] or so_line.product_id.name)
|
||||
additional_name = name_per_id.get(so_line.id)
|
||||
if additional_name:
|
||||
name = '%s %s' % (name, additional_name)
|
||||
result.append((so_line.id, name))
|
||||
return result
|
||||
|
||||
#=== HOOKS ===#
|
||||
|
||||
def _is_delivery(self):
|
||||
|
||||
@@ -290,7 +290,7 @@ class TestSaleOrder(SaleCommon):
|
||||
"No validity date must be specified if the company validity duration is 0")
|
||||
|
||||
def test_so_names(self):
|
||||
"""Test custom context key for name_get & name_search.
|
||||
"""Test custom context key for display_name & name_search.
|
||||
|
||||
Note: this key is used in sale_expense & sale_timesheet modules.
|
||||
"""
|
||||
@@ -302,7 +302,7 @@ class TestSaleOrder(SaleCommon):
|
||||
self.assertNotIn(self.sale_order.partner_id.name, self.sale_order.display_name)
|
||||
self.assertIn(
|
||||
self.sale_order.partner_id.name,
|
||||
self.sale_order.with_context(sale_show_partner_name=True).name_get()[0][1])
|
||||
self.sale_order.with_context(sale_show_partner_name=True).display_name)
|
||||
|
||||
def test_state_changes(self):
|
||||
"""Test some untested state changes methods & logic."""
|
||||
|
||||
@@ -13,7 +13,7 @@ class SaleOrder(models.Model):
|
||||
|
||||
@api.model
|
||||
def _name_search(self, name, domain=None, operator='ilike', limit=None, order=None):
|
||||
""" For expense, we want to show all sales order but only their name_get (no ir.rule applied), this is the only way to do it. """
|
||||
""" For expense, we want to show all sales order but only their display_name (no ir.rule applied), this is the only way to do it. """
|
||||
if (
|
||||
self._context.get('sale_expense_all_order')
|
||||
and self.user_has_groups('sales_team.group_sale_salesman')
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo noupdate="1">
|
||||
|
||||
<!-- Required simply to set SO on expense before submitting. Used to avoid crash on name_get/name_search -->
|
||||
<!-- Required simply to set SO on expense before submitting. Used to avoid crash on display_name/name_search -->
|
||||
<record id="sale_order_rule_expense_user" model="ir.rule">
|
||||
<field name="name">Expense Employee can read confirmed SO</field>
|
||||
<field ref="sale.model_sale_order" name="model_id"/>
|
||||
|
||||
@@ -37,7 +37,6 @@ class ProjectUpdate(models.Model):
|
||||
('is_downpayment', '=', False),
|
||||
]),
|
||||
)
|
||||
name_by_sol = dict(sols.with_context(with_price_unit=True).name_get())
|
||||
product_uom_unit = self.env.ref('uom.product_uom_unit')
|
||||
product_uom_hour = self.env.ref('uom.product_uom_hour')
|
||||
company_uom = self.env.company.timesheet_encode_uom_id
|
||||
@@ -50,7 +49,7 @@ class ProjectUpdate(models.Model):
|
||||
qty_invoiced = sol.product_uom._compute_quantity(sol.qty_invoiced, company_uom, raise_if_failure=False)
|
||||
unit = sol.product_uom if is_unit else company_uom
|
||||
services.append({
|
||||
'name': name_by_sol[sol.id],
|
||||
'name': sol.with_context(with_price_unit=True).display_name,
|
||||
'sold_value': product_uom_qty,
|
||||
'effective_value': qty_delivered,
|
||||
'remaining_value': product_uom_qty - qty_delivered,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user