TIP: You can type at any time to perform a new search.

Security findings

Repository
odoo/odoo · module folder
Module version
2.1
Category
Human Resources/Expenses
Folder size
6.46 MB
License
LGPL-3
Application
Yes
Auto-installable
No
Website
https://www.odoo.com/app/expenses
Last tracking update
2026-10-05 00:19:49
Authors
Odoo S.A.
Maintainers
Odoo S.A.
Committers
Xavier Morel, Raphael Collet, Thibault Delavallée, Odoo Translation Bot, Christophe Matthieu, Aaron Bohy, Géry Debongnie, Yannick Tivisse, Jorge Pinna Puissant, Romeo Fragomeli, Victor Feyens, Adrien Dieudonné, Sébastien Theys, oco-odoo, Julien Mougenot, Anh Thao Pham (pta), David Beguin, Brice bib Bartoletti, Tiffany Chang (tic), Pierre Paridans, Romain Estievenart, william-andre, Víctor Martínez, John Laterre (jol), luvi, Victor Piryns (pivi), Mahamadasif Ansari, amdi-odoo, Ali Alfie (alal), hupo-odoo, Dylan Kiss (dyki), Paolo Gatti, Julien Alardot (jual), Chong Wang (cwg), Harsh Modi, Arnaud Sibille, guva-odoo, Harsh Shah, hatr-odoo, Patricia Daloze (pda), gteboul, Abdo Mongy, Hesham Saleh, Saif (segn), Victor Miguel Armenta Carrillo, roto-odoo, Chris Duvivier, Pierre Pulinckx, Michaël Mattiello, ppat-odoo, Sherif Gabr, Krzysztof Magusiak (krma), krip-odoo, sagu-odoo, bhra-odoo, mojem, bhna-odoo, thha-odoo, agbr-odoo, Mongy (abmn), Jeanne Delneste, Julien Launois (jula), Patrick Stooks, Yagnik ✗ (yagp), h4818, leclerc-leo, malb, Saurabh, Victor Decleire, Amr Elkhatieb, Mohamed Barakat, Mahmoudk3m, smjo-odoo, Abo Taha, soza-odoo, ELCO, Khaj-odoo, chpa-odoo, Oussema Heni, Chengyan Wang, Wajih-Wanis, apan-odoo, Léo Leclerc, Julien Coppin (jucop), Julien Piron, Jean Schoenlaub, pusu-odoo
Odoo dependencies
Python dependencies
None
System dependencies
None
Required by
l10n_din5008_expense, project_hr_expense, sale_expense
Description
Manage expenses by Employees
============================

This application allows you to manage your employees' daily expenses. It gives you access to your employees’ fee notes and give you the right to complete and validate or refuse the notes. After validation it creates an invoice for the employee.
Employee can encode their own expenses and the validation flow puts it automatically in the accounting after validation by managers.


The whole flow is implemented as:
---------------------------------
* Draft expense
* Submitted by the employee to his manager
* Approved by his manager
* Validation by the accountant and accounting entries creation

This module also uses analytic accounting and is compatible with the invoice on timesheet module so that you are able to automatically re-invoice your customers' expenses if your work by project.
    

Code Analysis info_outline

