Skip to content

Commit

Permalink
[FIX] split line carry commit budget
Browse files Browse the repository at this point in the history
  • Loading branch information
Saran440 committed Jul 25, 2024
1 parent a1e04b1 commit 4b64d5e
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 133 deletions.
45 changes: 9 additions & 36 deletions budget_control/models/analytic_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,44 +192,17 @@ def _auto_create_next_analytic(self, next_date_range):
next_analytic.write(val_update)
return next_analytic

@api.model
def _get_analytic_date(self, analytic_account, order):
"""
Finds the minimum or maximum date of an analytic account.
:param analytic_account: Analytic account record
:param order: The order to search for the earliest or latest date
:return: The earliest or latest date found, or None if no records
"""

# Access the analytic line model
AnalyticAccount = self.env["account.analytic.account"]

# Construct the domain to search for the specific analytic account
domain = [('id', 'in', [analytic_id for analytic_id, _ in analytic_account.items()])]
# Perform the search
result = AnalyticAccount.search(domain, order=order, limit=1)

# Return the date if a record is found, else None
return result

@api.model
def next_year_analytic(self, analytic_distribution, auto_create=True):
def next_year_analytic(self, auto_create=True):
"""Find next analytic from analytic date_to + 1,
if bm_date_to = False, this is an open end analytic, always return False"""
next_analytic_distribution = {}
for analytic_id, aa_percent in analytic_distribution.items():
analytic = self.browse(int(analytic_id))
# Use same analytic
if not analytic.bm_date_to:
next_analytic_distribution[str(analytic_id)] = aa_percent
continue
next_date_range = analytic.bm_date_to + relativedelta(days=1)
next_analytic = analytic._find_next_analytic(next_date_range)
if not next_analytic and auto_create:
next_analytic = analytic._auto_create_next_analytic(next_date_range)
next_analytic_distribution[str(next_analytic.id)] = aa_percent
return next_analytic_distribution
self.ensure_one()
if not self.bm_date_to:
return False
next_date_range = self.bm_date_to + relativedelta(days=1)
next_analytic = self._find_next_analytic(next_date_range)
if not next_analytic and auto_create:
next_analytic = self._auto_create_next_analytic(next_date_range)
return next_analytic

def _check_budget_control_status(self, budget_period_id=False):
"""Warning for budget_control on budget_period, but not in controlled"""
Expand Down
15 changes: 12 additions & 3 deletions budget_control/models/base_budget_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,9 +472,17 @@ def commit_budget(self, reverse=False, **vals):
to_commit = self.env.context.get("force_commit") or self._valid_commit_state()
if self.can_commit and to_commit:
budget_commit_vals = []
analytic_account = self._convert_analytics(
analytic_distribution=vals.get("analytic_distribution", False)
)
# Specific analytic account
if vals.get("analytic_account_id", False):
analytic_account = vals["analytic_account_id"]
else:
analytic_account = self._convert_analytics(
analytic_distribution=vals.get("analytic_distribution", False)
)
# Delete analytic_distribution from vals
if vals.get("analytic_distribution"):
del vals["analytic_distribution"]

