[IMP] hr_timesheet: Move timesheet_cost into a separate module.
The field timesheet_cost defined on hr_employee in hr_timesheet would be useful in other modules (eg planning and MRP) as well. Therefore with this commit the field is moved into a separate module upon which hr_timesheet will have a dependency. In addition this field is renamed to employee_hourly_wage, which is a more accurate and neutral name for this field, as it will not only be used in timesheets. task-2929518 closes odoo/odoo#97988 Related: odoo/enterprise#30359 Related: odoo/upgrade#3853 Signed-off-by: Kevin Baptiste <kba@odoo.com>
This commit is contained in:
committed by
Kevin Baptiste
parent
04aa56e9f0
commit
a3eec47f35
@@ -0,0 +1,3 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import models
|
||||
@@ -0,0 +1,22 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
{
|
||||
'name': 'Employee Hourly Wage',
|
||||
'version': '1.0',
|
||||
'category': 'Services/Employee Hourly Cost',
|
||||
'summary': 'Employee Hourly Wage',
|
||||
'description': """
|
||||
This module assigns an hourly wage to employees to be used by other modules.
|
||||
============================================================================
|
||||
|
||||
""",
|
||||
'depends': ['hr'],
|
||||
'data': [
|
||||
'security/hr_hourly_cost_security.xml',
|
||||
'views/hr_employee_views.xml',
|
||||
],
|
||||
'demo': [
|
||||
'data/hr_hourly_cost_demo.xml',
|
||||
],
|
||||
'license': 'LGPL-3',
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<!-- Employee -->
|
||||
<record id="hr.employee_admin" model="hr.employee">
|
||||
<field name="hourly_cost">100</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_vad" model="hr.employee">
|
||||
<field name="hourly_cost">35</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_jth" model="hr.employee">
|
||||
<field name="hourly_cost">25</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_niv" model="hr.employee">
|
||||
<field name="hourly_cost">45</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_jod" model="hr.employee">
|
||||
<field name="hourly_cost">55</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_jve" model="hr.employee">
|
||||
<field name="hourly_cost">15</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_fme" model="hr.employee">
|
||||
<field name="hourly_cost">45</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_chs" model="hr.employee">
|
||||
<field name="hourly_cost">20</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_ngh" model="hr.employee">
|
||||
<field name="hourly_cost">40</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_jgo" model="hr.employee">
|
||||
<field name="hourly_cost">45</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_lur" model="hr.employee">
|
||||
<field name="hourly_cost">35</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_jep" model="hr.employee">
|
||||
<field name="hourly_cost">25</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_jog" model="hr.employee">
|
||||
<field name="hourly_cost">40</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_fpi" model="hr.employee">
|
||||
<field name="hourly_cost">50</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_mit" model="hr.employee">
|
||||
<field name="hourly_cost">15</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_hne" model="hr.employee">
|
||||
<field name="hourly_cost">10</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_qdp" model="hr.employee">
|
||||
<field name="hourly_cost">75</field>
|
||||
<field name="parent_id" ref="hr.employee_admin"/>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_stw" model="hr.employee">
|
||||
<field name="hourly_cost">65</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_al" model="hr.employee">
|
||||
<field name="hourly_cost">50</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_han" model="hr.employee">
|
||||
<field name="hourly_cost">35</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -0,0 +1,3 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import hr_employee
|
||||
+1
-2
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import fields, models
|
||||
@@ -7,6 +6,6 @@ from odoo import fields, models
|
||||
class HrEmployee(models.Model):
|
||||
_inherit = 'hr.employee'
|
||||
|
||||
timesheet_cost = fields.Monetary('Cost', currency_field='currency_id',
|
||||
hourly_cost = fields.Monetary('Hourly Cost', currency_field='currency_id',
|
||||
groups="hr.group_hr_user", default=0.0)
|
||||
currency_id = fields.Many2one('res.currency', related='company_id.currency_id', readonly=True)
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
<record id="group_hourly_cost_manager" model="res.groups">
|
||||
<field name="name">Administrator</field>
|
||||
<field name="category_id" ref="base.module_category_services_employee_hourly_cost"/>
|
||||
<field name="implied_ids" eval="[(4, ref('hr.group_hr_user'))]"/>
|
||||
<field name="users" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="view_employee_form" model="ir.ui.view">
|
||||
<field name="name">view.employee.form.inherit.hr.employee.hourly.wage</field>
|
||||
<field name="model">hr.employee</field>
|
||||
<field name="inherit_id" ref="hr.view_employee_form"/>
|
||||
<field name="priority" eval="40"/>
|
||||
<field name="arch" type="xml">
|
||||
<group name="application_group" position="attributes">
|
||||
<attribute name="string">Application Settings</attribute>
|
||||
</group>
|
||||
<group name="application_group" position="inside">
|
||||
<label for="hourly_cost" groups="hr_hourly_cost.group_hourly_cost_manager"/>
|
||||
<div name="hourly_cost" groups="hr_hourly_cost.group_hourly_cost_manager">
|
||||
<field name="hourly_cost" class="oe_inline"/> per hour
|
||||
<field name="currency_id" invisible="1"/>
|
||||
</div>
|
||||
</group>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -20,7 +20,7 @@ It is completely integrated with the cost accounting module. It allows you to se
|
||||
up a management by affair.
|
||||
""",
|
||||
'website': 'https://www.odoo.com/app/timesheet',
|
||||
'depends': ['hr', 'analytic', 'project', 'uom'],
|
||||
'depends': ['hr', 'hr_hourly_cost', 'analytic', 'project', 'uom'],
|
||||
'data': [
|
||||
'security/hr_timesheet_security.xml',
|
||||
'security/ir.model.access.csv',
|
||||
|
||||
@@ -6,88 +6,6 @@
|
||||
<field name="groups_id" eval="[(4, ref('group_hr_timesheet_user'))]"/>
|
||||
</record>
|
||||
|
||||
<!-- Employee -->
|
||||
<record id="hr.employee_admin" model="hr.employee">
|
||||
<field name="timesheet_cost">100</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_vad" model="hr.employee">
|
||||
<field name="timesheet_cost">35</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_jth" model="hr.employee">
|
||||
<field name="timesheet_cost">25</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_niv" model="hr.employee">
|
||||
<field name="timesheet_cost">45</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_jod" model="hr.employee">
|
||||
<field name="timesheet_cost">55</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_jve" model="hr.employee">
|
||||
<field name="timesheet_cost">15</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_fme" model="hr.employee">
|
||||
<field name="timesheet_cost">45</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_chs" model="hr.employee">
|
||||
<field name="timesheet_cost">20</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_ngh" model="hr.employee">
|
||||
<field name="timesheet_cost">40</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_jgo" model="hr.employee">
|
||||
<field name="timesheet_cost">45</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_lur" model="hr.employee">
|
||||
<field name="timesheet_cost">35</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_jep" model="hr.employee">
|
||||
<field name="timesheet_cost">25</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_jog" model="hr.employee">
|
||||
<field name="timesheet_cost">40</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_fpi" model="hr.employee">
|
||||
<field name="timesheet_cost">50</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_mit" model="hr.employee">
|
||||
<field name="timesheet_cost">15</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_hne" model="hr.employee">
|
||||
<field name="timesheet_cost">10</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_qdp" model="hr.employee">
|
||||
<field name="timesheet_cost">75</field>
|
||||
<field name="parent_id" ref="hr.employee_admin"/>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_stw" model="hr.employee">
|
||||
<field name="timesheet_cost">65</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_al" model="hr.employee">
|
||||
<field name="timesheet_cost">50</field>
|
||||
</record>
|
||||
|
||||
<record id="hr.employee_han" model="hr.employee">
|
||||
<field name="timesheet_cost">35</field>
|
||||
</record>
|
||||
|
||||
<!-- Projects -->
|
||||
<record id="project.project_project_1" model="project.project">
|
||||
<field name="allow_timesheets" eval="True"/>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import hr_employee
|
||||
from . import hr_timesheet
|
||||
from . import ir_http
|
||||
from . import ir_ui_menu
|
||||
|
||||
@@ -284,7 +284,7 @@ class AccountAnalyticLine(models.Model):
|
||||
# (re)compute the amount (depending on unit_amount, employee_id for the cost, and account_id for currency)
|
||||
if any(field_name in values for field_name in ['unit_amount', 'employee_id', 'account_id']):
|
||||
for timesheet in sudo_self:
|
||||
cost = timesheet._employee_timesheet_cost()
|
||||
cost = timesheet._hourly_cost()
|
||||
amount = -timesheet.unit_amount * cost
|
||||
amount_converted = timesheet.employee_id.currency_id._convert(
|
||||
amount, timesheet.account_id.currency_id or timesheet.currency_id, self.env.company, timesheet.date)
|
||||
@@ -306,9 +306,9 @@ class AccountAnalyticLine(models.Model):
|
||||
def _get_timesheet_time_day(self):
|
||||
return self._convert_hours_to_days(self.unit_amount)
|
||||
|
||||
def _employee_timesheet_cost(self):
|
||||
def _hourly_cost(self):
|
||||
self.ensure_one()
|
||||
return self.employee_id.timesheet_cost or 0.0
|
||||
return self.employee_id.hourly_cost or 0.0
|
||||
|
||||
def _get_report_base_filename(self):
|
||||
task_ids = self.task_id
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
<record id="group_timesheet_manager" model="res.groups">
|
||||
<field name="name">Administrator</field>
|
||||
<field name="category_id" ref="base.module_category_services_timesheets"/>
|
||||
<field name="implied_ids" eval="[(4, ref('hr_timesheet.group_hr_timesheet_approver')), (4, ref('hr.group_hr_user'))]"/>
|
||||
<field name="implied_ids" eval="[(4, ref('hr_timesheet.group_hr_timesheet_approver')), (4, ref('hr.group_hr_user')),
|
||||
(4, ref('hr_hourly_cost.group_hourly_cost_manager'))]"/>
|
||||
<field name="users" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/>
|
||||
</record>
|
||||
|
||||
|
||||
@@ -253,8 +253,8 @@ class TestTimesheet(TestCommonTimesheet):
|
||||
def test_recompute_amount_for_multiple_timesheets(self):
|
||||
""" Check that amount is recomputed correctly when setting unit_amount for multiple timesheets at once. """
|
||||
Timesheet = self.env['account.analytic.line']
|
||||
self.empl_employee.timesheet_cost = 5.0
|
||||
self.empl_employee2.timesheet_cost = 6.0
|
||||
self.empl_employee.hourly_cost = 5.0
|
||||
self.empl_employee2.hourly_cost = 6.0
|
||||
# create a timesheet for each employee
|
||||
timesheet_1 = Timesheet.with_user(self.user_employee).create({
|
||||
'project_id': self.project_customer.id,
|
||||
|
||||
@@ -30,19 +30,9 @@
|
||||
<record id="hr_employee_view_form_inherit_timesheet" model="ir.ui.view">
|
||||
<field name="name">hr.employee.form.timesheet</field>
|
||||
<field name="model">hr.employee</field>
|
||||
<field name="inherit_id" ref="hr.view_employee_form"/>
|
||||
<field name="inherit_id" ref="hr_hourly_cost.view_employee_form"/>
|
||||
<field name="priority" eval="40"/>
|
||||
<field name="arch" type="xml">
|
||||
<group name="application_group" position="attributes">
|
||||
<attribute name="string">Application Settings</attribute>
|
||||
</group>
|
||||
<group name="application_group" position="inside">
|
||||
<label for="timesheet_cost" groups="hr_timesheet.group_timesheet_manager"/>
|
||||
<div name="timesheet" groups="hr_timesheet.group_timesheet_manager">
|
||||
<field name="timesheet_cost" class="oe_inline"/> per hour
|
||||
<field name="currency_id" invisible="1"/>
|
||||
</div>
|
||||
</group>
|
||||
<xpath expr="//div[@name='button_box']" position="inside">
|
||||
<button class="oe_stat_button" type="action" name="%(timesheet_action_from_employee)d" icon="fa-calendar" groups="hr_timesheet.group_hr_timesheet_user">
|
||||
<div class="o_stat_info">
|
||||
|
||||
@@ -36,7 +36,7 @@ class TimesheetAttendance(models.Model):
|
||||
FROM (
|
||||
SELECT
|
||||
-hr_attendance.id AS id,
|
||||
hr_employee.timesheet_cost AS emp_cost,
|
||||
hr_employee.hourly_cost AS emp_cost,
|
||||
resource_resource.user_id AS user_id,
|
||||
hr_attendance.worked_hours AS attendance,
|
||||
NULL AS timesheet,
|
||||
@@ -48,7 +48,7 @@ class TimesheetAttendance(models.Model):
|
||||
UNION ALL
|
||||
SELECT
|
||||
ts.id AS id,
|
||||
hr_employee.timesheet_cost AS emp_cost,
|
||||
hr_employee.hourly_cost AS emp_cost,
|
||||
ts.user_id AS user_id,
|
||||
NULL AS attendance,
|
||||
ts.unit_amount AS timesheet,
|
||||
|
||||
@@ -156,9 +156,9 @@ class AccountAnalyticLine(models.Model):
|
||||
self.ensure_one()
|
||||
return self.env['project.sale.line.employee.map'].search([('project_id', '=', self.project_id.id), ('employee_id', '=', self.employee_id.id)])
|
||||
|
||||
def _employee_timesheet_cost(self):
|
||||
def _hourly_cost(self):
|
||||
if self.project_id.pricing_type == 'employee_rate':
|
||||
mapping_entry = self._get_employee_mapping_entry()
|
||||
if mapping_entry:
|
||||
return mapping_entry.cost
|
||||
return super()._employee_timesheet_cost()
|
||||
return super()._hourly_cost()
|
||||
|
||||
@@ -24,7 +24,7 @@ class ProjectProductEmployeeMap(models.Model):
|
||||
price_unit = fields.Float("Unit Price", compute='_compute_price_unit', store=True, readonly=True)
|
||||
currency_id = fields.Many2one('res.currency', string="Currency", compute='_compute_currency_id', store=True, readonly=False)
|
||||
cost = fields.Monetary(currency_field='cost_currency_id', compute='_compute_cost', store=True, readonly=False,
|
||||
help="This cost overrides the employee's default timesheet cost in employee's HR Settings")
|
||||
help="This cost overrides the employee's default employee hourly wage in employee's HR Settings")
|
||||
display_cost = fields.Monetary(currency_field='cost_currency_id', compute="_compute_display_cost", inverse="_inverse_display_cost", string="Hourly Cost")
|
||||
cost_currency_id = fields.Many2one('res.currency', string="Cost Currency", related='employee_id.currency_id', readonly=True)
|
||||
is_cost_changed = fields.Boolean('Is Cost Manually Changed', compute='_compute_is_cost_changed', store=True)
|
||||
@@ -55,12 +55,12 @@ class ProjectProductEmployeeMap(models.Model):
|
||||
for line in self:
|
||||
line.currency_id = line.sale_line_id.currency_id if line.sale_line_id else False
|
||||
|
||||
@api.depends('employee_id.timesheet_cost')
|
||||
@api.depends('employee_id.hourly_cost')
|
||||
def _compute_cost(self):
|
||||
self.env.remove_to_compute(self._fields['is_cost_changed'], self)
|
||||
for map_entry in self:
|
||||
if not map_entry.is_cost_changed:
|
||||
map_entry.cost = map_entry.employee_id.timesheet_cost or 0.0
|
||||
map_entry.cost = map_entry.employee_id.hourly_cost or 0.0
|
||||
|
||||
def _get_working_hours_per_calendar(self, is_uom_day=False):
|
||||
resource_calendar_per_hours = {}
|
||||
@@ -104,7 +104,7 @@ class ProjectProductEmployeeMap(models.Model):
|
||||
@api.depends('cost')
|
||||
def _compute_is_cost_changed(self):
|
||||
for map_entry in self:
|
||||
map_entry.is_cost_changed = map_entry.employee_id and map_entry.cost != map_entry.employee_id.timesheet_cost
|
||||
map_entry.is_cost_changed = map_entry.employee_id and map_entry.cost != map_entry.employee_id.hourly_cost
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
|
||||
@@ -34,23 +34,23 @@ class TestCommonSaleTimesheet(TestSaleProjectCommon):
|
||||
|
||||
cls.employee_user = cls.env['hr.employee'].create({
|
||||
'name': 'Employee User',
|
||||
'timesheet_cost': 15,
|
||||
'hourly_cost': 15,
|
||||
})
|
||||
cls.employee_manager = cls.env['hr.employee'].create({
|
||||
'name': 'Employee Manager',
|
||||
'timesheet_cost': 45,
|
||||
'hourly_cost': 45,
|
||||
})
|
||||
|
||||
cls.employee_company_B = cls.env['hr.employee'].create({
|
||||
'name': 'Gregor Clegane',
|
||||
'user_id': cls.user_employee_company_B.id,
|
||||
'timesheet_cost': 15,
|
||||
'hourly_cost': 15,
|
||||
})
|
||||
|
||||
cls.manager_company_B = cls.env['hr.employee'].create({
|
||||
'name': 'Cersei Lannister',
|
||||
'user_id': cls.user_manager_company_B.id,
|
||||
'timesheet_cost': 45,
|
||||
'hourly_cost': 45,
|
||||
})
|
||||
|
||||
# Account and project
|
||||
|
||||
@@ -112,13 +112,13 @@ class TestProject(TestCommonSaleTimesheet):
|
||||
'sale_line_id': self.project_global.sale_line_id.id,
|
||||
})
|
||||
self.assertFalse(employee_mapping.is_cost_changed)
|
||||
self.assertEqual(employee_mapping.cost, self.employee_manager.timesheet_cost)
|
||||
self.assertEqual(employee_mapping.cost, self.employee_manager.hourly_cost)
|
||||
|
||||
employee_mapping.cost = 5
|
||||
self.assertTrue(employee_mapping.is_cost_changed)
|
||||
self.assertEqual(employee_mapping.cost, 5)
|
||||
|
||||
self.employee_manager.timesheet_cost = 80
|
||||
self.employee_manager.hourly_cost = 80
|
||||
self.assertTrue(employee_mapping.is_cost_changed)
|
||||
self.assertEqual(employee_mapping.cost, 5)
|
||||
|
||||
@@ -126,9 +126,9 @@ class TestProject(TestCommonSaleTimesheet):
|
||||
self.assertTrue(employee_mapping.is_cost_changed)
|
||||
self.assertEqual(employee_mapping.cost, 5)
|
||||
|
||||
employee_mapping.cost = self.employee_user.timesheet_cost
|
||||
employee_mapping.cost = self.employee_user.hourly_cost
|
||||
employee_mapping.employee_id = self.employee_company_B
|
||||
self.assertEqual(employee_mapping.cost, self.employee_company_B.timesheet_cost)
|
||||
self.assertEqual(employee_mapping.cost, self.employee_company_B.hourly_cost)
|
||||
|
||||
def test_analytic_account_balance(self):
|
||||
"""
|
||||
@@ -150,7 +150,7 @@ class TestProject(TestCommonSaleTimesheet):
|
||||
})
|
||||
|
||||
unit_amount = 6
|
||||
expected_analytic_account_balance = - self.employee_user.timesheet_cost * unit_amount
|
||||
expected_analytic_account_balance = - self.employee_user.hourly_cost * unit_amount
|
||||
self.project_global.write({
|
||||
'sale_line_id': sale_line.id,
|
||||
'sale_line_employee_ids': [
|
||||
|
||||
@@ -16,7 +16,7 @@ class TestProjectBilling(TestCommonSaleTimesheet):
|
||||
# set up
|
||||
cls.employee_tde = cls.env['hr.employee'].create({
|
||||
'name': 'Employee TDE',
|
||||
'timesheet_cost': 42,
|
||||
'hourly_cost': 42,
|
||||
})
|
||||
|
||||
cls.partner_2 = cls.env['res.partner'].create({
|
||||
|
||||
@@ -95,13 +95,13 @@ class TestSaleTimesheetProjectProfitability(TestCommonSaleTimesheet):
|
||||
{
|
||||
'id': 'billable_manual',
|
||||
'sequence': sequence_per_invoice_type['billable_manual'],
|
||||
'billed': (timesheet1.unit_amount + timesheet2.unit_amount) * -self.employee_user.timesheet_cost,
|
||||
'billed': (timesheet1.unit_amount + timesheet2.unit_amount) * -self.employee_user.hourly_cost,
|
||||
'to_bill': 0.0,
|
||||
},
|
||||
],
|
||||
'total': {
|
||||
'to_bill': 0.0,
|
||||
'billed': (timesheet1.unit_amount + timesheet2.unit_amount) * -self.employee_user.timesheet_cost
|
||||
'billed': (timesheet1.unit_amount + timesheet2.unit_amount) * -self.employee_user.hourly_cost
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -129,21 +129,21 @@ class TestSaleTimesheetProjectProfitability(TestCommonSaleTimesheet):
|
||||
{
|
||||
'id': 'billable_manual',
|
||||
'sequence': sequence_per_invoice_type['billable_manual'],
|
||||
'billed': (timesheet1.unit_amount + timesheet2.unit_amount) * -self.employee_user.timesheet_cost,
|
||||
'billed': (timesheet1.unit_amount + timesheet2.unit_amount) * -self.employee_user.hourly_cost,
|
||||
'to_bill': 0.0,
|
||||
},
|
||||
{
|
||||
'id': 'non_billable',
|
||||
'sequence': sequence_per_invoice_type['non_billable'],
|
||||
'billed': timesheet3.unit_amount * -self.employee_manager.timesheet_cost,
|
||||
'billed': timesheet3.unit_amount * -self.employee_manager.hourly_cost,
|
||||
'to_bill': 0.0,
|
||||
},
|
||||
],
|
||||
'total': {
|
||||
'to_bill': 0.0,
|
||||
'billed':
|
||||
(timesheet1.unit_amount + timesheet2.unit_amount) * -self.employee_user.timesheet_cost
|
||||
+ timesheet3.unit_amount * -self.employee_manager.timesheet_cost,
|
||||
(timesheet1.unit_amount + timesheet2.unit_amount) * -self.employee_user.hourly_cost
|
||||
+ timesheet3.unit_amount * -self.employee_manager.hourly_cost,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -172,21 +172,21 @@ class TestSaleTimesheetProjectProfitability(TestCommonSaleTimesheet):
|
||||
{
|
||||
'id': 'billable_time',
|
||||
'sequence': sequence_per_invoice_type['billable_time'],
|
||||
'billed': (timesheet1.unit_amount + timesheet2.unit_amount) * -self.employee_user.timesheet_cost,
|
||||
'billed': (timesheet1.unit_amount + timesheet2.unit_amount) * -self.employee_user.hourly_cost,
|
||||
'to_bill': 0.0,
|
||||
},
|
||||
{
|
||||
'id': 'non_billable',
|
||||
'sequence': sequence_per_invoice_type['non_billable'],
|
||||
'billed': timesheet3.unit_amount * -self.employee_manager.timesheet_cost,
|
||||
'billed': timesheet3.unit_amount * -self.employee_manager.hourly_cost,
|
||||
'to_bill': 0.0,
|
||||
},
|
||||
],
|
||||
'total': {
|
||||
'to_bill': 0.0,
|
||||
'billed':
|
||||
(timesheet1.unit_amount + timesheet2.unit_amount) * -self.employee_user.timesheet_cost
|
||||
+ timesheet3.unit_amount * -self.employee_manager.timesheet_cost,
|
||||
(timesheet1.unit_amount + timesheet2.unit_amount) * -self.employee_user.hourly_cost
|
||||
+ timesheet3.unit_amount * -self.employee_manager.hourly_cost,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user