Views touched (44)
XML IDNameModelTypeStatus
account_journal_dashboard_kanban_view_inherit_expense account.journal.dashboard.kanban.inherit.expense account.journal kanban Inherits account.account_journal_dashboard_kanban_view
account_journal_view_form_inherit_hr_expense account.journal.form.inherit.hr.expense account.journal form Inherits account.view_account_journal_form
direct_expense direct_expense ir.ui.view qweb New
hr_department_view_kanban hr.department.kanban.inherit hr.department kanban Inherits hr.hr_department_view_kanban
hr_employee_search_view hr.employee.search.view hr.employee search Inherits hr.view_employee_filter
hr_employee_view_form_inherit_expense hr.employee.view.form.expense hr.employee form Inherits hr.view_employee_form
hr_expense_approve_duplicate_view_form hr.expense.approve.duplicate form New
hr_expense_kanban_view hr.expense.kanban hr.expense kanban Inherits hr_expense_view_expenses_analysis_kanban
hr_expense_kanban_view_header hr.expense.kanban hr.expense kanban Inherits hr_expense_view_expenses_analysis_kanban
hr_expense_kanban_view_minimal hr.expense.kanban hr.expense kanban Inherits hr_expense_view_expenses_analysis_kanban
hr_expense_refuse_wizard_view_form hr.expense.refuse.wizard.form hr.expense.refuse.wizard form New
hr_expense_split Expense split hr.expense.split.wizard form New
hr_expense_split_form_view hr.expense.split.form hr.expense.split form New
hr_expense_template_refuse_reason hr_expense_template_refuse_reason ir.ui.view qweb New
hr_expense_template_register hr_expense_template_register ir.ui.view qweb New
hr_expense_template_register_no_user hr_expense_template_register_no_user ir.ui.view qweb New
hr_expense_template_submitted_expenses hr_expense_template_submitted_expenses ir.ui.view qweb New
hr_expense_view_activity hr.expense.activity hr.expense activity New
hr_expense_view_expenses_analysis_kanban hr.expense.kanban hr.expense kanban New
hr_expense_view_expenses_analysis_tree hr.expense.list hr.expense list New
hr_expense_view_form hr.expense.view.form hr.expense form New
hr_expense_view_form_without_header hr.expense.view.form hr.expense form Inherits hr_expense.hr_expense_view_form
hr_expense_view_graph hr.expense.graph hr.expense graph New
hr_expense_view_pivot hr.expense.pivot hr.expense pivot New
hr_expense_view_search hr.expense.view.search hr.expense search New
hr_expense_view_search_with_panel hr.expense.view.search.with.panel hr.expense search Inherits hr_expense_view_search
match_bill match_bill ir.ui.view qweb New
product_product_expense_categories_tree_view product.product.expense.categories.list.view product.product list New
product_product_expense_form_view product.product.expense.form product.product form New
product_product_expense_kanban_view product.product.kanban.expense product.product kanban Inherits product.product_kanban_view
product_product_expense_tree_view product.product.expense.list product.product list New
product_template_form_view product.template.form.inherit product.template form Inherits product.product_template_form_view
product_template_search_view_inherit_hr_expense product.template.search.view.inherit.hr_expense product.template search Inherits product.product_template_search_view
report_expense report_expense ir.ui.view qweb New
report_expense_img report_expense_img ir.ui.view qweb New
res_config_settings_view_form res.config.settings.view.form.inherit.hr.expense res.config.settings form Inherits base.res_config_settings_view_form
view_account_invoice_filter_inherit_expense account.invoice.select.inherit account.move Inherits account.view_account_invoice_filter
view_employee_tree_inherit_expense hr.employee.list.expense hr.employee list Inherits hr.view_employee_tree
view_expenses_tree hr.expense.list hr.expense list Inherits hr_expense_view_expenses_analysis_tree
view_move_form_inherit_expense account.move.form.inherit account.move form Inherits account.view_move_form
view_move_list_expense account.move.hr.expense.list account.move list New
view_my_expenses_tree hr.expense.list hr.expense list Inherits hr_expense.view_expenses_tree
view_payment_form_inherit_expense account.payment.form.inherit account.payment form Inherits account.view_account_payment_form
view_product_hr_expense_form product.template.expense.form product.template form Inherits product.product_template_form_view
HTTP endpoints (0)

No HTTP endpoints found for this module.

Models touched (24)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (1)
  • business_domain Selection
    ondelete={'expense': 'cascade'} selection_add=[('expense', 'Expense')]
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • open_draft_moves_linked_to_expense(self)

New fields (4)
  • bill_paid_by_employee Boolean
    compute='_compute_bill_paid_by_employee'
  • existing_expense_ids One2many → hr.expense
    comodel_name='hr.expense' inverse_name='existing_bill_id'
  • expense_ids One2many → hr.expense
    comodel_name='hr.expense' inverse_name='account_move_id'
  • nb_expenses Integer
    compute='_compute_nb_expenses' compute_sudo=True string='Number of Expenses'
Public methods (2)
  • action_open_expense(self)
  • button_cancel(self)

New fields (1)
  • expense_id Many2one → hr.expense
    copy=True index='btree_not_null' string='Expense' args: 'hr.expense'
Public methods (0)

No public methods.

New fields (1)
  • expense_ids One2many
    related='move_id.expense_ids'
