Browse Source

Merge 9293c8cf8f into 344f622326

pull/161/merge
Holger Brunn 3 years ago
committed by GitHub
parent
commit
e8dfd6a213
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      .travis.yml
  2. 59
      analytic_entries_report_fiscalyear/README.rst
  3. 4
      analytic_entries_report_fiscalyear/__init__.py
  4. 22
      analytic_entries_report_fiscalyear/__openerp__.py
  5. 52
      analytic_entries_report_fiscalyear/i18n/nl.po
  6. 4
      analytic_entries_report_fiscalyear/models/__init__.py
  7. 132
      analytic_entries_report_fiscalyear/models/analytic_entries_report.py
  8. BIN
      analytic_entries_report_fiscalyear/static/description/icon.png
  9. 4
      analytic_entries_report_fiscalyear/tests/__init__.py
  10. 15
      analytic_entries_report_fiscalyear/tests/test_analytic_entries_report_fiscalyear.py
  11. 36
      analytic_entries_report_fiscalyear/views/analytics_entry_report.xml

1
.travis.yml

@ -37,6 +37,7 @@ before_install:
install:
- git clone https://github.com/OCA/maintainer-quality-tools.git ${HOME}/maintainer-quality-tools
- export PATH=${HOME}/maintainer-quality-tools/travis:${PATH}
- pip install sqlparse
- travis_install_nightly
script:

59
analytic_entries_report_fiscalyear/README.rst

