From ecc60666422e64e52e0b92e850193add491fedf0 Mon Sep 17 00:00:00 2001 From: uso-odoo Date: Fri, 14 Apr 2023 12:59:42 +0530 Subject: [PATCH] [FIX] tools,spreadsheet_account: prevent traceback for day out of month In the 'Accounting Settings' of 'Fisical Year', When the User tries to set 'February' as a month and the 29th as a Day and Save it, It will allow the user to save but when the User opens the spreadsheet dashboard in the terminal, same error will be generated. Steps To Produce:- 1) Install the 'spreadsheet_account' module 2) Go to Settings -> Accounting 3) In the 'Fiscal Periods' of 'Fiscal Year', In 'Last Day' select 'February' month and set 29 as a Day 4) Go to the Accounting module, Customer->Invoices 5) In the 'Favorites', Select 'Insert Link in a Spreadsheet'. 6) Open Spreadsheet, Click on the 'Dashboard' Tab The Error will be generated in Backend(Terminal) Applying these changes will resolve this issue. sentry - 4079962029 closes odoo/odoo#140011 X-original-commit: 1323829d3b5e134300f326f86c887f1cad6119f4 Signed-off-by: Laurent Smet (las) --- addons/spreadsheet_account/models/account.py | 4 ++- odoo/tools/date_utils.py | 32 ++++++++------------ 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/addons/spreadsheet_account/models/account.py b/addons/spreadsheet_account/models/account.py index e5e88de87c3..cdbe2757ec1 100644 --- a/addons/spreadsheet_account/models/account.py +++ b/addons/spreadsheet_account/models/account.py @@ -2,6 +2,7 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from datetime import date +import calendar from dateutil.relativedelta import relativedelta from odoo import models, api, _ @@ -24,7 +25,8 @@ class AccountMove(models.Model): fiscal_month = int(company.fiscalyear_last_month) if not (fiscal_day == 31 and fiscal_month == 12): year += 1 - current = date(year, fiscal_month, fiscal_day) + max_day = calendar.monthrange(year, fiscal_month)[1] + current = date(year, fiscal_month, min(fiscal_day, max_day)) start, end = date_utils.get_fiscal_year(current, fiscal_day, fiscal_month) elif period_type == "month": start = date(year, month, 1) diff --git a/odoo/tools/date_utils.py b/odoo/tools/date_utils.py index 48f99731e93..b66483be614 100644 --- a/odoo/tools/date_utils.py +++ b/odoo/tools/date_utils.py @@ -45,39 +45,33 @@ def get_quarter(date): def get_fiscal_year(date, day=31, month=12): ''' Compute the fiscal year dates range on which the 'date' parameter belongs to. A fiscal year is the period used by governments for accounting purposes and vary between countries. - By default, calling this method with only one parameter gives the calendar year because the ending date of the fiscal year is set to the YYYY-12-31. - :param date: A datetime.datetime or datetime.date object. :param day: The day of month the fiscal year ends. :param month: The month of year the fiscal year ends. :return: A tuple (date_from, date_to) having the same object type as the 'date' parameter. ''' - max_day = calendar.monthrange(date.year, month)[1] - date_to = type(date)(date.year, month, min(day, max_day)) - # Force at 29 February instead of 28 in case of leap year. - if date_to.month == 2 and date_to.day == 28 and max_day == 29: - date_to = type(date)(date.year, 2, 29) + def fix_day(year, month, day): + max_day = calendar.monthrange(year, month)[1] + if (month == 2 and day in (28, max_day)) or (month != 2 and day in (30, max_day)): + return max_day + return min(day, max_day) + + day = fix_day(date.year, month, day) + date_to = type(date)(date.year, month, day) if date <= date_to: date_from = date_to - relativedelta(years=1) - max_day = calendar.monthrange(date_from.year, date_from.month)[1] - - # Force at 29 February instead of 28 in case of leap year. - if date_from.month == 2 and date_from.day == 28 and max_day == 29: - date_from = type(date)(date_from.year, 2, 29) - + day = fix_day(date_from.year, date_from.month, date_from.day) + date_from = type(date)(date_from.year, date_from.month, day) date_from += relativedelta(days=1) else: date_from = date_to + relativedelta(days=1) - max_day = calendar.monthrange(date_to.year + 1, date_to.month)[1] - date_to = type(date)(date.year + 1, month, min(day, max_day)) - - # Force at 29 February instead of 28 in case of leap year. - if date_to.month == 2 and date_to.day == 28 and max_day == 29: - date_to += relativedelta(days=1) + date_to = date_to + relativedelta(years=1) + day = fix_day(date_to.year, date_to.month, date_to.day) + date_to = type(date)(date_to.year, date_to.month, day) return date_from, date_to