Public methods (2)
  • action_open_expense(self)
  • write(self, vals)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (1)
  • hr_expense_ids Many2many → hr.expense
    column1='tax_id' column2='expense_id' comodel_name='hr.expense' copy=False readonly=True relation='expense_tax'
Public methods (0)

No public methods.

New fields (1)
  • expenses_to_approve_count Integer
    compute='_compute_expenses_to_approve_count' string='Expenses to Approve'
Public methods (0)

No public methods.

New fields (2)
  • expense_manager_id Many2one → res.users
    comodel_name='res.users' compute='_compute_expense_manager' domain=_group_hr_expense_user_domain help='Select the user responsible for approving "Expenses" of this employee.\nIf empty, the approval is done by an Administrator or Approver (determined in settings/users).' readonly=False store=True string='Expense Approver'
  • filter_for_expense Boolean
    groups='hr.group_hr_user,hr_expense.group_hr_expense_manager' search='_search_filter_for_expense' store=False
Public methods (0)

No public methods.

New fields (1)
  • expense_manager_id Many2one → res.users
    readonly=True args: 'res.users'
Public methods (0)

No public methods.

New fields (1)
  • filter_for_expense Boolean
    search='_search_filter_for_expense' store=False
Public methods (0)

No public methods.

New fields (57)
  • account_id Many2one → account.account
    check_company=True comodel_name='account.account' compute='_compute_account_id' domain="[('account_type', 'not in', ('asset_receivable', 'liability_payable', 'asset_cash', 'liability_credit_card'))]" help='An expense account is expected for employee paid expenses and company paid expenses without a matched bill.\nFor company paid expenses with a matched bill, the account needs to be the payable account of the bill.' precompute=True readonly=False store=True string='Account'
  • account_move_id Many2one → account.move
    comodel_name='account.move' copy=False index='btree_not_null' readonly=True string='Journal Entry'
  • amount_residual Monetary
    currency_field='company_currency_id' readonly=True related='account_move_id.amount_residual' string='Amount Due'
  • approval_date Datetime
    readonly=True string='Approval Date'
  • approval_state Selection
    copy=False readonly=True selection=EXPENSE_APPROVAL_STATE
  • attachment_ids One2many → ir.attachment
    comodel_name='ir.attachment' domain=[('res_model', '=', 'hr.expense')] inverse_name='res_id' string='Attachments'
  • can_approve Boolean
    compute='_compute_can_approve' readonly=True string='Can Approve'
  • can_edit_account Boolean
    compute='_compute_can_edit_account'
  • can_reset Boolean
    compute='_compute_can_reset' readonly=True string='Can Reset'
  • company_currency_id Many2one → res.currency
    comodel_name='res.currency' readonly=True related='company_id.currency_id' string='Report Company Currency'
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> index=True readonly=True required=True string='Company'
  • currency_id Many2one → res.currency
    comodel_name='res.currency' compute='_compute_currency_id' default=<expr> precompute=True readonly=False required=True store=True string='Currency'
  • currency_rate Float
    compute='_compute_currency_rate' digits=(16, 9) readonly=True tracking=True
  • date Date
    default=fields.Date.context_today string='Date'
  • department_id Many2one → hr.department
    comodel_name='hr.department' compute='_compute_from_employee_id' copy=False store=True string='Department'
  • description Text
    string='Internal Notes'
  • duplicate_expense_ids Many2many → hr.expense
    comodel_name='hr.expense' compute='_compute_duplicate_expense_ids'
  • employee_id Many2one → hr.employee
    check_company=True comodel_name='hr.employee' compute='_compute_employee_id' default=_default_employee_id domain=[('filter_for_expense', '=', True)] index=True precompute=True readonly=False store=True string='Employee' tracking=True
  • existing_bill_id Many2one → account.move
    comodel_name='account.move' copy=False domain="[\n ('company_id', '=', company_id),\n ('move_type', '=', 'in_invoice'),\n ('state', 'in', ['posted', 'draft']),\n ('amount_residual', '>', 0),\n '|', ('partner_id', '=', vendor_id), (not vendor_id, '=', True),\n ]" index='btree_not_null' string='Existing Bill'
  • expense_job_position_limit_amount Monetary
    compute='_compute_expense_job_position_limit_amount' currency_field='company_currency_id' string='Job Position Limit'
  • expense_job_position_limit_amount_currency Monetary
    compute='_compute_expense_job_position_limit_amount_currency' currency_field='currency_id' string='Job Position Limit in Currency'
  • former_sheet_id Integer
    string='Former Report'
  • has_existing_bill Boolean
    help=' - When a bill already exists, the payment will use the supplier payable account so it can be matched with the bill.\n - When no bill exists, the payment will be recorded directly on the expense account, as usual.\n '
  • has_expense_job_position_limit Boolean
    compute='_compute_has_expense_job_position_limit'
  • is_editable Boolean
    compute='_compute_is_editable' readonly=True string='Is Editable By Current User'
  • is_expense_exceeding_job_position_limit Boolean
    compute='_compute_is_expense_exceeding_job_position_limit'
  • is_multiple_currency Boolean
    compute='_compute_is_multiple_currency' string='Is currency_id different from the company_currency_id'
  • is_own_expense Boolean
    compute='_compute_is_own_expense'
  • journal_id Many2one → account.journal
    comodel_name='account.journal' compute='_compute_journal_id'
  • label_currency_rate Char
    compute='_compute_currency_rate' readonly=True
  • last_notification_date Datetime
    copy=False readonly=True string='Last Notification Date'
  • manager_id Many2one → res.users
    comodel_name='res.users' compute='_compute_from_employee_id' copy=False domain=<expr> store=True string='Manager' tracking=True
  • message_main_attachment_checksum Char
    related='message_main_attachment_id.checksum'
  • name Char
    compute='_compute_name' copy=True precompute=True readonly=False store=True string='Description'
  • nb_attachment Integer
    compute='_compute_nb_attachment' string='Number of Attachments'
  • payment_method_line_id Many2one → account.payment.method.line
    comodel_name='account.payment.method.line' compute='_compute_payment_method_line_id' domain="[('id', 'in', selectable_payment_method_line_ids)]" help='The payment method used when the expense is paid by the company.' index=True readonly=False store=True string='Payment Method'
  • payment_mode Selection
    default='own_account' required=True selection=[('own_account', 'Employee (Through a Purchase Receipt)'), ('company_account', 'None (Paid by Company)')] string='Reimbursement' tracking=True
  • price_unit Float
    compute='_compute_price_unit' copy=True min_display_digits='Product Price' precompute=True readonly=True required=True store=True string='Unit Price'
  • product_description Html
    compute='_compute_product_description'
  • product_has_cost Boolean
    compute='_compute_from_product'
  • product_has_tax Boolean
    compute='_compute_from_product' string='Whether tax is defined on a selected product'
  • product_id Many2one → product.product
    check_company=True comodel_name='product.product' domain=[('can_be_expensed', '=', True)] index=True ondelete='restrict' string='Product' tracking=True
  • product_uom_id Many2one → uom.uom
    comodel_name='uom.uom' compute='_compute_uom_id' copy=True precompute=True store=True string='Unit'
  • quantity Float
    default=1 digits='Product Unit' required=True
  • same_receipt_expense_ids Many2many → hr.expense
    comodel_name='hr.expense' compute='_compute_same_receipt_expense_ids'
  • selectable_payment_method_line_ids Many2many → account.payment.method.line
    comodel_name='account.payment.method.line' compute='_compute_selectable_payment_method_line_ids' compute_sudo=True
  • split_expense_count Integer
    compute='_compute_split_expense_count' string='Number of Split Expenses'
  • split_expense_origin_id Many2one → hr.expense
    comodel_name='hr.expense' help='Original expense from a split.' string='Origin Split Expense'
  • state Selection
    compute='_compute_state' copy=False default='draft' index=True readonly=True selection=[('draft', 'Draft'), ('submitted', 'Submitted'), ('approved', 'Approved'), ('posted', 'Posted'), ('in_payment', 'In Payment'), ('paid', 'Paid'), ('refused', 'Refused')] store=True string='Status' tracking=True
  • tax_amount Monetary
    compute='_compute_tax_amount' currency_field='company_currency_id' help='Tax amount in company currency' precompute=True store=True string='Tax amount'
  • tax_amount_currency Monetary
    compute='_compute_tax_amount_currency' currency_field='currency_id' help='Tax amount in currency' precompute=True store=True string='Tax amount in Currency'
  • tax_ids Many2many → account.tax
    check_company=True column1='expense_id' column2='tax_id' comodel_name='account.tax' compute='_compute_tax_ids' domain="[('type_tax_use', '=', 'purchase')]" help='Both price-included and price-excluded taxes will behave as price-included taxes for expenses.' precompute=True readonly=False relation='expense_tax' store=True string='Included taxes'
  • total_amount Monetary
    compute='_compute_total_amount' currency_field='company_currency_id' inverse='_inverse_total_amount' precompute=True readonly=False store=True string='Total' tracking=True
  • total_amount_currency Monetary
    compute='_compute_total_amount_currency' currency_field='currency_id' precompute=True readonly=False store=True string='Total In Currency' tracking=True
  • untaxed_amount Monetary
    compute='_compute_tax_amount' currency_field='currency_id' precompute=True store=True string='Total Untaxed Amount'
  • untaxed_amount_currency Monetary
    compute='_compute_tax_amount_currency' currency_field='currency_id' precompute=True store=True string='Total Untaxed Amount In Currency'
  • vendor_id Many2one → res.partner
    comodel_name='res.partner' string='Vendor'
