Skip to content

Commit

Permalink
[FIX] clear morethan advance, accounting is mistake
Browse files Browse the repository at this point in the history
  • Loading branch information
Saran440 committed Nov 24, 2023
1 parent 7454475 commit bacb865
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 110 deletions.
155 changes: 56 additions & 99 deletions hr_expense_advance_clearing/models/hr_expense.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
from odoo.tools import float_compare


class HrExpense(models.Model):
Expand All @@ -27,12 +26,13 @@ class HrExpense(models.Model):
help="Expense created from this advance expense line",
)

def _get_product_advance(self):
return self.env.ref("hr_expense_advance_clearing.product_emp_advance", False)

@api.constrains("advance")
def _check_advance(self):
for expense in self.filtered("advance"):
emp_advance = self.env.ref(
"hr_expense_advance_clearing.product_emp_advance"
)
emp_advance = expense._get_product_advance()
if not emp_advance.property_account_expense_id:
raise ValidationError(
_("Employee advance product has no payable account")
Expand All @@ -55,100 +55,57 @@ def _check_advance(self):
def onchange_advance(self):
self.tax_ids = False
if self.advance:
self.product_id = self.env.ref(
"hr_expense_advance_clearing.product_emp_advance"
)

def _get_account_move_line_values(self):
"""Create move line (journal) from clearing"""
move_line_values_by_expense = {}
for expense in self:
advance_to_clear = expense.sheet_id.advance_sheet_residual
move_line_name = (
expense.employee_id.name + ": " + expense.name.split("\n")[0][:64]
)
account_src = expense.account_id
account_dst = expense._get_expense_account_destination()
account_date = (
expense.date
or expense.sheet_id.accounting_date
or fields.Date.context_today(expense)
)
self.product_id = self._get_product_advance()

move_line_values = []
unit_amount = expense.unit_amount or expense.total_amount
quantity = expense.quantity if expense.unit_amount else 1
taxes = expense.tax_ids.with_context(round=True).compute_all(
unit_amount, expense.currency_id, quantity, expense.product_id
)
total_amount = 0.0
total_amount_currency = 0.0
partner_id = (
expense.employee_id.sudo().address_home_id.commercial_partner_id.id
)
# source move line
balance = expense.total_amount_company - expense.amount_tax_company
amount_currency = expense.total_amount - expense.amount_tax
move_line_src = {
"name": move_line_name,
"quantity": expense.quantity or 1,
"debit": balance if balance > 0 else 0,
"credit": -balance if balance < 0 else 0,
"amount_currency": amount_currency,
"account_id": account_src.id,
"product_id": expense.product_id.id,
"product_uom_id": expense.product_uom_id.id,
"analytic_distribution": expense.analytic_distribution,
"expense_id": expense.id,
"partner_id": partner_id,
"tax_ids": [(6, 0, expense.tax_ids.ids)],
"tax_tag_ids": [(6, 0, taxes["base_tags"])],
"currency_id": expense.currency_id.id,
}
move_line_values.append(move_line_src)
total_amount -= expense.total_amount_company
total_amount_currency -= expense.total_amount
def _get_move_line_src(self, move_line_name, partner_id):
self.ensure_one()
unit_amount = self.unit_amount or self.total_amount
quantity = self.quantity if self.unit_amount else 1
taxes = self.tax_ids.with_context(round=True).compute_all(
unit_amount, self.currency_id, quantity, self.product_id
)
amount_currency = self.total_amount - self.amount_tax
balance = self.total_amount_company - self.amount_tax_company
ml_src_dict = {
"name": move_line_name,
"quantity": quantity,
"debit": balance if balance > 0 else 0,
"credit": -balance if balance < 0 else 0,
"amount_currency": amount_currency,
"account_id": self.account_id.id,
"product_id": self.product_id.id,
"product_uom_id": self.product_uom_id.id,
"analytic_distribution": self.analytic_distribution,
"expense_id": self.id,
"partner_id": partner_id,
"tax_ids": [(6, 0, self.tax_ids.ids)],
"tax_tag_ids": [(6, 0, taxes["base_tags"])],
"currency_id": self.currency_id.id,
}
return ml_src_dict

# destination move line
emp_advance = self.env.ref(
"hr_expense_advance_clearing.product_emp_advance"
)
move_line_dst = {
"name": move_line_name,
"debit": total_amount > 0 and total_amount,
"credit": total_amount < 0 and -total_amount,
"account_id": emp_advance.property_account_expense_id.id,
"date_maturity": account_date,
"amount_currency": total_amount_currency,
"currency_id": expense.currency_id.id,
"expense_id": expense.id,
"partner_id": partner_id,
}
# Check clearing > advance, it will split line
credit = move_line_dst["credit"]
# cr payable -> cr advance
remain_payable = 0.0
payable_move_line = []
if (
float_compare(
credit,
advance_to_clear,
precision_rounding=expense.currency_id.rounding,
)
== 1
):
remain_payable = credit - advance_to_clear
move_line_dst["credit"] = advance_to_clear
move_line_dst["amount_currency"] = -advance_to_clear
advance_to_clear = 0.0
# extra payable line
payable_move_line = move_line_dst.copy()
payable_move_line["credit"] = remain_payable
payable_move_line["amount_currency"] = -remain_payable
payable_move_line["account_id"] = account_dst
# Add destination first
move_line_values.append(move_line_dst)
if payable_move_line:
move_line_values.append(payable_move_line)
move_line_values_by_expense[expense.id] = move_line_values
return move_line_values_by_expense
def _get_move_line_dst(
self,
move_line_name,
partner_id,
total_amount,
total_amount_currency,
account_advance,
):
account_date = (
self.date
or self.sheet_id.accounting_date
or fields.Date.context_today(self)
)
ml_dst_dict = {
"name": move_line_name,
"debit": total_amount > 0 and total_amount,
"credit": total_amount < 0 and -total_amount,
"account_id": account_advance.id,
"date_maturity": account_date,
"amount_currency": total_amount_currency,
"currency_id": self.currency_id.id,
"expense_id": self.id,
"partner_id": partner_id,
}
return ml_dst_dict
78 changes: 68 additions & 10 deletions hr_expense_advance_clearing/models/hr_expense_sheet.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,13 @@ def _compute_payment_state(self):
sheet.payment_state = "paid"
return res

def _get_product_advance(self):
return self.env.ref("hr_expense_advance_clearing.product_emp_advance", False)

@api.depends("account_move_id.line_ids.amount_residual")
def _compute_clearing_residual(self):
emp_advance = self.env.ref(
"hr_expense_advance_clearing.product_emp_advance", False
)
for sheet in self:
emp_advance = sheet._get_product_advance()
residual_company = 0.0
if emp_advance:
for line in sheet.sudo().account_move_id.line_ids:
Expand All @@ -99,7 +100,6 @@ def _compute_clearing_count(self):

def action_sheet_move_create(self):
res = super().action_sheet_move_create()
emp_advance = self.env.ref("hr_expense_advance_clearing.product_emp_advance")
for sheet in self:
if not sheet.advance_sheet_id:
continue
Expand All @@ -113,6 +113,7 @@ def action_sheet_move_create(self):
sheet.account_move_id.line_ids
| sheet.advance_sheet_id.account_move_id.line_ids
)
emp_advance = sheet._get_product_advance()
account_id = emp_advance.property_account_expense_id.id
adv_move_lines = (
self.env["account.move.line"]
Expand Down Expand Up @@ -145,6 +146,68 @@ def action_sheet_move_create(self):
)
return res

