From d1d12574c32a70815c4552c41dfb922f94a9219a Mon Sep 17 00:00:00 2001
From: "Guillaume (guva)" <guva@odoo.com>
Date: Tue, 2 May 2023 11:29:14 +0000
Subject: [PATCH] [FIX] hr_expense: expense{_sheet} state reset move to draft

Override the button_draft method, in order to
reset the expense and expense_sheet state
when resetting a move to draft.

Steps:

- Create an expense
- Submit and approve the report
- Post journal entry and register payment
- Reset the JE to draft
-> The expense and expense sheet states
   remain the same as before resetting
   to draft. They should be respectively
   'approved' and 'post'

opw-3279364

closes odoo/odoo#120286

Signed-off-by: John Laterre (jol) <jol@odoo.com>
---
 addons/hr_expense/models/account_move.py |  6 +++
 addons/hr_expense/tests/test_expenses.py | 60 ++++++++++++++++++++++++
 2 files changed, 66 insertions(+)

diff --git a/addons/hr_expense/models/account_move.py b/addons/hr_expense/models/account_move.py
index 17fbeceeedb3..69c63470b920 100644
--- a/addons/hr_expense/models/account_move.py
+++ b/addons/hr_expense/models/account_move.py
@@ -12,3 +12,9 @@ class AccountMove(models.Model):
             if l.expense_id:
                 l.expense_id.refuse_expense(reason=_("Payment Cancelled"))
         return super().button_cancel()
+
+    def button_draft(self):
+        for line in self.line_ids:
+            if line.expense_id:
+                line.expense_id.sheet_id.write({'state': 'post'})
+        return super().button_draft()
diff --git a/addons/hr_expense/tests/test_expenses.py b/addons/hr_expense/tests/test_expenses.py
index ba660191e1f2..073a110c84ef 100644
--- a/addons/hr_expense/tests/test_expenses.py
+++ b/addons/hr_expense/tests/test_expenses.py
@@ -350,3 +350,63 @@ class TestExpenses(TestExpenseCommon):
             'amount_paid': formatLang(self.env, 11.0, currency_obj=self.env.company.currency_id),
             'currency': self.env.company.currency_id
         })
+
+    def test_reset_move_to_draft(self):
+        """
+        Test the state of an expense and its report
+        after resetting the paid move to draft
+        """
+        # Create expense and report
+        expense = self.env['hr.expense'].create({
+            'name': 'expense_1',
+            'employee_id': self.expense_employee.id,
+            'product_id': self.product_a.id,
+            'unit_amount': 1000.00,
+        })
+        expense.action_submit_expenses()
+        expense_sheet = expense.sheet_id
+
+        self.assertEqual(expense.state, 'draft', 'Expense state must be draft before sheet submission')
+        self.assertEqual(expense_sheet.state, 'draft', 'Sheet state must be draft before submission')
+
+        # Submit report
+        expense_sheet.action_submit_sheet()
+
+        self.assertEqual(expense.state, 'reported', 'Expense state must be reported after sheet submission')
+        self.assertEqual(expense_sheet.state, 'submit', 'Sheet state must be submit after submission')
+
+        # Approve report
+        expense_sheet.approve_expense_sheets()
+
+        self.assertEqual(expense.state, 'approved', 'Expense state must be draft after sheet approval')
+        self.assertEqual(expense_sheet.state, 'approve', 'Sheet state must be draft after approval')
+
+        # Create move
+        expense_sheet.action_sheet_move_create()
+
+        self.assertEqual(expense.state, 'approved', 'Expense state must be draft after posting move')
+        self.assertEqual(expense_sheet.state, 'post', 'Sheet state must be draft after posting move')
+
+        # Pay move
+        move = expense_sheet.account_move_id
+        self.env['account.payment.register'].with_context(active_model='account.move', active_ids=move.ids).create({
+            'amount': 1000.0,
+        })._create_payments()
+
+        self.assertEqual(expense.state, 'done', 'Expense state must be done after payment')
+        self.assertEqual(expense_sheet.state, 'done', 'Sheet state must be done after payment')
+
+        # Reset move to draft
+        move.button_draft()
+
+        self.assertEqual(expense.state, 'approved', 'Expense state must be approved after resetting move to draft')
+        self.assertEqual(expense_sheet.state, 'post', 'Sheet state must be done after resetting move to draft')
+
+        # Post and pay move again
+        move.action_post()
+        self.env['account.payment.register'].with_context(active_model='account.move', active_ids=move.ids).create({
+            'amount': 1000.0,
+        })._create_payments()
+
+        self.assertEqual(expense.state, 'done', 'Expense state must be done after payment')
+        self.assertEqual(expense_sheet.state, 'done', 'Sheet state must be done after payment')
-- 
GitLab