Public methods (22)
  • action_approve(self)
    Approve an expense, pops a wizard if a duplicated expense is found to confirm they are all valid expenses
  • action_approve_duplicates(self)
  • action_cap_reimbursement_to_policy(self)
  • action_open_account_move(self)
  • action_open_account_payment(self)
  • action_open_split_expense(self)
  • action_pay(self)
    Register payment shortcut on the expense form view
  • action_refuse(self)
    Refuse an expense with a reason
  • action_reset(self)
    Reset an expense to draft state, reversing the accounting entries if needed
  • action_show_duplicate_expense_ids(self)
  • action_show_same_receipt_expense_ids(self)
  • action_split_wizard(self)
  • action_submit(self)
    Submit a draft expense to an approve, may skip to the approval step if no approver on the employee nor the expense
  • attach_document(self, **kwargs)
    When an attachment is uploaded as a receipt, set it as the main attachment.
  • create(self, vals_list)
    @api.model_create_multi
  • create_expense_from_attachments(self, attachment_ids=None, view_type='list')
    @api.model
    Create the expenses from files. :return: An action redirecting to hr.expense list view.
  • get_empty_list_help(self, help_message)
    @api.model
  • get_expense_dashboard(self, domain=None)
    @api.model
  • get_views(self, views, options=None)
    @api.model
  • message_new(self, msg_dict, custom_values=None)
    @api.model
  • update_activities_and_mails(self)
    Update the "Review this expense" activity with the new state of the expense, also sends mail to approver to ask them to act
  • write(self, vals)