def _get_move_line_vals(self):
self.ensure_one()
move_line_vals = []
advance_to_clear = self.advance_sheet_residual
emp_advance = self._get_product_advance()
account_advance = emp_advance.property_account_expense_id
for expense in self.expense_line_ids:
move_line_name = (
expense.employee_id.name + ": " + expense.name.split("\n")[0][:64]
)
total_amount = 0.0
total_amount_currency = 0.0
partner_id = (
expense.employee_id.sudo().address_home_id.commercial_partner_id.id
)
# source move line
move_line_src = expense._get_move_line_src(move_line_name, partner_id)
move_line_values = [move_line_src]
total_amount -= expense.total_amount_company
total_amount_currency -= expense.total_amount

# destination move line
move_line_dst = expense._get_move_line_dst(
move_line_name,
partner_id,
total_amount,
total_amount_currency,
account_advance,
)
# Check clearing > advance, it will split line
credit = move_line_dst["credit"]
# cr payable -> cr advance
remain_payable = 0.0
payable_move_line = []
if (
float_compare(
credit,
advance_to_clear,
precision_rounding=expense.currency_id.rounding,
)
== 1
):
remain_payable = credit - advance_to_clear
move_line_dst["credit"] = advance_to_clear
move_line_dst["amount_currency"] = -advance_to_clear
advance_to_clear = 0.0
# extra payable line
payable_move_line = move_line_dst.copy()
payable_move_line["credit"] = remain_payable
payable_move_line["amount_currency"] = -remain_payable
payable_move_line[
"account_id"
] = expense._get_expense_account_destination()
else:
advance_to_clear -= credit
# Add destination first
move_line_values.append(move_line_dst)
if payable_move_line:
move_line_values.append(payable_move_line)
move_line_vals.extend(move_line_values)
return move_line_vals

def _prepare_bill_vals(self):
"""create journal entry instead of bills when clearing document"""
self.ensure_one()
Expand All @@ -157,12 +220,7 @@ def _prepare_bill_vals(self):
_("Advance: %s has no amount to clear") % (self.name)
)
res["move_type"] = "entry"
move_line_vals = []

for expense in self.expense_line_ids:
# get move line values
move_line_values_by_expense = expense._get_account_move_line_values()
move_line_vals.extend(move_line_values_by_expense.get(expense.id))
move_line_vals = self._get_move_line_vals()
res["line_ids"] = [Command.create(x) for x in move_line_vals]
return res

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ def default_get(self, fields_list):
return self._default_return_advance(fields_list)
return super().default_get(fields_list)

def _get_product_advance(self):
return self.env.ref("hr_expense_advance_clearing.product_emp_advance", False)

def _validate_over_return(self):
"""Actual remaining = amount to clear - clear pending
and it is not legit to return more than remaining"""
Expand Down Expand Up @@ -113,7 +116,7 @@ def expense_post_return_advance(self):
ctx = self._context.copy()
ctx.update({"skip_account_move_synchronization": True})
expense_sheet = move_ids.line_ids.expense_id.sheet_id
emp_advance = self.env.ref("hr_expense_advance_clearing.product_emp_advance")
emp_advance = self._get_product_advance()
advance_account = emp_advance.property_account_expense_id
# Create return advance and post it
batches = self._get_batches()
Expand Down

0 comments on commit bacb865

Please sign in to comment.