[IMP] sale_timesheet: display price_unit in SOL name_get

Before this commit, when many sales order items have a same product with
a different price_unit, the user cannot know which one of these sales
order items has the product with the expensive price with just the
name_get of the SOL in task form view.

This commit adds the price_unit in the name_get of the sale order items
only for the sales order items in a same sales order have the same
product.

task-2376382

closes #66157
This commit is contained in:
Xavier BOL (xbo)
2021-03-17 14:57:33 +01:00
parent 1b60102b20
commit ffae2fd626
2 changed files with 55 additions and 34 deletions
+53 -32
View File
@@ -2,10 +2,11 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import math
from collections import defaultdict
from odoo import api, fields, models, _
from odoo.osv import expression
from odoo.tools import float_compare
from odoo.tools import float_compare, format_amount
class SaleOrder(models.Model):
@@ -134,41 +135,61 @@ class SaleOrderLine(models.Model):
def name_get(self):
res = super(SaleOrderLine, self).name_get()
if self.env.context.get('with_remaining_hours'):
with_remaining_hours = self.env.context.get('with_remaining_hours')
with_price_unit = self.env.context.get('with_price_unit')
if with_remaining_hours or with_price_unit:
names = dict(res)
result = []
uom_hour = self.env.ref('uom.product_uom_hour')
uom_day = self.env.ref('uom.product_uom_day')
uom_hour = with_remaining_hours and self.env.ref('uom.product_uom_hour')
uom_day = with_remaining_hours and self.env.ref('uom.product_uom_day')
sols_by_so_dict = with_price_unit and defaultdict(lambda: self.env[self._name]) # key: (sale_order_id, product_id), value: sale order line
for line in self:
name = names.get(line.id)
if line.remaining_hours_available:
company = self.env.company
encoding_uom = company.timesheet_encode_uom_id
remaining_time = ''
if encoding_uom == uom_hour:
hours, minutes = divmod(abs(line.remaining_hours) * 60, 60)
round_minutes = minutes / 30
minutes = math.ceil(round_minutes) if line.remaining_hours >= 0 else math.floor(round_minutes)
if minutes > 1:
minutes = 0
hours += 1
else:
minutes = minutes * 30
remaining_time = ' ({sign}{hours:02.0f}:{minutes:02.0f})'.format(
sign='-' if line.remaining_hours < 0 else '',
hours=hours,
minutes=minutes)
elif encoding_uom == uom_day:
remaining_days = company.project_time_mode_id._compute_quantity(line.remaining_hours, encoding_uom, round=False)
remaining_time = ' ({qty:.02f} {unit})'.format(
qty=remaining_days,
unit=_('days') if abs(remaining_days) > 1 else _('day')
if with_remaining_hours:
name = names.get(line.id)
if line.remaining_hours_available:
company = self.env.company
encoding_uom = company.timesheet_encode_uom_id
remaining_time = ''
if encoding_uom == uom_hour:
hours, minutes = divmod(abs(line.remaining_hours) * 60, 60)
round_minutes = minutes / 30
minutes = math.ceil(round_minutes) if line.remaining_hours >= 0 else math.floor(round_minutes)
if minutes > 1:
minutes = 0
hours += 1
else:
minutes = minutes * 30
remaining_time = ' ({sign}{hours:02.0f}:{minutes:02.0f})'.format(
sign='-' if line.remaining_hours < 0 else '',
hours=hours,
minutes=minutes)
elif encoding_uom == uom_day:
remaining_days = company.project_time_mode_id._compute_quantity(line.remaining_hours, encoding_uom, round=False)
remaining_time = ' ({qty:.02f} {unit})'.format(
qty=remaining_days,
unit=_('days') if abs(remaining_days) > 1 else _('day')
)
name = '{name}{remaining_time}'.format(
name=name,
remaining_time=remaining_time
)
name = '{name}{remaining_time}'.format(
name=name,
remaining_time=remaining_time
)
result.append((line.id, name))
if with_price_unit:
names[line.id] = name
if not with_price_unit:
result.append((line.id, name))
if with_price_unit:
sols_by_so_dict[line.order_id.id, line.product_id.id] += line
if with_price_unit:
for sols in sols_by_so_dict.values():
if len(sols) > 1:
result += [(
line.id,
'%s - %s' % (
names.get(line.id), format_amount(self.env, line.price_unit, line.currency_id))
) for line in sols]
else:
result.append((sols.id, names.get(sols.id)))
return result
return res
@@ -153,7 +153,7 @@
<field name="timesheet_invoice_id" invisible="1"/>
<field name="so_line"
attrs="{'column_invisible': [('parent.allow_billable', '=', False)]}"
context="{'with_remaining_hours': True}" options="{'no_create': True, 'no_open': True}"
context="{'with_remaining_hours': True, 'with_price_unit': True}" options="{'no_create': True, 'no_open': True}"
domain="[('is_service', '=', True), ('order_partner_id', 'child_of', parent.commercial_partner_id), ('is_expense', '=', False), ('state', 'in', ['sale', 'done']), ('order_id', '=?', parent.project_sale_order_id)]"
optional="hide"/>
</xpath>
@@ -192,7 +192,7 @@
<field name="inherit_id" ref="project.view_task_form2"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='sale_line_id']" position="attributes">
<attribute name="context">{'with_remaining_hours': True}</attribute>
<attribute name="context">{'with_remaining_hours': True, 'with_price_unit': True}</attribute>
<attribute name="attrs">
{'invisible': ['|', ('allow_billable', '=', False), ('partner_id', '=', False)]}
</attribute>