@ -0,0 +1,59 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:alt: License: AGPL-3
=====================================================
Analytic Entries Statistics per fiscal period or year
=====================================================
Standard statistics over analytic entries don't allow grouping per fiscal year
or period. This is partly because this concept doesn't fit analytic entries
completely, as they don't necessarily are connected to a fiscal period.
This addon overrides the standard analytic entries statistics to figure out the
fiscal period based on the linked move line and falls back to the date if
there's none.
Usage
=====
After installation of this module, you'll find filters for the fiscal year and
period.
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/91/8.0
For further information, please visit:
* https://www.odoo.com/forum/help-1
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/analytic_entries_report_fiscalyear/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
`here <https://github.com/OCA/analytic_entries_report_fiscalyear/issues/new?body=module:%20analytic_entries_report_fiscalyear%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Credits
=======
Contributors
------------
* Holger Brunn <hbrunn@therp.nl>
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.

4
analytic_entries_report_fiscalyear/__init__.py

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# © 2015 Therp BV <http://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import models

22
analytic_entries_report_fiscalyear/__openerp__.py

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# © 2015 Therp BV <http://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
"name": "Analytic Entries Statistics per fiscal period or year",
"version": "8.0.1.0.1",
"license": "AGPL-3",
"author": "Odoo Community Association (OCA),Therp BV",
"website": "https://github.com/OCA/account-financial-reporting",
"category": "Accounting & Finance",
"depends": [
'account',
],
"data": [
"views/analytics_entry_report.xml",
],
"external_dependencies": {
'python': [
'sqlparse',
],
},
}

52
analytic_entries_report_fiscalyear/i18n/nl.po

@ -0,0 +1,52 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * analytic_entries_report_fiscalyear
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 6.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-01-17 17:49+0000\n"
"PO-Revision-Date: 2014-01-17 17:49+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: analytic_entries_report_fiscalyear
#: field:analytic.entries.report,period_id:0
msgid "Fiscal period"
msgstr "Fiscale periode"
#. module: analytic_entries_report_fiscalyear
#: view:analytic.entries.report:0
msgid "Period"
msgstr "Periode"
#. module: analytic_entries_report_fiscalyear
#: view:analytic.entries.report:0
msgid "Fiscal year-1"
msgstr "Boekjaar-1"
#. module: analytic_entries_report_fiscalyear
#: view:analytic.entries.report:0
#: field:analytic.entries.report,fiscalyear_id:0
msgid "Fiscal year"
msgstr "Boekjaar"
#. module: analytic_entries_report_fiscalyear
#: model:ir.model,name:analytic_entries_report_fiscalyear.model_analytic_entries_report
msgid "Analytic Entries Statistics"
msgstr "Kostenplaats boekingen analyses"
#. module: analytic_entries_report_fiscalyear
#: view:analytic.entries.report:0
msgid "Period-1"
msgstr "Periode-1"
#. module: analytic_entries_report_fiscalyear
#: view:analytic.entries.report:0
msgid "Fiscal periods"
msgstr "Fiscale perioden"

4
analytic_entries_report_fiscalyear/models/__init__.py

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# © 2015 Therp BV <http://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import analytic_entries_report

132
analytic_entries_report_fiscalyear/models/analytic_entries_report.py

@ -0,0 +1,132 @@
# -*- coding: utf-8 -*-
# © 2015 Therp BV <http://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import collections
try:
import sqlparse
except ImportError as err:
import logging
logging.debug(err)
import datetime
from psycopg2.extensions import AsIs
from dateutil.relativedelta import relativedelta
from openerp import api, models, fields
class AnalyticEntriesReport(models.Model):
_inherit = 'analytic.entries.report'
fiscalyear_id = fields.Many2one('account.fiscalyear', 'Fiscal year')
period_id = fields.Many2one('account.period', 'Fiscal period')
def init(self, cr):
"""Here, we try to be less invasive than the usual blunt overwrite of
the sql view"""
# added joins to account_period & account_move_line
# added appropriate fields to select list and group by
super(AnalyticEntriesReport, self).init(cr)
cr.execute("select pg_get_viewdef(%s::regclass)", (self._table,))
for statement in sqlparse.parse(cr.fetchone()[0]):
current_keyword = None
for token in statement:
if token.is_keyword:
current_keyword = token
if isinstance(token, sqlparse.sql.IdentifierList) and\
current_keyword.value == 'SELECT':
last = None
for last in token:
pass
token.insert_after(last, sqlparse.sql.Token(
sqlparse.tokens.Generic,
',coalesce(ml.period_id, p.id) as period_id,'
'coalesce(p_from_move.fiscalyear_id, p.fiscalyear_id) '
'as fiscalyear_id'
))
if isinstance(
token,
(sqlparse.sql.IdentifierList, sqlparse.sql.Parenthesis)
) and current_keyword.value == 'FROM':
def find_table(token):
if isinstance(token, sqlparse.sql.Identifier) and\
token.get_real_name() == 'account_analytic_line':
return token
if not isinstance(token, collections.Iterable):
return
for child_token in token:
result = find_table(child_token)
if result:
return result
table = find_table(token)
assert table
table.parent.insert_after(table, sqlparse.sql.Token(
sqlparse.tokens.Generic,
' left outer join account_period p '
'on p.special = False and p.date_start <= a.date '
'and p.date_stop >= a.date '
'left outer join account_move_line ml '
'on a.move_id = ml.id '
'left outer join account_period p_from_move '
'on ml.period_id = p_from_move.id '))
if isinstance(token, sqlparse.sql.IdentifierList) and\
current_keyword.value == 'GROUP BY':
last = None
for last in token:
pass
token.insert_after(last, sqlparse.sql.Token(
sqlparse.tokens.Generic,
', coalesce(p_from_move.fiscalyear_id,'
'p.fiscalyear_id),'
'coalesce(ml.period_id, p.id)'))
cr.execute("create or replace view %s as (%s)",
(AsIs(self._table), AsIs(str(statement)[:-1])))
@api.model
def _apply_custom_operators(self, domain):
adjusted_domain = []
for proposition in domain:
if not isinstance(proposition, tuple) and\
not isinstance(proposition, list) or\
len(proposition) != 3:
# we can't use expression.is_leaf here because of our custom
# operator
adjusted_domain.append(proposition)
continue
field, operator, value = proposition
if field.endswith('fiscalyear_id') and operator == 'offset':
date = datetime.date.today() + relativedelta(years=value)
fiscalyear_id = self.env['account.fiscalyear'].find(dt=date)
adjusted_domain.append((field, '=', fiscalyear_id))
elif field.endswith('period_id') and operator == 'offset':
current_period = self.env['account.period'].with_context(
account_period_prefer_normal=True).find()
direction = '>='
if value < 0:
direction = '<='
periods = current_period.search(
[
('date_start', direction, current_period.date_start),
('special', '=', False),
], limit=(abs(value) + 1) or 1, order='date_start ' +
('asc' if direction == '>=' else 'desc')
)
adjusted_domain.append((field, '=', periods[value].id))
else:
adjusted_domain.append(proposition)
return adjusted_domain
@api.model
def read_group(self, domain, fields, groupby, offset=0, limit=None,
orderby=False, lazy=True):
'''Override read_group to respect filters whose domain can't be
computed on the client side'''
adjusted_domain = self._apply_custom_operators(domain)
return super(AnalyticEntriesReport, self).read_group(
adjusted_domain, fields, groupby,
offset=offset, limit=limit, orderby=orderby, lazy=lazy)

BIN
analytic_entries_report_fiscalyear/static/description/icon.png

After

Width: 128  |  Height: 128  |  Size: 9.2 KiB

4
analytic_entries_report_fiscalyear/tests/__init__.py

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# © 2016 Therp BV <http://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import test_analytic_entries_report_fiscalyear

15
analytic_entries_report_fiscalyear/tests/test_analytic_entries_report_fiscalyear.py

@ -0,0 +1,15 @@
# -*- coding: utf-8 -*-
# © 2016 Therp BV <http://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp.tests.common import TransactionCase
class TestAnalyticEntriesReportFiscalyear(TransactionCase):
def test_analytic_entries_report_fiscalyear(self):
self.env['analytic.entries.report'].read_group(
[
('fiscalyear_id', 'offset', 0),
('period_id', 'offset', 0),
],
['period_id'],
['period_id'])

36
analytic_entries_report_fiscalyear/views/analytics_entry_report.xml

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<record id="view_account_analytic_entries_search" model="ir.ui.view">
<field name="model">analytic.entries.report</field>
<field name="inherit_id" ref="account.view_account_analytic_entries_search" />
<field name="arch" type="xml">
<field name="date" position="replace">
<field name="period_id" type="col" />
</field>
</field>
</record>
<record id="view_analytic_entries_report_search" model="ir.ui.view">
<field name="model">analytic.entries.report</field>
<field name="inherit_id" ref="account.view_analytic_entries_report_search" />
<field name="arch" type="xml">
<xpath expr="." position="inside">
<group string="Fiscal periods" name="fiscal_periods">
<filter string="Fiscal year" name="filter_fiscalyear"
domain="[('fiscalyear_id', 'offset', 0)]" />
<filter string="Fiscal year-1" name="filter_fiscalyear-1"
domain="[('fiscalyear_id', 'offset', -1)]" />
<separator />
<filter string="Period" name="filter_period"
domain="[('period_id', 'offset', 0)]" />
<filter string="Period-1" name="filter_period-1"
domain="[('period_id', 'offset', -1)]" />
</group>
</xpath>
</field>
</record>
<record id="account.action_analytic_entries_report" model="ir.actions.act_window">
<field name="context">{'search_default_filter_fiscalyear':1, 'group_by_no_leaf':1, 'search_default_Account':1}</field>
</record>
</data>
</openerp>
Loading…
Cancel
Save