for analytic in analytic_account:
# Set amount_currency
budget_vals = self._init_docline_budget_vals(vals, analytic.id)
Expand All @@ -483,6 +491,7 @@ def commit_budget(self, reverse=False, **vals):
# Case force use_amount_commit, this should overwrite tax compute
if self.env.context.get("use_amount_commit"):
budget_vals["amount_currency"] = self.amount_commit
# Case forward_commit
if self.env.context.get("fwd_amount_commit"):
budget_vals["amount_currency"] = self.env.context.get(
"fwd_amount_commit"
Expand Down
125 changes: 61 additions & 64 deletions budget_control/models/budget_commit_forward.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def _compute_missing_analytic(self):
for rec in self:
rec.missing_analytic = any(
rec.forward_line_ids.filtered_domain(
[("to_analytic_distribution", "=", False)]
[("to_analytic_account_id", "=", False)]
)
)

Expand Down Expand Up @@ -98,30 +98,28 @@ def _prepare_vals_forward(self, docs, res_model):
analytic_account = (
doc.fwd_analytic_distribution or doc[doc._budget_analytic_field]
)
# Get analytic min date
analytic_min_date = AnalyticAccount._get_analytic_date(analytic_account, "bm_date_to asc")
method_type = False
to_analytic_account_id = False
if analytic_min_date.bm_date_to and analytic_min_date.bm_date_to < self.to_date_commit:
method_type = "new"

# to_analytic_account_id = analytic.next_year_analytic(
# auto_create=False
# )
value_dict.append(
{
"forward_id": self.id,
"analytic_distribution": analytic_account,
"method_type": method_type,
"res_model": res_model,
"res_id": doc.id,
"document_id": "{},{}".format(doc._name, doc.id),
"document_number": self._get_document_number(doc),
"to_analytic_distribution": {},
"amount_commit": doc.amount_commit,
"date_commit": doc.fwd_date_commit or doc.date_commit,
}
)
for analytic_id, aa_percent in analytic_account.items():
method_type = False
analytic = AnalyticAccount.browse(int(analytic_id))
if (
analytic.bm_date_to
and analytic.bm_date_to < self.to_date_commit
):
method_type = "new"
value_dict.append(
{
"forward_id": self.id,
"analytic_account_id": analytic_id,
"analytic_percent": aa_percent / 100,
"method_type": method_type,
"res_model": res_model,
"res_id": doc.id,
"document_id": "{},{}".format(doc._name, doc.id),
"document_number": self._get_document_number(doc),
"amount_commit": doc.amount_commit * aa_percent / 100,
"date_commit": doc.fwd_date_commit or doc.date_commit,
}
)
return value_dict

def action_review_budget_commit(self):
Expand All @@ -140,13 +138,12 @@ def get_budget_commit_forward(self, res_model):
Line.create(vals)

def create_missing_analytic(self):
AnalyticAccount = self.env["account.analytic.account"]
for rec in self:
for line in rec.forward_line_ids.filtered_domain(
[("to_analytic_distribution", "=", False)]
[("to_analytic_account_id", "=", False)]
):
line.to_analytic_distribution = (
AnalyticAccount.next_year_analytic(line.analytic_distribution)
line.to_analytic_account_id = (
line.analytic_account_id.next_year_analytic()
)

def preview_budget_commit_forward_info(self):
Expand Down Expand Up @@ -184,13 +181,13 @@ def _get_forward_initial_commit(self, domain):
self.ensure_one()
forwards = self.env["budget.commit.forward.line"].read_group(
domain,
["to_analytic_distribution", "amount_commit"],
["to_analytic_distribution"],
orderby="to_analytic_distribution",
)
["to_analytic_account_id", "amount_commit"],
["to_analytic_account_id"],
orderby="to_analytic_account_id",
)
res = [
{
"analytic_distribution": f["to_analytic_distribution"],
"analytic_account_id": f["to_analytic_account_id"][0],
"initial_commit": f["amount_commit"],
}
for f in forwards
Expand All @@ -200,7 +197,7 @@ def _get_forward_initial_commit(self, domain):
def _do_forward_commit(self, reverse=False):
"""Create carry forward budget move to all related documents"""
self = self.sudo()
_analytic_field = "analytic_distribution" if reverse else "to_analytic_distribution"
_analytic_field = "analytic_account_id" if reverse else "to_analytic_account_id"
for rec in self:
group_document = {}
# Group by document
Expand All @@ -210,11 +207,10 @@ def _do_forward_commit(self, reverse=False):
else:
group_document[line.document_id] = [line]
for doc, fwd_line in group_document.items():
# Convert to json
fwd_analytic_distribution = {}
for line in fwd_line:
fwd_analytic_distribution[
str(line[_analytic_field].id)
] = line.analytic_percent
fwd_analytic_distribution[str(line[_analytic_field].id)] = line.analytic_percent * 100
doc.write(
{
"fwd_analytic_distribution": fwd_analytic_distribution,
Expand All @@ -234,12 +230,12 @@ def _do_update_initial_commit(self, reverse=False):
"""Update all Analytic Account's initial commit value related to budget period"""
self.ensure_one()
# Reset initial when cancel document only
Analytic = self.env["account.analytic.account"]
AnalyticAccount = self.env["account.analytic.account"]
domain = [("forward_id", "=", self.id)]
if reverse:
forward_vals = self._get_forward_initial_commit(domain)
for val in forward_vals:
analytic = Analytic.browse(val["analytic_account_id"])
analytic = AnalyticAccount.browse(val["analytic_account_id"])
analytic.initial_commit -= val["initial_commit"]
return
forward_duplicate = self.env["budget.commit.forward"].search(
Expand All @@ -252,7 +248,7 @@ def _do_update_initial_commit(self, reverse=False):
domain.append(("forward_id.state", "in", ["review", "done"]))
forward_vals = self._get_forward_initial_commit(domain)
for val in forward_vals:
analytic = Analytic.browse(val["analytic_account_id"])
analytic = AnalyticAccount.browse(val["analytic_account_id"])
# Check first forward commit in the year, it should overwrite initial commit
if not forward_duplicate:
analytic.initial_commit = val["initial_commit"]
Expand Down Expand Up @@ -296,7 +292,6 @@ def action_draft(self):

class BudgetCommitForwardLine(models.Model):
_name = "budget.commit.forward.line"
_inherit = "analytic.mixin"
_description = "Budget Commit Forward Line"

forward_id = fields.Many2one(
Expand All @@ -307,6 +302,15 @@ class BudgetCommitForwardLine(models.Model):
readonly=True,
ondelete="cascade",
)
analytic_account_id = fields.Many2one(
comodel_name="account.analytic.account",
index=True,
required=True,
readonly=True,
)
analytic_percent = fields.Float(
readonly=True,
)
method_type = fields.Selection(
selection=[
("new", "New"),
Expand All @@ -316,13 +320,13 @@ class BudgetCommitForwardLine(models.Model):
help="New: if the analytic has ended, 'To Analytic Account' is required\n"
"Extended: if the analytic has ended, but want to extend to next period date end",
)
to_analytic_distribution = fields.Json(
string="To Analytic",
compute="_compute_to_analytic_distribution",
to_analytic_account_id = fields.Many2one(
comodel_name="account.analytic.account",
string="Forward to Analytic",
compute="_compute_to_analytic_account_id",
store=True,
)
bm_date_to = fields.Date(
string="Date To",
compute="_compute_bm_date_to",
)
res_model = fields.Selection(
Expand Down Expand Up @@ -362,40 +366,33 @@ class BudgetCommitForwardLine(models.Model):
readonly=True,
)

@api.depends("analytic_distribution")
@api.depends("analytic_account_id")
def _compute_bm_date_to(self):
AnalyticAccount = self.env["account.analytic.account"]
for rec in self:
analytic_min_date = AnalyticAccount._get_analytic_date(rec.analytic_distribution, "bm_date_to asc")
rec.bm_date_to = analytic_min_date.bm_date_to
rec.bm_date_to = rec.analytic_account_id.bm_date_to

@api.depends("method_type")
def _compute_to_analytic_distribution(self):
AnalyticAccount = self.env["account.analytic.account"]
def _compute_to_analytic_account_id(self):
for rec in self:
if not rec.analytic_distribution:
continue
analytic_min_date = AnalyticAccount._get_analytic_date(rec.analytic_distribution, "bm_date_to asc")

# Case analytic has no end date, always use same analytic
if not analytic_min_date.bm_date_to:
rec.to_analytic_distribution = rec.analytic_distribution
if not rec.analytic_account_id.bm_date_to:
rec.to_analytic_account_id = rec.analytic_account_id
rec.method_type = False
continue
# Case analytic has extended end date that cover new commit date, use same analytic
if (
analytic_min_date.bm_date_to
and analytic_min_date.bm_date_to >= rec.forward_id.to_date_commit
rec.analytic_account_id.bm_date_to
and rec.analytic_account_id.bm_date_to >= rec.forward_id.to_date_commit
):
rec.to_analytic_distribution = rec.analytic_distribution
rec.to_analytic_account_id = rec.analytic_account_id
rec.method_type = "extend"
continue
# Case want to extend analytic to end of next budget period
if rec.method_type == "extend":
rec.to_analytic_distribution = rec.analytic_distribution
rec.to_analytic_account_id = rec.analytic_account_id
continue
# Case want to use next analytic, if exists
if rec.method_type == "new":
rec.to_analytic_distribution = AnalyticAccount.next_year_analytic(
rec.analytic_distribution, auto_create=False
rec.to_analytic_account_id = rec.analytic_account_id.next_year_analytic(
auto_create=False
)
12 changes: 8 additions & 4 deletions budget_control/views/budget_commit_forward_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,19 @@
<field name="arch" type="xml">
<tree editable="bottom" create="0">
<field name="document_id" invisible="1" />
<field name="analytic_distribution" widget="analytic_distribution" />
<field name="analytic_account_id" />
<field name="analytic_percent" widget="percentage" optional="show" />
<field name="bm_date_to" optional="hide" />
<field
name="method_type"
optional="show"
attrs="{'required': [('bm_date_to', '!=', False)],
'readonly': [('bm_date_to', '=', False)]}"
/>
<field name="to_analytic_distribution" widget="analytic_distribution" optional="show" />
<field
name="to_analytic_account_id"
optional="show"
/>
<field name="document_number" optional="show" />
<field name="date_commit" />
<field name="currency_id" invisible="1" />
Expand All @@ -46,10 +50,10 @@
<group>
<group>
<field name="document_id" invisible="1" />
<field name="analytic_distribution" />
<field name="analytic_account_id" />
<field name="bm_date_to" invisible="1" />
<field name="method_type" />
<field name="to_analytic_distribution" />
<field name="to_analytic_account_id" />
</group>
<group>
<field name="document_number" />
Expand Down
Loading

0 comments on commit 4b64d5e

Please sign in to comment.