New fields (1)
  • expense_ids Many2many → hr.expense
    readonly=True args: 'hr.expense'
Public methods (3)
  • action_approve(self)
  • action_refuse(self)
  • default_get(self, fields)
    @api.model

New fields (5)
  • company_currency_id Many2one
    related='product_id.cost_currency_id'
  • job_ids Many2many → hr.job
    comodel_name='hr.job' help='Leave empty to define the limit for all job positions.' string='Job Positions'
  • limit_amount Monetary
    currency_field='company_currency_id' required=True string='Limit'
  • product_id Many2one → product.product
    comodel_name='product.product' index=True ondelete='cascade' required=True
  • sequence Integer
    default=10
Public methods (0)

No public methods.

New fields (2)
  • expense_ids Many2many → hr.expense
    comodel_name='hr.expense'
  • reason Char
    required=True string='Reason'
Public methods (1)
  • action_refuse(self)

New fields (15)
  • approval_date Datetime
    readonly=True string='Approval Date'
  • approval_state Selection
    copy=False readonly=True selection=EXPENSE_APPROVAL_STATE
  • company_id Many2one → res.company
    comodel_name='res.company'
  • currency_id Many2one → res.currency
    comodel_name='res.currency'
  • employee_id Many2one → hr.employee
    comodel_name='hr.employee' required=True string='Employee'
  • expense_id Many2one → hr.expense
    comodel_name='hr.expense' string='Expense'
  • manager_id Many2one → res.users
    comodel_name='res.users' domain=<expr> readonly=True string='Manager'
  • name Char
    required=True string='Description'
  • product_has_cost Boolean
    compute='_compute_from_product_id' store=True string='Is product with non zero cost selected'
  • product_has_tax Boolean
    compute='_compute_product_has_tax' string='Whether tax is defined on a selected product'
  • product_id Many2one → product.product
    check_company=True comodel_name='product.product' domain=[('can_be_expensed', '=', True)] required=True string='Product'
  • tax_amount_currency Monetary
    compute='_compute_tax_amount_currency' string='Tax amount in Currency'
  • tax_ids Many2many → account.tax
    check_company=True comodel_name='account.tax' domain="[('type_tax_use', '=', 'purchase')]"
  • total_amount_currency Monetary
    compute='_compute_from_product_id' readonly=False required=True store=True string='Total In Currency'
  • wizard_id Many2one → hr.expense.split.wizard
    comodel_name='hr.expense.split.wizard'
