From 8c7d7661d95101846d0de3da16bc4f4039998b70 Mon Sep 17 00:00:00 2001 From: Damien Crier Date: Wed, 27 Apr 2016 15:32:36 +0200 Subject: [PATCH] [ADD] add module "account_fiscal_year" --- account_fiscal_year/README.rst | 78 +++++++++++++++++++ account_fiscal_year/__init__.py | 6 ++ account_fiscal_year/__openerp__.py | 30 +++++++ account_fiscal_year/data/date_range_type.xml | 10 +++ account_fiscal_year/models/__init__.py | 8 ++ account_fiscal_year/models/date_range.py | 25 ++++++ account_fiscal_year/models/date_range_type.py | 12 +++ account_fiscal_year/models/res_company.py | 45 +++++++++++ account_fiscal_year/tests/__init__.py | 6 ++ .../tests/test_account_fiscal_year.py | 54 +++++++++++++ account_fiscal_year/views/date_range_type.xml | 27 +++++++ 11 files changed, 301 insertions(+) create mode 100644 account_fiscal_year/README.rst create mode 100644 account_fiscal_year/__init__.py create mode 100644 account_fiscal_year/__openerp__.py create mode 100644 account_fiscal_year/data/date_range_type.xml create mode 100644 account_fiscal_year/models/__init__.py create mode 100644 account_fiscal_year/models/date_range.py create mode 100644 account_fiscal_year/models/date_range_type.py create mode 100644 account_fiscal_year/models/res_company.py create mode 100644 account_fiscal_year/tests/__init__.py create mode 100644 account_fiscal_year/tests/test_account_fiscal_year.py create mode 100644 account_fiscal_year/views/date_range_type.xml diff --git a/account_fiscal_year/README.rst b/account_fiscal_year/README.rst new file mode 100644 index 00000000..e4cde719 --- /dev/null +++ b/account_fiscal_year/README.rst @@ -0,0 +1,78 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +=================== +Account Fiscal Year +=================== + +This module extends date.range.type to add fiscal_year flag. + +Override official res_company.compute_fiscal_year_dates to get the +fiscal year date start / date end for any given date. +That methods first looks for a date range of type fiscal year that +encloses the give date. +If it does not find it, it falls back on the standard Odoo +technique based on the day/month of end of fiscal year. + +Installation +============ + +Just install it + +Configuration +============= + +Nothing + +Usage +===== + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/{repo_id}/{branch} + +.. repo_id is available in https://github.com/OCA/maintainer-tools/blob/master/tools/repos_with_ids.txt +.. branch is "8.0" for example + +Known issues / Roadmap +====================== + +* ... + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues +`_. In case of trouble, please +check there if your issue has already been reported. If you spotted it first, +help us smashing it by providing a detailed and welcomed feedback. + +Credits +======= + +Images +------ + +* Odoo Community Association: `Icon `_. + +Contributors +------------ + +* Damien Crier +* ... + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit https://odoo-community.org. diff --git a/account_fiscal_year/__init__.py b/account_fiscal_year/__init__.py new file mode 100644 index 00000000..bf8a462e --- /dev/null +++ b/account_fiscal_year/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# Author: Damien Crier +# Copyright 2016 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import models diff --git a/account_fiscal_year/__openerp__.py b/account_fiscal_year/__openerp__.py new file mode 100644 index 00000000..48325cfb --- /dev/null +++ b/account_fiscal_year/__openerp__.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Author: Damien Crier +# Copyright 2016 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +{ + 'name': 'Account Fiscal Year', + 'version': '9.0.0.1.0', + 'category': 'Accounting', + 'author': 'Camptocamp SA,' + 'Odoo Community Association (OCA)', + 'website': 'http://www.camptocamp.com', + 'depends': [ + 'account', + 'date_range' + ], + 'data': [ + 'data/date_range_type.xml', + 'views/date_range_type.xml', + ], + 'test': [ + ], + 'demo': [ + ], + 'qweb': [ + ], + 'installable': True, + 'application': True, + 'auto_install': False, + 'license': 'AGPL-3', +} diff --git a/account_fiscal_year/data/date_range_type.xml b/account_fiscal_year/data/date_range_type.xml new file mode 100644 index 00000000..40ec799a --- /dev/null +++ b/account_fiscal_year/data/date_range_type.xml @@ -0,0 +1,10 @@ + + + + + Fiscal Year + + + + + diff --git a/account_fiscal_year/models/__init__.py b/account_fiscal_year/models/__init__.py new file mode 100644 index 00000000..cd0d2142 --- /dev/null +++ b/account_fiscal_year/models/__init__.py @@ -0,0 +1,8 @@ +# -*- coding: utf-8 -*- +# Author: Damien Crier +# Copyright 2016 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import date_range +from . import date_range_type +from . import res_company diff --git a/account_fiscal_year/models/date_range.py b/account_fiscal_year/models/date_range.py new file mode 100644 index 00000000..45c72a59 --- /dev/null +++ b/account_fiscal_year/models/date_range.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Author: Damien Crier +# Copyright 2016 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from openerp import models +from openerp.tools import (DEFAULT_SERVER_DATETIME_FORMAT) + + +class DateRange(models.Model): + _inherit = 'date.range' + + def find_daterange_fy_start(self, date): + """ + try to find a date range with type 'fiscalyear' + with @param:date <= date_start + """ + fy_id = self.env.ref('account_fiscal_year.fiscalyear') + date_str = date.strftime(DEFAULT_SERVER_DATETIME_FORMAT) + s_args = [ + ('type_id', '=', fy_id.id), + ('date_start', '<=', date_str), + ('company_id', '=', self.company_id.id), + ] + date_range = self.env['date.range'].search(s_args) + return date_range.date_start diff --git a/account_fiscal_year/models/date_range_type.py b/account_fiscal_year/models/date_range_type.py new file mode 100644 index 00000000..f621fd10 --- /dev/null +++ b/account_fiscal_year/models/date_range_type.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +# Author: Damien Crier +# Copyright 2016 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from openerp import models, fields + + +class DateRangeType(models.Model): + _inherit = "date.range.type" + + fiscal_year = fields.Boolean(string='Is fiscal year ?', default=False) diff --git a/account_fiscal_year/models/res_company.py b/account_fiscal_year/models/res_company.py new file mode 100644 index 00000000..b7741b1d --- /dev/null +++ b/account_fiscal_year/models/res_company.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Author: Damien Crier +# Copyright 2016 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from openerp import models, fields, api +from openerp.tools import (DEFAULT_SERVER_DATETIME_FORMAT) + + +class ResCompany(models.Model): + _inherit = 'res.company' + + def find_daterange_fy(self, date): + """ + try to find a date range with type 'fiscalyear' + with @param:date contained in its date_start/date_end interval + """ + fy_id = self.env.ref('account_fiscal_year.fiscalyear') + date_str = date.strftime(DEFAULT_SERVER_DATETIME_FORMAT) + s_args = [ + ('type_id', '=', fy_id.id), + ('date_start', '<=', date_str), + ('date_end', '>=', date_str), + ('company_id', '=', self.id), + ] + date_range = self.env['date.range'].search(s_args) + return date_range + + @api.multi + def compute_fiscalyear_dates(self, date): + """ Computes the start and end dates of the fiscalyear where the given + 'date' belongs to + @param date: a datetime object + @returns: a dictionary with date_from and date_to + """ + self = self[0] + date_range = self.find_daterange_fy(date) + if date_range: + # do stuff and override 'normal' behaviour + return { + 'date_from': fields.Date.from_string(date_range[0].date_start), + 'date_to': fields.Date.from_string(date_range[0].date_end), + } + else: + # fall back to standard Odoo computation + return super(ResCompany, self).compute_fiscalyear_dates(date) diff --git a/account_fiscal_year/tests/__init__.py b/account_fiscal_year/tests/__init__.py new file mode 100644 index 00000000..a3ec533e --- /dev/null +++ b/account_fiscal_year/tests/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# Author: Damien Crier +# Copyright 2016 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import test_account_fiscal_year diff --git a/account_fiscal_year/tests/test_account_fiscal_year.py b/account_fiscal_year/tests/test_account_fiscal_year.py new file mode 100644 index 00000000..ad7c1f5a --- /dev/null +++ b/account_fiscal_year/tests/test_account_fiscal_year.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Author: Damien Crier +# Copyright 2016 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +import openerp.tests.common as common +from openerp import fields +from openerp.tools import (DEFAULT_SERVER_DATE_FORMAT, + DEFAULT_SERVER_DATETIME_FORMAT) + + +def to_odoo_datetime(date): + return date.strftime(DEFAULT_SERVER_DATETIME_FORMAT) + + +def to_odoo_date(date): + return date.strftime(DEFAULT_SERVER_DATE_FORMAT) + + +class TestAccountFiscalYear(common.TransactionCase): + + def setUp(self): + super(TestAccountFiscalYear, self).setUp() + self.today_date = fields.Date.from_string(fields.Date.today()) + self.company = self.env.ref('base.main_company') + + def test_example(self): + demo_date_range = self.env['date.range'].create( + {'name': 'FY%s' % (self.today_date.year), + 'date_start': '%s-01-01' % self.today_date.year, + 'date_end': '%s-12-31' % self.today_date.year, + 'type_id': self.env.ref('account_fiscal_year.fiscalyear').id, + 'company_id': self.company.id, + 'active': True}) + result = self.company.compute_fiscalyear_dates(self.today_date) + self.assertEqual(to_odoo_datetime(result['date_from']), + demo_date_range.date_start) + self.assertEqual(to_odoo_datetime(result['date_to']), + demo_date_range.date_end) + + def test_example2(self): + demo_date_range = self.env['date.range'].create( + {'name': 'FY%s' % (self.today_date.year), + 'date_start': '%s-03-01' % self.today_date.year, + 'date_end': '%s-12-31' % self.today_date.year, + 'type_id': self.env.ref('account_fiscal_year.fiscalyear').id, + 'company_id': self.company.id, + 'active': True}) + result = self.company.compute_fiscalyear_dates(self.today_date) + if to_odoo_date(self.today_date) >= demo_date_range.date_start: + self.assertEqual(to_odoo_datetime(result['date_from']), + demo_date_range.date_start) + self.assertEqual(to_odoo_datetime(result['date_to']), + demo_date_range.date_end) diff --git a/account_fiscal_year/views/date_range_type.xml b/account_fiscal_year/views/date_range_type.xml new file mode 100644 index 00000000..2acc7804 --- /dev/null +++ b/account_fiscal_year/views/date_range_type.xml @@ -0,0 +1,27 @@ + + + + + + date.range.type.tree + date.range.type + + + + + + + + + date.range.type.form + date.range.type + + + + + + + + + +