[IMP] sale_timesheet: split non billable type for timesheet
Timesheet logged on project created from a SO line are not exactly the same as the non billable ones. To ease the reporting, we split the non billable type of timesheet: when timesheeting directly on a project (whatever the product config), the billable type will be 'no task found'. The Overview is adapt to display the 2 'non billable' categories.
This commit is contained in:
@@ -24,7 +24,7 @@ class SaleTimesheetController(http.Controller):
|
||||
'domain': domain,
|
||||
}
|
||||
hour_rounding = request.env.ref('product.product_uom_hour').rounding
|
||||
billable_types = ['non_billable', 'billable_time', 'billable_fixed']
|
||||
billable_types = ['non_billable', 'non_billable_project', 'billable_time', 'billable_fixed']
|
||||
|
||||
# -- Dashboard (per billable type)
|
||||
dashboard_values = {
|
||||
@@ -69,6 +69,7 @@ class SaleTimesheetController(http.Controller):
|
||||
repartition_employee.setdefault(employee_id, dict(
|
||||
employee_id=data['employee_id'][0],
|
||||
employee_name=data['employee_id'][1],
|
||||
non_billable_project=0.0,
|
||||
non_billable=0.0,
|
||||
billable_time=0.0,
|
||||
billable_fixed=0.0,
|
||||
|
||||
@@ -11,7 +11,8 @@ class AccountAnalyticLine(models.Model):
|
||||
timesheet_invoice_type = fields.Selection([
|
||||
('billable_time', 'Billable Time'),
|
||||
('billable_fixed', 'Billable Fixed'),
|
||||
('non_billable', 'Non Billable')], string="Billable Type", readonly=True, copy=False)
|
||||
('non_billable', 'Non Billable'),
|
||||
('non_billable_project', 'No task found')], string="Billable Type", readonly=True, copy=False)
|
||||
timesheet_invoice_id = fields.Many2one('account.invoice', string="Invoice", readonly=True, copy=False, help="Invoice created from the timesheet")
|
||||
timesheet_revenue = fields.Monetary("Revenue", default=0.0, readonly=True, currency_field='company_currency_id', copy=False)
|
||||
|
||||
@@ -83,14 +84,14 @@ class AccountAnalyticLine(models.Model):
|
||||
timesheet_uom = self.env.user.company_id.project_time_mode_id
|
||||
|
||||
# default values
|
||||
billable_type = 'non_billable'
|
||||
billable_type = 'non_billable_project' if not timesheet.task_id else 'non_billable'
|
||||
unit_amount = timesheet.unit_amount
|
||||
so_line = timesheet.so_line
|
||||
revenue = 0.0
|
||||
billable_type = 'non_billable'
|
||||
|
||||
# set the revenue and billable type according to the product and the SO line
|
||||
if so_line.product_id.type == 'service' and so_line.product_id.service_type == 'timesheet':
|
||||
if timesheet.task_id and so_line.product_id.type == 'service' and so_line.product_id.service_type == 'timesheet':
|
||||
# find the analytic account to convert revenue into its currency
|
||||
analytic_account = timesheet.account_id
|
||||
# convert the unit of mesure into hours
|
||||
|
||||
@@ -35,6 +35,10 @@
|
||||
background-color: #5bc0de;
|
||||
color: white;
|
||||
}
|
||||
.o_progress_non_billable_project {
|
||||
background-color: @brand-primary;
|
||||
color: white;
|
||||
}
|
||||
.o_progress_non_billable {
|
||||
background-color: gray;
|
||||
color: white;
|
||||
|
||||
@@ -19,21 +19,21 @@
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th rowspan="4">
|
||||
<th rowspan="5">
|
||||
<a type="action" t-att-domain="json.dumps(domain)" context="{'pivot_row_groupby': ['date:month'],'pivot_column_groupby': ['timesheet_invoice_type'], 'pivot_measures': ['unit_amount']}">Hours</a>
|
||||
</th>
|
||||
<td class="o_timesheet_plan_dashboard_cell">
|
||||
<t t-esc="dashboard['hours']['billable_time']"/> h
|
||||
</td>
|
||||
<td>Time and material</td>
|
||||
<th rowspan="4">
|
||||
<th rowspan="5">
|
||||
<a type="action" t-att-domain="json.dumps(domain)" context="{'pivot_row_groupby': ['date:month', 'employee_id'], 'pivot_column_groupby': ['timesheet_invoice_type'],'pivot_measures': ['unit_amount']}">Rates</a>
|
||||
</th>
|
||||
<td class="o_timesheet_plan_dashboard_cell">
|
||||
<t t-esc="dashboard['rates']['billable_time']"/> %
|
||||
</td>
|
||||
<td>Time and material</td>
|
||||
<th rowspan="4">
|
||||
<th rowspan="5">
|
||||
<a type="action" t-att-domain="json.dumps(domain)" context="{'pivot_row_groupby': ['timesheet_invoice_id'], 'pivot_column_groupby': ['date:month'],'pivot_measures': ['amount', 'timesheet_revenue']}">Profitability</a>
|
||||
</th>
|
||||
<td class="o_timesheet_plan_dashboard_cell">
|
||||
@@ -61,13 +61,13 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="o_timesheet_plan_dashboard_cell">
|
||||
<t t-esc="dashboard['hours']['non_billable']"/> h
|
||||
<t t-esc="float_to_time(dashboard['hours']['non_billable_project'])"/>
|
||||
</td>
|
||||
<td>Non Billable</td>
|
||||
<td>No task found</td>
|
||||
<td class="o_timesheet_plan_dashboard_cell">
|
||||
<t t-esc="dashboard['rates']['non_billable']"/> %
|
||||
<t t-esc="dashboard['rates']['non_billable_project']"/> %
|
||||
</td>
|
||||
<td>Non Billable</td>
|
||||
<td>No task found</td>
|
||||
<td class="o_timesheet_plan_dashboard_cell">
|
||||
<t t-if="currency.position == 'before'" t-esc="currency.symbol"/>
|
||||
<t t-esc="dashboard['money_amount']['cost']"/>
|
||||
@@ -75,6 +75,18 @@
|
||||
</td>
|
||||
<td>Cost</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="o_timesheet_plan_dashboard_cell">
|
||||
<t t-esc="float_to_time(dashboard['hours']['non_billable'])"/>
|
||||
</td>
|
||||
<td>Non Billable</td>
|
||||
<td class="o_timesheet_plan_dashboard_cell">
|
||||
<t t-esc="dashboard['rates']['non_billable']"/> %
|
||||
</td>
|
||||
<td>Non Billable</td>
|
||||
<td class="o_timesheet_plan_dashboard_cell"></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="o_timesheet_plan_dashboard_total">
|
||||
<t t-esc="dashboard['hours']['total']"/> h
|
||||
@@ -104,6 +116,7 @@
|
||||
<div class="pull-right o_timesheet_plan_badge">
|
||||
<span class="badge o_progress_billable_fixed">Billable fixed</span>
|
||||
<span class="badge o_progress_billable_time">Billable time</span>
|
||||
<span class="badge o_progress_non_billable_project">No task found</span>
|
||||
<span class="badge o_progress_non_billable">Non billable</span>
|
||||
</div>
|
||||
<table class="table ">
|
||||
@@ -123,8 +136,9 @@
|
||||
<div t-if="repartition_employee[employee_id]['billable_fixed']" class="progress-bar o_progress_billable_fixed" t-att-style="'width: ' + str(repartition_employee[employee_id]['billable_fixed'] / repartition_employee[employee_id]['total'] * 100) + '%'" t-att-title="str(repartition_employee[employee_id]['billable_fixed']) + ' hours'">
|
||||
</div>
|
||||
<div t-if="repartition_employee[employee_id]['billable_time']" class="progress-bar o_progress_billable_time" t-att-style="'width: ' + str(repartition_employee[employee_id]['billable_time'] / repartition_employee[employee_id]['total'] * 100) + '%'" t-att-title="str(repartition_employee[employee_id]['billable_time']) + ' hours'">
|
||||
</div><div t-if="repartition_employee[employee_id]['non_billable_project']" class="progress-bar o_progress_non_billable_project" t-att-style="'width: ' + str(repartition_employee[employee_id]['non_billable_project'] / repartition_employee[employee_id]['total'] * 100) + '%'" t-att-title="float_to_time(repartition_employee[employee_id]['non_billable_project'])">
|
||||
</div>
|
||||
<div t-if="repartition_employee[employee_id]['non_billable']" class="progress-bar o_progress_non_billable" t-att-style="'width: ' + str(repartition_employee[employee_id]['non_billable'] / repartition_employee[employee_id]['total'] * 100) + '%'" t-att-title="str(repartition_employee[employee_id]['non_billable']) + ' hours'">
|
||||
<div t-if="repartition_employee[employee_id]['non_billable']" class="progress-bar o_progress_non_billable" t-att-style="'width: ' + str(repartition_employee[employee_id]['non_billable'] / repartition_employee[employee_id]['total'] * 100) + '%'" t-att-title="float_to_time(repartition_employee[employee_id]['non_billable'])">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
Reference in New Issue
Block a user