Public methods (1)
  • default_get(self, fields)
    @api.model

New fields (7)
  • currency_id Many2one → res.currency
    comodel_name='res.currency' related='expense_id.currency_id'
  • expense_id Many2one → hr.expense
    comodel_name='hr.expense' required=True string='Expense'
  • expense_split_line_ids One2many → hr.expense.split
    comodel_name='hr.expense.split' inverse_name='wizard_id'
  • split_possible Boolean
    compute='_compute_split_possible' help='The sum of after split shut remain the same'
  • tax_amount_currency Monetary
    compute='_compute_tax_amount_currency' currency_field='currency_id' string='Taxes'
  • total_amount_currency Monetary
    compute='_compute_total_amount_currency' currency_field='currency_id' string='Total Amount'
  • total_amount_currency_original Monetary
    currency_field='currency_id' help='Total amount of the original Expense that we are splitting' related='expense_id.total_amount_currency' string='Total amount original'
Public methods (1)
  • action_split_expense(self)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (1)
  • expense_job_position_limit_ids One2many → hr.expense.product.job.position.limit
    comodel_name='hr.expense.product.job.position.limit' copy=True inverse_name='product_id' string='Job Position Limits'
Public methods (2)
  • get_standard_price_update_warning(self, new_standard_price)
  • write(self, vals)

New fields (1)
  • can_be_expensed Boolean
    compute='_compute_can_be_expensed' help='Specify whether the product can be selected in an expense.' init_storage=<expr> readonly=False store=True string='Expenses'
Public methods (1)
  • default_get(self, fields)
    @api.model

New fields (2)
  • company_expense_allowed_payment_method_line_ids Many2many → account.payment.method.line
    check_company=True domain="[('payment_type', '=', 'outbound'), ('journal_id', '!=', False), ('journal_id.active', '=', True)]" string='Payment methods available for expenses paid by company' args: 'account.payment.method.line'
  • expense_journal_id Many2one → account.journal
    check_company=True domain="[('type', '=', 'purchase')]" help="The company's default journal used when an employee expense is created." string='Default Expense Journal' args: 'account.journal'
Public methods (0)

No public methods.

New fields (8)
  • company_expense_allowed_payment_method_line_ids Many2many → account.payment.method.line
    check_company=True comodel_name='account.payment.method.line' domain="[('payment_type', '=', 'outbound'), ('journal_id.active', '=', True)]" readonly=False related='company_id.company_expense_allowed_payment_method_line_ids'
  • expense_journal_id Many2one → account.journal
    check_company=True domain="[('type', '=', 'purchase')]" readonly=False related='company_id.expense_journal_id' args: 'account.journal'
  • hr_expense_alias_domain_id Many2one → mail.alias.domain
    comodel_name='mail.alias.domain' compute='_compute_hr_expense_alias_domain_id' inverse='_inverse_hr_expense_alias_domain_id' readonly=False
  • hr_expense_alias_prefix Char
    compute='_compute_hr_expense_alias_prefix' readonly=False store=True args: 'Default Alias Name for Expenses'
  • hr_expense_use_mailgateway Boolean
    config_parameter='hr_expense.use_mailgateway' string='Let your employees record expenses by email'
  • module_hr_expense_extract Boolean
    string='Send bills to OCR to generate expenses'
  • module_hr_expense_stripe Boolean
    string='Link your stripe issuing account to manage company credit cards for your employees through Odoo'
  • module_hr_payroll_expense Boolean
    string='Reimburse Expenses in Payslip'
Public methods (2)
  • get_values(self)
    @api.model
  • set_values(self)

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…