[ENH] account_spread_cost_revenue: add calculate by days feature
This commit is contained in:
parent
fb9f29fc0c
commit
0fdbf6f02c
@ -3,6 +3,7 @@
|
||||
|
||||
import calendar
|
||||
import time
|
||||
from datetime import timedelta
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
@ -44,6 +45,11 @@ class AccountSpread(models.Model):
|
||||
help="Period length for the entries",
|
||||
required=True,
|
||||
)
|
||||
days_calc = fields.Boolean(
|
||||
string="Calculate by days",
|
||||
default=False,
|
||||
help="Use number of days to calculate amount",
|
||||
)
|
||||
use_invoice_line_account = fields.Boolean()
|
||||
credit_account_id = fields.Many2one(
|
||||
"account.account",
|
||||
@ -242,6 +248,7 @@ class AccountSpread(models.Model):
|
||||
self.period_type = self.template_id.period_type
|
||||
if self.template_id.start_date:
|
||||
self.spread_date = self.template_id.start_date
|
||||
self.days_calc = self.template_id.days_calc
|
||||
|
||||
@api.depends("invoice_type", "company_id")
|
||||
def _compute_journal_id(self):
|
||||
@ -368,8 +375,9 @@ class AccountSpread(models.Model):
|
||||
|
||||
for x in range(len(posted_line_ids), number_of_periods):
|
||||
sequence = x + 1
|
||||
date = self._get_last_day_of_month(spread_date)
|
||||
amount = self._compute_board_amount(
|
||||
sequence, unposted_amount, number_of_periods
|
||||
sequence, unposted_amount, number_of_periods, date
|
||||
)
|
||||
amount = self.currency_id.round(amount)
|
||||
rounding = self.currency_id.rounding
|
||||
@ -380,7 +388,7 @@ class AccountSpread(models.Model):
|
||||
"amount": amount,
|
||||
"spread_id": self.id,
|
||||
"name": self._get_spread_entry_name(sequence),
|
||||
"date": self._get_last_day_of_month(spread_date),
|
||||
"date": date,
|
||||
}
|
||||
commands.append((0, False, vals))
|
||||
|
||||
@ -398,22 +406,78 @@ class AccountSpread(models.Model):
|
||||
self.ensure_one()
|
||||
return self.period_number + 1 if month_day != 1 else self.period_number
|
||||
|
||||
@staticmethod
|
||||
def _get_first_day_of_month(spread_date):
|
||||
return spread_date + relativedelta(day=1)
|
||||
|
||||
@staticmethod
|
||||
def _get_last_day_of_month(spread_date):
|
||||
return spread_date + relativedelta(day=31)
|
||||
|
||||
def _compute_board_amount(self, sequence, amount, number_of_periods):
|
||||
def _get_spread_start_date(self, period_type, spread_end_date):
|
||||
self.ensure_one()
|
||||
spread_start_date = spread_end_date + relativedelta(days=1)
|
||||
if period_type == "month":
|
||||
spread_start_date = spread_end_date + relativedelta(day=1)
|
||||
elif period_type == "quarter":
|
||||
spread_start_date = spread_start_date - relativedelta(months=3)
|
||||
elif period_type == "year":
|
||||
spread_start_date = spread_start_date - relativedelta(years=1)
|
||||
spread_start_date = self._get_first_day_of_month(spread_start_date)
|
||||
spread_start_date = max(spread_start_date, self.spread_date)
|
||||
return spread_start_date
|
||||
|
||||
def _get_spread_end_date(self, period_type, period_number, spread_start_date):
|
||||
self.ensure_one()
|
||||
spread_end_date = spread_start_date
|
||||
number_of_periods = (
|
||||
period_number if spread_start_date.day != 1 else period_number - 1
|
||||
)
|
||||
if period_type == "month":
|
||||
spread_end_date = spread_start_date + relativedelta(
|
||||
months=number_of_periods
|
||||
)
|
||||
elif period_type == "quarter":
|
||||
months = number_of_periods * 3
|
||||
spread_end_date = spread_start_date + relativedelta(months=months)
|
||||
elif period_type == "year":
|
||||
spread_end_date = spread_start_date + relativedelta(years=number_of_periods)
|
||||
# calculate by days and not first day of month should compute residual day only
|
||||
if self.days_calc and spread_end_date.day != 1:
|
||||
spread_end_date = spread_end_date - timedelta(days=1)
|
||||
else:
|
||||
spread_end_date = self._get_last_day_of_month(spread_end_date)
|
||||
return spread_end_date
|
||||
|
||||
def _get_amount_per_day(self, amount):
|
||||
self.ensure_one()
|
||||
spread_start_date = self.spread_date
|
||||
spread_end_date = self._get_spread_end_date(
|
||||
self.period_type, self.period_number, spread_start_date
|
||||
)
|
||||
number_of_days = (spread_end_date - spread_start_date).days + 1
|
||||
return amount / number_of_days
|
||||
|
||||
def _compute_board_amount(
|
||||
self, sequence, amount, number_of_periods, spread_end_date
|
||||
):
|
||||
"""Calculates the amount for the spread lines."""
|
||||
self.ensure_one()
|
||||
amount_to_spread = self.total_amount
|
||||
period = self.period_number
|
||||
if sequence != number_of_periods:
|
||||
amount = amount_to_spread / self.period_number
|
||||
amount = amount_to_spread / period
|
||||
if sequence == 1:
|
||||
date = self.spread_date
|
||||
month_days = calendar.monthrange(date.year, date.month)[1]
|
||||
days = month_days - date.day + 1
|
||||
period = self.period_number
|
||||
amount = (amount_to_spread / period) / month_days * days
|
||||
if self.days_calc:
|
||||
spread_start_date = self._get_spread_start_date(
|
||||
self.period_type, spread_end_date
|
||||
)
|
||||
days = (spread_end_date - spread_start_date).days + 1
|
||||
amount = self._get_amount_per_day(amount_to_spread) * days
|
||||
return amount
|
||||
|
||||
def compute_spread_board(self):
|
||||
|
@ -50,6 +50,11 @@ class AccountSpreadTemplate(models.Model):
|
||||
help="Period length for the entries",
|
||||
)
|
||||
start_date = fields.Date()
|
||||
days_calc = fields.Boolean(
|
||||
string="Calculate by days",
|
||||
default=False,
|
||||
help="Use number of days to calculate amount",
|
||||
)
|
||||
auto_spread = fields.Boolean(
|
||||
string="Auto assign template on invoice validate",
|
||||
help="If checked, provide option to auto create spread during "
|
||||
@ -120,6 +125,7 @@ class AccountSpreadTemplate(models.Model):
|
||||
"template_id": self.id,
|
||||
"journal_id": self.spread_journal_id.id,
|
||||
"use_invoice_line_account": self.use_invoice_line_account,
|
||||
"days_calc": self.days_calc,
|
||||
"company_id": company.id,
|
||||
}
|
||||
|
||||
|
@ -249,6 +249,7 @@
|
||||
domain="[('company_id', '=', company_id)]"
|
||||
widget="selection"
|
||||
/>
|
||||
<field name="days_calc" />
|
||||
</group>
|
||||
</group>
|
||||
<notebook name="notebook">
|
||||
|
@ -26,6 +26,7 @@
|
||||
<field name="period_number" />
|
||||
<field name="period_type" />
|
||||
<field name="start_date" />
|
||||
<field name="days_calc" />
|
||||
</group>
|
||||
<group>
|
||||
<field name="use_invoice_line_account" />
|
||||
|
Loading…
Reference in New Issue
Block a user