[IMP] sale_{project,timesheet} : format hours and differenciate sol

With this improvement,
* in the Project Updates kanban/tree side pannel :
	> Hours are displayed 'HH:mm Hours'
* in the Project Updates form description :
	> idem
	> Sales Order Items with the same products also display their
price to differentiate them.

task-2841685

closes odoo/odoo#90624

Related: odoo/enterprise#27753
Signed-off-by: Laurent Stukkens (ltu) <ltu@odoo.com>
This commit is contained in:
Audric Onockx (auon)
2022-06-13 16:51:17 +02:00
parent cc8fe32512
commit 439836ba63
4 changed files with 31 additions and 17 deletions
@@ -1,6 +1,7 @@
/** @odoo-module */
import { patch } from 'web.utils';
import { formatFloatTime, formatFloat } from "@web/fields/formatters";
import ProjectRightPanel from '@project/js/right_panel/project_right_panel';
patch(ProjectRightPanel.prototype, '@sale_project/right_panel/project_right_panel', {
@@ -24,5 +25,9 @@ patch(ProjectRightPanel.prototype, '@sale_project/right_panel/project_right_pane
if (saleItems && saleItems.total > saleItems.data.length) {
await this._loadAdditionalSalesOrderItems();
}
},
formatValue(value, unit) {
return unit === 'Hours' ? formatFloatTime(value) : formatFloat(value);
}
});
@@ -42,9 +42,9 @@
</a>
<t t-else="" t-esc="sol_name"/>
</td>
<td align="right"><t t-esc="sale_item.product_uom_qty"/> <t t-esc="uom_name"/></td>
<td align="right"><t t-esc="sale_item.qty_delivered"/> <t t-esc="uom_name"/></td>
<td align="right"><t t-esc="sale_item.qty_invoiced"/> <t t-esc="uom_name"/></td>
<td align="right"><t t-esc="formatValue(sale_item.product_uom_qty, uom_name)"/> <t t-esc="uom_name"/></td>
<td align="right"><t t-esc="formatValue(sale_item.qty_delivered, uom_name)"/> <t t-esc="uom_name"/></td>
<td align="right"><t t-esc="formatValue(sale_item.qty_invoiced, uom_name)"/> <t t-esc="uom_name"/></td>
</tr>
<tr class="o_rightpanel_nohover" t-if="sale_items.total &gt; sale_items.data.length">
<td>
+17 -8
View File
@@ -3,6 +3,7 @@
from odoo import api, models
from odoo.tools import float_utils, format_amount, formatLang
from odoo.tools.misc import format_duration
class ProjectUpdate(models.Model):
@@ -21,12 +22,14 @@ class ProjectUpdate(models.Model):
'show_activities': template_values['show_activities'] or show_sold or bool(profitability),
'services': services,
'profitability': profitability,
'format_value': lambda value, is_hour: str(round(value, 2)) if not is_hour else format_duration(value),
}
@api.model
def _get_services_values(self, project):
if not project.allow_billable:
return {}
services = []
total_sold, total_effective, total_remaining = 0, 0, 0
sols = self.env['sale.order.line'].search(
@@ -35,33 +38,39 @@ class ProjectUpdate(models.Model):
('is_downpayment', '=', False),
]),
)
name_by_sol = dict(sols.name_get())
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
for sol in sols:
#We only want to consider hours and days for this calculation
is_unit = sol.product_uom == product_uom_unit
if sol.product_uom.category_id == self.env.company.timesheet_encode_uom_id.category_id or is_unit:
product_uom_qty = sol.product_uom._compute_quantity(sol.product_uom_qty, self.env.company.timesheet_encode_uom_id, raise_if_failure=False)
qty_delivered = sol.product_uom._compute_quantity(sol.qty_delivered, self.env.company.timesheet_encode_uom_id, raise_if_failure=False)
if sol.product_uom.category_id == company_uom.category_id or is_unit:
product_uom_qty = sol.product_uom._compute_quantity(sol.product_uom_qty, company_uom, raise_if_failure=False)
qty_delivered = sol.product_uom._compute_quantity(sol.qty_delivered, company_uom, raise_if_failure=False)
unit = sol.product_uom if is_unit else company_uom
services.append({
'name': name_by_sol[sol.id] if len(sols.order_id) > 1 else sol.name,
'name': name_by_sol[sol.id],
'sold_value': product_uom_qty,
'effective_value': qty_delivered,
'remaining_value': product_uom_qty - qty_delivered,
'unit': sol.product_uom.name if is_unit else self.env.company.timesheet_encode_uom_id.name,
'unit': unit.name,
'is_unit': is_unit,
'is_hour': unit == product_uom_hour,
'sol': sol,
})
if sol.product_uom.category_id == self.env.company.timesheet_encode_uom_id.category_id:
if sol.product_uom.category_id == company_uom.category_id:
total_sold += product_uom_qty
total_effective += qty_delivered
total_remaining = total_sold - total_effective
return {
'data': services,
'total_sold': total_sold,
'total_effective': total_effective,
'total_remaining': total_remaining,
'company_unit_name': self.env.company.timesheet_encode_uom_id.name,
'company_unit_name': company_uom.name,
'is_hour': company_uom == product_uom_hour,
}
@api.model
@@ -17,15 +17,15 @@
<tr t-foreach="services['data']" t-as="service">
<t t-set="is_unit" t-value="service['is_unit']"/>
<td t-attf-class="#{ 'font-italic' if is_unit else ''}"><t t-esc="service['name']"/></td>
<td t-attf-class="#{ 'font-italic' if is_unit else ''}" style="text-align: right; vertical-align: middle;"><t t-esc="format_lang(service['sold_value'], 1)"/> <t t-esc="service['unit']"/></td>
<td t-attf-class="#{ 'font-italic' if is_unit else ''}" style="text-align: right; vertical-align: middle;"><t t-esc="format_lang(service['effective_value'], 1)"/> <t t-esc="service['unit']"/></td>
<td t-attf-class="#{ 'font-italic' if is_unit else ''}" style="text-align: right; vertical-align: middle;"><t t-esc="format_lang(service['remaining_value'], 1)"/> <t t-esc="service['unit']"/></td>
<td t-attf-class="#{ 'font-italic' if is_unit else ''}" style="text-align: right; vertical-align: middle;"><t t-esc="format_value(service['sold_value'], service['is_hour'])"/> <t t-esc="service['unit']"/></td>
<td t-attf-class="#{ 'font-italic' if is_unit else ''}" style="text-align: right; vertical-align: middle;"><t t-esc="format_value(service['effective_value'], service['is_hour'])"/> <t t-esc="service['unit']"/></td>
<td t-attf-class="#{ 'font-italic' if is_unit else ''}" style="text-align: right; vertical-align: middle;"><t t-esc="format_value(service['remaining_value'], service['is_hour'])"/> <t t-esc="service['unit']"/></td>
</tr>
<tfoot>
<td style="font-weight: bolder; text-align: right">Total</td>
<td style="font-weight: bolder; text-align: right; vertical-align: middle;"><t t-esc="format_lang(services['total_sold'], 1)"/> <t t-esc="services['company_unit_name']"/></td>
<td style="font-weight: bolder; text-align: right; vertical-align: middle;"><t t-esc="format_lang(services['total_effective'], 1)"/> <t t-esc="services['company_unit_name']"/></td>
<td style="font-weight: bolder; text-align: right; vertical-align: middle;"><t t-esc="format_lang(services['total_remaining'], 1)"/> <t t-esc="services['company_unit_name']"/></td>
<td style="font-weight: bolder; text-align: right; vertical-align: middle;"><t t-esc="format_value(services['total_sold'], services['is_hour'])"/> <t t-esc="services['company_unit_name']"/></td>
<td style="font-weight: bolder; text-align: right; vertical-align: middle;"><t t-esc="format_value(services['total_effective'], services['is_hour'])"/> <t t-esc="services['company_unit_name']"/></td>
<td style="font-weight: bolder; text-align: right; vertical-align: middle;"><t t-esc="format_value(services['total_remaining'], services['is_hour'])"/> <t t-esc="services['company_unit_name']"/></td>
</tfoot>
</tbody>
</table>