| REPOSITORY | |
|---|---|
| REPOSITORY | odoo/odoo |
| GIT | |
| GIT | https://github.com/odoo/odoo.git |
| GIT FOLDER | |
| GIT FOLDER | https://github.com/odoo/odoo/tree/19.0/sale_timesheet |
| VERSION | |
| VERSION | 0.1.0 |
| CATEGORY | |
| CATEGORY | Sales/Sales |
| LICENSE | |
| LICENSE | LGPL-3 |
| APPLICATION | |
| APPLICATION | No |
| AUTO-INSTALLABLE | |
| AUTO-INSTALLABLE | Yes |
| AUTHORS | |
| AUTHORS | Odoo S.A. |
| MAINTAINERS | |
| MAINTAINERS | Odoo S.A. |
| COMMITTERS | |
| COMMITTERS | Raphael Collet, Odoo Translation Bot, Stéphane Bidoul, Thibault Delavallée, Xavier Morel, Lucas Perais (lpe), Yannick Tivisse, Julien Castiaux, Victor Feyens, Andrea Grazioso (agr-odoo), Paul Morelle, Julien Mougenot, svs-odoo, Prakash Prajapati, Tiffany Chang (tic), Gorash, Mathieu Duckerts-Antoine, William Braeckman, william-andre, Audric Onockx (auon), Renaud Thiry, Vincent Larcin, alsh-odoo, Louis Wicket (wil), Victor Piryns (pivi), Pierre-Yves Dufays, Levi Siuzdak (sile), Antoine Boonen, Dylan Kiss (dyki), Xavier Bol (xbo), Brieuc-brd, rajh-odoo, Youssef Bashandy, bary, Maxime de Neuville, suth-odoo, kcv-odoo, Tanguy Quéguineur, nihp-odoo, aamo-odoo, thle-odoo, Mathieu Coutant, Patricia Daloze (pda), guce, Pierre Pulinckx (PIPU), Kawtar Drissi El Bouzaidi (kdeb), David Van Droogenbroeck (DROD), Mohammad Abdulmoneim (abdu), Michaël Mattiello, Pierre Pulinckx, Bastien PIERRE, K Theja (kthe), bona-odoo, Krzysztof Magusiak (krma), Mahdi Alijani (malj), Harrison Hutton, Maeva De Keyser (MDEK), nsirjacobs, mjvi-odoo, bhra-odoo, defl, mohannedah, Amr Elkhatieb, Maxime de Neuville (mane), damrOdoo, Merlin Guillaume, Abdelouahab Laaroussi (abla), Farah (ahmfa), ksin-odoo, chpa-odoo, Dhruvkumar Nagar |
| WEBSITE | |
| WEBSITE | |
| LAST TRACKING UPDATE | |
| LAST TRACKING UPDATE | 2026-07-06 14:10:18 |
| ODOO DEPENDENCIES | |
| ODOO DEPENDENCIES |
odoo/odoo: - sale_project - sale_management - sale - sales_team - base - base_setup - web - bus - web_tour - html_editor - account_payment - account - onboarding - product - uom - analytic - portal - http_routing - auth_signup - digest - resource - payment - utm - sale_service - project_account - project - rating - hr_timesheet - hr - phone_validation - resource_mail - hr_hourly_cost |
| PYTHON DEPENDENCIES | |
| PYTHON DEPENDENCIES | Not have |
| SYSTEM DEPENDENCIES | |
| SYSTEM DEPENDENCIES | Not have |
| DESCRIPTION | |
| DESCRIPTION | Allows to sell timesheets in your sales order ============================================= This module set the right product on all timesheet lines according to the order/contract you work on. This allows to have real delivered quantities in sales orders. |
| XML ID | Name | Model | Type | Status |
|---|---|---|---|---|
account_invoice_view_form_inherit_sale_timesheet |
account.invoice.form.inherit.timesheet | account.move | xpath | Inherits account.view_move_form |
hr_timesheet_line_form_inherit |
account.analytic.line.form.inherit | account.analytic.line | xpath | Inherits hr_timesheet.hr_timesheet_line_form |
hr_timesheet_line_tree_inherit |
account.analytic.line.list.inherit | account.analytic.line | xpath | Inherits hr_timesheet.hr_timesheet_line_tree |
hr_timesheet_report_search_sale_timesheet |
timesheets.analysis.report.search | timesheets.analysis.report | search | Inherits sale_timesheet.timesheet_view_search |
portal_invoice_page_inherit |
portal_invoice_page_inherit | ir.ui.view | qweb | Inherits account.portal_invoice_page |
portal_my_task_inherit |
portal_my_task_inherit | ir.ui.view | qweb | Inherits project.portal_my_task |
portal_my_timesheets_inherit |
portal_my_timesheets_inherit | ir.ui.view | qweb | Inherits hr_timesheet.portal_my_timesheets |
portal_timesheet_table_inherit |
portal_timesheet_table_inherit | ir.ui.view | qweb | Inherits hr_timesheet.portal_timesheet_table |
product_template_view_search_sale_timesheet |
product.template.search.timesheet | product.template | filter | Inherits product.product_template_search_view |
project_project_view_form |
project.project.form.inherit | project.project | xpath | Inherits hr_timesheet.project_invoice_form |
project_project_view_kanban_inherit_sale_timesheet |
project.project.kanban.inherit.sale.timesheet | project.project | xpath | Inherits hr_timesheet.view_project_kanban_inherited |
project_project_view_kanban_inherit_sale_timesheet_so_button |
project.project.kanban.inherit.sale.timesheet.so.button | project.project | xpath | Inherits project.view_project_kanban |
project_sharing_inherit_project_task_view_form |
project.task.form.inherit.timesheet | project.task | xpath | Inherits hr_timesheet.project_sharing_inherit_project_task_view_form |
project_task_view_form_inherit_sale_timesheet |
project.task.form.inherit.timesheet | project.task | xpath | Inherits project.view_task_form2 |
project_task_view_search_inherit_sale_timesheet |
project.task.view.search.inherit | project.task | filter | Inherits hr_timesheet.project_task_view_search |
report_timesheet_account_move |
report_timesheet_account_move | ir.ui.view | qweb | New |
report_timesheet_sale_order |
report_timesheet_sale_order | ir.ui.view | qweb | New |
res_config_settings_view_form |
res.config.settings.view.form.inherit.sale.timesheet | res.config.settings | xpath | Inherits hr_timesheet.res_config_settings_view_form |
sale_advance_payment_inv_timesheet_view_form |
sale_timesheet.sale.advance.payment.inv.view.form | sale.advance.payment.inv | form | Inherits sale.view_sale_advance_payment_inv |
sale_order_portal_content_inherit |
sale_order_portal_content_inherit | ir.ui.view | qweb | Inherits sale.sale_order_portal_template |
timesheet_sale_page |
timesheet_sale_page | ir.ui.view | qweb | New |
timesheet_view_search |
account.analytic.line.search | account.analytic.line | xpath | Inherits hr_timesheet.hr_timesheet_line_search |
timesheete_analysis_report_form |
timesheets.analysis.report.form | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_form |
timesheets_analysis_report_graph_inherit |
timesheets.analysis.report.graph | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_pivot_employee |
timesheets_analysis_report_graph_invoice_type |
timesheets.analysis.report.graph | timesheets.analysis.report | graph | New |
timesheets_analysis_report_graph_project_inherit |
timesheets.analysis.report.graph.project | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_graph_project |
timesheets_analysis_report_graph_task_inherit |
timesheets.analysis.report.graph.task | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_graph_task |
timesheets_analysis_report_graph_timesheet_grid |
timesheets.analysis.report.graph | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_graph_employee |
timesheets_analysis_report_list_inherited |
timesheets.analysis.report.list.inherited | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_list |
timesheets_analysis_report_pivot_inherit |
timesheets.analysis.report.pivot | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_pivot_employee |
timesheets_analysis_report_pivot_invoice_type |
timesheets.analysis.report.pivot | timesheets.analysis.report | pivot | New |
timesheets_analysis_report_pivot_project_inherit |
timesheets.analysis.report.pivot.project | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_pivot_project |
timesheets_analysis_report_pivot_task_inherit |
timesheets.analysis.report.pivot.task | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_pivot_task |
view_calendar_account_analytic_line |
account.analytic.line.calendar | account.analytic.line | field | Inherits hr_timesheet.view_calendar_account_analytic_line |
view_calendar_account_analytic_line_multi_create |
account.analytic.line.calendar.multi_create | account.analytic.line | field | Inherits hr_timesheet.view_calendar_account_analytic_line_multi_create |
view_hr_timesheet_line_graph_employee_per_date |
account.analytic.line.graph.employee.per.date | account.analytic.line | graph | New |
view_hr_timesheet_line_graph_invoice_employee |
account.analytic.line.graph.invoice.employee | account.analytic.line | xpath | Inherits view_hr_timesheet_line_graph_employee_per_date |
view_hr_timesheet_line_pivot_billing_rate |
account.analytic.line.pivot.billing.rate | account.analytic.line | pivot | New |
view_hr_timesheet_line_pivot_inherited |
account.analytic.line.pivot | account.analytic.line | xpath | Inherits hr_timesheet.view_hr_timesheet_line_pivot |
view_order_form_inherit_sale_timesheet |
sale.order.form.sale.timesheet | sale.order | button | Inherits sale_project.view_order_form_inherit_sale_project |
view_product_timesheet_form |
product.template.timesheet.form | product.template | field | Inherits sale.product_template_form_view |
view_task_project_user_fsm_graph_base_inherited |
report.project.task.user.fsm.graph.base.inherited | report.project.task.user | field | Inherits project.view_task_project_user_fsm_graph_base |
view_task_project_user_fsm_pivot_base_inherited |
report.project.task.user.fsm.pivot.base.inherited | report.project.task.user | field | Inherits project.view_task_project_user_fsm_pivot_base |
view_task_project_user_pivot_inherited |
report.project.task.user.pivot.inherited | report.project.task.user | field | Inherits project.view_task_project_user_pivot |
view_task_tree2_inherited |
project.task.list.inherited | project.task | xpath | Inherits hr_timesheet.view_task_tree2_inherited |
allow_billable
Boolean
related='project_id.allow_billable'
commercial_partner_id
Many2one → res.partner
compute='_compute_commercial_partner'
args: 'res.partner'
is_so_line_edited
Boolean
order_id
Many2one
index=True
readonly=True
related='so_line.order_id'
store=True
sale_order_state
Selection
related='order_id.state'
so_line
Many2one
compute='_compute_so_line'
domain=_domain_so_line
falsy_value_label='Non-billable'
help='Sales order item to which the time spent will be added in order to be invoiced to your customer. Remove the sales order item for the timesheet entry to be non-billable.'
readonly=False
store=True
timesheet_invoice_id
Many2one → account.move
copy=False
help='Invoice created from the timesheet'
index='btree_not_null'
readonly=True
string='Invoice'
args: 'account.move'
timesheet_invoice_type
Selection
compute='_compute_timesheet_invoice_type'
compute_sudo=True
readonly=True
store=True
string='Billable Type'
args: TIMESHEET_INVOICE_TYPES
action_invoice_from_timesheet(self)
action_sale_order_from_timesheet(self)
timesheet_count
Integer
compute='_compute_timesheet_count'
compute_sudo=True
export_string_translation=False
args: 'Number of timesheets'
timesheet_encode_uom_id
Many2one → uom.uom
export_string_translation=False
related='company_id.timesheet_encode_uom_id'
args: 'uom.uom'
timesheet_ids
One2many → account.analytic.line
copy=False
export_string_translation=False
readonly=True
string='Timesheets'
args: 'account.analytic.line', 'timesheet_invoice_id'
timesheet_total_duration
Integer
compute='_compute_timesheet_total_duration'
compute_sudo=True
help='Total recorded duration, expressed in the encoding UoM, and rounded to the unit'
args: 'Timesheet Total Duration'
action_post(self)
action_view_timesheet(self)
No new fields.
Public methods (1)unlink(self)
No new fields.
Public methods (1)reverse_moves(self, is_modify=False)
No new fields.
Public methods (1)default_get(self, fields)
No new fields.
Public methods (1)write(self, vals)
project_id
Many2one
domain="['|', ('company_id', '=', False), '&', ('company_id', '=?', company_id), ('company_id', '=', current_company_id), ('allow_billable', '=', True), ('pricing_type', '=', 'task_rate'), ('allow_timesheets', 'in', [service_policy == 'delivered_timesheet', True]), ('is_template', '=', False)]"
project_template_id
Many2one
domain="['|', ('company_id', '=', False), '&', ('company_id', '=?', company_id), ('company_id', '=', current_company_id), ('allow_billable', '=', True), ('allow_timesheets', 'in', [service_policy == 'delivered_timesheet', True]), ('is_template', '=', True)]"
service_type
Selection
ondelete={'timesheet': 'set manual'}
selection_add=[('timesheet', 'Timesheets on project (one fare per SO/Project)')]
service_upsell_threshold
Float
default=1
help='Percentage of time delivered compared to the prepaid amount that must be reached for the upselling opportunity activity to be triggered.'
args: 'Threshold'
service_upsell_threshold_ratio
Char
compute='_compute_service_upsell_threshold_ratio'
export_string_translation=False
write(self, vals)
allocated_hours
Float
billing_type
Selection
compute='_compute_billing_type'
default='not_billable'
readonly=False
required=True
selection=[('not_billable', 'not billable'), ('manually', 'billed manually')]
store=True
partner_id
Many2one
compute='_compute_partner_id'
readonly=False
store=True
pricing_type
Selection
compute='_compute_pricing_type'
default='task_rate'
help='The task rate is perfect if you would like to bill different services to different customers at different rates. The fixed rate is perfect if you bill a service at a fixed rate per hour or day worked regardless of the employee who performed it. The employee rate is preferable if your employees deliver the same service at a different rate. For instance, junior and senior consultants would deliver the same service (= consultancy), but at a different rate because of their level of seniority.'
search='_search_pricing_type'
string='Pricing'
args: [('task_rate', 'Task rate'), ('fixed_rate', 'Project rate'), ('employee_rate', 'Employee rate')]
sale_line_employee_ids
One2many → project.sale.line.employee.map
copy=False
export_string_translation=False
help="Sales order item that will be selected by default on the timesheets of the corresponding employee. It bypasses the sales order item defined on the project and the task, and can be modified on each timesheet entry if necessary. In other words, it defines the rate at which an employee's time is billed based on their expertise, skills or experience, for instance.\nIf you would like to bill the same service at a different rate, you need to create two separate sales order items as each sales order item can only have a single unit price at a time.\nYou can also define the hourly company cost of your employees for their timesheets on this project specifically. It will bypass the timesheet cost set on the employee."
args: 'project.sale.line.employee.map', 'project_id', 'Sale line/Employee map'
timesheet_product_id
Many2one → product.product
check_company=True
compute='_compute_timesheet_product_id'
default=_default_timesheet_product_id
domain="[\n ('type', '=', 'service'),\n ('invoice_policy', '=', 'delivery'),\n ('service_type', '=', 'timesheet'),\n ]"
help='Service that will be used by default when invoicing the time spent on a task. It can be modified on each task individually by selecting a specific sales order item.'
readonly=False
store=True
string='Timesheet Product'
args: 'product.product'
warning_employee_rate
Boolean
compute='_compute_warning_employee_rate'
compute_sudo=True
export_string_translation=False
action_billable_time_button(self)
action_profitability_items(self, section_name, domain=None, res_id=False)
action_project_timesheets(self)
action_view_timesheet(self)
default_get(self, fields)
get_panel_data(self)
write(self, vals)
company_id
Many2one → res.company
export_string_translation=False
related='project_id.company_id'
string='Company'
args: 'res.company'
cost
Monetary
compute='_compute_cost'
currency_field='cost_currency_id'
help="This cost overrides the employee's default employee hourly wage in employee's HR Settings"
readonly=False
store=True
cost_currency_id
Many2one → res.currency
export_string_translation=False
readonly=True
related='employee_id.currency_id'
string='Cost Currency'
args: 'res.currency'
currency_id
Many2one → res.currency
compute='_compute_currency_id'
readonly=False
store=True
string='Currency'
args: 'res.currency'
display_cost
Monetary
compute='_compute_display_cost'
currency_field='cost_currency_id'
groups='project.group_project_manager,hr.group_hr_user'
inverse='_inverse_display_cost'
string='Hourly Cost'
employee_id
Many2one → hr.employee
domain="[('id', 'not in', existing_employee_ids)]"
required=True
args: 'hr.employee', 'Employee'
existing_employee_ids
Many2many → hr.employee
compute='_compute_existing_employee_ids'
compute_sudo=True
export_string_translation=False
args: 'hr.employee'
is_cost_changed
Boolean
compute='_compute_is_cost_changed'
export_string_translation=False
store=True
args: 'Is Cost Manually Changed'
partner_id
Many2one
export_string_translation=False
related='project_id.partner_id'
price_unit
Float
compute='_compute_price_unit'
readonly=True
store=True
args: 'Unit Price'
project_id
Many2one → project.project
domain=[('is_template', '=', False)]
index=True
required=True
args: 'project.project', 'Project'
sale_line_id
Many2one → sale.order.line
compute='_compute_sale_line_id'
domain=<expr>
readonly=False
store=True
args: 'sale.order.line', 'Sales Order Item'
sale_order_id
Many2one
export_string_translation=False
related='project_id.sale_order_id'
create(self, vals_list)
write(self, vals)
has_multi_sol
Boolean
compute='_compute_has_multi_sol'
compute_sudo=True
is_project_map_empty
Boolean
compute='_compute_is_project_map_empty'
args: 'Is Project map empty'
last_sol_of_customer
Many2one → sale.order.line
compute='_compute_last_sol_of_customer'
args: 'sale.order.line'
pricing_type
Selection
related='project_id.pricing_type'
remaining_hours_available
Boolean
related='sale_line_id.remaining_hours_available'
remaining_hours_so
Float
compute='_compute_remaining_hours_so'
compute_sudo=True
search='_search_remaining_hours_so'
args: 'Time Remaining on SO'
sale_order_id
Many2one
domain="['|', '|', ('partner_id', '=', partner_id), ('partner_id.commercial_partner_id.id', 'parent_of', partner_id), ('partner_id', 'parent_of', partner_id)]"
timesheet_product_id
Many2one
related='project_id.timesheet_product_id'
TASK_PORTAL_READABLE_FIELDS(self)
remaining_hours_so
Float
groups='hr_timesheet.group_hr_timesheet_user'
readonly=True
args: 'Time Remaining on SO'
No public methods.
invoice_policy
Boolean
help='Timesheets taken when invoicing time spent'
string='Invoice Policy'
No public methods.
date_end_invoice_timesheet
Date
help='Only timesheets not yet invoiced (and validated, if applicable) from this period will be invoiced. If the period is not indicated, all timesheets not yet invoiced (and validated, if applicable) will be invoiced without distinction.'
string='End Date'
date_start_invoice_timesheet
Date
help='Only timesheets not yet invoiced (and validated, if applicable) from this period will be invoiced. If the period is not indicated, all timesheets not yet invoiced (and validated, if applicable) will be invoiced without distinction.'
string='Start Date'
invoicing_timesheet_enabled
Boolean
compute='_compute_invoicing_timesheet_enabled'
export_string_translation=False
store=True
No public methods.
show_hours_recorded_button
Boolean
compute='_compute_show_hours_recorded_button'
compute_sudo=True
export_string_translation=False
groups='hr_timesheet.group_hr_timesheet_user'
timesheet_count
Float
compute='_compute_timesheet_count'
export_string_translation=False
groups='hr_timesheet.group_hr_timesheet_user'
string='Timesheet activities'
timesheet_encode_uom_id
Many2one → uom.uom
export_string_translation=False
related='company_id.timesheet_encode_uom_id'
args: 'uom.uom'
timesheet_total_duration
Integer
compute='_compute_timesheet_total_duration'
compute_sudo=True
export_string_translation=False
groups='hr_timesheet.group_hr_timesheet_user'
help='Total recorded duration, expressed in the encoding UoM, and rounded to the unit'
args: 'Timesheet Total Duration'
action_view_timesheet(self)
create(self, vals_list)
analytic_line_ids
One2many
domain=[('project_id', '=', False)]
has_displayed_warning_upsell
Boolean
copy=False
export_string_translation=False
args: 'Has Displayed Warning Upsell'
qty_delivered_method
Selection
selection_add=[('timesheet', 'Timesheets')]
remaining_hours
Float
compute='_compute_remaining_hours'
compute_sudo=True
store=True
args: 'Time Remaining on SO'
remaining_hours_available
Boolean
compute='_compute_remaining_hours_available'
compute_sudo=True
timesheet_ids
One2many → account.analytic.line
domain=[('project_id', '!=', False)]
export_string_translation=False
string='Timesheets'
args: 'account.analytic.line', 'so_line'
No public methods.
billable_time
Float
help='Number of hours/days linked to a SOL.'
readonly=True
args: 'Billable Time'
margin
Monetary
currency_field='currency_id'
help='Timesheets revenues minus the costs'
readonly=True
args: 'Margin'
non_billable_time
Float
help='Number of hours/days not linked to a SOL.'
readonly=True
args: 'Non-billable Time'
order_id
Many2one → sale.order
readonly=True
string='Sales Order'
args: 'sale.order'
so_line
Many2one → sale.order.line
readonly=True
string='Sales Order Item'
args: 'sale.order.line'
timesheet_invoice_id
Many2one → account.move
help='Invoice created from the timesheet'
readonly=True
string='Invoice'
args: 'account.move'
timesheet_invoice_type
Selection
readonly=True
string='Billable Type'
args: TIMESHEET_INVOICE_TYPES
timesheet_revenues
Monetary
currency_field='currency_id'
help='Number of hours spent multiplied by the unit price per hour/day.'
readonly=True
args: 'Timesheet Revenues'
No public methods.
| XML ID | Name | Model | Type | Status |
|---|---|---|---|---|
account_invoice_view_form_inherit_sale_timesheet |
account.invoice.form.inherit.timesheet | account.move | xpath | Inherits account.view_move_form |
hr_timesheet_line_form_inherit |
account.analytic.line.form.inherit | account.analytic.line | xpath | Inherits hr_timesheet.hr_timesheet_line_form |
hr_timesheet_line_tree_inherit |
account.analytic.line.list.inherit | account.analytic.line | xpath | Inherits hr_timesheet.hr_timesheet_line_tree |
hr_timesheet_report_search_sale_timesheet |
timesheets.analysis.report.search | timesheets.analysis.report | search | Inherits sale_timesheet.timesheet_view_search |
portal_invoice_page_inherit |
portal_invoice_page_inherit | ir.ui.view | qweb | Inherits account.portal_invoice_page |
portal_my_task_inherit |
portal_my_task_inherit | ir.ui.view | qweb | Inherits project.portal_my_task |
portal_my_timesheets_inherit |
portal_my_timesheets_inherit | ir.ui.view | qweb | Inherits hr_timesheet.portal_my_timesheets |
portal_timesheet_table_inherit |
portal_timesheet_table_inherit | ir.ui.view | qweb | Inherits hr_timesheet.portal_timesheet_table |
product_template_view_search_sale_timesheet |
product.template.search.timesheet | product.template | filter | Inherits product.product_template_search_view |
project_create_invoice_view_form |
project.create.invoice.view.form | project.create.invoice | form | New |
project_project_view_form |
project.project.form.inherit | project.project | xpath | Inherits hr_timesheet.project_invoice_form |
project_project_view_kanban_inherit_sale_timesheet |
project.project.kanban.inherit.sale.timesheet | project.project | xpath | Inherits hr_timesheet.view_project_kanban_inherited |
project_project_view_kanban_inherit_sale_timesheet_so_button |
project.project.kanban.inherit.sale.timesheet.so.button | project.project | xpath | Inherits project.view_project_kanban |
project_sharing_inherit_project_task_view_form |
project.task.form.inherit.timesheet | project.task | xpath | Inherits hr_timesheet.project_sharing_inherit_project_task_view_form |
project_task_view_form_inherit_sale_timesheet |
project.task.form.inherit.timesheet | project.task | xpath | Inherits project.view_task_form2 |
project_task_view_search_inherit_sale_timesheet |
project.task.view.search.inherit | project.task | filter | Inherits hr_timesheet.project_task_view_search |
project_update_default_description |
project_update_default_description | ir.ui.view | qweb | Inherits project.project_update_default_description |
report_timesheet_account_move |
report_timesheet_account_move | ir.ui.view | qweb | New |
report_timesheet_sale_order |
report_timesheet_sale_order | ir.ui.view | qweb | New |
res_config_settings_view_form |
res.config.settings.view.form.inherit.sale.timesheet | res.config.settings | xpath | Inherits hr_timesheet.res_config_settings_view_form |
sale_advance_payment_inv_timesheet_view_form |
sale_timesheet.sale.advance.payment.inv.view.form | sale.advance.payment.inv | xpath | Inherits sale.view_sale_advance_payment_inv |
sale_order_portal_content_inherit |
sale_order_portal_content_inherit | ir.ui.view | qweb | Inherits sale.sale_order_portal_template |
timesheet_sale_page |
timesheet_sale_page | ir.ui.view | qweb | New |
timesheet_view_search |
account.analytic.line.search | account.analytic.line | xpath | Inherits hr_timesheet.hr_timesheet_line_search |
timesheete_analysis_report_form |
timesheets.analysis.report.form | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_form |
timesheets_analysis_report_graph_inherit |
timesheets.analysis.report.graph | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_pivot_employee |
timesheets_analysis_report_graph_invoice_type |
timesheets.analysis.report.graph | timesheets.analysis.report | graph | New |
timesheets_analysis_report_graph_project_inherit |
timesheets.analysis.report.graph.project | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_graph_project |
timesheets_analysis_report_graph_task_inherit |
timesheets.analysis.report.graph.task | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_graph_task |
timesheets_analysis_report_graph_timesheet_grid |
timesheets.analysis.report.graph | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_graph_employee |
timesheets_analysis_report_list_inherited |
timesheets.analysis.report.list.inherited | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_list |
timesheets_analysis_report_pivot_inherit |
timesheets.analysis.report.pivot | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_pivot_employee |
timesheets_analysis_report_pivot_invoice_type |
timesheets.analysis.report.pivot | timesheets.analysis.report | pivot | New |
timesheets_analysis_report_pivot_project_inherit |
timesheets.analysis.report.pivot.project | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_pivot_project |
timesheets_analysis_report_pivot_task_inherit |
timesheets.analysis.report.pivot.task | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_pivot_task |
view_hr_timesheet_line_graph_employee_per_date |
account.analytic.line.graph.employee.per.date | account.analytic.line | graph | New |
view_hr_timesheet_line_graph_invoice_employee |
account.analytic.line.graph.invoice.employee | account.analytic.line | xpath | Inherits view_hr_timesheet_line_graph_employee_per_date |
view_hr_timesheet_line_pivot_billing_rate |
account.analytic.line.pivot.billing.rate | account.analytic.line | pivot | New |
view_hr_timesheet_line_pivot_inherited |
account.analytic.line.pivot | account.analytic.line | xpath | Inherits hr_timesheet.view_hr_timesheet_line_pivot |
view_order_form_inherit_sale_timesheet |
sale.order.form.sale.timesheet | sale.order | data | Inherits sale_project.view_order_form_inherit_sale_project |
view_product_timesheet_form |
product.template.timesheet.form | product.template | field | Inherits sale.product_template_form_view |
view_task_form2_inherit_sale_timesheet |
view.task.form2.inherit | project.task | xpath | Inherits sale_project.view_sale_project_inherit_form |
view_task_project_user_fsm_graph_base_inherited |
report.project.task.user.fsm.graph.base.inherited | report.project.task.user | field | Inherits project.view_task_project_user_fsm_graph_base |
view_task_project_user_fsm_pivot_base_inherited |
report.project.task.user.fsm.pivot.base.inherited | report.project.task.user | field | Inherits project.view_task_project_user_fsm_pivot_base |
view_task_project_user_pivot_inherited |
report.project.task.user.pivot.inherited | report.project.task.user | xpath | Inherits project.view_task_project_user_pivot |
view_task_tree2_inherited |
project.task.list.inherited | project.task | xpath | Inherits hr_timesheet.view_task_tree2_inherited |
allow_billable
Boolean
related='project_id.allow_billable'
commercial_partner_id
Many2one → res.partner
compute='_compute_commercial_partner'
args: 'res.partner'
is_so_line_edited
Boolean
order_id
Many2one
index=True
readonly=True
related='so_line.order_id'
store=True
sale_order_state
Selection
related='order_id.state'
so_line
Many2one
compute='_compute_so_line'
domain=_domain_so_line
help='Sales order item to which the time spent will be added in order to be invoiced to your customer. Remove the sales order item for the timesheet entry to be non-billable.'
readonly=False
store=True
timesheet_invoice_id
Many2one → account.move
copy=False
help='Invoice created from the timesheet'
index='btree_not_null'
readonly=True
string='Invoice'
args: 'account.move'
timesheet_invoice_type
Selection
compute='_compute_timesheet_invoice_type'
compute_sudo=True
readonly=True
store=True
string='Billable Type'
args: TIMESHEET_INVOICE_TYPES
action_invoice_from_timesheet(self)
action_sale_order_from_timesheet(self)
timesheet_count
Integer
compute='_compute_timesheet_count'
compute_sudo=True
export_string_translation=False
args: 'Number of timesheets'
timesheet_encode_uom_id
Many2one → uom.uom
export_string_translation=False
related='company_id.timesheet_encode_uom_id'
args: 'uom.uom'
timesheet_ids
One2many → account.analytic.line
copy=False
export_string_translation=False
readonly=True
string='Timesheets'
args: 'account.analytic.line', 'timesheet_invoice_id'
timesheet_total_duration
Integer
compute='_compute_timesheet_total_duration'
compute_sudo=True
help='Total recorded duration, expressed in the encoding UoM, and rounded to the unit'
args: 'Timesheet Total Duration'
action_post(self)
action_view_timesheet(self)
No new fields.
Public methods (1)unlink(self)
No new fields.
Public methods (1)reverse_moves(self, is_modify=False)
No new fields.
Public methods (1)default_get(self, fields)
No new fields.
Public methods (1)write(self, vals)
project_id
Many2one
domain="['|', ('company_id', '=', False), '&', ('company_id', '=?', company_id), ('company_id', '=', current_company_id), ('allow_billable', '=', True), ('pricing_type', '=', 'task_rate'), ('allow_timesheets', 'in', [service_policy == 'delivered_timesheet', True])]"
project_template_id
Many2one
domain="['|', ('company_id', '=', False), '&', ('company_id', '=?', company_id), ('company_id', '=', current_company_id), ('allow_billable', '=', True), ('allow_timesheets', 'in', [service_policy == 'delivered_timesheet', True])]"
service_type
Selection
ondelete={'timesheet': 'set manual'}
selection_add=[('timesheet', 'Timesheets on project (one fare per SO/Project)')]
service_upsell_threshold
Float
default=1
help='Percentage of time delivered compared to the prepaid amount that must be reached for the upselling opportunity activity to be triggered.'
args: 'Threshold'
service_upsell_threshold_ratio
Char
compute='_compute_service_upsell_threshold_ratio'
export_string_translation=False
write(self, vals)
_candidate_orders
Many2many → sale.order
compute='_compute_candidate_orders'
export_string_translation=False
args: 'sale.order'
amount_to_invoice
Monetary
compute='_compute_amount_to_invoice'
currency_field='currency_id'
help='Total amount to invoice on the sales order, including all items (services, storables, expenses, ...)'
args: 'Amount to invoice'
currency_id
Many2one
export_string_translation=False
readonly=True
related='sale_order_id.currency_id'
project_id
Many2one → project.project
help='Project to make billable'
required=True
args: 'project.project', 'Project'
sale_order_id
Many2one → sale.order
domain="[('id', 'in', _candidate_orders)]"
required=True
string='Choose the Sales Order to invoice'
args: 'sale.order'
action_create_invoice(self)
default_get(self, fields)
allocated_hours
Float
billing_type
Selection
compute='_compute_billing_type'
default='not_billable'
readonly=False
required=True
selection=[('not_billable', 'not billable'), ('manually', 'billed manually')]
store=True
partner_id
Many2one
compute='_compute_partner_id'
readonly=False
store=True
pricing_type
Selection
compute='_compute_pricing_type'
default='task_rate'
help='The task rate is perfect if you would like to bill different services to different customers at different rates. The fixed rate is perfect if you bill a service at a fixed rate per hour or day worked regardless of the employee who performed it. The employee rate is preferable if your employees deliver the same service at a different rate. For instance, junior and senior consultants would deliver the same service (= consultancy), but at a different rate because of their level of seniority.'
search='_search_pricing_type'
string='Pricing'
args: [('task_rate', 'Task rate'), ('fixed_rate', 'Project rate'), ('employee_rate', 'Employee rate')]
sale_line_employee_ids
One2many → project.sale.line.employee.map
copy=False
export_string_translation=False
help="Sales order item that will be selected by default on the timesheets of the corresponding employee. It bypasses the sales order item defined on the project and the task, and can be modified on each timesheet entry if necessary. In other words, it defines the rate at which an employee's time is billed based on their expertise, skills or experience, for instance.\nIf you would like to bill the same service at a different rate, you need to create two separate sales order items as each sales order item can only have a single unit price at a time.\nYou can also define the hourly company cost of your employees for their timesheets on this project specifically. It will bypass the timesheet cost set on the employee."
args: 'project.sale.line.employee.map', 'project_id', 'Sale line/Employee map'
timesheet_product_id
Many2one → product.product
check_company=True
compute='_compute_timesheet_product_id'
default=_default_timesheet_product_id
domain="[\n ('type', '=', 'service'),\n ('invoice_policy', '=', 'delivery'),\n ('service_type', '=', 'timesheet'),\n ]"
help='Service that will be used by default when invoicing the time spent on a task. It can be modified on each task individually by selecting a specific sales order item.'
readonly=False
store=True
string='Timesheet Product'
args: 'product.product'
warning_employee_rate
Boolean
compute='_compute_warning_employee_rate'
compute_sudo=True
export_string_translation=False
action_billable_time_button(self)
action_profitability_items(self, section_name, domain=None, res_id=False)
action_view_timesheet(self)
default_get(self, fields)
get_panel_data(self)
write(self, values)
company_id
Many2one → res.company
export_string_translation=False
related='project_id.company_id'
string='Company'
args: 'res.company'
cost
Monetary
compute='_compute_cost'
currency_field='cost_currency_id'
help="This cost overrides the employee's default employee hourly wage in employee's HR Settings"
readonly=False
store=True
cost_currency_id
Many2one → res.currency
export_string_translation=False
readonly=True
related='employee_id.currency_id'
string='Cost Currency'
args: 'res.currency'
currency_id
Many2one → res.currency
compute='_compute_currency_id'
readonly=False
store=True
string='Currency'
args: 'res.currency'
display_cost
Monetary
compute='_compute_display_cost'
currency_field='cost_currency_id'
groups='project.group_project_manager,hr.group_hr_user'
inverse='_inverse_display_cost'
string='Hourly Cost'
employee_id
Many2one → hr.employee
domain="[('id', 'not in', existing_employee_ids)]"
required=True
args: 'hr.employee', 'Employee'
existing_employee_ids
Many2many → hr.employee
compute='_compute_existing_employee_ids'
export_string_translation=False
args: 'hr.employee'
is_cost_changed
Boolean
compute='_compute_is_cost_changed'
export_string_translation=False
store=True
args: 'Is Cost Manually Changed'
partner_id
Many2one
export_string_translation=False
related='project_id.partner_id'
price_unit
Float
compute='_compute_price_unit'
readonly=True
store=True
args: 'Unit Price'
project_id
Many2one → project.project
required=True
args: 'project.project', 'Project'
sale_line_id
Many2one → sale.order.line
compute='_compute_sale_line_id'
domain=<expr>
readonly=False
store=True
args: 'sale.order.line', 'Sales Order Item'
sale_order_id
Many2one
export_string_translation=False
related='project_id.sale_order_id'
create(self, vals_list)
write(self, values)
has_multi_sol
Boolean
compute='_compute_has_multi_sol'
compute_sudo=True
is_project_map_empty
Boolean
compute='_compute_is_project_map_empty'
args: 'Is Project map empty'
pricing_type
Selection
related='project_id.pricing_type'
remaining_hours_available
Boolean
related='sale_line_id.remaining_hours_available'
remaining_hours_so
Float
compute='_compute_remaining_hours_so'
compute_sudo=True
search='_search_remaining_hours_so'
args: 'Time Remaining on SO'
sale_order_id
Many2one
domain="['|', '|', ('partner_id', '=', partner_id), ('partner_id.commercial_partner_id.id', 'parent_of', partner_id), ('partner_id', 'parent_of', partner_id)]"
timesheet_product_id
Many2one
related='project_id.timesheet_product_id'
SELF_READABLE_FIELDS(self)
No new fields.
Public methods (0)No public methods.
remaining_hours_so
Float
groups='hr_timesheet.group_hr_timesheet_user'
readonly=True
args: 'Time Remaining on SO'
No public methods.
invoice_policy
Boolean
help='Timesheets taken when invoicing time spent'
string='Invoice Policy'
No public methods.
date_end_invoice_timesheet
Date
help='Only timesheets not yet invoiced (and validated, if applicable) from this period will be invoiced. If the period is not indicated, all timesheets not yet invoiced (and validated, if applicable) will be invoiced without distinction.'
string='End Date'
date_start_invoice_timesheet
Date
help='Only timesheets not yet invoiced (and validated, if applicable) from this period will be invoiced. If the period is not indicated, all timesheets not yet invoiced (and validated, if applicable) will be invoiced without distinction.'
string='Start Date'
invoicing_timesheet_enabled
Boolean
compute='_compute_invoicing_timesheet_enabled'
export_string_translation=False
store=True
No public methods.
show_hours_recorded_button
Boolean
compute='_compute_show_hours_recorded_button'
export_string_translation=False
groups='hr_timesheet.group_hr_timesheet_user'
timesheet_count
Float
compute='_compute_timesheet_count'
export_string_translation=False
groups='hr_timesheet.group_hr_timesheet_user'
string='Timesheet activities'
timesheet_encode_uom_id
Many2one → uom.uom
export_string_translation=False
related='company_id.timesheet_encode_uom_id'
args: 'uom.uom'
timesheet_total_duration
Integer
compute='_compute_timesheet_total_duration'
compute_sudo=True
export_string_translation=False
groups='hr_timesheet.group_hr_timesheet_user'
help='Total recorded duration, expressed in the encoding UoM, and rounded to the unit'
args: 'Timesheet Total Duration'
action_view_timesheet(self)
analytic_line_ids
One2many
domain=[('project_id', '=', False)]
has_displayed_warning_upsell
Boolean
copy=False
export_string_translation=False
args: 'Has Displayed Warning Upsell'
qty_delivered_method
Selection
selection_add=[('timesheet', 'Timesheets')]
remaining_hours
Float
compute='_compute_remaining_hours'
compute_sudo=True
store=True
args: 'Time Remaining on SO'
remaining_hours_available
Boolean
compute='_compute_remaining_hours_available'
compute_sudo=True
timesheet_ids
One2many → account.analytic.line
domain=[('project_id', '!=', False)]
export_string_translation=False
string='Timesheets'
args: 'account.analytic.line', 'so_line'
No public methods.
billable_time
Float
help='Number of hours/days linked to a SOL.'
readonly=True
args: 'Billable Time'
margin
Monetary
currency_field='currency_id'
help='Timesheets revenues minus the costs'
readonly=True
args: 'Margin'
non_billable_time
Float
help='Number of hours/days not linked to a SOL.'
readonly=True
args: 'Non-billable Time'
order_id
Many2one → sale.order
readonly=True
string='Sales Order'
args: 'sale.order'
so_line
Many2one → sale.order.line
readonly=True
string='Sales Order Item'
args: 'sale.order.line'
timesheet_invoice_id
Many2one → account.move
help='Invoice created from the timesheet'
readonly=True
string='Invoice'
args: 'account.move'
timesheet_invoice_type
Selection
readonly=True
string='Billable Type'
args: TIMESHEET_INVOICE_TYPES
timesheet_revenues
Monetary
currency_field='currency_id'
help='Number of hours spent multiplied by the unit price per hour/day.'
readonly=True
args: 'Timesheet Revenues'
No public methods.
| XML ID | Name | Model | Type | Status |
|---|---|---|---|---|
account_invoice_view_form_inherit_sale_timesheet |
account.invoice.form.inherit.timesheet | account.move | xpath | Inherits account.view_move_form |
hr_timesheet_line_form_inherit |
account.analytic.line.form.inherit | account.analytic.line | xpath | Inherits hr_timesheet.hr_timesheet_line_form |
hr_timesheet_line_tree_inherit |
account.analytic.line.tree.inherit | account.analytic.line | xpath | Inherits hr_timesheet.hr_timesheet_line_tree |
hr_timesheet_report_search_sale_timesheet |
timesheets.analysis.report.search | timesheets.analysis.report | search | Inherits sale_timesheet.timesheet_view_search |
portal_invoice_page_inherit |
portal_invoice_page_inherit | ir.ui.view | qweb | Inherits account.portal_invoice_page |
portal_my_task_inherit |
portal_my_task_inherit | ir.ui.view | qweb | Inherits project.portal_my_task |
portal_my_timesheets_inherit |
portal_my_timesheets_inherit | ir.ui.view | qweb | Inherits hr_timesheet.portal_my_timesheets |
portal_timesheet_table_inherit |
portal_timesheet_table_inherit | ir.ui.view | qweb | Inherits hr_timesheet.portal_timesheet_table |
portal_timesheet_table_inherit |
portal_timesheet_table_inherit | ir.ui.view | qweb | Inherits hr_timesheet.portal_timesheet_table |
product_template_view_search_sale_timesheet |
product.template.search.timesheet | product.template | xpath | Inherits product.product_template_search_view |
project_create_invoice_view_form |
project.create.invoice.view.form | project.create.invoice | form | New |
project_create_sale_order_view_form |
project.create.sale.order.wizard.form | project.create.sale.order | form | New |
project_project_view_form |
project.project.form.inherit | project.project | xpath | Inherits hr_timesheet.project_invoice_form |
project_project_view_kanban_inherit_sale_timesheet |
project.project.kanban.inherit.sale.timesheet | project.project | xpath | Inherits hr_timesheet.view_project_kanban_inherited |
project_project_view_kanban_inherit_sale_timesheet_so_button |
project.project.kanban.inherit.sale.timesheet.so.button | project.project | xpath | Inherits project.view_project_kanban |
project_sharing_inherit_project_task_view_form |
project.task.form.inherit.timesheet | project.task | xpath | Inherits hr_timesheet.project_sharing_inherit_project_task_view_form |
project_sharing_inherit_project_task_view_tree_sale_timesheet |
project.task.tree.inherit.sale.timesheet | project.task | field | Inherits project.project_sharing_project_task_view_tree |
project_task_view_form_inherit_sale_timesheet |
project.task.form.inherit.timesheet | project.task | xpath | Inherits project.view_task_form2 |
project_task_view_search_inherit_sale_timesheet |
project.task.view.search.inherit | project.task | filter | Inherits hr_timesheet.project_task_view_search |
project_update_default_description |
project_update_default_description | ir.ui.view | qweb | Inherits project.project_update_default_description |
report_timesheet_account_move |
report_timesheet_account_move | ir.ui.view | qweb | New |
report_timesheet_sale_order |
report_timesheet_sale_order | ir.ui.view | qweb | New |
res_config_settings_view_form |
res.config.settings.view.form.inherit.sale.timesheet | res.config.settings | xpath | Inherits hr_timesheet.res_config_settings_view_form |
sale_advance_payment_inv_timesheet_view_form |
sale_timesheet.sale.advance.payment.inv.view.form | sale.advance.payment.inv | xpath | Inherits sale.view_sale_advance_payment_inv |
sale_order_portal_content_inherit |
sale_order_portal_content_inherit | ir.ui.view | qweb | Inherits sale.sale_order_portal_template |
timesheet_sale_page |
timesheet_sale_page | ir.ui.view | qweb | New |
timesheet_view_search |
account.analytic.line.search | account.analytic.line | xpath | Inherits hr_timesheet.hr_timesheet_line_search |
timesheets_analysis_report_graph_inherit |
timesheets.analysis.report.graph | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_pivot_employee |
timesheets_analysis_report_graph_invoice_type |
timesheets.analysis.report.graph | timesheets.analysis.report | graph | New |
timesheets_analysis_report_graph_project_inherit |
timesheets.analysis.report.graph.project | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_graph_project |
timesheets_analysis_report_graph_task_inherit |
timesheets.analysis.report.graph.task | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_graph_task |
timesheets_analysis_report_graph_timesheet_grid |
timesheets.analysis.report.graph | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_graph_employee |
timesheets_analysis_report_pivot_inherit |
timesheets.analysis.report.pivot | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_pivot_employee |
timesheets_analysis_report_pivot_invoice_type |
timesheets.analysis.report.pivot | timesheets.analysis.report | pivot | New |
timesheets_analysis_report_pivot_project_inherit |
timesheets.analysis.report.pivot.project | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_pivot_project |
timesheets_analysis_report_pivot_task_inherit |
timesheets.analysis.report.pivot.task | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_pivot_task |
view_hr_timesheet_line_graph_employee_per_date |
account.analytic.line.graph.employee.per.date | account.analytic.line | graph | New |
view_hr_timesheet_line_graph_invoice_employee |
account.analytic.line.graph.invoice.employee | account.analytic.line | xpath | Inherits view_hr_timesheet_line_graph_employee_per_date |
view_hr_timesheet_line_pivot_billing_rate |
account.analytic.line.pivot.billing.rate | account.analytic.line | pivot | New |
view_hr_timesheet_line_pivot_inherited |
account.analytic.line.pivot | account.analytic.line | xpath | Inherits hr_timesheet.view_hr_timesheet_line_pivot |
view_order_form_inherit_sale_timesheet |
sale.order.form.sale.timesheet | sale.order | data | Inherits sale_project.view_order_form_inherit_sale_project |
view_product_timesheet_form |
product.template.timesheet.form | product.template | field | Inherits sale.product_template_form_view |
view_task_form2_inherit_sale_timesheet |
view.task.form2.inherit | project.task | xpath | Inherits sale_project.view_sale_project_inherit_form |
view_task_project_user_pivot_inherited |
report.project.task.user.pivot.inherited | report.project.task.user | xpath | Inherits project.view_task_project_user_pivot |
view_task_tree2_inherited |
project.task.tree.inherited | project.task | xpath | Inherits hr_timesheet.view_task_tree2_inherited |
allow_billable
Boolean
related='project_id.allow_billable'
commercial_partner_id
Many2one → res.partner
compute='_compute_commercial_partner'
args: 'res.partner'
is_so_line_edited
Boolean
order_id
Many2one
index=True
readonly=True
related='so_line.order_id'
store=True
so_line
Many2one
compute='_compute_so_line'
domain=_domain_so_line
help='Sales order item to which the time spent will be added in order to be invoiced to your customer. Remove the sales order item for the timesheet entry to be non-billable.'
readonly=False
store=True
timesheet_invoice_id
Many2one → account.move
copy=False
help='Invoice created from the timesheet'
index='btree_not_null'
readonly=True
string='Invoice'
args: 'account.move'
timesheet_invoice_type
Selection
compute='_compute_timesheet_invoice_type'
compute_sudo=True
readonly=True
store=True
string='Billable Type'
args: TIMESHEET_INVOICE_TYPES
action_invoice_from_timesheet(self)
action_sale_order_from_timesheet(self)
timesheet_count
Integer
compute='_compute_timesheet_count'
compute_sudo=True
args: 'Number of timesheets'
timesheet_encode_uom_id
Many2one → uom.uom
related='company_id.timesheet_encode_uom_id'
args: 'uom.uom'
timesheet_ids
One2many → account.analytic.line
copy=False
readonly=True
string='Timesheets'
args: 'account.analytic.line', 'timesheet_invoice_id'
timesheet_total_duration
Integer
compute='_compute_timesheet_total_duration'
compute_sudo=True
help='Total recorded duration, expressed in the encoding UoM, and rounded to the unit'
args: 'Timesheet Total Duration'
action_post(self)
action_view_timesheet(self)
No new fields.
Public methods (1)unlink(self)
No new fields.
Public methods (1)reverse_moves(self, is_modify=False)
No new fields.
Public methods (1)default_get(self, fields)
No new fields.
Public methods (1)write(self, vals)
project_id
Many2one
domain="['|', ('company_id', '=', False), '&', ('company_id', '=?', company_id), ('company_id', '=', current_company_id), ('allow_billable', '=', True), ('pricing_type', '=', 'task_rate'), ('allow_timesheets', 'in', [service_policy == 'delivered_timesheet', True])]"
project_template_id
Many2one
domain="['|', ('company_id', '=', False), '&', ('company_id', '=?', company_id), ('company_id', '=', current_company_id), ('allow_billable', '=', True), ('allow_timesheets', 'in', [service_policy == 'delivered_timesheet', True])]"
service_type
Selection
ondelete={'timesheet': 'set manual'}
selection_add=[('timesheet', 'Timesheets on project (one fare per SO/Project)')]
service_upsell_threshold
Float
default=1
help='Percentage of time delivered compared to the prepaid amount that must be reached for the upselling opportunity activity to be triggered.'
args: 'Threshold'
service_upsell_threshold_ratio
Char
compute='_compute_service_upsell_threshold_ratio'
write(self, vals)
_candidate_orders
Many2many → sale.order
compute='_compute_candidate_orders'
args: 'sale.order'
amount_to_invoice
Monetary
compute='_compute_amount_to_invoice'
currency_field='currency_id'
help='Total amount to invoice on the sales order, including all items (services, storables, expenses, ...)'
args: 'Amount to invoice'
currency_id
Many2one
readonly=True
related='sale_order_id.currency_id'
project_id
Many2one → project.project
help='Project to make billable'
required=True
args: 'project.project', 'Project'
sale_order_id
Many2one → sale.order
domain="[('id', 'in', _candidate_orders)]"
required=True
string='Choose the Sales Order to invoice'
args: 'sale.order'
action_create_invoice(self)
default_get(self, fields)
commercial_partner_id
Many2one
related='partner_id.commercial_partner_id'
company_id
Many2one
related='project_id.company_id'
info_invoice
Char
compute='_compute_info_invoice'
line_ids
One2many → project.create.sale.order.line
string='Lines'
args: 'project.create.sale.order.line', 'wizard_id'
partner_id
Many2one → res.partner
help='Customer of the sales order'
required=True
string='Customer'
args: 'res.partner'
project_id
Many2one → project.project
domain=[('sale_line_id', '=', False)]
help='Project for which we are creating a sales order'
required=True
args: 'project.project', 'Project'
sale_order_id
Many2one → sale.order
domain="['|', '|', ('partner_id', '=', partner_id), ('partner_id', 'child_of', commercial_partner_id), ('partner_id', 'parent_of', partner_id)]"
string='Sales Order'
args: 'sale.order'
action_create_sale_order(self)
default_get(self, fields)
currency_id
Many2one → res.currency
string='Currency'
args: 'res.currency'
employee_id
Many2one → hr.employee
help='Employee that has timesheets on the project.'
string='Employee'
args: 'hr.employee'
price_unit
Float
help='Unit price of the sales order item.'
args: 'Unit Price'
product_id
Many2one → product.product
domain=[('detailed_type', '=', 'service'), ('invoice_policy', '=', 'delivery'), ('service_type', '=', 'timesheet')]
help='Product of the sales order item. Must be a service invoiced based on timesheets on tasks.'
string='Service'
args: 'product.product'
wizard_id
Many2one → project.create.sale.order
required=True
args: 'project.create.sale.order'
No public methods.
allocated_hours
Float
billable_percentage
Integer
compute='_compute_billable_percentage'
groups='hr_timesheet.group_hr_timesheet_approver'
help='% of timesheets that are billable compared to the total number of timesheets linked to the AA of the project, rounded to the unit.'
billing_type
Selection
compute='_compute_billing_type'
default='not_billable'
readonly=False
required=True
selection=[('not_billable', 'not billable'), ('manually', 'billed manually')]
store=True
partner_id
Many2one
compute='_compute_partner_id'
readonly=False
store=True
pricing_type
Selection
compute='_compute_pricing_type'
default='task_rate'
help='The task rate is perfect if you would like to bill different services to different customers at different rates. The fixed rate is perfect if you bill a service at a fixed rate per hour or day worked regardless of the employee who performed it. The employee rate is preferable if your employees deliver the same service at a different rate. For instance, junior and senior consultants would deliver the same service (= consultancy), but at a different rate because of their level of seniority.'
search='_search_pricing_type'
string='Pricing'
args: [('task_rate', 'Task rate'), ('fixed_rate', 'Project rate'), ('employee_rate', 'Employee rate')]
sale_line_employee_ids
One2many → project.sale.line.employee.map
copy=False
help="Sales order item that will be selected by default on the timesheets of the corresponding employee. It bypasses the sales order item defined on the project and the task, and can be modified on each timesheet entry if necessary. In other words, it defines the rate at which an employee's time is billed based on their expertise, skills or experience, for instance.\nIf you would like to bill the same service at a different rate, you need to create two separate sales order items as each sales order item can only have a single unit price at a time.\nYou can also define the hourly company cost of your employees for their timesheets on this project specifically. It will bypass the timesheet cost set on the employee."
args: 'project.sale.line.employee.map', 'project_id', 'Sale line/Employee map'
timesheet_product_id
Many2one → product.product
check_company=True
compute='_compute_timesheet_product_id'
default=_default_timesheet_product_id
domain="[\n ('detailed_type', '=', 'service'),\n ('invoice_policy', '=', 'delivery'),\n ('service_type', '=', 'timesheet'),\n ]"
help='Service that will be used by default when invoicing the time spent on a task. It can be modified on each task individually by selecting a specific sales order item.'
readonly=False
store=True
string='Timesheet Product'
args: 'product.product'
warning_employee_rate
Boolean
compute='_compute_warning_employee_rate'
compute_sudo=True
action_billable_time_button(self)
action_make_billable(self)
action_profitability_items(self, section_name, domain=None, res_id=False)
action_view_timesheet(self)
default_get(self, fields)
get_panel_data(self)
write(self, values)
company_id
Many2one → res.company
related='project_id.company_id'
string='Company'
args: 'res.company'
cost
Monetary
compute='_compute_cost'
currency_field='cost_currency_id'
help="This cost overrides the employee's default employee hourly wage in employee's HR Settings"
readonly=False
store=True
cost_currency_id
Many2one → res.currency
readonly=True
related='employee_id.currency_id'
string='Cost Currency'
args: 'res.currency'
currency_id
Many2one → res.currency
compute='_compute_currency_id'
readonly=False
store=True
string='Currency'
args: 'res.currency'
display_cost
Monetary
compute='_compute_display_cost'
currency_field='cost_currency_id'
inverse='_inverse_display_cost'
string='Hourly Cost'
employee_id
Many2one → hr.employee
domain="[('id', 'not in', existing_employee_ids)]"
required=True
args: 'hr.employee', 'Employee'
existing_employee_ids
Many2many → hr.employee
compute='_compute_existing_employee_ids'
args: 'hr.employee'
is_cost_changed
Boolean
compute='_compute_is_cost_changed'
store=True
args: 'Is Cost Manually Changed'
partner_id
Many2one
related='project_id.partner_id'
price_unit
Float
compute='_compute_price_unit'
readonly=True
store=True
args: 'Unit Price'
project_id
Many2one → project.project
required=True
args: 'project.project', 'Project'
sale_line_id
Many2one → sale.order.line
compute='_compute_sale_line_id'
domain=<expr>
readonly=False
store=True
args: 'sale.order.line', 'Sales Order Item'
sale_order_id
Many2one
related='project_id.sale_order_id'
create(self, vals_list)
write(self, values)
has_multi_sol
Boolean
compute='_compute_has_multi_sol'
compute_sudo=True
is_project_map_empty
Boolean
compute='_compute_is_project_map_empty'
args: 'Is Project map empty'
pricing_type
Selection
related='project_id.pricing_type'
remaining_hours_available
Boolean
related='sale_line_id.remaining_hours_available'
remaining_hours_so
Float
compute='_compute_remaining_hours_so'
compute_sudo=True
search='_search_remaining_hours_so'
args: 'Remaining Hours on SO'
sale_order_id
Many2one
domain="['|', '|', ('partner_id', '=', partner_id), ('partner_id.commercial_partner_id.id', 'parent_of', partner_id), ('partner_id', 'parent_of', partner_id)]"
so_analytic_account_id
Many2one
related='sale_order_id.analytic_account_id'
string='Sale Order Analytic Account'
timesheet_product_id
Many2one
related='project_id.timesheet_product_id'
SELF_READABLE_FIELDS(self)
No new fields.
Public methods (0)No public methods.
No new fields.
Public methods (0)No public methods.
remaining_hours_so
Float
readonly=True
args: 'Remaining Hours on SO'
No public methods.
invoice_policy
Boolean
help='Timesheets taken when invoicing time spent'
string='Invoice Policy'
No public methods.
date_end_invoice_timesheet
Date
help='Only timesheets not yet invoiced (and validated, if applicable) from this period will be invoiced. If the period is not indicated, all timesheets not yet invoiced (and validated, if applicable) will be invoiced without distinction.'
string='End Date'
date_start_invoice_timesheet
Date
help='Only timesheets not yet invoiced (and validated, if applicable) from this period will be invoiced. If the period is not indicated, all timesheets not yet invoiced (and validated, if applicable) will be invoiced without distinction.'
string='Start Date'
invoicing_timesheet_enabled
Boolean
compute='_compute_invoicing_timesheet_enabled'
store=True
No public methods.
project_id
Many2one
check_company=True
domain="[('pricing_type', '!=', 'employee_rate'), ('analytic_account_id', '!=', False)]"
show_hours_recorded_button
Boolean
compute='_compute_show_hours_recorded_button'
groups='hr_timesheet.group_hr_timesheet_user'
timesheet_count
Float
compute='_compute_timesheet_count'
groups='hr_timesheet.group_hr_timesheet_user'
string='Timesheet activities'
timesheet_encode_uom_id
Many2one → uom.uom
related='company_id.timesheet_encode_uom_id'
args: 'uom.uom'
timesheet_total_duration
Integer
compute='_compute_timesheet_total_duration'
compute_sudo=True
groups='hr_timesheet.group_hr_timesheet_user'
help='Total recorded duration, expressed in the encoding UoM, and rounded to the unit'
args: 'Timesheet Total Duration'
action_view_timesheet(self)
analytic_line_ids
One2many
domain=[('project_id', '=', False)]
has_displayed_warning_upsell
Boolean
copy=False
args: 'Has Displayed Warning Upsell'
qty_delivered_method
Selection
selection_add=[('timesheet', 'Timesheets')]
remaining_hours
Float
compute='_compute_remaining_hours'
compute_sudo=True
store=True
args: 'Remaining Hours on SO'
remaining_hours_available
Boolean
compute='_compute_remaining_hours_available'
compute_sudo=True
timesheet_ids
One2many → account.analytic.line
domain=[('project_id', '!=', False)]
string='Timesheets'
args: 'account.analytic.line', 'so_line'
No public methods.
billable_time
Float
help='Number of hours/days linked to a SOL.'
readonly=True
args: 'Billable Hours'
margin
Float
help='Timesheets revenues minus the costs'
readonly=True
args: 'Margin'
non_billable_time
Float
help='Number of hours/days not linked to a SOL.'
readonly=True
args: 'Non-billable Hours'
order_id
Many2one → sale.order
readonly=True
string='Sales Order'
args: 'sale.order'
so_line
Many2one → sale.order.line
readonly=True
string='Sales Order Item'
args: 'sale.order.line'
timesheet_invoice_id
Many2one → account.move
help='Invoice created from the timesheet'
readonly=True
string='Invoice'
args: 'account.move'
timesheet_invoice_type
Selection
readonly=True
string='Billable Type'
args: TIMESHEET_INVOICE_TYPES
timesheet_revenues
Float
help='Number of hours spent multiplied by the unit price per hour/day.'
readonly=True
args: 'Timesheet Revenues'
No public methods.
| XML ID | Name | Model | Type | Status |
|---|---|---|---|---|
account_invoice_view_form_inherit_sale_timesheet |
account.invoice.form.inherit.timesheet | account.move | xpath | Inherits account.view_move_form |
hr_timesheet_line_form_inherit |
account.analytic.line.form.inherit | account.analytic.line | xpath | Inherits hr_timesheet.hr_timesheet_line_form |
hr_timesheet_line_tree_inherit |
account.analytic.line.tree.inherit | account.analytic.line | xpath | Inherits hr_timesheet.hr_timesheet_line_tree |
hr_timesheet_report_search_sale_timesheet |
timesheets.analysis.report.search | timesheets.analysis.report | xpath | Inherits hr_timesheet.hr_timesheet_report_search |
portal_invoice_page_inherit |
portal_invoice_page_inherit | ir.ui.view | qweb | Inherits account.portal_invoice_page |
portal_my_task_inherit |
portal_my_task_inherit | ir.ui.view | qweb | Inherits project.portal_my_task |
portal_my_timesheets_inherit |
portal_my_timesheets_inherit | ir.ui.view | qweb | Inherits hr_timesheet.portal_my_timesheets |
portal_timesheet_table_inherit |
portal_timesheet_table_inherit | ir.ui.view | qweb | Inherits hr_timesheet.portal_timesheet_table |
product_template_view_search_sale_timesheet |
product.template.search.timesheet | product.template | xpath | Inherits product.product_template_search_view |
project_create_invoice_view_form |
project.create.invoice.view.form | project.create.invoice | form | New |
project_create_sale_order_view_form |
project.create.sale.order.wizard.form | project.create.sale.order | form | New |
project_project_view_form |
project.project.form.inherit | project.project | xpath | Inherits hr_timesheet.project_invoice_form |
project_project_view_form_simplified_inherit |
project.project.view.form.simplified.inherit | project.project | xpath | Inherits hr_timesheet.project_project_view_form_simplified_inherit_timesheet |
project_project_view_kanban_inherit_sale_timesheet |
project.project.kanban.inherit.sale.timesheet | project.project | xpath | Inherits hr_timesheet.view_project_kanban_inherited |
project_project_view_kanban_inherit_sale_timesheet_so_button |
project.project.kanban.inherit.sale.timesheet.so.button | project.project | xpath | Inherits project.view_project_kanban |
project_sharing_inherit_project_task_view_form |
project.task.form.inherit.timesheet | project.task | xpath | Inherits project.project_sharing_project_task_view_form |
project_sharing_inherit_project_task_view_tree_sale_timesheet |
project.task.tree.inherit.sale.timesheet | project.task | xpath | Inherits hr_timesheet.project_sharing_inherit_project_task_view_tree |
project_task_view_form_inherit_sale_timesheet |
project.task.form.inherit.timesheet | project.task | xpath | Inherits project.view_task_form2 |
project_update_default_description |
project_update_default_description | ir.ui.view | qweb | Inherits project.project_update_default_description |
report_timesheet_account_move |
report_timesheet_account_move | ir.ui.view | qweb | New |
report_timesheet_sale_order |
report_timesheet_sale_order | ir.ui.view | qweb | New |
res_config_settings_view_form |
res.config.settings.view.form.inherit.sale.timesheet | res.config.settings | xpath | Inherits hr_timesheet.res_config_settings_view_form |
sale_advance_payment_inv_timesheet_view_form |
sale_timesheet.sale.advance.payment.inv.view.form | sale.advance.payment.inv | xpath | Inherits sale.view_sale_advance_payment_inv |
sale_order_portal_content_inherit |
sale_order_portal_content_inherit | ir.ui.view | qweb | Inherits sale.sale_order_portal_template |
timesheet_sale_page |
timesheet_sale_page | ir.ui.view | qweb | New |
timesheet_view_search |
account.analytic.line.search | account.analytic.line | xpath | Inherits hr_timesheet.hr_timesheet_line_search |
timesheets_analysis_report_graph_inherit |
timesheets.analysis.report.graph | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_pivot_employee |
timesheets_analysis_report_graph_invoice_type |
timesheets.analysis.report.graph | timesheets.analysis.report | graph | New |
timesheets_analysis_report_graph_project_inherit |
timesheets.analysis.report.graph.project | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_graph_project |
timesheets_analysis_report_graph_task_inherit |
timesheets.analysis.report.graph.task | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_graph_task |
timesheets_analysis_report_graph_timesheet_grid |
timesheets.analysis.report.graph | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_graph_employee |
timesheets_analysis_report_pivot_inherit |
timesheets.analysis.report.pivot | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_pivot_employee |
timesheets_analysis_report_pivot_invoice_type |
timesheets.analysis.report.pivot | timesheets.analysis.report | pivot | New |
timesheets_analysis_report_pivot_project_inherit |
timesheets.analysis.report.pivot.project | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_pivot_project |
timesheets_analysis_report_pivot_task_inherit |
timesheets.analysis.report.pivot.task | timesheets.analysis.report | xpath | Inherits hr_timesheet.timesheets_analysis_report_pivot_task |
view_hr_timesheet_line_graph_employee_per_date |
account.analytic.line.graph.employee.per.date | account.analytic.line | graph | New |
view_hr_timesheet_line_pivot_billing_rate |
account.analytic.line.pivot.billing.rate | account.analytic.line | pivot | New |
view_order_form_inherit_sale_timesheet |
sale.order.form.sale.timesheet | sale.order | data | Inherits sale_project.view_order_form_inherit_sale_project |
view_product_timesheet_form |
product.template.timesheet.form | product.template | field | Inherits sale.product_template_form_view |
view_sale_service_inherit_form2 |
sale.service.form.view.inherit | project.task | xpath | Inherits hr_timesheet.view_task_form2_inherited |
view_task_form2_inherit_sale_timesheet |
view.task.form2.inherit | project.task | xpath | Inherits sale_project.view_sale_project_inherit_form |
view_task_tree2_inherited |
project.task.tree.inherited | project.task | xpath | Inherits hr_timesheet.view_task_tree2_inherited |
commercial_partner_id
Many2one → res.partner
compute='_compute_commercial_partner'
args: 'res.partner'
is_so_line_edited
Boolean
order_id
Many2one
index=True
readonly=True
related='so_line.order_id'
store=True
so_line
Many2one
compute='_compute_so_line'
domain=_domain_so_line
help='Sales order item to which the time spent will be added in order to be invoiced to your customer. Remove the sales order item for the timesheet entry to be non-billable.'
readonly=False
store=True
timesheet_invoice_id
Many2one → account.move
copy=False
help='Invoice created from the timesheet'
index='btree_not_null'
readonly=True
string='Invoice'
args: 'account.move'
timesheet_invoice_type
Selection
compute='_compute_timesheet_invoice_type'
compute_sudo=True
readonly=True
store=True
string='Billable Type'
args: TIMESHEET_INVOICE_TYPES
write(self, values)
timesheet_count
Integer
compute='_compute_timesheet_count'
args: 'Number of timesheets'
timesheet_encode_uom_id
Many2one → uom.uom
related='company_id.timesheet_encode_uom_id'
args: 'uom.uom'
timesheet_ids
One2many → account.analytic.line
copy=False
readonly=True
string='Timesheets'
args: 'account.analytic.line', 'timesheet_invoice_id'
timesheet_total_duration
Integer
compute='_compute_timesheet_total_duration'
help='Total recorded duration, expressed in the encoding UoM, and rounded to the unit'
args: 'Timesheet Total Duration'
action_post(self)
action_view_timesheet(self)
No new fields.
Public methods (1)unlink(self)
No new fields.
Public methods (1)reverse_moves(self)
No new fields.
Public methods (1)write(self, vals)
project_id
Many2one
domain="[('company_id', '=', current_company_id), ('allow_billable', '=', True), ('pricing_type', '=', 'task_rate'), ('allow_timesheets', 'in', [service_policy == 'delivered_timesheet', True])]"
project_template_id
Many2one
domain="[('company_id', '=', current_company_id), ('allow_billable', '=', True), ('allow_timesheets', 'in', [service_policy == 'delivered_timesheet', True])]"
service_type
Selection
ondelete={'timesheet': 'set manual'}
selection_add=[('timesheet', 'Timesheets on project (one fare per SO/Project)')]
service_upsell_threshold
Float
default=1
help='Percentage of time delivered compared to the prepaid amount that must be reached for the upselling opportunity activity to be triggered.'
args: 'Threshold'
service_upsell_threshold_ratio
Char
compute='_compute_service_upsell_threshold_ratio'
write(self, vals)
_candidate_orders
Many2many → sale.order
compute='_compute_candidate_orders'
args: 'sale.order'
amount_to_invoice
Monetary
compute='_compute_amount_to_invoice'
currency_field='currency_id'
help='Total amount to invoice on the sales order, including all items (services, storables, expenses, ...)'
args: 'Amount to invoice'
currency_id
Many2one
readonly=True
related='sale_order_id.currency_id'
project_id
Many2one → project.project
help='Project to make billable'
required=True
args: 'project.project', 'Project'
sale_order_id
Many2one → sale.order
domain="[('id', 'in', _candidate_orders)]"
required=True
string='Choose the Sales Order to invoice'
args: 'sale.order'
action_create_invoice(self)
default_get(self, fields)
commercial_partner_id
Many2one
related='partner_id.commercial_partner_id'
company_id
Many2one
related='project_id.company_id'
info_invoice
Char
compute='_compute_info_invoice'
line_ids
One2many → project.create.sale.order.line
string='Lines'
args: 'project.create.sale.order.line', 'wizard_id'
partner_id
Many2one → res.partner
help='Customer of the sales order'
required=True
string='Customer'
args: 'res.partner'
project_id
Many2one → project.project
domain=[('sale_line_id', '=', False)]
help='Project for which we are creating a sales order'
required=True
args: 'project.project', 'Project'
sale_order_id
Many2one → sale.order
domain="['|', '|', ('partner_id', '=', partner_id), ('partner_id', 'child_of', commercial_partner_id), ('partner_id', 'parent_of', partner_id)]"
string='Sales Order'
args: 'sale.order'
action_create_sale_order(self)
default_get(self, fields)
currency_id
Many2one → res.currency
string='Currency'
args: 'res.currency'
employee_id
Many2one → hr.employee
help='Employee that has timesheets on the project.'
string='Employee'
args: 'hr.employee'
price_unit
Float
help='Unit price of the sales order item.'
args: 'Unit Price'
product_id
Many2one → product.product
domain=[('detailed_type', '=', 'service'), ('invoice_policy', '=', 'delivery'), ('service_type', '=', 'timesheet')]
help='Product of the sales order item. Must be a service invoiced based on timesheets on tasks.'
string='Service'
args: 'product.product'
wizard_id
Many2one → project.create.sale.order
required=True
args: 'project.create.sale.order'
No public methods.
allocated_hours
Float
compute='_compute_allocated_hours'
readonly=False
store=True
billable_percentage
Integer
compute='_compute_billable_percentage'
groups='hr_timesheet.group_hr_timesheet_approver'
help='% of timesheets that are billable compared to the total number of timesheets linked to the AA of the project, rounded to the unit.'
display_create_order
Boolean
compute='_compute_display_create_order'
partner_id
Many2one
compute='_compute_partner_id'
readonly=False
store=True
pricing_type
Selection
compute='_compute_pricing_type'
default='task_rate'
help='The task rate is perfect if you would like to bill different services to different customers at different rates. The fixed rate is perfect if you bill a service at a fixed rate per hour or day worked regardless of the employee who performed it. The employee rate is preferable if your employees deliver the same service at a different rate. For instance, junior and senior consultants would deliver the same service (= consultancy), but at a different rate because of their level of seniority.'
search='_search_pricing_type'
string='Pricing'
args: [('task_rate', 'Task rate'), ('fixed_rate', 'Project rate'), ('employee_rate', 'Employee rate')]
sale_line_employee_ids
One2many → project.sale.line.employee.map
copy=False
help="Sales order item that will be selected by default on the timesheets of the corresponding employee. It bypasses the sales order item defined on the project and the task, and can be modified on each timesheet entry if necessary. In other words, it defines the rate at which an employee's time is billed based on their expertise, skills or experience, for instance.\nIf you would like to bill the same service at a different rate, you need to create two separate sales order items as each sales order item can only have a single unit price at a time.\nYou can also define the hourly company cost of your employees for their timesheets on this project specifically. It will bypass the timesheet cost set on the employee."
args: 'project.sale.line.employee.map', 'project_id', 'Sale line/Employee map'
timesheet_product_id
Many2one → product.product
compute='_compute_timesheet_product_id'
default=_default_timesheet_product_id
domain="[\n ('detailed_type', '=', 'service'),\n ('invoice_policy', '=', 'delivery'),\n ('service_type', '=', 'timesheet'),\n '|', ('company_id', '=', False), ('company_id', '=', company_id)]"
help='Service that will be used by default when invoicing the time spent on a task. It can be modified on each task individually by selecting a specific sales order item.'
readonly=False
store=True
string='Timesheet Product'
args: 'product.product'
warning_employee_rate
Boolean
compute='_compute_warning_employee_rate'
compute_sudo=True
action_billable_time_button(self)
action_make_billable(self)
action_profitability_items(self, section_name, domain=None, res_id=False)
action_view_timesheet(self)
default_get(self, fields)
get_panel_data(self)
write(self, values)
company_id
Many2one → res.company
related='project_id.company_id'
string='Company'
args: 'res.company'
cost
Monetary
compute='_compute_cost'
currency_field='cost_currency_id'
help="This cost overrides the employee's default employee hourly wage in employee's HR Settings"
readonly=False
store=True
cost_currency_id
Many2one → res.currency
readonly=True
related='employee_id.currency_id'
string='Cost Currency'
args: 'res.currency'
currency_id
Many2one → res.currency
compute='_compute_currency_id'
readonly=False
store=True
string='Currency'
args: 'res.currency'
display_cost
Monetary
compute='_compute_display_cost'
currency_field='cost_currency_id'
inverse='_inverse_display_cost'
string='Hourly Cost'
employee_id
Many2one → hr.employee
required=True
args: 'hr.employee', 'Employee'
is_cost_changed
Boolean
compute='_compute_is_cost_changed'
store=True
args: 'Is Cost Manually Changed'
partner_id
Many2one
related='project_id.partner_id'
price_unit
Float
compute='_compute_price_unit'
readonly=True
store=True
args: 'Unit Price'
project_id
Many2one → project.project
required=True
args: 'project.project', 'Project'
sale_line_id
Many2one → sale.order.line
compute='_compute_sale_line_id'
domain=<expr>
readonly=False
store=True
args: 'sale.order.line', 'Sales Order Item'
create(self, vals_list)
write(self, values)
allow_billable
Boolean
related='project_id.allow_billable'
has_multi_sol
Boolean
compute='_compute_has_multi_sol'
compute_sudo=True
is_project_map_empty
Boolean
compute='_compute_is_project_map_empty'
args: 'Is Project map empty'
pricing_type
Selection
related='project_id.pricing_type'
remaining_hours_available
Boolean
related='sale_line_id.remaining_hours_available'
remaining_hours_so
Float
compute='_compute_remaining_hours_so'
compute_sudo=True
search='_search_remaining_hours_so'
args: 'Remaining Hours on SO'
sale_order_id
Many2one
domain="['|', '|', ('partner_id', '=', partner_id), ('partner_id', 'child_of', commercial_partner_id), ('partner_id', 'parent_of', partner_id)]"
so_analytic_account_id
Many2one
related='sale_order_id.analytic_account_id'
string='Sale Order Analytic Account'
timesheet_product_id
Many2one
related='project_id.timesheet_product_id'
SELF_READABLE_FIELDS(self)
No new fields.
Public methods (0)No public methods.
No new fields.
Public methods (0)No public methods.
invoice_policy
Boolean
help='Timesheets taken when invoicing time spent'
string='Invoice Policy'
No public methods.
date_end_invoice_timesheet
Date
help='Only timesheets not yet invoiced (and validated, if applicable) from this period will be invoiced. If the period is not indicated, all timesheets not yet invoiced (and validated, if applicable) will be invoiced without distinction.'
string='End Date'
date_start_invoice_timesheet
Date
help='Only timesheets not yet invoiced (and validated, if applicable) from this period will be invoiced. If the period is not indicated, all timesheets not yet invoiced (and validated, if applicable) will be invoiced without distinction.'
string='Start Date'
invoicing_timesheet_enabled
Boolean
compute='_compute_invoicing_timesheet_enabled'
store=True
No public methods.
project_id
Many2one
domain="[('pricing_type', '!=', 'employee_rate'), ('analytic_account_id', '!=', False), ('company_id', '=', company_id)]"
timesheet_count
Float
compute='_compute_timesheet_ids'
groups='hr_timesheet.group_hr_timesheet_user'
string='Timesheet activities'
timesheet_encode_uom_id
Many2one → uom.uom
related='company_id.timesheet_encode_uom_id'
args: 'uom.uom'
timesheet_ids
Many2many → account.analytic.line
compute='_compute_timesheet_ids'
string='Timesheet activities associated to this sale'
args: 'account.analytic.line'
timesheet_total_duration
Integer
compute='_compute_timesheet_total_duration'
help='Total recorded duration, expressed in the encoding UoM, and rounded to the unit'
args: 'Timesheet Total Duration'
action_view_timesheet(self)
analytic_line_ids
One2many
domain=[('project_id', '=', False)]
has_displayed_warning_upsell
Boolean
copy=False
args: 'Has Displayed Warning Upsell'
qty_delivered_method
Selection
selection_add=[('timesheet', 'Timesheets')]
remaining_hours
Float
compute='_compute_remaining_hours'
compute_sudo=True
store=True
args: 'Remaining Hours on SO'
remaining_hours_available
Boolean
compute='_compute_remaining_hours_available'
compute_sudo=True
timesheet_ids
One2many → account.analytic.line
domain=[('project_id', '!=', False)]
string='Timesheets'
args: 'account.analytic.line', 'so_line'
name_get(self)
billable_time
Float
help='Number of hours/days linked to a SOL.'
readonly=True
args: 'Billable Hours'
margin
Float
help='Timesheets revenues minus the costs'
readonly=True
args: 'Margin'
non_billable_time
Float
help='Number of hours/days not linked to a SOL.'
readonly=True
args: 'Non-billable Hours'
order_id
Many2one → sale.order
readonly=True
string='Sales Order'
args: 'sale.order'
so_line
Many2one → sale.order.line
readonly=True
string='Sales Order Item'
args: 'sale.order.line'
timesheet_invoice_id
Many2one → account.move
help='Invoice created from the timesheet'
readonly=True
string='Invoice'
args: 'account.move'
timesheet_invoice_type
Selection
readonly=True
string='Billable Type'
args: TIMESHEET_INVOICE_TYPES
timesheet_revenues
Float
help='Number of hours spent multiplied by the unit price per hour/day.'
readonly=True
args: 'Timesheet Revenues'
No public methods.
| REPOSITORY | |
|---|---|
| REPOSITORY | odoo/odoo |
| GIT | |
| GIT | https://github.com/odoo/odoo.git |
| GIT FOLDER | |
| GIT FOLDER | https://github.com/odoo/odoo/tree/15.0/sale_timesheet |
| VERSION | |
| VERSION | 0.1.0 |
| CATEGORY | |
| CATEGORY | Hidden |
| LICENSE | |
| LICENSE | LGPL-3 |
| APPLICATION | |
| APPLICATION | No |
| AUTO-INSTALLABLE | |
| AUTO-INSTALLABLE | Yes |
| AUTHORS | |
| AUTHORS | |
| MAINTAINERS | |
| MAINTAINERS | |
| COMMITTERS | |
| COMMITTERS | Raphael Collet, Odoo Translation Bot, Martin Trigaux, Thibault Delavallée, Christophe Simonis, Xavier Morel, Goffin Simon, Thibault Francois, Aaron Bohy, GitHub, Barad Mahendra, Yannick Tivisse, Christophe Monniez, Adrian Torres, wan, Xavier-Do, Victor Feyens, Andrea Grazioso (agr-odoo), Julien Mougenot, Anh Thao Pham (pta), Alvaro Fuentes, Ivan Yelizariev, Philémon van Helden, Prakash Prajapati, Kamesh Patel, Tiffany Chang (tic), Nathan Marotte (nama), Mathieu Duckerts-Antoine, jbw, Djamel (otd), Hiral Bhavsar, jbm-odoo, William Braeckman, root, Kevin Baptiste, Stefan-Calin Crainiciuc (stcc), Xavier BOL (xbo), roen-odoo, prro-odoo, Mitali Patel, Nicolas (vin), william-andre, Audric Onockx (auon), Florian Vranckx, Pouya Malekinejad, Thibault Libioulle, Laurent Stukkens (LTU), Vincent Larcin, Pierrot (prro), Thomas Lefebvre (thle), Victor Piryns (pivi), Andrew Gavgavian, Levi Siuzdak (sile), Bruno Boi, Krina Oza, Kamlesh Pathekar, Cedric Prieels (cpr), Leloup Loïc (lole), Raouf, Xavier Bol (xbo), Leonardo Pavan Rocha, Dawn Hwang, Mattis Megevand (mmeg), Giang Phạm, Nidhi Patel, ravb-odoo, Abderraouf Ghrissi (abgh), Anjali |
| WEBSITE | |
| WEBSITE | |
| LAST TRACKING UPDATE | |
| LAST TRACKING UPDATE | 2026-07-06 00:25:27 |
| ODOO DEPENDENCIES | |
| ODOO DEPENDENCIES |
odoo/odoo: - sale_project - sale_management - sale - sales_team - base - base_setup - web - bus - web_tour - payment - account - product - uom - analytic - portal - web_editor - http_routing - auth_signup - digest - resource - utm - project - rating - hr_timesheet - hr |
| PYTHON DEPENDENCIES | |
| PYTHON DEPENDENCIES | Not have |
| SYSTEM DEPENDENCIES | |
| SYSTEM DEPENDENCIES | Not have |
| DESCRIPTION | |
| DESCRIPTION | Allows to sell timesheets in your sales order ============================================= This module set the right product on all timesheet lines according to the order/contract you work on. This allows to have real delivered quantities in sales orders. |
| XML ID | Name | Model | Type | Status |
|---|---|---|---|---|
account_invoice_view_form_inherit_sale_timesheet |
account.invoice.form.inherit.timesheet | account.move | xpath | Inherits account.view_move_form |
hr_timesheet_line_form_inherit |
account.analytic.line.form.inherit | account.analytic.line | xpath | Inherits hr_timesheet.hr_timesheet_line_form |
hr_timesheet_line_tree_inherit |
account.analytic.line.tree.inherit | account.analytic.line | xpath | Inherits hr_timesheet.hr_timesheet_line_tree |
portal_invoice_page_inherit |
portal_invoice_page_inherit | ir.ui.view | qweb | Inherits account.portal_invoice_page |
portal_my_task_inherit |
portal_my_task_inherit | ir.ui.view | qweb | Inherits project.portal_my_task |
portal_my_timesheets_inherit |
portal_my_timesheets_inherit | ir.ui.view | qweb | Inherits hr_timesheet.portal_my_timesheets |
portal_timesheet_table_inherit |
portal_timesheet_table_inherit | ir.ui.view | qweb | Inherits hr_timesheet.portal_timesheet_table |
product_template_view_search_sale_timesheet |
product.template.search.timesheet | product.template | xpath | Inherits product.product_template_search_view |
project_create_invoice_view_form |
project.create.invoice.view.form | project.create.invoice | form | New |
project_create_sale_order_view_form |
project.create.sale.order.wizard.form | project.create.sale.order | form | New |
project_profitability_report_view_graph |
project.profitability.report.graph | project.profitability.report | graph | New |
project_profitability_report_view_pivot |
project.profitability.report.pivot | project.profitability.report | pivot | New |
project_profitability_report_view_search |
project.profitability.report.search | project.profitability.report | search | New |
project_profitability_report_view_tree |
project.profitability.report.view.tree | project.profitability.report | tree | New |
project_project_view_form |
project.project.form.inherit | project.project | xpath | Inherits hr_timesheet.project_invoice_form |
project_project_view_form_salesman |
project.project.form.inherit.salesman | project.project | field | Inherits sale_timesheet.project_project_view_form |
project_project_view_form_simplified_inherit |
project.project.view.form.simplified.inherit | project.project | field | Inherits hr_timesheet.project_project_view_form_simplified_inherit_timesheet |
project_project_view_kanban_inherit_sale_timesheet |
project.project.kanban.inherit.sale.timesheet | project.project | xpath | Inherits hr_timesheet.view_project_kanban_inherited |
project_sharing_inherit_project_task_view_form |
project.task.form.inherit.timesheet | project.task | xpath | Inherits project.project_sharing_project_task_view_form |
project_task_view_form_inherit_sale_timesheet |
project.task.form.inherit.timesheet | project.task | xpath | Inherits project.view_task_form2 |
project_task_view_form_inherit_sale_timesheet_editable |
project.task.form.view.form.inherit.sale.timesheet.editable | project.task | xpath | Inherits project_task_view_form_inherit_sale_timesheet |
project_update_default_description |
project_update_default_description | ir.ui.view | qweb | Inherits project.project_update_default_description |
res_config_settings_view_form |
res.config.settings.view.form.inherit.sale.timesheet | res.config.settings | xpath | Inherits hr_timesheet.res_config_settings_view_form |
sale_advance_payment_inv_timesheet_view_form |
sale_timesheet.sale.advance.payment.inv.view.form | sale.advance.payment.inv | xpath | Inherits sale.view_sale_advance_payment_inv |
sale_order_portal_content_inherit |
sale_order_portal_content_inherit | ir.ui.view | qweb | Inherits sale.sale_order_portal_template |
timesheet_view_pivot_revenue |
account.analytic.line.pivot.revenue | account.analytic.line | pivot | New |
timesheet_view_search |
account.analytic.line.search | account.analytic.line | xpath | Inherits hr_timesheet.hr_timesheet_line_search |
view_hr_timesheet_line_pivot_billing_rate |
account.analytic.line.pivot.billing.rate | account.analytic.line | pivot | New |
view_order_form_inherit_sale_timesheet |
sale.order.form.sale.timesheet | sale.order | data | Inherits sale_project.view_order_form_inherit_sale_project |
view_product_timesheet_form |
product.template.timesheet.form | product.template | xpath | Inherits sale.product_template_form_view_invoice_policy |
view_sale_service_inherit_form2 |
sale.service.form.view.inherit | project.task | xpath | Inherits project.view_task_form2 |
view_task_form2_inherit_sale_timesheet |
view.task.form2.inherit | project.task | xpath | Inherits project.view_task_form2 |
commercial_partner_id
Many2one → res.partner
compute='_compute_commercial_partner'
args: 'res.partner'
is_so_line_edited
Boolean
order_id
Many2one
readonly=True
related='so_line.order_id'
store=True
so_line
Many2one
compute='_compute_so_line'
domain="[('is_service', '=', True), ('is_expense', '=', False), ('state', 'in', ['sale', 'done']), ('order_partner_id', 'child_of', commercial_partner_id)]"
readonly=False
store=True
timesheet_invoice_id
Many2one → account.move
copy=False
help='Invoice created from the timesheet'
readonly=True
string='Invoice'
args: 'account.move'
timesheet_invoice_type
Selection
compute='_compute_timesheet_invoice_type'
compute_sudo=True
readonly=True
store=True
string='Billable Type'
args: [('billable_time', 'Billed on Timesheets'), ('billable_fixed', 'Billed at a Fixed price'), ('non_billable', 'Non Billable Tasks'), ('timesheet_revenues', 'Timesheet Revenues'), ('service_revenues', 'Service Revenues'), ('other_revenues', 'Other Revenues'), ('other_costs', 'Other Costs')]
write(self, values)
timesheet_count
Integer
compute='_compute_timesheet_count'
args: 'Number of timesheets'
timesheet_encode_uom_id
Many2one → uom.uom
related='company_id.timesheet_encode_uom_id'
args: 'uom.uom'
timesheet_ids
One2many → account.analytic.line
copy=False
readonly=True
string='Timesheets'
args: 'account.analytic.line', 'timesheet_invoice_id'
timesheet_total_duration
Integer
compute='_compute_timesheet_total_duration'
help='Total recorded duration, expressed in the encoding UoM, and rounded to the unit'
args: 'Timesheet Total Duration'
action_view_timesheet(self)
No new fields.
Public methods (1)unlink(self)
No new fields.
Public methods (1)write(self, vals)
project_id
Many2one
domain="[('company_id', '=', current_company_id), ('allow_billable', '=', True), ('pricing_type', '=', 'task_rate'), ('allow_timesheets', 'in', [service_policy == 'delivered_timesheet', True])]"
project_template_id
Many2one
domain="[('company_id', '=', current_company_id), ('allow_billable', '=', True), ('allow_timesheets', 'in', [service_policy == 'delivered_timesheet', True])]"
service_policy
Selection
compute='_compute_service_policy'
inverse='_inverse_service_policy'
string='Service Invoicing Policy'
args: <expr>
service_type
Selection
ondelete={'timesheet': 'set default'}
selection_add=[('timesheet', 'Timesheets on project (one fare per SO/Project)')]
service_upsell_threshold
Float
default=1
help='Percentage of time delivered compared to the prepaid amount that must be reached for the upselling opportunity activity to be triggered.'
args: 'Threshold'
service_upsell_threshold_ratio
Char
compute='_compute_service_upsell_threshold_ratio'
write(self, vals)
_candidate_orders
Many2many → sale.order
compute='_compute_candidate_orders'
args: 'sale.order'
amount_to_invoice
Monetary
compute='_compute_amount_to_invoice'
currency_field='currency_id'
help='Total amount to invoice on the sales order, including all items (services, storables, expenses, ...)'
args: 'Amount to invoice'
currency_id
Many2one
readonly=True
related='sale_order_id.currency_id'
project_id
Many2one → project.project
help='Project to make billable'
required=True
args: 'project.project', 'Project'
sale_order_id
Many2one → sale.order
domain="[('id', 'in', _candidate_orders)]"
required=True
string='Choose the Sales Order to invoice'
args: 'sale.order'
action_create_invoice(self)
default_get(self, fields)
commercial_partner_id
Many2one
related='partner_id.commercial_partner_id'
company_id
Many2one
related='project_id.company_id'
info_invoice
Char
compute='_compute_info_invoice'
line_ids
One2many → project.create.sale.order.line
string='Lines'
args: 'project.create.sale.order.line', 'wizard_id'
partner_id
Many2one → res.partner
help='Customer of the sales order'
required=True
string='Customer'
args: 'res.partner'
project_id
Many2one → project.project
domain=[('sale_line_id', '=', False)]
help='Project for which we are creating a sales order'
required=True
args: 'project.project', 'Project'
sale_order_id
Many2one → sale.order
domain="['|', '|', ('partner_id', '=', partner_id), ('partner_id', 'child_of', commercial_partner_id), ('partner_id', 'parent_of', partner_id)]"
string='Sales Order'
args: 'sale.order'
action_create_sale_order(self)
default_get(self, fields)
currency_id
Many2one → res.currency
string='Currency'
args: 'res.currency'
employee_id
Many2one → hr.employee
help='Employee that has timesheets on the project.'
string='Employee'
args: 'hr.employee'
price_unit
Float
help='Unit price of the sales order item.'
args: 'Unit Price'
product_id
Many2one → product.product
domain=[('detailed_type', '=', 'service'), ('invoice_policy', '=', 'delivery'), ('service_type', '=', 'timesheet')]
help='Product of the sales order item. Must be a service invoiced based on timesheets on tasks.'
string='Service'
args: 'product.product'
wizard_id
Many2one → project.create.sale.order
required=True
args: 'project.create.sale.order'
No public methods.
amount_untaxed_invoiced
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Amount Invoiced'
amount_untaxed_to_invoice
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Amount to Invoice'
analytic_account_id
Many2one → account.analytic.account
readonly=True
string='Analytic Account'
args: 'account.analytic.account'
company_id
Many2one → res.company
readonly=True
string='Project Company'
args: 'res.company'
currency_id
Many2one → res.currency
readonly=True
string='Project Currency'
args: 'res.currency'
expense_amount_untaxed_invoiced
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Amount Re-invoiced'
expense_amount_untaxed_to_invoice
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Amount to Re-invoice'
expense_cost
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Other Costs'
line_date
Date
readonly=True
args: 'Date'
margin
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Margin'
order_confirmation_date
Datetime
readonly=True
args: 'Sales Order Confirmation Date'
other_revenues
Float
digits=(16, 2)
group_operator='sum'
help='All revenues that are not from timesheets and that are linked to the analytic account of the project.'
readonly=True
args: 'Other Revenues'
partner_id
Many2one → res.partner
readonly=True
string='Customer'
args: 'res.partner'
product_id
Many2one → product.product
readonly=True
string='Product'
args: 'product.product'
project_id
Many2one → project.project
readonly=True
string='Project'
args: 'project.project'
sale_line_id
Many2one → sale.order.line
readonly=True
string='Sale Order Line'
args: 'sale.order.line'
sale_order_id
Many2one → sale.order
readonly=True
string='Sale Order'
args: 'sale.order'
task_id
Many2one → project.task
readonly=True
string='Task'
args: 'project.task'
timesheet_cost
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Timesheet Cost'
timesheet_unit_amount
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Timesheet Duration'
user_id
Many2one → res.users
readonly=True
string='Project Manager'
args: 'res.users'
init(self)
allow_billable
Boolean
help='Invoice your time and material from tasks.'
args: 'Billable'
billable_percentage
Integer
compute='_compute_billable_percentage'
groups='hr_timesheet.group_hr_timesheet_approver'
help='% of timesheets that are billable compared to the total number of timesheets linked to the AA of the project, rounded to the unit.'
display_create_order
Boolean
compute='_compute_display_create_order'
partner_id
Many2one
compute='_compute_partner_id'
readonly=False
store=True
pricing_type
Selection
compute='_compute_pricing_type'
default='task_rate'
help='The task rate is perfect if you would like to bill different services to different customers at different rates. The fixed rate is perfect if you bill a service at a fixed rate per hour or day worked regardless of the employee who performed it. The employee rate is preferable if your employees deliver the same service at a different rate. For instance, junior and senior consultants would deliver the same service (= consultancy), but at a different rate because of their level of seniority.'
search='_search_pricing_type'
string='Pricing'
args: [('task_rate', 'Task rate'), ('fixed_rate', 'Project rate'), ('employee_rate', 'Employee rate')]
sale_line_employee_ids
One2many → project.sale.line.employee.map
copy=False
help="Employee/Sale Order Item Mapping:\n Defines to which sales order item an employee's timesheet entry will be linked.By extension, it defines the rate at which an employee's time on the project is billed."
args: 'project.sale.line.employee.map', 'project_id', 'Sale line/Employee map'
timesheet_product_id
Many2one → product.product
compute='_compute_timesheet_product_id'
default=_default_timesheet_product_id
domain="[\n ('detailed_type', '=', 'service'),\n ('invoice_policy', '=', 'delivery'),\n ('service_type', '=', 'timesheet'),\n '|', ('company_id', '=', False), ('company_id', '=', company_id)]"
help='Select a Service product with which you would like to bill your time spent on tasks.'
readonly=False
store=True
string='Timesheet Product'
args: 'product.product'
warning_employee_rate
Boolean
compute='_compute_warning_employee_rate'
compute_sudo=True
action_billable_time_button(self)
action_make_billable(self)
action_open_project_invoices(self)
action_view_all_rating(self)
action_view_timesheet(self)
default_get(self, fields)
get_panel_data(self)
write(self, values)
company_id
Many2one → res.company
related='project_id.company_id'
string='Company'
args: 'res.company'
cost
Monetary
compute='_compute_cost'
currency_field='cost_currency_id'
help="This cost overrides the employee's default timesheet cost in employee's HR Settings"
readonly=False
store=True
cost_currency_id
Many2one → res.currency
readonly=True
related='employee_id.currency_id'
string='Cost Currency'
args: 'res.currency'
currency_id
Many2one → res.currency
compute='_compute_currency_id'
readonly=False
store=True
string='Currency'
args: 'res.currency'
employee_id
Many2one → hr.employee
required=True
args: 'hr.employee', 'Employee'
is_cost_changed
Boolean
compute='_compute_is_cost_changed'
store=True
args: 'Is Cost Manually Changed'
partner_id
Many2one
related='project_id.partner_id'
price_unit
Float
compute='_compute_price_unit'
readonly=True
store=True
args: 'Unit Price'
project_id
Many2one → project.project
required=True
args: 'project.project', 'Project'
sale_line_id
Many2one → sale.order.line
compute='_compute_sale_line_id'
domain="[\n ('is_service', '=', True),\n ('is_expense', '=', False),\n ('state', 'in', ['sale', 'done']),\n ('order_partner_id', '=?', partner_id),\n '|', ('company_id', '=', False), ('company_id', '=', company_id)]"
readonly=False
store=True
args: 'sale.order.line', 'Sale Order Item'
create(self, values)
write(self, values)
allow_billable
Boolean
related='project_id.allow_billable'
has_multi_sol
Boolean
compute='_compute_has_multi_sol'
compute_sudo=True
is_project_map_empty
Boolean
compute='_compute_is_project_map_empty'
args: 'Is Project map empty'
pricing_type
Selection
related='project_id.pricing_type'
remaining_hours_available
Boolean
related='sale_line_id.remaining_hours_available'
remaining_hours_so
Float
compute='_compute_remaining_hours_so'
compute_sudo=True
args: 'Remaining Hours on SO'
sale_order_id
Many2one
domain="['|', '|', ('partner_id', '=', partner_id), ('partner_id', 'child_of', commercial_partner_id), ('partner_id', 'parent_of', partner_id)]"
so_analytic_account_id
Many2one
related='sale_order_id.analytic_account_id'
string='Sale Order Analytic Account'
timesheet_product_id
Many2one
related='project_id.timesheet_product_id'
SELF_READABLE_FIELDS(self)
No new fields.
Public methods (0)No public methods.
No new fields.
Public methods (0)No public methods.
invoice_policy
Boolean
help='Timesheets taken when invoicing time spent'
string='Invoice Policy'
No public methods.
date_end_invoice_timesheet
Date
help='Only timesheets not yet invoiced (and validated, if applicable) from this period will be invoiced. If the period is not indicated, all timesheets not yet invoiced (and validated, if applicable) will be invoiced without distinction.'
string='End Date'
date_start_invoice_timesheet
Date
help='Only timesheets not yet invoiced (and validated, if applicable) from this period will be invoiced. If the period is not indicated, all timesheets not yet invoiced (and validated, if applicable) will be invoiced without distinction.'
string='Start Date'
invoicing_timesheet_enabled
Boolean
default=_default_invoicing_timesheet_enabled
create_invoices(self)
project_id
Many2one
domain="[('pricing_type', '!=', 'employee_rate'), ('analytic_account_id', '!=', False), ('company_id', '=', company_id)]"
timesheet_count
Float
compute='_compute_timesheet_ids'
groups='hr_timesheet.group_hr_timesheet_user'
string='Timesheet activities'
timesheet_encode_uom_id
Many2one → uom.uom
related='company_id.timesheet_encode_uom_id'
args: 'uom.uom'
timesheet_ids
Many2many → account.analytic.line
compute='_compute_timesheet_ids'
string='Timesheet activities associated to this sale'
args: 'account.analytic.line'
timesheet_total_duration
Integer
compute='_compute_timesheet_total_duration'
help='Total recorded duration, expressed in the encoding UoM, and rounded to the unit'
args: 'Timesheet Total Duration'
action_view_timesheet(self)
analytic_line_ids
One2many
domain=[('project_id', '=', False)]
has_displayed_warning_upsell
Boolean
copy=False
args: 'Has Displayed Warning Upsell'
qty_delivered_method
Selection
selection_add=[('timesheet', 'Timesheets')]
remaining_hours
Float
compute='_compute_remaining_hours'
compute_sudo=True
store=True
args: 'Remaining Hours on SO'
remaining_hours_available
Boolean
compute='_compute_remaining_hours_available'
compute_sudo=True
name_get(self)
| REPOSITORY | |
|---|---|
| REPOSITORY | odoo/odoo |
| GIT | |
| GIT | https://github.com/odoo/odoo.git |
| GIT FOLDER | |
| GIT FOLDER | https://github.com/odoo/odoo/tree/14.0/sale_timesheet |
| VERSION | |
| VERSION | 0.1.0 |
| CATEGORY | |
| CATEGORY | Hidden |
| LICENSE | |
| LICENSE | LGPL-3 |
| APPLICATION | |
| APPLICATION | No |
| AUTO-INSTALLABLE | |
| AUTO-INSTALLABLE | Yes |
| AUTHORS | |
| AUTHORS | |
| MAINTAINERS | |
| MAINTAINERS | |
| COMMITTERS | |
| COMMITTERS | Raphael Collet, Odoo Translation Bot, Martin Trigaux, Olivier Dony, Thibault Delavallée, Christophe Simonis, Xavier Morel, Goffin Simon, Nicolas Martinelli, Thibault Francois, Jeremy Kersten, GitHub, Barad Mahendra, Yannick Tivisse, Laurent Smet, Christophe Monniez, Jorge Pinna Puissant, wan, Julien Castiaux, Rémi Rahir, Xavier-Do, Victor Feyens, Andrea Grazioso (agr-odoo), fw-bot, Anh Thao Pham (pta), Luis González, Alvaro Fuentes, Rémy Baranx (bar), Lucas Lefèvre, Ivan Yelizariev, Touati Djamel (otd), Prakash Prajapati, Kamesh Patel, Nathan Marotte (nama), Mathieu Duckerts-Antoine, Djamel (otd), Hiral Bhavsar, Benjamin Frantzen (bfr), jbm-odoo, Arnaud Joset, Yann Papouin, Kevin Baptiste, Pierre Verkest, Xavier BOL (xbo), roen-odoo, Hubert Van de Walle (huvw), jdoutreloux, prro-odoo, Jigar Vaghela, MerlinGuillaume, Audric Onockx (auon), william, Pouya Malekinejad, Antoine Vandevenne (anv), Thibault Libioulle, Laurent Stukkens (LTU), Pierrot (prro), Thomas Lefebvre (thle), Victor Piryns (pivi), Krina Oza, ntlquynh2209, sang250399 |
| WEBSITE | |
| WEBSITE | |
| LAST TRACKING UPDATE | |
| LAST TRACKING UPDATE | 2026-07-06 00:14:28 |
| ODOO DEPENDENCIES | |
| ODOO DEPENDENCIES |
odoo/odoo: - sale_project - sale_management - sale - sales_team - base - base_setup - web - bus - web_tour - payment - account - product - uom - analytic - portal - web_editor - http_routing - auth_signup - digest - resource - utm - project - rating - hr_timesheet - hr |
| PYTHON DEPENDENCIES | |
| PYTHON DEPENDENCIES | Not have |
| SYSTEM DEPENDENCIES | |
| SYSTEM DEPENDENCIES | Not have |
| DESCRIPTION | |
| DESCRIPTION | Allows to sell timesheets in your sales order ============================================= This module set the right product on all timesheet lines according to the order/contract you work on. This allows to have real delivered quantities in sales orders. |
| XML ID | Name | Model | Type | Status |
|---|---|---|---|---|
account_invoice_view_form_inherit_sale_timesheet |
account.invoice.form.inherit.timesheet | account.move | xpath | Inherits account.view_move_form |
assets_backend |
sale timesheet assets | ir.ui.view | qweb | Inherits web.assets_backend |
assets_frontend |
report timesheet assets | ir.ui.view | qweb | Inherits web.assets_frontend |
portal_invoice_page_inherit_timesheet |
portal_invoice_page_inherit_timesheet | ir.ui.view | qweb | Inherits account.portal_invoice_page |
portal_my_timesheets_inherit |
portal_my_timesheets_inherit | ir.ui.view | qweb | Inherits hr_timesheet.portal_my_timesheets |
product_template_view_search_sale_timesheet |
product.template.search.timesheet | product.template | xpath | Inherits product.product_template_search_view |
progressbar |
project overview progressbar segments | ir.ui.view | qweb | New |
project_create_invoice_view_form |
project.create.invoice.view.form | project.create.invoice | form | New |
project_create_sale_order_view_form |
project.create.sale.order.wizard.form | project.create.sale.order | form | New |
project_profitability_report_view_graph |
project.profitability.report.graph | project.profitability.report | graph | New |
project_profitability_report_view_pivot |
project.profitability.report.pivot | project.profitability.report | pivot | New |
project_profitability_report_view_search |
project.profitability.report.search | project.profitability.report | search | New |
project_project_view_form |
project.project.form.inherit | project.project | div | Inherits hr_timesheet.project_invoice_form |
project_project_view_form_salesman |
project.project.form.inherit.salesman | project.project | field | Inherits sale_timesheet.project_project_view_form |
project_project_view_form_simplified_inherit |
project.project.view.form.simplified.inherit | project.project | field | Inherits hr_timesheet.project_project_view_form_simplified_inherit_timesheet |
project_project_view_kanban_inherit_sale_timesheet |
project.project.kanban.inherit.sale.timesheet | project.project | xpath | Inherits hr_timesheet.view_project_kanban_inherited |
project_task_create_sale_order_view_form |
project.task.create.sale.order.wizard.form | project.task.create.sale.order | form | New |
project_task_view_form_inherit_sale_timesheet |
project.task.form.inherit.timesheet | project.task | xpath | Inherits project.view_task_form2 |
quick_create_task_form_sale_timesheet |
project.task.form.inherit.timesheet | project.task | field | Inherits project.quick_create_task_form |
report_invoice_document |
report_invoice_document | ir.ui.view | qweb | Inherits account.report_invoice_document |
res_config_settings_view_form |
res.config.settings.view.form.inherit.sale.timesheet | res.config.settings | xpath | Inherits hr_timesheet.res_config_settings_view_form |
sale_advance_payment_inv_timesheet_view_form |
sale_timesheet.sale.advance.payment.inv.view.form | sale.advance.payment.inv | xpath | Inherits sale.view_sale_advance_payment_inv |
sale_order_portal_content_inherit |
sale_order_portal_content_inherit | ir.ui.view | qweb | Inherits sale.sale_order_portal_content |
sale_order_portal_template_inherit |
sale_order_portal_template_inherit | ir.ui.view | qweb | Inherits sale.sale_order_portal_template |
timesheet_plan |
Timesheet Plan | project.project | qweb | New |
timesheet_view_pivot_revenue |
account.analytic.line.pivot.revenue | account.analytic.line | pivot | New |
timesheet_view_search |
account.analytic.line.search | account.analytic.line | xpath | Inherits hr_timesheet.hr_timesheet_line_search |
timesheet_view_tree_sale |
account.analytic.line.view.tree.with.allow.billable | account.analytic.line | xpath | Inherits hr_timesheet.timesheet_view_tree_user |
view_hr_timesheet_line_pivot_billing_rate |
account.analytic.line.pivot.billing.rate | account.analytic.line | pivot | New |
view_order_form_inherit_sale_timesheet |
sale.order.form.sale.timesheet | sale.order | data | Inherits sale_project.view_order_form_inherit_sale_project |
view_product_timesheet_form |
product.template.timesheet.form | product.template | xpath | Inherits sale.product_template_form_view_invoice_policy |
view_sale_service_inherit_form2 |
sale.service.form.view.inherit | project.task | xpath | Inherits project.view_task_form2 |
view_task_form2_inherit_sale_timesheet |
view.task.form2.inherit | project.task | xpath | Inherits project.view_task_form2 |
non_allow_billable
Boolean
help='Your timesheet will not be billed.'
args: 'Non-Billable'
so_line
Many2one
compute='_compute_so_line'
readonly=False
store=True
timesheet_invoice_id
Many2one → account.move
copy=False
help='Invoice created from the timesheet'
readonly=True
string='Invoice'
args: 'account.move'
timesheet_invoice_type
Selection
compute='_compute_timesheet_invoice_type'
compute_sudo=True
readonly=True
store=True
string='Billable Type'
args: [('billable_time', 'Billed on Timesheets'), ('billable_fixed', 'Billed at a Fixed price'), ('non_billable', 'Non Billable Tasks'), ('non_billable_timesheet', 'Non Billable Timesheet'), ('non_billable_project', 'No task found')]
unlink(self)
write(self, values)
timesheet_count
Integer
compute='_compute_timesheet_count'
args: 'Number of timesheets'
timesheet_ids
One2many → account.analytic.line
copy=False
readonly=True
string='Timesheets'
args: 'account.analytic.line', 'timesheet_invoice_id'
action_view_timesheet(self)
No new fields.
Public methods (1)unlink(self)
No new fields.
Public methods (2)unlink(self)
write(self, vals)
project_id
Many2one
domain="[('company_id', '=', current_company_id), ('allow_billable', '=', True), ('bill_type', '=', 'customer_task'), ('allow_timesheets', 'in', [service_policy == 'delivered_timesheet', True])]"
project_template_id
Many2one
domain="[('company_id', '=', current_company_id), ('allow_billable', '=', True), ('bill_type', '=', 'customer_project'), ('allow_timesheets', 'in', [service_policy == 'delivered_timesheet', True])]"
service_policy
Selection
compute='_compute_service_policy'
inverse='_inverse_service_policy'
string='Service Invoicing Policy'
args: [('ordered_timesheet', 'Prepaid'), ('delivered_timesheet', 'Timesheets on tasks'), ('delivered_manual', 'Milestones (manually set quantities on order)')]
service_type
Selection
ondelete={'timesheet': 'set default'}
selection_add=[('timesheet', 'Timesheets on project (one fare per SO/Project)')]
unlink(self)
write(self, vals)
_candidate_orders
Many2many → sale.order
compute='_compute_candidate_orders'
args: 'sale.order'
amount_to_invoice
Monetary
compute='_compute_amount_to_invoice'
currency_field='currency_id'
help='Total amount to invoice on the sales order, including all items (services, storables, expenses, ...)'
args: 'Amount to invoice'
currency_id
Many2one
readonly=True
related='sale_order_id.currency_id'
project_id
Many2one → project.project
help='Project to make billable'
required=True
args: 'project.project', 'Project'
sale_order_id
Many2one → sale.order
domain="[('id', 'in', _candidate_orders)]"
required=True
string='Choose the Sales Order to invoice'
args: 'sale.order'
action_create_invoice(self)
default_get(self, fields)
commercial_partner_id
Many2one
related='partner_id.commercial_partner_id'
company_id
Many2one
related='project_id.company_id'
info_invoice
Char
compute='_compute_info_invoice'
line_ids
One2many → project.create.sale.order.line
string='Lines'
args: 'project.create.sale.order.line', 'wizard_id'
link_selection
Selection
default='create'
required=True
args: [('create', 'Create a new sales order'), ('link', 'Link to an existing sales order')]
partner_id
Many2one → res.partner
help='Customer of the sales order'
required=True
string='Customer'
args: 'res.partner'
pricing_type
Selection
related='project_id.pricing_type'
project_id
Many2one → project.project
domain=[('sale_line_id', '=', False)]
help='Project for which we are creating a sales order'
required=True
args: 'project.project', 'Project'
sale_order_id
Many2one → sale.order
domain="['|', '|', ('partner_id', '=', partner_id), ('partner_id', 'child_of', commercial_partner_id), ('partner_id', 'parent_of', partner_id)]"
string='Sales Order'
args: 'sale.order'
action_create_sale_order(self)
action_link_sale_order(self)
default_get(self, fields)
currency_id
Many2one → res.currency
string='Currency'
args: 'res.currency'
employee_id
Many2one → hr.employee
help='Employee that has timesheets on the project.'
string='Employee'
args: 'hr.employee'
price_unit
Float
help='Unit price of the sales order item.'
args: 'Unit Price'
product_id
Many2one → product.product
domain=[('type', '=', 'service'), ('invoice_policy', '=', 'delivery'), ('service_type', '=', 'timesheet')]
help='Product of the sales order item. Must be a service invoiced based on timesheets on tasks.'
string='Service'
args: 'product.product'
sale_line_id
Many2one → sale.order.line
compute='_compute_sale_line_id'
readonly=False
store=True
args: 'sale.order.line', 'Sale Order Item'
wizard_id
Many2one → project.create.sale.order
required=True
args: 'project.create.sale.order'
No public methods.
amount_untaxed_invoiced
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Untaxed Amount Invoiced'
amount_untaxed_to_invoice
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Untaxed Amount to Invoice'
analytic_account_id
Many2one → account.analytic.account
readonly=True
string='Analytic Account'
args: 'account.analytic.account'
company_id
Many2one → res.company
readonly=True
string='Project Company'
args: 'res.company'
currency_id
Many2one → res.currency
readonly=True
string='Project Currency'
args: 'res.currency'
expense_amount_untaxed_invoiced
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Untaxed Amount Re-invoiced'
expense_amount_untaxed_to_invoice
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Untaxed Amount to Re-invoice'
expense_cost
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Other Costs'
line_date
Date
readonly=True
args: 'Date'
margin
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Margin'
order_confirmation_date
Datetime
readonly=True
args: 'Sales Order Confirmation Date'
other_revenues
Float
digits=(16, 2)
group_operator='sum'
help='All revenues that are not from timesheets and that are linked to the analytic account of the project.'
readonly=True
args: 'Other Revenues'
partner_id
Many2one → res.partner
readonly=True
string='Customer'
args: 'res.partner'
product_id
Many2one → product.product
readonly=True
string='Product'
args: 'product.product'
project_id
Many2one → project.project
readonly=True
string='Project'
args: 'project.project'
sale_line_id
Many2one → sale.order.line
readonly=True
string='Sale Order Line'
args: 'sale.order.line'
sale_order_id
Many2one → sale.order
readonly=True
string='Sale Order'
args: 'sale.order'
timesheet_cost
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Timesheet Cost'
timesheet_unit_amount
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Timesheet Duration'
user_id
Many2one → res.users
readonly=True
string='Project Manager'
args: 'res.users'
init(self)
No new fields.
Public methods (0)No public methods.
allow_billable
Boolean
help='Invoice your time and material from tasks.'
args: 'Billable'
bill_type
Selection
default='customer_task'
help='When billing tasks individually, a Sales Order will be created from each task. It is perfect if you would like to bill different services to different customers at different rates. \n When billing the whole project, a Sales Order will be created from the project instead. This option is better if you would like to bill all the tasks of a given project to a specific customer either at a fixed rate, or at an employee rate.'
string='Invoice Tasks to'
args: [('customer_task', 'Different customers'), ('customer_project', 'A unique customer')]
display_create_order
Boolean
compute='_compute_display_create_order'
pricing_type
Selection
default='fixed_rate'
help='The fixed rate is perfect if you bill a service at a fixed rate per hour or day worked regardless of the employee who performed it. The employee rate is preferable if your employees deliver the same service at a different rate. For instance, junior and senior consultants would deliver the same service (= consultancy), but at a different rate because of their level of seniority.'
string='Pricing'
args: [('fixed_rate', 'Project rate'), ('employee_rate', 'Employee rate')]
sale_line_employee_ids
One2many → project.sale.line.employee.map
copy=False
help="Employee/Sale Order Item Mapping:\n Defines to which sales order item an employee's timesheet entry will be linked.By extension, it defines the rate at which an employee's time on the project is billed."
args: 'project.sale.line.employee.map', 'project_id', 'Sale line/Employee map'
timesheet_product_id
Many2one → product.product
compute='_compute_timesheet_product_id'
default=_default_timesheet_product_id
domain="[\n ('type', '=', 'service'),\n ('invoice_policy', '=', 'delivery'),\n ('service_type', '=', 'timesheet'),\n '|', ('company_id', '=', False), ('company_id', '=', company_id)]"
help='Select a Service product with which you would like to bill your time spent on tasks.'
readonly=False
store=True
string='Timesheet Product'
args: 'product.product'
warning_employee_rate
Boolean
compute='_compute_warning_employee_rate'
action_make_billable(self)
action_view_timesheet(self)
action_view_timesheet_plan(self)
default_get(self, fields)
write(self, values)
company_id
Many2one → res.company
related='project_id.company_id'
string='Company'
args: 'res.company'
currency_id
Many2one → res.currency
compute='_compute_price_unit'
readonly=False
store=True
string='Currency'
args: 'res.currency'
employee_id
Many2one → hr.employee
required=True
args: 'hr.employee', 'Employee'
price_unit
Float
compute='_compute_price_unit'
readonly=True
store=True
args: 'Unit Price'
project_id
Many2one → project.project
required=True
args: 'project.project', 'Project'
sale_line_id
Many2one → sale.order.line
domain=[('is_service', '=', True)]
args: 'sale.order.line', 'Sale Order Item'
timesheet_product_id
Many2one → product.product
domain="[\n ('type', '=', 'service'),\n ('invoice_policy', '=', 'delivery'),\n ('service_type', '=', 'timesheet'),\n '|', ('company_id', '=', False), ('company_id', '=', company_id)]"
string='Service'
args: 'product.product'
create(self, values)
write(self, values)
allow_billable
Boolean
related='project_id.allow_billable'
analytic_account_id
Many2one → account.analytic.account
related='sale_order_id.analytic_account_id'
args: 'account.analytic.account'
bill_type
Selection
related='project_id.bill_type'
display_create_order
Boolean
compute='_compute_display_create_order'
has_multi_sol
Boolean
compute='_compute_has_multi_sol'
compute_sudo=True
is_project_map_empty
Boolean
compute='_compute_is_project_map_empty'
args: 'Is Project map empty'
non_allow_billable
Boolean
help='Your timesheets linked to this task will not be billed.'
args: 'Non-Billable'
pricing_type
Selection
related='project_id.pricing_type'
project_sale_order_id
Many2one
compute='_compute_project_sale_order_id'
related=None
search='_search_project_sale_order_id'
remaining_hours_available
Boolean
related='sale_line_id.remaining_hours_available'
remaining_hours_so
Float
compute='_compute_remaining_hours_so'
compute_sudo=True
args: 'Remaining Hours on SO'
sale_order_id
Many2one
compute='_compute_sale_order_id'
domain="['|', '|', ('partner_id', '=', partner_id), ('partner_id', 'child_of', commercial_partner_id), ('partner_id', 'parent_of', partner_id)]"
readonly=False
store=True
timesheet_product_id
Many2one → product.product
domain="[\n ('type', '=', 'service'),\n ('invoice_policy', '=', 'delivery'),\n ('service_type', '=', 'timesheet'),\n '|', ('company_id', '=', False), ('company_id', '=', company_id)]"
help='Select a Service product with which you would like to bill your time spent on this task.'
string='Service'
args: 'product.product'
action_make_billable(self)
default_get(self, fields)
write(self, values)
commercial_partner_id
Many2one
related='partner_id.commercial_partner_id'
currency_id
Many2one → res.currency
readonly=False
related='product_id.currency_id'
string='Currency'
args: 'res.currency'
info_invoice
Char
compute='_compute_info_invoice'
link_selection
Selection
default='create'
required=True
args: [('create', 'Create a new sales order'), ('link', 'Link to an existing sales order')]
partner_id
Many2one → res.partner
help='Customer of the sales order'
required=True
string='Customer'
args: 'res.partner'
price_unit
Float
help='Unit price of the sales order item.'
args: 'Unit Price'
product_id
Many2one → product.product
domain=[('type', '=', 'service'), ('invoice_policy', '=', 'delivery'), ('service_type', '=', 'timesheet')]
help='Product of the sales order item. Must be a service invoiced based on timesheets on tasks. The existing timesheet will be linked to this product.'
required=True
string='Service'
args: 'product.product'
sale_line_id
Many2one → sale.order.line
domain="[('is_service', '=', True), ('order_partner_id', 'child_of', commercial_partner_id), ('is_expense', '=', False), ('state', 'in', ['sale', 'done']), ('order_id', '=?', sale_order_id)]"
args: 'sale.order.line', 'Sales Order Item'
sale_order_id
Many2one → sale.order
domain="['|', '|', ('partner_id', '=', partner_id), ('partner_id', 'child_of', commercial_partner_id), ('partner_id', 'parent_of', partner_id)]"
string='Sales Order'
args: 'sale.order'
task_id
Many2one → project.task
domain=[('sale_line_id', '=', False)]
help='Task for which we are creating a sales order'
required=True
args: 'project.task', 'Task'
action_create_sale_order(self)
action_link_sale_order(self)
default_get(self, fields)
No new fields.
Public methods (0)No public methods.
date_end_invoice_timesheet
Date
help='Only timesheets not yet invoiced (and validated, if applicable) from this period will be invoiced. If the period is not indicated, all timesheets not yet invoiced (and validated, if applicable) will be invoiced without distinction.'
string='End Date'
date_start_invoice_timesheet
Date
help='Only timesheets not yet invoiced (and validated, if applicable) from this period will be invoiced. If the period is not indicated, all timesheets not yet invoiced (and validated, if applicable) will be invoiced without distinction.'
string='Start Date'
invoicing_timesheet_enabled
Boolean
default=_default_invoicing_timesheet_enabled
create_invoices(self)
project_id
Many2one
domain="['|', ('bill_type', '=', 'customer_task'), ('pricing_type', '=', 'fixed_rate'), ('analytic_account_id', '!=', False), ('company_id', '=', company_id)]"
timesheet_count
Float
compute='_compute_timesheet_ids'
groups='hr_timesheet.group_hr_timesheet_user'
string='Timesheet activities'
timesheet_encode_uom_id
Many2one → uom.uom
related='company_id.timesheet_encode_uom_id'
args: 'uom.uom'
timesheet_ids
Many2many → account.analytic.line
compute='_compute_timesheet_ids'
string='Timesheet activities associated to this sale'
args: 'account.analytic.line'
timesheet_total_duration
Integer
compute='_compute_timesheet_total_duration'
help='Total recorded duration, expressed in the encoding UoM, and rounded to the unit'
args: 'Timesheet Total Duration'
action_view_project_ids(self)
action_view_timesheet(self)
analytic_line_ids
One2many
domain=[('project_id', '=', False)]
qty_delivered_method
Selection
selection_add=[('timesheet', 'Timesheets')]
remaining_hours
Float
compute='_compute_remaining_hours'
args: 'Remaining Hours on SO'
remaining_hours_available
Boolean
compute='_compute_remaining_hours_available'
name_get(self)
| REPOSITORY | |
|---|---|
| REPOSITORY | odoo/odoo |
| GIT | |
| GIT | https://github.com/odoo/odoo.git |
| GIT FOLDER | |
| GIT FOLDER | https://github.com/odoo/odoo/tree/13.0/sale_timesheet |
| VERSION | |
| VERSION | 0.1.0 |
| CATEGORY | |
| CATEGORY | Hidden |
| LICENSE | |
| LICENSE | LGPL-3 |
| APPLICATION | |
| APPLICATION | No |
| AUTO-INSTALLABLE | |
| AUTO-INSTALLABLE | Yes |
| AUTHORS | |
| AUTHORS | |
| MAINTAINERS | |
| MAINTAINERS | |
| COMMITTERS | |
| COMMITTERS | Raphael Collet, Odoo Translation Bot, Christophe Matthieu, Martin Trigaux, Denis Ledoux, Christophe Simonis, Xavier Morel, Goffin Simon, Nicolas Martinelli, qdp-odoo, Géry Debongnie, Aaron Bohy, GitHub, Damien Bouvy, Yannick Tivisse, Odoo Online, jem-odoo, Christophe Monniez, Jorge Pinna Puissant, Toufik Ben Jaa, Adrian Torres, Aurélien Warnon, Priyanka Kakadiya, Xavier-Do, Victor Feyens, Andrea Grazioso (agr-odoo), Shreya Modi, fw-bot, Anh Thao Pham (pta), svs-odoo, Ivan Yelizariev, Prakash Prajapati, Djamel (otd), qho, Romain Estievenart, Kevin Baptiste, Xavier BOL (xbo), Geoffroy Larue, Audric Onockx (auon), Antoine Vandevenne (anv), Thibault Libioulle, MaxLarue |
| WEBSITE | |
| WEBSITE | |
| LAST TRACKING UPDATE | |
| LAST TRACKING UPDATE | 2026-07-06 00:06:42 |
| ODOO DEPENDENCIES | |
| ODOO DEPENDENCIES |
odoo/odoo: - sale_management - sale - sales_team - base - base_setup - web - bus - web_tour - payment - account - product - uom - analytic - portal - web_editor - http_routing - auth_signup - digest - resource - utm - hr_timesheet - hr - mail_bot - project - rating |
| PYTHON DEPENDENCIES | |
| PYTHON DEPENDENCIES | Not have |
| SYSTEM DEPENDENCIES | |
| SYSTEM DEPENDENCIES | Not have |
| DESCRIPTION | |
| DESCRIPTION | Allows to sell timesheets in your sales order ============================================= This module set the right product on all timesheet lines according to the order/contract you work on. This allows to have real delivered quantities in sales orders. |
| XML ID | Name | Model | Type | Status |
|---|---|---|---|---|
account_invoice_view_form_inherit_sale_timesheet |
account.invoice.form.inherit.timesheet | account.move | xpath | Inherits account.view_move_form |
assets_backend |
sale timesheet assets | ir.ui.view | qweb | Inherits web.assets_backend |
assets_frontend |
report timesheet assets | ir.ui.view | qweb | Inherits web.assets_frontend |
portal_invoice_page_inherit_timesheet |
portal_invoice_page_inherit_timesheet | ir.ui.view | qweb | Inherits account.portal_invoice_page |
product_template_view_search_sale_timesheet |
product.template.search.timesheet | product.template | xpath | Inherits product.product_template_search_view |
progressbar |
project overview progressbar segments | ir.ui.view | qweb | New |
project_create_invoice_view_form |
project.create.invoice.view.form | project.create.invoice | form | New |
project_create_sale_order_view_form |
project.create.sale.order.wizard.form | project.create.sale.order | form | New |
project_profitability_report_view_graph |
project.profitability.report.graph | project.profitability.report | graph | New |
project_profitability_report_view_pivot |
project.profitability.report.pivot | project.profitability.report | pivot | New |
project_profitability_report_view_search |
project.profitability.report.search | project.profitability.report | search | New |
project_project_view_form |
project.project.form.inherit | project.project | xpath | Inherits project.edit_project |
project_project_view_kanban_inherit_sale_timesheet |
project.project.kanban.inherit.sale.timesheet | project.project | xpath | Inherits hr_timesheet.view_project_kanban_inherited |
project_task_view_form_inherit_sale_line_editable |
project.task.form.inherit.sale.line.editable.salesman | project.task | xpath | Inherits view_sale_service_inherit_form2 |
project_task_view_form_inherit_sale_timesheet |
project.task.form.inherit.timesheet | project.task | xpath | Inherits hr_timesheet.view_task_form2_inherited |
project_task_view_form_sale_order |
project.task.form.inherit.sale.order | project.task | div | Inherits project.view_task_form2 |
project_task_view_search |
project.task.search.inherit | project.task | xpath | Inherits project.view_task_search_form |
res_config_settings_view_form |
res.config.settings.view.form.inherit.sale.timesheet | res.config.settings | xpath | Inherits hr_timesheet.res_config_settings_view_form |
timesheet_plan |
Timesheet Plan | project.project | nav | New |
timesheet_view_pivot_revenue |
account.analytic.line.pivot.revenue | account.analytic.line | pivot | New |
timesheet_view_search |
account.analytic.line.search | account.analytic.line | xpath | Inherits hr_timesheet.hr_timesheet_line_search |
view_order_form_inherit_sale_timesheet |
sale.order.form.sale.timesheet | sale.order | data | Inherits sale.view_order_form |
view_product_timesheet_form |
product.template.timesheet.form | product.template | xpath | Inherits sale.product_template_form_view_invoice_policy |
view_sale_service_inherit_form2 |
sale.service.form.view.inherit | project.task | field | Inherits project.view_task_form2 |
timesheet_invoice_id
Many2one → account.move
copy=False
help='Invoice created from the timesheet'
readonly=True
string='Invoice'
args: 'account.move'
timesheet_invoice_type
Selection
compute='_compute_timesheet_invoice_type'
compute_sudo=True
readonly=True
store=True
string='Billable Type'
args: [('billable_time', 'Billed on Timesheets'), ('billable_fixed', 'Billed at a Fixed price'), ('non_billable', 'Non Billable Tasks'), ('non_billable_project', 'No task found')]
write(self, values)
timesheet_count
Integer
compute='_compute_timesheet_count'
args: 'Number of timesheets'
timesheet_ids
One2many → account.analytic.line
copy=False
readonly=True
string='Timesheets'
args: 'account.analytic.line', 'timesheet_invoice_id'
action_view_timesheet(self)
No new fields.
Public methods (1)create(self, vals_list)
No new fields.
Public methods (1)write(self, values)
project_id
Many2one → project.project
company_dependent=True
domain=[('billable_type', '=', 'no')]
help='Select a non billable project on which tasks can be created. This setting must be set for each company.'
args: 'project.project', 'Project'
project_template_id
Many2one → project.project
company_dependent=True
copy=True
domain=[('billable_type', '=', 'no')]
help='Select a non billable project to be the skeleton of the new created project when selling the current product. Its stages and tasks will be duplicated.'
args: 'project.project', 'Project Template'
service_policy
Selection
compute='_compute_service_policy'
inverse='_inverse_service_policy'
string='Service Invoicing Policy'
args: [('ordered_timesheet', 'Ordered quantities'), ('delivered_timesheet', 'Timesheets on tasks'), ('delivered_manual', 'Milestones (manually set quantities on order)')]
service_tracking
Selection
default='no'
help="On Sales order confirmation, this product can generate a project and/or task. From those, you can track the service you are selling.\n 'In sale order's project': Will use the sale order's configured project if defined or fallback to creating a new project based on the selected template."
string='Service Tracking'
args: [('no', "Don't create task"), ('task_global_project', 'Create a task in an existing project'), ('task_in_project', "Create a task in sales order's project"), ('project_only', 'Create a new project but no task')]
service_type
Selection
selection_add=[('timesheet', 'Timesheets on project (one fare per SO/Project)')]
write(self, values)
amount_to_invoice
Monetary
compute='_compute_amount_to_invoice'
currency_field='currency_id'
help='Total amount to invoice on the sales order, including all items (services, storables, expenses, ...)'
args: 'Amount to invoice'
currency_id
Many2one
readonly=True
related='sale_order_id.currency_id'
project_id
Many2one → project.project
help='Project to make billable'
required=True
args: 'project.project', 'Project'
sale_order_id
Many2one → sale.order
required=True
string='Choose the Sales Order to invoice'
args: 'sale.order'
action_create_invoice(self)
default_get(self, fields)
billable_type
Selection
default='project_rate'
help='* At Project Rate: All timesheets on the project will be billed at the same rate\n* At Employee Rate: Timesheets will be billed at a rate defined at employee level'
required=True
string='Billing Type'
args: [('project_rate', 'At Project Rate'), ('employee_rate', 'At Employee Rate')]
company_id
Many2one
related='project_id.company_id'
currency_id
Many2one → res.currency
readonly=False
related='product_id.currency_id'
string='Currency'
args: 'res.currency'
line_ids
One2many → project.create.sale.order.line
string='Lines'
args: 'project.create.sale.order.line', 'wizard_id'
partner_id
Many2one → res.partner
help='Customer of the sales order'
required=True
string='Customer'
args: 'res.partner'
price_unit
Float
help='Unit price of the sales order item.'
args: 'Unit Price'
product_id
Many2one → product.product
domain=[('type', '=', 'service'), ('invoice_policy', '=', 'delivery'), ('service_type', '=', 'timesheet')]
help='Product of the sales order item. Must be a service invoiced based on timesheets on tasks.'
string='Service'
args: 'product.product'
project_id
Many2one → project.project
domain=[('sale_line_id', '=', False)]
help='Project for which we are creating a sales order'
required=True
args: 'project.project', 'Project'
action_create_sale_order(self)
default_get(self, fields)
currency_id
Many2one → res.currency
readonly=False
related='product_id.currency_id'
string='Currency'
args: 'res.currency'
employee_id
Many2one → hr.employee
help='Employee that has timesheets on the project.'
required=True
string='Employee'
args: 'hr.employee'
price_unit
Float
default=1.0
help='Unit price of the sales order item.'
args: 'Unit Price'
product_id
Many2one → product.product
domain=[('type', '=', 'service'), ('invoice_policy', '=', 'delivery'), ('service_type', '=', 'timesheet')]
help='Product of the sales order item. Must be a service invoiced based on timesheets on tasks.'
required=True
string='Service'
args: 'product.product'
wizard_id
Many2one → project.create.sale.order
required=True
args: 'project.create.sale.order'
No public methods.
amount_untaxed_invoiced
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Untaxed Amount Invoiced'
amount_untaxed_to_invoice
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Untaxed Amount To Invoice'
analytic_account_id
Many2one → account.analytic.account
readonly=True
string='Analytic Account'
args: 'account.analytic.account'
company_id
Many2one → res.company
readonly=True
string='Project Company'
args: 'res.company'
currency_id
Many2one → res.currency
readonly=True
string='Project Currency'
args: 'res.currency'
expense_amount_untaxed_invoiced
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Untaxed Re-invoiced Amount'
expense_amount_untaxed_to_invoice
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Untaxed Amount to Re-invoice'
expense_cost
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Other Cost'
order_confirmation_date
Datetime
readonly=True
args: 'Sales Order Confirmation Date'
partner_id
Many2one → res.partner
readonly=True
string='Customer'
args: 'res.partner'
product_id
Many2one → product.product
readonly=True
string='Product'
args: 'product.product'
project_id
Many2one → project.project
readonly=True
string='Project'
args: 'project.project'
sale_line_id
Many2one → sale.order.line
readonly=True
string='Sale Order Line'
args: 'sale.order.line'
sale_order_id
Many2one → sale.order
readonly=True
string='Sale Order'
args: 'sale.order'
timesheet_cost
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Timesheet Cost'
timesheet_unit_amount
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Timesheet Unit Amount'
user_id
Many2one → res.users
readonly=True
string='Project Manager'
args: 'res.users'
init(self)
No new fields.
Public methods (0)No public methods.
billable_type
Selection
compute='_compute_billable_type'
compute_sudo=True
help='At which rate timesheets will be billed:\n - At task rate: each time spend on a task is billed at task rate.\n - At employee rate: each employee log time billed at his rate.\n - No Billable: track time without invoicing it'
store=True
string='Billable Type'
args: [('task_rate', 'At Task Rate'), ('employee_rate', 'At Employee Rate'), ('no', 'No Billable')]
sale_line_employee_ids
One2many → project.sale.line.employee.map
copy=False
help="Employee/Sale Order Item Mapping:\n Defines to which sales order item an employee's timesheet entry will be linked.By extension, it defines the rate at which an employee's time on the project is billed."
args: 'project.sale.line.employee.map', 'project_id', 'Sale line/Employee map'
sale_line_id
Many2one → sale.order.line
copy=False
domain="[('is_expense', '=', False), ('order_id', '=', sale_order_id), ('state', 'in', ['sale', 'done']), '|', ('company_id', '=', False), ('company_id', '=', company_id)]"
help="Sales order item to which the project is linked. If an employee timesheets on a task that does not have a sale order item defines, and if this employee is not in the 'Employee/Sales Order Item Mapping' of the project, the timesheet entry will be linked to the sales order item defined on the project."
args: 'sale.order.line', 'Sales Order Item'
sale_order_id
Many2one → sale.order
copy=False
domain="[('partner_id', '=', partner_id)]"
help='Sales order to which the project is linked.'
readonly=True
args: 'sale.order', 'Sales Order'
action_make_billable(self)
action_view_timesheet(self)
action_view_timesheet_plan(self)
employee_id
Many2one → hr.employee
required=True
args: 'hr.employee', 'Employee'
price_unit
Float
readonly=True
related='sale_line_id.price_unit'
project_id
Many2one → project.project
default=_default_project_id
domain=[('billable_type', '!=', 'no')]
required=True
args: 'project.project', 'Project'
sale_line_id
Many2one → sale.order.line
domain=[('is_service', '=', True)]
required=True
args: 'sale.order.line', 'Sale Order Item'
No public methods.
billable_type
Selection
compute='_compute_billable_type'
compute_sudo=True
store=True
string='Billable Type'
args: [('task_rate', 'At Task Rate'), ('employee_rate', 'At Employee Rate'), ('no', 'No Billable')]
is_project_map_empty
Boolean
compute='_compute_is_project_map_empty'
args: 'Is Project map empty'
sale_line_id
Many2one → sale.order.line
copy=False
default=_default_sale_line_id
domain="[('is_service', '=', True), ('order_partner_id', '=', partner_id), ('is_expense', '=', False), ('state', 'in', ['sale', 'done'])]"
help="Sales order item to which the task is linked. If an employee timesheets on a this task, and if this employee is not in the 'Employee/Sales Order Item Mapping' of the project, the timesheet entry will be linked to this sales order item."
args: 'sale.order.line', 'Sales Order Item'
sale_order_id
Many2one → sale.order
compute='_compute_sale_order_id'
help='Sales order to which the task is linked.'
readonly=False
store=True
args: 'sale.order', 'Sales Order'
action_view_so(self)
rating_get_partner_id(self)
unlink(self)
write(self, values)
project_id
Many2one → project.project
domain="[('billable_type', 'in', ('no', 'task_rate')), ('analytic_account_id', '!=', False), ('company_id', '=', company_id)]"
help='Select a non billable project on which tasks can be created.'
readonly=True
states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}
args: 'project.project', 'Project'
project_ids
Many2many → project.project
compute='_compute_project_ids'
copy=False
groups='project.group_project_user'
help='Projects used in this sales order.'
string='Projects'
args: 'project.project'
tasks_count
Integer
compute='_compute_tasks_ids'
groups='project.group_project_user'
string='Tasks'
tasks_ids
Many2many → project.task
compute='_compute_tasks_ids'
string='Tasks associated to this sale'
args: 'project.task'
timesheet_count
Float
compute='_compute_timesheet_ids'
groups='hr_timesheet.group_hr_timesheet_user'
string='Timesheet activities'
timesheet_encode_uom_id
Many2one → uom.uom
related='company_id.timesheet_encode_uom_id'
args: 'uom.uom'
timesheet_ids
Many2many → account.analytic.line
compute='_compute_timesheet_ids'
string='Timesheet activities associated to this sale'
args: 'account.analytic.line'
timesheet_total_duration
Float
compute='_compute_timesheet_total_duration'
help='Total recorded duration, expressed in the encoding UoM'
args: 'Timesheet Total Duration'
visible_project
Boolean
compute='_compute_visible_project'
readonly=True
args: 'Display project'
action_view_project_ids(self)
action_view_task(self)
action_view_timesheet(self)
analytic_line_ids
One2many
domain=[('project_id', '=', False)]
is_service
Boolean
compute='_compute_is_service'
compute_sudo=True
help='Sales Order item should generate a task and/or a project, depending on the product settings.'
store=True
args: 'Is a Service'
project_id
Many2one → project.project
copy=False
help='Project generated by the sales order item'
index=True
args: 'project.project', 'Generated Project'
qty_delivered_method
Selection
selection_add=[('timesheet', 'Timesheets')]
task_id
Many2one → project.task
copy=False
help='Task generated by the sales order item'
index=True
args: 'project.task', 'Generated Task'
create(self, vals_list)
write(self, values)
| REPOSITORY | |
|---|---|
| REPOSITORY | odoo/odoo |
| GIT | |
| GIT | https://github.com/odoo/odoo.git |
| GIT FOLDER | |
| GIT FOLDER | https://github.com/odoo/odoo/tree/12.0/sale_timesheet |
| VERSION | |
| VERSION | 0.1.0 |
| CATEGORY | |
| CATEGORY | Hidden |
| LICENSE | |
| LICENSE | LGPL-3 |
| APPLICATION | |
| APPLICATION | No |
| AUTO-INSTALLABLE | |
| AUTO-INSTALLABLE | Yes |
| AUTHORS | |
| AUTHORS | |
| MAINTAINERS | |
| MAINTAINERS | |
| COMMITTERS | |
| COMMITTERS | Raphael Collet, Odoo Translation Bot, Martin Trigaux, Fabien Pinckaers, Thibault Delavallée, Christophe Simonis, Xavier Morel, Goffin Simon, Mohammed Shekha, Simon Lejeune, Nicolas Martinelli, qdp-odoo, Géry Debongnie, Aaron Bohy, GitHub, Yannick Tivisse, Alexandre Kühn, qsm-odoo, Toufik Benjaa, jem-odoo, Adrien Dieudonne, RomainLibert, Christophe Monniez, len-odoo, Jorge Pinna Puissant, Nans Lefebvre, Adrian Torres, XavierDo, Julien Castiaux, Xavier-Do, Andrea Grazioso (agr-odoo), Fanny He, Sébastien Theys, Anh Thao Pham (pta), Ivan Yelizariev, LofbergValentin, qho, tafaRU |
| WEBSITE | |
| WEBSITE | |
| LAST TRACKING UPDATE | |
| LAST TRACKING UPDATE | 2026-07-05 23:57:01 |
| ODOO DEPENDENCIES | |
| ODOO DEPENDENCIES |
odoo/odoo: - sale_management - sale - sales_team - base - base_setup - web - bus - web_tour - payment - account - product - decimal_precision - uom - analytic - portal - http_routing - digest - hr_timesheet - hr - resource - project - rating |
| PYTHON DEPENDENCIES | |
| PYTHON DEPENDENCIES | Not have |
| SYSTEM DEPENDENCIES | |
| SYSTEM DEPENDENCIES | Not have |
| DESCRIPTION | |
| DESCRIPTION | Allows to sell timesheets in your sales order ============================================= This module set the right product on all timesheet lines according to the order/contract you work on. This allows to have real delivered quantities in sales orders. |
| XML ID | Name | Model | Type | Status |
|---|---|---|---|---|
account_invoice_view_form_inherit_sale_timesheet |
account.invoice.form.inherit.timesheet | account.invoice | xpath | Inherits account.invoice_form |
assets_backend |
sale timesheet assets | ir.ui.view | qweb | Inherits web.assets_backend |
product_template_view_search_sale_timesheet |
product.template.search.timesheet | product.template | xpath | Inherits product.product_template_search_view |
project_create_invoice_view_form |
project.create.invoice.view.form | project.create.invoice | form | New |
project_create_sale_order_view_form |
project.create.sale.order.wizard.form | project.create.sale.order | form | New |
project_profitability_report_view_graph |
project.profitability.report.graph | project.profitability.report | graph | New |
project_profitability_report_view_pivot |
project.profitability.report.pivot | project.profitability.report | pivot | New |
project_profitability_report_view_search |
project.profitability.report.search | project.profitability.report | search | New |
project_project_view_form |
project.project.form.inherit | project.project | xpath | Inherits project.edit_project |
project_project_view_kanban_inherit_sale_timesheet |
project.project.kanban.inherit.sale.timesheet | project.project | xpath | Inherits hr_timesheet.view_project_kanban_inherited |
project_project_view_search |
project.project.search.inherit | project.project | xpath | Inherits project.view_project_project_filter |
project_task_assign_so_line_view_form |
project.task.assign.sale.wizard.form | project.task.assign.sale | form | New |
project_task_view_form_inherit_sale_line_editable |
project.task.form.inherit.sale.line.editable.salesman | project.task | xpath | Inherits view_sale_service_inherit_form2 |
project_task_view_form_inherit_sale_timesheet |
project.task.form.inherit.timesheet | project.task | xpath | Inherits hr_timesheet.view_task_form2_inherited |
project_task_view_form_sale_order |
project.task.form.inherit.sale.order | project.task | xpath | Inherits project.view_task_form2 |
project_task_view_search |
project.task.search.inherit | project.task | xpath | Inherits project.view_task_search_form |
qunit_suite |
timesheet plan tests | ir.ui.view | qweb | Inherits web.qunit_suite |
res_config_settings_view_form |
res.config.settings.view.form.inherit.sale.timesheet | res.config.settings | xpath | Inherits hr_timesheet.res_config_settings_view_form |
timesheet_plan |
Timesheet Plan | ir.ui.view | qweb | New |
timesheet_view_pivot_revenue |
account.analytic.line.pivot.revenue | account.analytic.line | pivot | New |
timesheet_view_search |
account.analytic.line.search | account.analytic.line | xpath | Inherits hr_timesheet.hr_timesheet_line_search |
view_order_form_inherit_sale_timesheet |
sale.order.form.sale.timesheet | sale.order | data | Inherits sale.view_order_form |
view_product_timesheet_form |
product.template.timesheet.form | product.template | xpath | Inherits sale.product_template_form_view_invoice_policy |
view_sale_service_inherit_form2 |
sale.service.form.view.inherit | project.task | field | Inherits project.view_task_form2 |
timesheet_invoice_id
Many2one → account.invoice
copy=False
help='Invoice created from the timesheet'
readonly=True
string='Invoice'
args: 'account.invoice'
timesheet_invoice_type
Selection
compute='_compute_timesheet_invoice_type'
compute_sudo=True
readonly=True
store=True
string='Billable Type'
args: [('billable_time', 'Billable Time'), ('billable_fixed', 'Billable Fixed'), ('non_billable', 'Non Billable'), ('non_billable_project', 'No task found')]
write(self, values)
timesheet_count
Integer
compute='_compute_timesheet_count'
args: 'Number of timesheets'
timesheet_ids
One2many → account.analytic.line
copy=False
readonly=True
string='Timesheets'
args: 'account.analytic.line', 'timesheet_invoice_id'
action_view_timesheet(self)
No new fields.
Public methods (1)create(self, values)
No new fields.
Public methods (0)No public methods.
project_id
Many2one → project.project
company_dependent=True
domain=[('billable_type', '=', 'no')]
help='Select a non billable project on which tasks can be created. This setting must be set for each company.'
args: 'project.project', 'Project'
project_template_id
Many2one → project.project
company_dependent=True
copy=True
domain=[('billable_type', '=', 'no')]
help='Select a non billable project to be the skeleton of the new created project when selling the current product. Its stages and tasks will be duplicated.'
args: 'project.project', 'Project Template'
service_policy
Selection
compute='_compute_service_policy'
inverse='_inverse_service_policy'
string='Service Invoicing Policy'
args: [('ordered_timesheet', 'Ordered quantities'), ('delivered_timesheet', 'Timesheets on tasks'), ('delivered_manual', 'Milestones (manually set quantities on order)')]
service_tracking
Selection
default='no'
help='On Sales order confirmation, this product can generate a project and/or task. From those, you can track the service you are selling.'
string='Service Tracking'
args: [('no', "Don't create task"), ('task_global_project', 'Create a task in an existing project'), ('task_new_project', 'Create a task in a new project'), ('project_only', 'Create a new project but no task')]
service_type
Selection
selection_add=[('timesheet', 'Timesheets on project (one fare per SO/Project)')]
No public methods.
amount_to_invoice
Monetary
compute='_compute_amount_to_invoice'
currency_field='currency_id'
help='Total amount to invoice on the sales order, including all items (services, storables, expenses, ...)'
args: 'Amount to invoice'
currency_id
Many2one
readonly=True
related='sale_order_id.currency_id'
project_id
Many2one → project.project
help='Project to make billable'
required=True
args: 'project.project', 'Project'
sale_order_id
Many2one → sale.order
required=True
string='Choose the Sales Order to invoice'
args: 'sale.order'
action_create_invoice(self)
default_get(self, fields)
billable_type
Selection
default='project_rate'
help='* At Project Rate: All timesheets on the project will be billed at the same rate\n* At Employee Rate: Timesheets will be billed at a rate defined at employee level'
required=True
string='Billing Type'
args: [('project_rate', 'At Project Rate'), ('employee_rate', 'At Employee Rate')]
currency_id
Many2one → res.currency
readonly=False
related='product_id.currency_id'
string='Currency'
args: 'res.currency'
line_ids
One2many → project.create.sale.order.line
string='Lines'
args: 'project.create.sale.order.line', 'wizard_id'
partner_id
Many2one → res.partner
domain=[('customer', '=', True)]
help='Customer of the sales order'
required=True
string='Customer'
args: 'res.partner'
price_unit
Float
help='Unit price of the sales order item.'
args: 'Unit Price'
product_id
Many2one → product.product
domain=[('type', '=', 'service'), ('invoice_policy', '=', 'delivery'), ('service_type', '=', 'timesheet')]
help='Product of the sales order item. Must be a service invoiced based on timesheets on tasks.'
string='Service'
args: 'product.product'
project_id
Many2one → project.project
domain=[('sale_line_id', '=', False)]
help='Project for which we are creating a sales order'
required=True
args: 'project.project', 'Project'
action_create_sale_order(self)
default_get(self, fields)
currency_id
Many2one → res.currency
readonly=False
related='product_id.currency_id'
string='Currency'
args: 'res.currency'
employee_id
Many2one → hr.employee
help='Employee that has timesheets on the project.'
required=True
string='Employee'
args: 'hr.employee'
price_unit
Float
default=1.0
help='Unit price of the sales order item.'
args: 'Unit Price'
product_id
Many2one → product.product
domain=[('type', '=', 'service'), ('invoice_policy', '=', 'delivery'), ('service_type', '=', 'timesheet')]
help='Product of the sales order item. Must be a service invoiced based on timesheets on tasks.'
required=True
string='Service'
args: 'product.product'
wizard_id
Many2one → project.create.sale.order
required=True
args: 'project.create.sale.order'
No public methods.
amount_untaxed_invoiced
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Untaxed Amount Invoiced'
amount_untaxed_to_invoice
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Untaxed Amount To Invoice'
analytic_account_id
Many2one → account.analytic.account
readonly=True
string='Analytic Account'
args: 'account.analytic.account'
company_id
Many2one → res.company
readonly=True
string='Project Company'
args: 'res.company'
currency_id
Many2one → res.currency
readonly=True
string='Project Currency'
args: 'res.currency'
expense_amount_untaxed_invoiced
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Untaxed Re-invoiced Amount'
expense_amount_untaxed_to_invoice
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Untaxed Amount to Re-invoiced'
expense_cost
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Other Cost'
order_confirmation_date
Datetime
readonly=True
args: 'Sales Order Confirmation Date'
partner_id
Many2one → res.partner
readonly=True
string='Customer'
args: 'res.partner'
product_id
Many2one → product.product
readonly=True
string='Product'
args: 'product.product'
project_id
Many2one → project.project
readonly=True
string='Project'
args: 'project.project'
sale_line_id
Many2one → sale.order.line
readonly=True
string='Sale Order Line'
args: 'sale.order.line'
sale_order_id
Many2one → sale.order
readonly=True
string='Sale Order'
args: 'sale.order'
timesheet_cost
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Timesheet Cost'
timesheet_unit_amount
Float
digits=(16, 2)
group_operator='sum'
readonly=True
args: 'Timesheet Unit Amount'
user_id
Many2one → res.users
readonly=True
string='Project Manager'
args: 'res.users'
init(self)
billable_type
Selection
compute='_compute_billable_type'
compute_sudo=True
help='Billable type implies:\n - At task rate: each time spend on a task is billed at task rate.\n - At employee rate: each employee log time billed at his rate.\n - No Billable: track time without invoicing it'
store=True
string='Billable Type'
args: [('task_rate', 'At Task Rate'), ('employee_rate', 'At Employee Rate'), ('no', 'No Billable')]
sale_line_employee_ids
One2many → project.sale.line.employee.map
copy=False
args: 'project.sale.line.employee.map', 'project_id', 'Sale line/Employee map'
sale_line_id
Many2one → sale.order.line
copy=False
domain="[('is_expense', '=', False), ('order_id', '=', sale_order_id), ('state', 'in', ['sale', 'done'])]"
help='Sale order line from which the project has been created. Used for tracability.'
args: 'sale.order.line', 'Sales Order Item'
sale_order_id
Many2one → sale.order
copy=False
domain="[('partner_id', '=', partner_id)]"
readonly=True
args: 'sale.order', 'Sales Order'
action_make_billable(self)
action_view_timesheet(self)
action_view_timesheet_plan(self)
employee_id
Many2one → hr.employee
required=True
args: 'hr.employee', 'Employee'
price_unit
Float
readonly=True
related='sale_line_id.price_unit'
project_id
Many2one → project.project
default=_default_project_id
domain=[('billable_type', '!=', 'no')]
required=True
args: 'project.project', 'Project'
sale_line_id
Many2one → sale.order.line
domain=[('is_service', '=', True)]
required=True
args: 'sale.order.line', 'Sale Order Item'
No public methods.
billable_type
Selection
compute='_compute_billable_type'
compute_sudo=True
store=True
string='Billable Type'
args: [('task_rate', 'At Task Rate'), ('employee_rate', 'At Employee Rate'), ('no', 'No Billable')]
is_project_map_empty
Boolean
compute='_compute_is_project_map_empty'
args: 'Is Project map empty'
sale_line_id
Many2one → sale.order.line
default=_default_sale_line_id
domain="[('is_service', '=', True), ('order_partner_id', '=', partner_id), ('is_expense', '=', False), ('state', 'in', ['sale', 'done'])]"
args: 'sale.order.line', 'Sales Order Item'
sale_order_id
Many2one → sale.order
compute='_compute_sale_order_id'
compute_sudo=True
readonly=True
store=True
args: 'sale.order', 'Sales Order'
action_view_so(self)
rating_get_partner_id(self)
unlink(self)
write(self, values)
partner_id
Many2one → res.partner
readonly=True
related='sale_line_id.order_partner_id'
args: 'res.partner'
sale_line_id
Many2one → sale.order.line
domain=[('is_service', '=', True)]
help='Sale order line to link to selected tasks'
args: 'sale.order.line', 'Sales Order Item'
task_ids
Many2many → project.task
domain=[('parent_id', '=', False)]
help='Select the tasks to assign to the Sale Order Items. You can only choose task (no sub tasks).'
string='Tasks'
args: 'project.task', 'project_task_assign_so_line_rel', 'task_id', 'wizard_id'
action_assign_sale_line(self)
default_get(self, fields)
project_ids
Many2many → project.project
compute='_compute_project_ids'
copy=False
groups='project.group_project_user'
help='Projects used in this sales order.'
string='Projects'
args: 'project.project'
tasks_count
Integer
compute='_compute_tasks_ids'
groups='project.group_project_user'
string='Tasks'
tasks_ids
Many2many → project.task
compute='_compute_tasks_ids'
string='Tasks associated to this sale'
args: 'project.task'
timesheet_count
Float
compute='_compute_timesheet_ids'
groups='hr_timesheet.group_hr_timesheet_user'
string='Timesheet activities'
timesheet_ids
Many2many → account.analytic.line
compute='_compute_timesheet_ids'
string='Timesheet activities associated to this sale'
args: 'account.analytic.line'
action_view_project_ids(self)
action_view_task(self)
action_view_timesheet(self)
analytic_line_ids
One2many
domain=[('project_id', '=', False)]
is_service
Boolean
compute='_compute_is_service'
compute_sudo=True
help='Sales Order item should generate a task and/or a project, depending on the product settings.'
store=True
args: 'Is a Service'
project_id
Many2one → project.project
copy=False
help='Project generated by the sales order item'
index=True
args: 'project.project', 'Generated Project'
qty_delivered_method
Selection
selection_add=[('timesheet', 'Timesheets')]
task_id
Many2one → project.task
copy=False
help='Task generated by the sales order item'
index=True
args: 'project.task', 'Generated Task'
create(self, vals_list)
write(self, values)
| REPOSITORY | |
|---|---|
| REPOSITORY | odoo/odoo |
| GIT | |
| GIT | https://github.com/odoo/odoo.git |
| GIT FOLDER | |
| GIT FOLDER | https://github.com/odoo/odoo/tree/11.0/sale_timesheet |
| VERSION | |
| VERSION | 0.1.0 |
| CATEGORY | |
| CATEGORY | Hidden |
| LICENSE | |
| LICENSE | LGPL-3 |
| APPLICATION | |
| APPLICATION | No |
| AUTO-INSTALLABLE | |
| AUTO-INSTALLABLE | Yes |
| AUTHORS | |
| AUTHORS | |
| MAINTAINERS | |
| MAINTAINERS | |
| COMMITTERS | |
| COMMITTERS | Odoo Translation Bot, Martin Trigaux, Fabien Pinckaers, Olivier Dony, Thibault Delavallée, Christophe Simonis, Goffin Simon, Nicolas Martinelli, Nicolas Lempereur, Jérome Maes, Julien Legros, Richard Mathot, Géry Debongnie, Aaron Bohy, Jeremy Kersten, GitHub, Lucas Perais (lpe), Yannick Tivisse, qsm-odoo, Odoo Online, jem-odoo, fwi-odoo, tbe-odoo, Adrien Dieudonne, Christophe Monniez, Nans Lefebvre, Denis Vermylen, amoyaux, Julien Castiaux |
| WEBSITE | |
| WEBSITE | https://www.odoo.com/page/warehouse |
| LAST TRACKING UPDATE | |
| LAST TRACKING UPDATE | 2026-07-05 23:53:42 |
| ODOO DEPENDENCIES | |
| ODOO DEPENDENCIES |
odoo/odoo: - sale_management - sale - sales_team - base - base_setup - web - bus - web_tour - account - product - decimal_precision - analytic - web_planner - portal - http_routing - account_invoicing - hr_timesheet - hr - resource - project |
| PYTHON DEPENDENCIES | |
| PYTHON DEPENDENCIES | Not have |
| SYSTEM DEPENDENCIES | |
| SYSTEM DEPENDENCIES | Not have |
| DESCRIPTION | |
| DESCRIPTION | Allows to sell timesheets in your sales order ============================================= This module set the right product on all timesheet lines according to the order/contract you work on. This allows to have real delivered quantities in sales orders. |
| XML ID | Name | Model | Type | Status |
|---|---|---|---|---|
account_invoice_view_form_inherit_sale_timesheet |
account.invoice.form.inherit.timesheet | account.invoice | xpath | Inherits account.invoice_form |
assets_backend |
sale timesheet assets | ir.ui.view | qweb | Inherits web.assets_backend |
hr_timesheet_employee_extd_form |
hr.timesheet.employee.extd_form | hr.employee | xpath | Inherits hr_timesheet.hr_employee_view_form_inherit_timesheet |
product_template_search_view_sale_timesheet |
product.template.search.timesheet | product.template | xpath | Inherits product.product_template_search_view |
project_project_view_kanban_inherit_sale_timesheet |
project.project.kanban.inherit.sale.timesheet | project.project | xpath | Inherits hr_timesheet.view_project_kanban_inherited |
project_task_view_form_inherit_sale_timesheet |
project.task.form.inherit.timesheet | project.task | xpath | Inherits hr_timesheet.view_task_form2_inherited |
res_config_settings_view_form |
res.config.settings.view.form.inherit.sale.timesheet | res.config.settings | xpath | Inherits hr_timesheet.res_config_settings_view_form |
timesheet_plan |
Timesheet Plan | ir.ui.view | qweb | New |
timesheet_view_pivot_revenue |
account.analytic.line.pivot.revenue | account.analytic.line | pivot | New |
timesheet_view_search |
account.analytic.line.search | account.analytic.line | xpath | Inherits hr_timesheet.hr_timesheet_line_search |
view_order_form_inherit_sale_timesheet |
sale.order.form.sale.timesheet | sale.order | data | Inherits sale.view_order_form |
view_product_timesheet_form |
product.template.timesheet.form | product.template | xpath | Inherits sale.product_template_form_view_invoice_policy |
view_sale_service_inherit_form2 |
sale.service.form.view.inherit | project.task | xpath | Inherits project.view_task_form2 |
timesheet_invoice_id
Many2one → account.invoice
copy=False
help='Invoice created from the timesheet'
readonly=True
string='Invoice'
args: 'account.invoice'
timesheet_invoice_type
Selection
copy=False
readonly=True
string='Billable Type'
args: [('billable_time', 'Billable Time'), ('billable_fixed', 'Billable Fixed'), ('non_billable', 'Non Billable'), ('non_billable_project', 'No task found')]
timesheet_revenue
Monetary
copy=False
currency_field='company_currency_id'
default=0.0
readonly=True
args: 'Revenue'
create(self, values)
write(self, values)
timesheet_count
Integer
compute='_compute_timesheet_count'
args: 'Number of timesheets'
timesheet_ids
One2many → account.analytic.line
copy=False
readonly=True
string='Timesheets'
args: 'account.analytic.line', 'timesheet_invoice_id'
action_view_timesheet(self)
invoice_validate(self)
currency_id
Many2one → res.currency
readonly=True
related='company_id.currency_id'
args: 'res.currency'
timesheet_cost
Monetary
currency_field='currency_id'
default=0.0
args: 'Timesheet Cost'
No public methods.
project_id
Many2one → project.project
company_dependent=True
domain=[('sale_line_id', '=', False)]
help='Select a non billable project on which tasks can be created. This setting must be set for each company.'
args: 'project.project', 'Project'
service_policy
Selection
compute='_compute_service_policy'
inverse='_inverse_service_policy'
string='Invoice based on'
args: [('ordered_timesheet', 'Ordered quantities'), ('delivered_timesheet', 'Timesheets on tasks'), ('delivered_manual', 'Milestones (manually set quantities on order)')]
service_tracking
Selection
default='no'
help='On Sales order confirmation, this product can generate a project and/or task. From those, you can track the service you are selling.'
string='Service Tracking'
args: [('no', "Don't create task"), ('task_global_project', 'Create a task in an existing project'), ('task_new_project', 'Create a task in a new project'), ('project_only', 'Create a new project but no task')]
service_type
Selection
selection_add=[('timesheet', 'Timesheets on project (one fare per SO/Project)')]
No public methods.
sale_line_id
Many2one → sale.order.line
help='Sale order line from which the project has been created. Used for tracability.'
readonly=True
args: 'sale.order.line', 'Sales Order Line'
action_view_timesheet(self)
action_view_timesheet_plan(self)
sale_line_id
Many2one → sale.order.line
default=_default_sale_line_id
domain="[('is_service', '=', True), ('order_partner_id', '=', partner_id)]"
args: 'sale.order.line', 'Sales Order Item'
action_view_so(self)
create(self, values)
onchange_parent_id(self)
unlink(self)
write(self, values)
project_ids
Many2many → project.project
compute='_compute_project_ids'
copy=False
groups='project.group_project_user'
help='Projects used in this sales order.'
string='Projects'
args: 'project.project'
project_project_id
Many2one → project.project
compute='_compute_project_project_id'
string='Project associated to this sale'
args: 'project.project'
tasks_count
Integer
compute='_compute_tasks_ids'
groups='project.group_project_user'
string='Tasks'
tasks_ids
Many2many → project.task
compute='_compute_tasks_ids'
string='Tasks associated to this sale'
args: 'project.task'
timesheet_count
Float
compute='_compute_timesheet_ids'
groups='hr_timesheet.group_hr_timesheet_user'
string='Timesheet activities'
timesheet_ids
Many2many → account.analytic.line
compute='_compute_timesheet_ids'
string='Timesheet activities associated to this sale'
args: 'account.analytic.line'
action_confirm(self)
action_view_project_ids(self)
action_view_task(self)
action_view_timesheet(self)
is_service
Boolean
compute='_compute_is_service'
compute_sudo=True
help='Sales Order item should generate a task and/or a project, depending on the product settings.'
store=True
args: 'Is a Service'
task_id
Many2one → project.task
help='Task generated by the sales order item'
index=True
args: 'project.task', 'Task'
create(self, values)
| REPOSITORY | |
|---|---|
| REPOSITORY | odoo/odoo |
| GIT | |
| GIT | https://github.com/odoo/odoo.git |
| GIT FOLDER | |
| GIT FOLDER | https://github.com/odoo/odoo/tree/10.0/sale_timesheet |
| VERSION | |
| VERSION | 0.1.0 |
| CATEGORY | |
| CATEGORY | Hidden |
| LICENSE | |
| LICENSE | LGPL-3 |
| APPLICATION | |
| APPLICATION | No |
| AUTO-INSTALLABLE | |
| AUTO-INSTALLABLE | Yes |
| AUTHORS | |
| AUTHORS | |
| MAINTAINERS | |
| MAINTAINERS | |
| COMMITTERS | |
| COMMITTERS | Odoo Translation Bot, Martin Trigaux, Fabien Pinckaers, Antony Lesuisse, Olivier Dony, Thibault Delavallée, Denis Ledoux, Christophe Simonis, David Monjoie, Goffin Simon, Nicolas Martinelli, Julien Legros, qdp-odoo, Aaron Bohy, Lucas Perais (lpe), Damien Bouvy, Yannick Tivisse, Tanguy Charlier |
| WEBSITE | |
| WEBSITE | https://www.odoo.com/page/warehouse |
| LAST TRACKING UPDATE | |
| LAST TRACKING UPDATE | 2026-07-05 23:50:47 |
| ODOO DEPENDENCIES | |
| ODOO DEPENDENCIES |
odoo/odoo: - sale - sales_team - base - base_setup - web_kanban - web - bus - web_tour - account - product - decimal_precision - report - analytic - web_planner - procurement - hr_timesheet - hr - resource - project |
| PYTHON DEPENDENCIES | |
| PYTHON DEPENDENCIES | Not have |
| SYSTEM DEPENDENCIES | |
| SYSTEM DEPENDENCIES | Not have |
| DESCRIPTION | |
| DESCRIPTION | Allows to sell timesheets in your sales order ============================================= This module set the right product on all timesheet lines according to the order/contract you work on. This allows to have real delivered quantities in sales orders. |
| XML ID | Name | Model | Type | Status |
|---|---|---|---|---|
hr_timesheet_employee_extd_form |
hr.timesheet.employee.extd_form | hr.employee | xpath | Inherits hr.view_employee_form |
view_order_form_inherit_sale_timesheet |
sale.order.form.sale.timesheet | sale.order | data | Inherits sale.view_order_form |
view_procurement_task_form |
procurement.procurement.form.view.inherit | procurement.order | field | Inherits procurement.procurement_form_view |
view_product_timesheet_form |
product.template.timesheet.form | product.template | xpath | Inherits sale.product_template_form_view_invoice_policy |
view_sale_service_inherit_form2 |
sale.service.form.view.inherit | project.task | xpath | Inherits project.view_task_form2 |
No new fields.
Public methods (2)create(self, values)
write(self, values)
account_id
Many2one → account.account
string='Account'
args: 'account.account'
timesheet_cost
Float
default=0.0
args: 'Timesheet Cost'
No public methods.
task_id
Many2one → project.task
copy=False
args: 'project.task', 'Task'
No public methods.
No new fields.
Public methods (0)No public methods.
project_id
Many2one → project.project
company_dependent=True
help='Create a task under this project on sale order validation. This setting must be set for each company.'
args: 'project.project', 'Project'
track_service
Selection
selection_add=[('timesheet', 'Timesheets on project'), ('task', 'Create a task and track hours')]
No public methods.
procurement_id
Many2one → procurement.order
ondelete='set null'
args: 'procurement.order', 'Procurement'
sale_line_id
Many2one → sale.order.line
related='procurement_id.sale_line_id'
store=True
args: 'sale.order.line', 'Sales Order Line'
action_view_so(self)
onchange_parent_id(self)
unlink(self)
project_time_mode_id
Many2one → product.uom
default=_get_default_uom_id
args: 'product.uom', 'Timesheet UoM'
No public methods.
project_project_id
Many2one → project.project
compute='_compute_project_project_id'
string='Project associated to this sale'
args: 'project.project'
tasks_count
Integer
compute='_compute_tasks_ids'
string='Tasks'
tasks_ids
Many2many → project.task
compute='_compute_tasks_ids'
string='Tasks associated to this sale'
args: 'project.task'
timesheet_count
Float
compute='_compute_timesheet_ids'
string='Timesheet activities'
timesheet_ids
Many2many → account.analytic.line
compute='_compute_timesheet_ids'
string='Timesheet activities associated to this sale'
args: 'account.analytic.line'
action_confirm(self)
action_view_project_project(self)
action_view_task(self)
action_view_timesheet(self)
No new fields.
Public methods (1)create(self, values)
| REPOSITORY | |
|---|---|
| REPOSITORY | odoo/odoo |
| GIT | |
| GIT | https://github.com/odoo/odoo.git |
| GIT FOLDER | |
| GIT FOLDER | https://github.com/odoo/odoo/tree/9.0/sale_timesheet |
| VERSION | |
| VERSION | 1.0 |
| CATEGORY | |
| CATEGORY | Hidden |
| LICENSE | |
| LICENSE | LGPL-3 |
| APPLICATION | |
| APPLICATION | No |
| AUTO-INSTALLABLE | |
| AUTO-INSTALLABLE | Yes |
| AUTHORS | |
| AUTHORS | OpenERP SA |
| MAINTAINERS | |
| MAINTAINERS | OpenERP SA |
| COMMITTERS | |
| COMMITTERS | Odoo Translation Bot, Martin Trigaux, Olivier Dony, Denis Ledoux, Goffin Simon, Nicolas Martinelli, Damien Bouvy |
| WEBSITE | |
| WEBSITE | https://www.odoo.com/page/warehouse |
| LAST TRACKING UPDATE | |
| LAST TRACKING UPDATE | 2026-07-05 23:48:30 |
| ODOO DEPENDENCIES | |
| ODOO DEPENDENCIES |
odoo/odoo: - sale - sales_team - base - base_setup - web_kanban - web - bus - account - product - decimal_precision - report - analytic - web_tip - web_planner - procurement - hr_timesheet - hr - resource - hr_attendance |
| PYTHON DEPENDENCIES | |
| PYTHON DEPENDENCIES | Not have |
| SYSTEM DEPENDENCIES | |
| SYSTEM DEPENDENCIES | Not have |
| DESCRIPTION | |
| DESCRIPTION | Allows to sell timesheets in your sales order ============================================= This module set the right product on all timesheet lines according to the order/contract you work on. This allows to have real delivered quantities in sales orders. |
| XML ID | Name | Model | Type | Status |
|---|---|---|---|---|
hr_timesheet_employee_extd_form |
hr.timesheet.employee.extd_form | hr.employee | xpath | Inherits hr.view_employee_form |
view_order_form_inherit_sale_timesheet |
sale.order.form.sale.timesheet | sale.order | data | Inherits sale.view_order_form |
view_product_timesheet_form |
product.template.timesheet.form | product.template | xpath | Inherits sale.product_template_form_view_invoice_policy |
No new fields.
Public methods (2)create(self, values)
write(self, values)
timesheet_cost
Float
default=0.0
string='Timesheet Cost'
No public methods.
track_service
Selection
selection_add=[('timesheet', 'Timesheets on contract')]
onchange_type_timesheet(self)
project_time_mode_id
Many2one → product.uom
default=_get_uom_hours
string='Timesheet UoM'
args: 'product.uom'
No public methods.
timesheet_count
Float
compute='_compute_timesheet_ids'
string='Timesheet activities'
timesheet_ids
Many2many → account.analytic.line
compute='_compute_timesheet_ids'
string='Timesheet activities associated to this sale'
args: 'account.analytic.line'
action_confirm(self)
action_view_timesheet(self)
No new fields.
Public methods (0)No public methods.