diff --git a/NEWS.rst b/NEWS.rst index ca3104ce09509fea04d3b4d52dbbb4e22a7bae54_TkVXUy5yc3Q=..639f810c23f63f1526b46bf5b538d2e47bdd4018_TkVXUy5yc3Q= 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -2,6 +2,11 @@ Changelog ========= +16.0.1.2.0 +---------- + +Add ``find(date)`` method + 16.0.1.1.0 ---------- diff --git a/__manifest__.py b/__manifest__.py index ca3104ce09509fea04d3b4d52dbbb4e22a7bae54_X19tYW5pZmVzdF9fLnB5..639f810c23f63f1526b46bf5b538d2e47bdd4018_X19tYW5pZmVzdF9fLnB5 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -22,7 +22,7 @@ "name": "Accounting Periods", "license": "AGPL-3", "summary": "Add period accounting concept", - "version": "16.0.1.1.0", + "version": "16.0.1.2.0", "category": "Accounting/Accounting", "author": "XCG Consulting", "website": "https://orbeet.io/", diff --git a/models/account_move.py b/models/account_move.py index ca3104ce09509fea04d3b4d52dbbb4e22a7bae54_bW9kZWxzL2FjY291bnRfbW92ZS5weQ==..639f810c23f63f1526b46bf5b538d2e47bdd4018_bW9kZWxzL2FjY291bnRfbW92ZS5weQ== 100644 --- a/models/account_move.py +++ b/models/account_move.py @@ -18,7 +18,7 @@ # ############################################################################## -from odoo import _, exceptions, fields, models, tools +from odoo import fields, models class AccountMove(models.Model): @@ -46,70 +46,7 @@ for accdoc in self: acc_date = accdoc.date or today - company = accdoc.company_id - period_domain = [ - ("company_id", "=", company.id), - ("date_start", "<=", acc_date), - ("date_effective_cutoff", ">=", acc_date), - ] - - # Periods are ordered by date so selecting the first one is fine. - period = self.env["account.period"].search( - period_domain + [("state", "!=", "done")], - limit=1, - ) - if not period: - # Create missing periods on-the-fly when running tests / DB populate. - if ( - tools.config["test_enable"] - or tools.config["test_file"] - or self.env.context.get("install_demo", False) - or hasattr(self.env.registry, "populated_models") - ) and ( - not self.env.context.get("period_close_enable") - or not self.env["account.period"].search( - period_domain + [("state", "=", "done")], - limit=1, - ) - ): - year_start = acc_date.replace(day=1, month=1) - year_end = acc_date.replace(day=31, month=12) - fiscalyear = ( - self.env["account.fiscal.year"] - .sudo() - .search( - [ - ("company_id", "=", company.id), - ("date_from", "<=", year_start), - ("date_to", ">=", year_end), - ], - limit=1, - ) - ) - if not fiscalyear: - fiscalyear = ( - self.env["account.fiscal.year"] - .sudo() - .create( - { - "company_id": company.id, - "date_from": year_start, - "date_to": year_end, - "name": str(acc_date.year), - } - ) - ) - fiscalyear.create_periods() - period = self.env["account.period"].search( - period_domain + [("state", "!=", "done")], - limit=1, - ) - - else: - raise exceptions.UserError( - _("No period found around %(date)s in the company %(name)s.") - % {"date": acc_date, "name": company.sudo().name} - ) + period = self.env["account.period"].find(date=acc_date) # When we are between the period end and cut-off date, force the # last day of the period. diff --git a/models/account_period.py b/models/account_period.py index ca3104ce09509fea04d3b4d52dbbb4e22a7bae54_bW9kZWxzL2FjY291bnRfcGVyaW9kLnB5..639f810c23f63f1526b46bf5b538d2e47bdd4018_bW9kZWxzL2FjY291bnRfcGVyaW9kLnB5 100644 --- a/models/account_period.py +++ b/models/account_period.py @@ -17,7 +17,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # ############################################################################## -from odoo import api, fields, models +from odoo import _, api, exceptions, fields, models, tools class AccountPeriod(models.Model): @@ -89,3 +89,73 @@ res = super().unlink() date_range_record.unlink() return res + + def find(self, date=None): + if not date: + date = fields.Date.context_today(self) + + company = self.env.company + domain = [ + ("company_id", "=", company.id), + ("date_start", "<=", date), + ("date_effective_cutoff", ">=", date), + ] + period = self.search( + domain + [("state", "!=", "done")], + limit=1, + ) + + if not period: + # Create missing periods on-the-fly when running tests / DB populate. + if ( + tools.config["test_enable"] + or tools.config["test_file"] + or self.env.context.get("install_demo", False) + or hasattr(self.env.registry, "populated_models") + ) and ( + not self.env.context.get("period_close_enable") + or not self.env["account.period"].search( + domain + [("state", "=", "done")], + limit=1, + ) + ): + year_start = date.replace(day=1, month=1) + year_end = date.replace(day=31, month=12) + fiscalyear = ( + self.env["account.fiscal.year"] + .sudo() + .search( + [ + ("company_id", "=", company.id), + ("date_from", "<=", year_start), + ("date_to", ">=", year_end), + ], + limit=1, + ) + ) + if not fiscalyear: + fiscalyear = ( + self.env["account.fiscal.year"] + .sudo() + .create( + { + "company_id": company.id, + "date_from": year_start, + "date_to": year_end, + "name": str(date.year), + } + ) + ) + fiscalyear.create_periods() + period = self.env["account.period"].search( + domain + [("state", "!=", "done")], + limit=1, + ) + + else: + raise exceptions.UserError( + _("No period found around %(date)s in the company %(name)s.") + % {"date": date, "name": company.sudo().name} + ) + + return period diff --git a/tests/test_account_period.py b/tests/test_account_period.py index ca3104ce09509fea04d3b4d52dbbb4e22a7bae54_dGVzdHMvdGVzdF9hY2NvdW50X3BlcmlvZC5weQ==..639f810c23f63f1526b46bf5b538d2e47bdd4018_dGVzdHMvdGVzdF9hY2NvdW50X3BlcmlvZC5weQ== 100644 --- a/tests/test_account_period.py +++ b/tests/test_account_period.py @@ -18,5 +18,7 @@ # ############################################################################## +import datetime + from freezegun import freeze_time @@ -21,6 +23,6 @@ from freezegun import freeze_time -from odoo import exceptions, fields, models +from odoo import exceptions, fields from odoo.tests import tagged from odoo.addons.account.tests.common import AccountTestInvoicingCommon @@ -45,8 +47,10 @@ cls.env = cls.env(context=dict(cls.env.context, period_close_enable=True)) + cls.Period = cls.env["account.period"] + def test_001_invoice_dates_with_periods(self): """Check invoice date corresponding to periods.""" # Dates & period around today. year = fields.Date.from_string(self.today).year @@ -48,9 +52,9 @@ def test_001_invoice_dates_with_periods(self): """Check invoice date corresponding to periods.""" # Dates & period around today. year = fields.Date.from_string(self.today).year - period_today = self._get_period(pivot_date=self.today) + period_today = self.Period.find(date=self.today) # Control: Default dates & period around today. accdoc = self._make_invoice(company=period_today.company_id) @@ -62,7 +66,7 @@ # Force a date on the invoice; ensure period selection follows it. date_2017 = self.today.replace(year=2017) - period_2017 = self._get_period(pivot_date=date_2017) + period_2017 = self.Period.find(date=date_2017) accdoc_2017 = self._make_invoice( invoice_date=date_2017, company=period_2017.company_id ) @@ -86,7 +90,7 @@ """Check the "Close period" dialog box.""" # Find the period around today. We should have one in demo data. - period_today = self._get_period() + period_today = self.Period.find() self.assertEqual(period_today.state, "draft") @@ -118,26 +122,6 @@ } ) - def _get_period(self, pivot_date=None) -> models.Model: - """Find the period around the specified date (defaults to today). - - :return: The period, an Odoo "account.period" record set. - """ - - if pivot_date is None: - pivot_date = self.today - - period = self.env["account.period"].search( - [ - ("company_id", "=", self.env.company.id), - ("date_start", "<=", pivot_date), - ("date_end", ">=", pivot_date), - ("state", "=", "draft"), - ] - ) - self.assertEqual(len(period), 1) - return period - def _make_invoice(self, amount=None, invoice_date=None, post=False, company=None): return self.init_invoice( "out_invoice", @@ -180,3 +164,18 @@ self.assertFalse(date_ranges) self.assertEqual(len(periods), 0) self.assertEqual(len(date_ranges), 0) + + def test_005_find_period(self): + # Today + date_today = datetime.date.today() + period_today_str = self.Period.find().name + period_today_date = datetime.datetime.strptime(period_today_str, "%Y/%m").date() + self.assertEqual(period_today_date.month, date_today.month) + self.assertEqual(period_today_date.year, date_today.year) + + # 2017/02 + date_2017 = datetime.date(2017, 2, 1) + period_2017_str = self.Period.find(date_2017).name + period_2017_date = datetime.datetime.strptime(period_2017_str, "%Y/%m").date() + self.assertEqual(period_2017_date.month, date_2017.month) + self.assertEqual(period_2017_date.year, date_2017.year)