Skip to content

Commit

Permalink
[MIG] hr_expense_invoice: Migration to 17.0
Browse files Browse the repository at this point in the history
Actions performed:
- Deprecated `hr.expense.reference` field as part of [1].
- Merged the `hr.expense.is_editable` and `hr.expense.sheet_is_editable`
  fields as part of [1].
- Renamed `hr.expense.unit_amount` to `hr.expense.price_unit`.
- Renamed `hr.expense.attachment_number` to `hr.expense.nb_attachment`.
- Renamed `hr.expense.approve_expense_sheets()` to
  `hr.expense.action_approve_expense_sheets()`.
- Renamed `hr.expense.account_move_id` to `hr.expense.account_move_ids`.
- Switched from old %-based string formatting to f-strings.
- Replaced the use of `attrs` in views with their equivalent Python
  expressions as part of [2].
- Adapted the `hr.expense.sheet` records creation in tests.
- Removed the use of `hr.employee.address_home_id` in tests since it has
  been split into multiple fields.

[1]: odoo/odoo#130244
[2]: odoo/odoo#104741
  • Loading branch information
desdelinux authored and xmglord committed Aug 12, 2024
1 parent e658292 commit be9291f
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 171 deletions.
2 changes: 1 addition & 1 deletion hr_expense_invoice/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

{
"name": "Supplier invoices on HR expenses",
"version": "16.0.2.0.0",
"version": "17.0.1.0.0",
"category": "Human Resources",
"author": "Tecnativa, Odoo Community Association (OCA)",
"license": "AGPL-3",
Expand Down
2 changes: 1 addition & 1 deletion hr_expense_invoice/models/account_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def _check_payable_receivable(self):
_self = self.filtered("expense_id")
return super(AccountMoveLine, (self - _self))._check_payable_receivable()

def reconcile(self):
def __reconcile(self):
"""Mark expenses paid by employee having invoice when reconciling them."""
expenses = self.move_id.source_invoice_expense_id
not_paid_expenses = expenses.filtered(lambda x: x.state != "done")
Expand Down
61 changes: 8 additions & 53 deletions hr_expense_invoice/models/hr_expense.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def _prepare_invoice_values(self):
{
"product_id": self.product_id.id,
"name": self.name,
"price_unit": self.unit_amount or self.total_amount,
"price_unit": self.price_unit or self.total_amount,
"quantity": self.quantity,
"account_id": self.account_id.id,
"analytic_distribution": self.analytic_distribution,
Expand All @@ -46,37 +46,11 @@ def _prepare_invoice_values(self):
]
return {
"name": "/",
"ref": self.reference,
"move_type": "in_invoice",
"invoice_date": self.date,
"invoice_line_ids": invoice_lines,
}

def action_move_create(self):
"""Don't let super to create any move:
- Paid by company: there's already the invoice.
- Paid by employee: we create here a journal entry transferring the AP
balance from the invoice partner to the employee.
"""
expenses_with_invoice = self.filtered("invoice_id")
res = super(HrExpense, self - expenses_with_invoice).action_move_create()
# Create AP transfer entry for expenses paid by employees
for expense in expenses_with_invoice:
if expense.payment_mode == "own_account":
move = self.env["account.move"].create(
expense._prepare_own_account_transfer_move_vals()
)
move.action_post()
# reconcile with the invoice
ap_lines = expense.invoice_id.line_ids.filtered(
lambda x: x.display_type == "payment_term"
)
transfer_line = move.line_ids.filtered(
lambda x: x.partner_id == self.invoice_id.partner_id
)
(ap_lines + transfer_line).reconcile()
return res

def _prepare_own_account_transfer_move_vals(self):
self.ensure_one()
self = self.with_company(self.company_id)
Expand All @@ -88,7 +62,7 @@ def _prepare_own_account_transfer_move_vals(self):
],
limit=1,
)
employee_partner = self.employee_id.sudo().address_home_id.commercial_partner_id
employee_partner = self.employee_id.sudo().address_id.commercial_partner_id
invoice_partner = self.invoice_id.partner_id
ap_lines = self.invoice_id.line_ids.filtered(
lambda x: x.display_type == "payment_term"
Expand Down Expand Up @@ -131,7 +105,7 @@ def action_expense_create_invoice(self):
"invoice_id": invoice.id,
"quantity": 1,
"tax_ids": False,
"unit_amount": invoice.amount_total,
"price_unit": invoice.amount_total,
}
)
return True
Expand All @@ -153,27 +127,26 @@ def _onchange_invoice_id(self):
"""
if self.invoice_id:
self.quantity = 1
self.reference = self.invoice_id.name
self.date = self.invoice_id.date
if self.invoice_id.company_id != self.company_id:
# for avoiding to trigger dependent computes
self.company_id = self.invoice_id.company_id.id

# tax_ids put as dependency for assuring this is computed after setting tax_ids
@api.depends("invoice_id", "tax_ids")
def _compute_unit_amount(self):
def _compute_price_unit(self):
with_invoice = self.filtered("invoice_id")
for record in with_invoice:
record.unit_amount = record.invoice_id.amount_total
return super(HrExpense, self - with_invoice)._compute_unit_amount()
record.price_unit = record.invoice_id.amount_total
return super(HrExpense, self - with_invoice)._compute_price_unit()

# tax_ids put as dependency for assuring this is computed after setting tax_ids
@api.depends("invoice_id", "tax_ids")
def _compute_amount(self):
def _compute_total_amount(self):
with_invoice = self.filtered("invoice_id")
for record in with_invoice:
record.total_amount = record.invoice_id.amount_total
return super(HrExpense, self - with_invoice)._compute_amount()
return super(HrExpense, self - with_invoice)._compute_total_amount()

@api.depends("invoice_id")
def _compute_currency_id(self):
Expand All @@ -188,21 +161,3 @@ def _compute_tax_ids(self):
for record in with_invoice:
record.tax_ids = [(5,)]
return super(HrExpense, self - with_invoice)._compute_tax_ids()

@api.depends(
"transfer_move_ids.line_ids.amount_residual",
"transfer_move_ids.line_ids.amount_residual_currency",
)
def _compute_amount_residual(self):
"""Compute the amount residual for expenses paid by employee with invoices."""
applicable_expenses = self.filtered(lambda x: x.transfer_move_ids)
for rec in applicable_expenses:
if not rec.currency_id or rec.currency_id == rec.company_currency_id:
residual_field = "amount_residual"
else:
residual_field = "amount_residual_currency"
payment_term_lines = rec.transfer_move_ids.sudo().line_ids.filtered(
lambda x: x.account_type in ("asset_receivable", "liability_payable")
)
rec.amount_residual = -sum(payment_term_lines.mapped(residual_field))
return super(HrExpense, self - applicable_expenses)._compute_amount_residual()
43 changes: 38 additions & 5 deletions hr_expense_invoice/models/hr_expense_sheet.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,37 @@ class HrExpenseSheet(models.Model):

invoice_count = fields.Integer(compute="_compute_invoice_count")

# TODOMIG:
def _do_create_moves(self):
"""Don't let super to create any move:
- Paid by company: there's already the invoice.
- Paid by employee: we create here a journal entry transferring the AP
balance from the invoice partner to the employee.
"""
expense_sheets_with_invoices = self.filtered(
lambda sheet: all(expense.invoice_id for expense in sheet.expense_line_ids)
)
res = super(
HrExpenseSheet, self - expense_sheets_with_invoices
)._do_create_moves()
# Create AP transfer entry for expenses paid by employees
for expense in expense_sheets_with_invoices.expense_line_ids:
if expense.payment_mode == "own_account":
move = self.env["account.move"].create(
expense._prepare_own_account_transfer_move_vals()
)
move.action_post()
# reconcile with the invoice
ap_lines = expense.invoice_id.line_ids.filtered(
lambda x: x.display_type == "payment_term"
)
transfer_line = move.line_ids.filtered(
lambda x: x.partner_id
== self.expense_line_ids.invoice_id.partner_id
)
(ap_lines + transfer_line).reconcile()
return res

def action_sheet_move_create(self):
"""Perform extra checks and set proper state and payment state according linked
invoices.
Expand All @@ -23,7 +54,7 @@ def action_sheet_move_create(self):
self.filtered(
lambda x: x.expense_line_ids.invoice_id
and x.payment_mode == "company_account"
)._compute_payment_state()
)._compute_from_account_move_ids()
return res

