Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions hr_expense_move_sync/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
====================
HR Expense Move Sync
====================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:placeholder
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fhr--expense-lightgray.png?logo=github
:target: https://github.com/OCA/hr-expense/tree/18.0/hr_expense_move_sync
:alt: OCA/hr-expense
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/hr-expense-18-0/hr-expense-18-0-hr_expense_move_sync
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/hr-expense&target_branch=18.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module adds automatic synchronization between approved expense
reports and their linked draft journal entries. When an expense is
edited after approval, the linked vendor bills or journal entries are
regenerated to reflect the changes.

**Table of contents**

.. contents::
:local:

Configuration
=============

By default, manual sync is enabled. After approving an expense report,
you can click the **Sync Accounting Entries** button on the expense
sheet to regenerate the draft journal entries with the latest expense
data.

To enable automatic sync, go to **Settings > Expenses** and tick
*Auto-sync expense moves*. When enabled, saving any edit on an approved
expense automatically regenerates the linked draft journal entries.

In both modes, posted or paid journal entries are never affected.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/hr-expense/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/hr-expense/issues/new?body=module:%20hr_expense_move_sync%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* Ecosoft

Contributors
------------

- Saran Lim. <saranl@ecosoft.co.th>

Maintainers
-----------

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

.. |maintainer-Saran440| image:: https://github.com/Saran440.png?size=40px
:target: https://github.com/Saran440
:alt: Saran440

Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-Saran440|

This module is part of the `OCA/hr-expense <https://github.com/OCA/hr-expense/tree/18.0/hr_expense_move_sync>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
3 changes: 3 additions & 0 deletions hr_expense_move_sync/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import models
18 changes: 18 additions & 0 deletions hr_expense_move_sync/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2026 Ecosoft Co., Ltd. (http://ecosoft.co.th)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

{
"name": "HR Expense Move Sync",
"version": "18.0.1.0.0",
"license": "AGPL-3",
"category": "Human Resources",
"author": "Ecosoft, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/hr-expense",
"depends": ["hr_expense"],
"data": [
"views/hr_expense_sheet_views.xml",
"views/res_config_settings_views.xml",
],
"installable": True,
"maintainers": ["Saran440"],
}
7 changes: 7 additions & 0 deletions hr_expense_move_sync/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import res_company
from . import res_config_settings
from . import account_move
from . import hr_expense_sheet
from . import hr_expense
18 changes: 18 additions & 0 deletions hr_expense_move_sync/models/account_move.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2026 Ecosoft Co., Ltd. (http://ecosoft.co.th)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import models


class AccountMove(models.Model):
_inherit = "account.move"

def button_draft(self):
return super(
AccountMove, self.with_context(skip_move_refresh=True)
).button_draft()

def button_cancel(self):
return super(
AccountMove, self.with_context(skip_move_refresh=True)
).button_cancel()
29 changes: 29 additions & 0 deletions hr_expense_move_sync/models/hr_expense.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Copyright 2026 Ecosoft Co., Ltd. (http://ecosoft.co.th)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import models


class HrExpense(models.Model):
_inherit = "hr.expense"

def _is_auto_refresh(self):
return self.env.company.auto_refresh_account_moves

def _domain_refresh(self, sheet):
return sheet and sheet.state == "approve" and sheet.account_move_ids

def write(self, vals):
sheets_to_refresh = self.env["hr.expense.sheet"]
# skip_move_refresh is set by account.move button_draft/button_cancel:
# when a move is reset/cancelled, the writes triggered on its expense
# lines are not user edits and must not regenerate the draft move.
if self._is_auto_refresh() and not self.env.context.get("skip_move_refresh"):
for expense in self:
sheet = expense.sheet_id
if expense._domain_refresh(sheet):
sheets_to_refresh |= sheet
res = super().write(vals)
if sheets_to_refresh:
sheets_to_refresh._refresh_account_moves()
return res
39 changes: 39 additions & 0 deletions hr_expense_move_sync/models/hr_expense_sheet.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright 2026 Ecosoft Co., Ltd. (http://ecosoft.co.th)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import models


class HrExpenseSheet(models.Model):
_inherit = "hr.expense.sheet"

def action_sync_account_moves(self):
"""manually regenerate draft account moves
to sync with the current expense line data."""
return self._refresh_account_moves()

def _refresh_account_moves(self):
"""Delete draft account moves (and linked payments) then recreate
them to sync with the current expense line data.

This is called after expense fields that affect the move are
modified while the sheet is in the 'approve' state.
"""
sheets_to_recreate = self.env["hr.expense.sheet"]
for sheet in self:
draft_moves = sheet.sudo().account_move_ids.filtered(
lambda m: m.state == "draft"
)
if not draft_moves:
continue

# Delete linked payments first (company_account flow)
payments = draft_moves.origin_payment_id
if payments:
payments.sudo().unlink()
else:
draft_moves.sudo().unlink()
sheets_to_recreate |= sheet
if sheets_to_recreate:
return sheets_to_recreate._do_create_moves()
return False
15 changes: 15 additions & 0 deletions hr_expense_move_sync/models/res_company.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright 2026 Ecosoft Co., Ltd. (http://ecosoft.co.th)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import fields, models


class ResCompany(models.Model):
_inherit = "res.company"

auto_refresh_account_moves = fields.Boolean(
string="Auto Sync Expense Moves",
default=False,
help="When enabled, editing an approved expense automatically "
"regenerates the linked draft journal entries to stay in sync.",
)
13 changes: 13 additions & 0 deletions hr_expense_move_sync/models/res_config_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright 2026 Ecosoft Co., Ltd. (http://ecosoft.co.th)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import fields, models


class ResConfigSettings(models.TransientModel):
_inherit = "res.config.settings"

auto_refresh_account_moves = fields.Boolean(
related="company_id.auto_refresh_account_moves",
readonly=False,
)
3 changes: 3 additions & 0 deletions hr_expense_move_sync/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"
10 changes: 10 additions & 0 deletions hr_expense_move_sync/readme/CONFIGURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
By default, manual sync is enabled. After approving an expense report,
you can click the **Sync Accounting Entries** button on the expense
sheet to regenerate the draft journal entries with the latest expense
data.

To enable automatic sync, go to **Settings > Expenses** and tick
*Auto-sync expense moves*. When enabled, saving any edit on an approved
expense automatically regenerates the linked draft journal entries.

In both modes, posted or paid journal entries are never affected.
1 change: 1 addition & 0 deletions hr_expense_move_sync/readme/CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Saran Lim. \<<saranl@ecosoft.co.th>\>
4 changes: 4 additions & 0 deletions hr_expense_move_sync/readme/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
This module adds automatic synchronization between approved expense
reports and their linked draft journal entries. When an expense is
edited after approval, the linked vendor bills or journal entries are
regenerated to reflect the changes.
Loading
Loading