def set_to_paid(self):
Expand All @@ -42,9 +73,8 @@ def _compute_invoice_count(self):

@api.depends(
"expense_line_ids.invoice_id.payment_state",
"expense_line_ids.amount_residual",
)
def _compute_payment_state(self):
def _compute_from_account_move_ids(self):
"""Determine the payment status for lines with expense invoices linked"""
invoice_sheets = self.filtered(lambda x: x.expense_line_ids.invoice_id)
invoice_sheets.payment_state = "not_paid"
Expand All @@ -61,15 +91,18 @@ def _compute_payment_state(self):
else:
lines_with_paid_invoices = len(
lines.filtered(
lambda x: x.transfer_move_ids and x.amount_residual == 0
lambda x: x.transfer_move_ids
# TODOMIG: and x.amount_residual == 0
)
)
lines_with_partial_invoices = 0 # TODO: Consider partial reconciliation
if lines_with_invoices == lines_with_paid_invoices:
sheet.payment_state = "paid"
elif lines_with_paid_invoices or lines_with_partial_invoices:
sheet.payment_state = "partial"
return super(HrExpenseSheet, self - invoice_sheets)._compute_payment_state()
return super(
HrExpenseSheet, self - invoice_sheets
)._compute_from_account_move_ids()

def _validate_expense_invoice(self):
"""Check several criteria that needs to be met for creating the move."""
Expand Down
Loading

0 comments on commit be9291f

Please sign in to comment.