{"action":"created","comment":{"url":"https://api.github.com/repos/acsone/account-financial-reporting/pulls/comments/29059621","id":29059621,"diff_hunk":"@@ -0,0 +1,830 @@\n+# -*- encoding: utf-8 -*-\n+##############################################################################\n+#\n+#    mis_builder module for OpenERP, Management Information System Builder\n+#    Copyright (C) 2014 ACSONE SA/NV (<http://acsone.eu>)\n+#\n+#    This file is a part of mis_builder\n+#\n+#    mis_builder is free software: you can redistribute it and/or modify\n+#    it under the terms of the GNU Affero General Public License v3 or later\n+#    as published by the Free Software Foundation, either version 3 of the\n+#    License, or (at your option) any later version.\n+#\n+#    mis_builder is distributed in the hope that it will be useful,\n+#    but WITHOUT ANY WARRANTY; without even the implied warranty of\n+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+#    GNU Affero General Public License v3 or later for more details.\n+#\n+#    You should have received a copy of the GNU Affero General Public License\n+#    v3 or later along with this program.\n+#    If not, see <http://www.gnu.org/licenses/>.\n+#\n+##############################################################################\n+\n+from datetime import datetime, timedelta\n+from dateutil import parser\n+import traceback\n+import re\n+import pytz\n+\n+from openerp.osv import orm, fields\n+from openerp.tools.safe_eval import safe_eval\n+from openerp.tools.translate import _\n+from openerp import tools\n+from collections import OrderedDict\n+from aep import AccountingExpressionProcessor\n+from openerp.api import Environment\n+\n+\n+class AutoStruct(object):\n+\n+    def __init__(self, **kwargs):\n+        for k, v in kwargs.items():\n+            setattr(self, k, v)\n+\n+\n+def _get_selection_label(selection, value):\n+    for v, l in selection:\n+        if v == value:\n+            return l\n+    return ''\n+\n+\n+def _utc_midnight(d, tz_name, add_day=0):\n+    d = datetime.strptime(d, tools.DEFAULT_SERVER_DATE_FORMAT)\n+    if add_day:\n+        d = d + timedelta(days=add_day)\n+    utc_tz = pytz.timezone('UTC')\n+    context_tz = pytz.timezone(tz_name)\n+    local_timestamp = context_tz.localize(d, is_dst=False)\n+    return datetime.strftime(local_timestamp.astimezone(utc_tz),\n+                             tools.DEFAULT_SERVER_DATETIME_FORMAT)\n+\n+\n+def _python_var(var_str):\n+    return re.sub(r'\\W|^(?=\\d)', '_', var_str).lower()\n+\n+\n+def _is_valid_python_var(name):\n+    return re.match(\"[_A-Za-z][_a-zA-Z0-9]*$\", name)\n+\n+\n+class mis_report_kpi(orm.Model):\n+\n+    \"\"\" A KPI is an element of a MIS report.\n+\n+    In addition to a name and description, it has an expression\n+    to compute it based on queries defined in the MIS report.\n+    It also has various informations defining how to render it\n+    (numeric or percentage or a string, a suffix, divider) and\n+    how to render comparison of two values of the KPI.\n+    KPI are ordered inside the MIS report, as some KPI expressions\n+    can depend on other KPI that need to be computed before.\n+    \"\"\"\n+\n+    _name = 'mis.report.kpi'\n+\n+    _columns = {\n+        'name': fields.char(size=32, required=True,\n+                            string='Name'),\n+        'description': fields.char(required=True,\n+                                   string='Description',\n+                                   translate=True),\n+        'expression': fields.char(required=True,\n+                                  string='Expression'),\n+        'default_css_style': fields.char(\n+            string='Default CSS style'),\n+        'css_style': fields.char(string='CSS style expression'),\n+        'type': fields.selection([('num', _('Numeric')),\n+                                  ('pct', _('Percentage')),\n+                                  ('str', _('String'))],\n+                                 required=True,\n+                                 string='Type'),\n+        'divider': fields.selection([('1e-6', _('µ')),\n+                                     ('1e-3', _('m')),\n+                                     ('1', _('1')),\n+                                     ('1e3', _('k')),\n+                                     ('1e6', _('M'))],\n+                                    string='Factor'),\n+        'dp': fields.integer(string='Rounding'),\n+        'suffix': fields.char(size=16, string='Suffix'),\n+        'compare_method': fields.selection([('diff', _('Difference')),\n+                                            ('pct', _('Percentage')),\n+                                            ('none', _('None'))],\n+                                           required=True,\n+                                           string='Comparison Method'),\n+        'sequence': fields.integer(string='Sequence'),\n+        'report_id': fields.many2one('mis.report', string='Report'),\n+    }\n+\n+    _defaults = {\n+        'type': 'num',\n+        'divider': '1',\n+        'dp': 0,\n+        'compare_method': 'pct',\n+        'sequence': 100,\n+    }\n+\n+    _order = 'sequence'\n+\n+    def _check_name(self, cr, uid, ids, context=None):\n+        for record_name in self.read(cr, uid, ids, ['name']):\n+            if not _is_valid_python_var(record_name['name']):\n+                return False\n+        return True\n+\n+    _constraints = [\n+        (_check_name, 'The name must be a valid python identifier', ['name']),\n+    ]\n+\n+    def onchange_name(self, cr, uid, ids, name, context=None):\n+        res = {}\n+        if name and not _is_valid_python_var(name):\n+            res['warning'] = {\n+                'title': 'Invalid name',\n+                'message': 'The name must be a valid python identifier'}\n+        return res\n+\n+    def onchange_description(self, cr, uid, ids, description, name,\n+                             context=None):\n+        \"\"\" construct name from description \"\"\"\n+        res = {}\n+        if description and not name:\n+            res = {'value': {'name': _python_var(description)}}\n+        return res\n+\n+    def onchange_type(self, cr, uid, ids, kpi_type, context=None):\n+        res = {}\n+        if kpi_type == 'pct':\n+            res['value'] = {'compare_method': 'diff'}\n+        elif kpi_type == 'str':\n+            res['value'] = {'compare_method': 'none',\n+                            'divider': '',\n+                            'dp': 0}\n+        return res\n+\n+    def _render(self, cr, uid, lang_id, kpi, value, context=None):\n+        \"\"\" render a KPI value as a unicode string, ready for display \"\"\"\n+        if kpi.type == 'num':\n+            return self._render_num(cr, uid, lang_id, value, kpi.divider,\n+                                    kpi.dp, kpi.suffix, context=context)\n+        elif kpi.type == 'pct':\n+            return self._render_num(cr, uid, lang_id, value, 0.01,\n+                                    kpi.dp, '%', context=context)\n+        else:\n+            return unicode(value)\n+\n+    def _render_comparison(self, cr, uid, lang_id, kpi, value, base_value,\n+                           average_value, average_base_value, context=None):\n+        \"\"\" render the comparison of two KPI values, ready for display \"\"\"\n+        if value is None or base_value is None:\n+            return ''\n+        if kpi.type == 'pct':\n+            return self._render_num(cr, uid, lang_id, value - base_value, 0.01,\n+                                    kpi.dp, _('pp'), sign='+', context=context)\n+        elif kpi.type == 'num':\n+            if average_value:\n+                value = value / float(average_value)\n+            if average_base_value:\n+                base_value = base_value / float(average_base_value)\n+            if kpi.compare_method == 'diff':\n+                return self._render_num(cr, uid, lang_id, value - base_value,\n+                                        kpi.divider,\n+                                        kpi.dp, kpi.suffix, sign='+',\n+                                        context=context)\n+            elif kpi.compare_method == 'pct' and base_value != 0:\n+                return self._render_num(cr, uid, lang_id,\n+                                        value / base_value - 1, 0.01,\n+                                        kpi.dp, '%', sign='+', context=context)\n+        return ''\n+\n+    def _render_num(self, cr, uid, lang_id, value, divider,\n+                    dp, suffix, sign='-', context=None):\n+        divider_label = _get_selection_label(\n+            self._columns['divider'].selection, divider)\n+        if divider_label == '1':\n+            divider_label = ''\n+        # format number following user language\n+        value = round(value / float(divider or 1), dp) or 0\n+        return '%s %s%s' % (self.pool['res.lang'].format(\n+            cr, uid, lang_id,\n+            '%%%s.%df' % (\n+                sign, dp),\n+            value,\n+            grouping=True,\n+            context=context),\n+            divider_label, suffix or '')\n+\n+\n+class mis_report_query(orm.Model):\n+\n+    \"\"\" A query to fetch data for a MIS report.\n+\n+    A query works on a model and has a domain and list of fields to fetch.\n+    At runtime, the domain is expanded with a \"and\" on the date/datetime field.\n+    \"\"\"\n+\n+    _name = 'mis.report.query'\n+\n+    def _get_field_names(self, cr, uid, ids, name, args, context=None):\n+        res = {}\n+        for query in self.browse(cr, uid, ids, context=context):\n+            field_names = []\n+            for field in query.field_ids:\n+                field_names.append(field.name)\n+            res[query.id] = ', '.join(field_names)\n+        return res\n+\n+    def onchange_field_ids(self, cr, uid, ids, field_ids, context=None):\n+        # compute field_names\n+        field_names = []\n+        for field in self.pool.get('ir.model.fields').read(\n+                cr, uid,\n+                field_ids[0][2],\n+                ['name'],\n+                context=context):\n+            field_names.append(field['name'])\n+        return {'value': {'field_names': ', '.join(field_names)}}\n+\n+    _columns = {\n+        'name': fields.char(size=32, required=True,\n+                            string='Name'),\n+        'model_id': fields.many2one('ir.model', required=True,\n+                                    string='Model'),\n+        'field_ids': fields.many2many('ir.model.fields', required=True,\n+                                      string='Fields to fetch'),\n+        'field_names': fields.function(_get_field_names, type='char',\n+                                       string='Fetched fields name',\n+                                       store={'mis.report.query':\n+                                              (lambda self, cr, uid, ids, c={}:\n+                                               ids, ['field_ids'], 20), }),\n+        'date_field': fields.many2one('ir.model.fields', required=True,\n+                                      string='Date field',\n+                                      domain=[('ttype', 'in',\n+                                               ('date', 'datetime'))]),\n+        'domain': fields.char(string='Domain'),\n+        'report_id': fields.many2one('mis.report', string='Report'),\n+    }\n+\n+    _order = 'name'\n+\n+    def _check_name(self, cr, uid, ids, context=None):\n+        for record_name in self.read(cr, uid, ids, ['name']):\n+            if not _is_valid_python_var(record_name['name']):\n+                return False\n+        return True\n+\n+    _constraints = [\n+        (_check_name, 'The name must be a valid python identifier', ['name']),\n+    ]\n+\n+\n+class mis_report(orm.Model):\n+\n+    \"\"\" A MIS report template (without period information)\n+\n+    The MIS report holds:\n+    * an implicit query fetching all the account balances;\n+      for each account, the balance is stored in a variable named\n+      bal_{code} where {code} is the account code\n+    * an implicit query fetching all the account balances solde;\n+      for each account, the balance solde is stored in a variable named\n+      bals_{code} where {code} is the account code\n+    * a list of explicit queries; the result of each query is\n+      stored in a variable with same name as a query, containing as list\n+      of data structures populated with attributes for each fields to fetch\n+    * a list of KPI to be evaluated based on the variables resulting\n+      from the balance and queries\n+    \"\"\"","path":"mis_builder/models/mis_builder.py","position":299,"original_position":299,"commit_id":"9b0334c4d55d6b6280f6790b8b40be28e85174f3","original_commit_id":"9b0334c4d55d6b6280f6790b8b40be28e85174f3","user":{"login":"sbidoul","id":692075,"avatar_url":"https://avatars.githubusercontent.com/u/692075?v=3","gravatar_id":"","url":"https://api.github.com/users/sbidoul","html_url":"https://github.com/sbidoul","followers_url":"https://api.github.com/users/sbidoul/followers","following_url":"https://api.github.com/users/sbidoul/following{/other_user}","gists_url":"https://api.github.com/users/sbidoul/gists{/gist_id}","starred_url":"https://api.github.com/users/sbidoul/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sbidoul/subscriptions","organizations_url":"https://api.github.com/users/sbidoul/orgs","repos_url":"https://api.github.com/users/sbidoul/repos","events_url":"https://api.github.com/users/sbidoul/events{/privacy}","received_events_url":"https://api.github.com/users/sbidoul/received_events","type":"User","site_admin":false},"body":"Doc to be updated.","created_at":"2015-04-24T15:42:42Z","updated_at":"2015-04-24T15:42:42Z","html_url":"https://github.com/acsone/account-financial-reporting/pull/2#discussion_r29059621","pull_request_url":"https://api.github.com/repos/acsone/account-financial-reporting/pulls/2","_links":{"self":{"href":"https://api.github.com/repos/acsone/account-financial-reporting/pulls/comments/29059621"},"html":{"href":"https://github.com/acsone/account-financial-reporting/pull/2#discussion_r29059621"},"pull_request":{"href":"https://api.github.com/repos/acsone/account-financial-reporting/pulls/2"}}},"pull_request":{"url":"https://api.github.com/repos/acsone/account-financial-reporting/pulls/2","id":34050480,"html_url":"https://github.com/acsone/account-financial-reporting/pull/2","diff_url":"https://github.com/acsone/account-financial-reporting/pull/2.diff","patch_url":"https://github.com/acsone/account-financial-reporting/pull/2.patch","issue_url":"https://api.github.com/repos/acsone/account-financial-reporting/issues/2","number":2,"state":"open","locked":false,"title":"PR for code review","user":{"login":"laetitia-gangloff","id":7602419,"avatar_url":"https://avatars.githubusercontent.com/u/7602419?v=3","gravatar_id":"","url":"https://api.github.com/users/laetitia-gangloff","html_url":"https://github.com/laetitia-gangloff","followers_url":"https://api.github.com/users/laetitia-gangloff/followers","following_url":"https://api.github.com/users/laetitia-gangloff/following{/other_user}","gists_url":"https://api.github.com/users/laetitia-gangloff/gists{/gist_id}","starred_url":"https://api.github.com/users/laetitia-gangloff/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/laetitia-gangloff/subscriptions","organizations_url":"https://api.github.com/users/laetitia-gangloff/orgs","repos_url":"https://api.github.com/users/laetitia-gangloff/repos","events_url":"https://api.github.com/users/laetitia-gangloff/events{/privacy}","received_events_url":"https://api.github.com/users/laetitia-gangloff/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-04-24T13:57:36Z","updated_at":"2015-04-24T15:42:42Z","closed_at":null,"merged_at":null,"merge_commit_sha":"fee043b50df343cdecaeadee8590d42f83b063ea","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/acsone/account-financial-reporting/pulls/2/commits","review_comments_url":"https://api.github.com/repos/acsone/account-financial-reporting/pulls/2/comments","review_comment_url":"https://api.github.com/repos/acsone/account-financial-reporting/pulls/comments{/number}","comments_url":"https://api.github.com/repos/acsone/account-financial-reporting/issues/2/comments","statuses_url":"https://api.github.com/repos/acsone/account-financial-reporting/statuses/9b0334c4d55d6b6280f6790b8b40be28e85174f3","head":{"label":"acsone:8.0-mis-builder-imp-refactor-using-sbi-aep","ref":"8.0-mis-builder-imp-refactor-using-sbi-aep","sha":"9b0334c4d55d6b6280f6790b8b40be28e85174f3","user":{"login":"acsone","id":7601056,"avatar_url":"https://avatars.githubusercontent.com/u/7601056?v=3","gravatar_id":"","url":"https://api.github.com/users/acsone","html_url":"https://github.com/acsone","followers_url":"https://api.github.com/users/acsone/followers","following_url":"https://api.github.com/users/acsone/following{/other_user}","gists_url":"https://api.github.com/users/acsone/gists{/gist_id}","starred_url":"https://api.github.com/users/acsone/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/acsone/subscriptions","organizations_url":"https://api.github.com/users/acsone/orgs","repos_url":"https://api.github.com/users/acsone/repos","events_url":"https://api.github.com/users/acsone/events{/privacy}","received_events_url":"https://api.github.com/users/acsone/received_events","type":"Organization","site_admin":false},"repo":{"id":21983318,"name":"account-financial-reporting","full_name":"acsone/account-financial-reporting","owner":{"login":"acsone","id":7601056,"avatar_url":"https://avatars.githubusercontent.com/u/7601056?v=3","gravatar_id":"","url":"https://api.github.com/users/acsone","html_url":"https://github.com/acsone","followers_url":"https://api.github.com/users/acsone/followers","following_url":"https://api.github.com/users/acsone/following{/other_user}","gists_url":"https://api.github.com/users/acsone/gists{/gist_id}","starred_url":"https://api.github.com/users/acsone/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/acsone/subscriptions","organizations_url":"https://api.github.com/users/acsone/orgs","repos_url":"https://api.github.com/users/acsone/repos","events_url":"https://api.github.com/users/acsone/events{/privacy}","received_events_url":"https://api.github.com/users/acsone/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/acsone/account-financial-reporting","description":"","fork":true,"url":"https://api.github.com/repos/acsone/account-financial-reporting","forks_url":"https://api.github.com/repos/acsone/account-financial-reporting/forks","keys_url":"https://api.github.com/repos/acsone/account-financial-reporting/keys{/key_id}","collaborators_url":"https://api.github.com/repos/acsone/account-financial-reporting/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/acsone/account-financial-reporting/teams","hooks_url":"https://api.github.com/repos/acsone/account-financial-reporting/hooks","issue_events_url":"https://api.github.com/repos/acsone/account-financial-reporting/issues/events{/number}","events_url":"https://api.github.com/repos/acsone/account-financial-reporting/events","assignees_url":"https://api.github.com/repos/acsone/account-financial-reporting/assignees{/user}","branches_url":"https://api.github.com/repos/acsone/account-financial-reporting/branches{/branch}","tags_url":"https://api.github.com/repos/acsone/account-financial-reporting/tags","blobs_url":"https://api.github.com/repos/acsone/account-financial-reporting/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/acsone/account-financial-reporting/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/acsone/account-financial-reporting/git/refs{/sha}","trees_url":"https://api.github.com/repos/acsone/account-financial-reporting/git/trees{/sha}","statuses_url":"https://api.github.com/repos/acsone/account-financial-reporting/statuses/{sha}","languages_url":"https://api.github.com/repos/acsone/account-financial-reporting/languages","stargazers_url":"https://api.github.com/repos/acsone/account-financial-reporting/stargazers","contributors_url":"https://api.github.com/repos/acsone/account-financial-reporting/contributors","subscribers_url":"https://api.github.com/repos/acsone/account-financial-reporting/subscribers","subscription_url":"https://api.github.com/repos/acsone/account-financial-reporting/subscription","commits_url":"https://api.github.com/repos/acsone/account-financial-reporting/commits{/sha}","git_commits_url":"https://api.github.com/repos/acsone/account-financial-reporting/git/commits{/sha}","comments_url":"https://api.github.com/repos/acsone/account-financial-reporting/comments{/number}","issue_comment_url":"https://api.github.com/repos/acsone/account-financial-reporting/issues/comments{/number}","contents_url":"https://api.github.com/repos/acsone/account-financial-reporting/contents/{+path}","compare_url":"https://api.github.com/repos/acsone/account-financial-reporting/compare/{base}...{head}","merges_url":"https://api.github.com/repos/acsone/account-financial-reporting/merges","archive_url":"https://api.github.com/repos/acsone/account-financial-reporting/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/acsone/account-financial-reporting/downloads","issues_url":"https://api.github.com/repos/acsone/account-financial-reporting/issues{/number}","pulls_url":"https://api.github.com/repos/acsone/account-financial-reporting/pulls{/number}","milestones_url":"https://api.github.com/repos/acsone/account-financial-reporting/milestones{/number}","notifications_url":"https://api.github.com/repos/acsone/account-financial-reporting/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/acsone/account-financial-reporting/labels{/name}","releases_url":"https://api.github.com/repos/acsone/account-financial-reporting/releases{/id}","created_at":"2014-07-18T14:40:00Z","updated_at":"2015-04-20T07:43:58Z","pushed_at":"2015-04-24T15:32:54Z","git_url":"git://github.com/acsone/account-financial-reporting.git","ssh_url":"git@github.com:acsone/account-financial-reporting.git","clone_url":"https://github.com/acsone/account-financial-reporting.git","svn_url":"https://github.com/acsone/account-financial-reporting","homepage":null,"size":3988,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"8.0"}},"base":{"label":"acsone:8.0","ref":"8.0","sha":"c4d1738d4fec5d578ac9e5b26d037e4b31902588","user":{"login":"acsone","id":7601056,"avatar_url":"https://avatars.githubusercontent.com/u/7601056?v=3","gravatar_id":"","url":"https://api.github.com/users/acsone","html_url":"https://github.com/acsone","followers_url":"https://api.github.com/users/acsone/followers","following_url":"https://api.github.com/users/acsone/following{/other_user}","gists_url":"https://api.github.com/users/acsone/gists{/gist_id}","starred_url":"https://api.github.com/users/acsone/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/acsone/subscriptions","organizations_url":"https://api.github.com/users/acsone/orgs","repos_url":"https://api.github.com/users/acsone/repos","events_url":"https://api.github.com/users/acsone/events{/privacy}","received_events_url":"https://api.github.com/users/acsone/received_events","type":"Organization","site_admin":false},"repo":{"id":21983318,"name":"account-financial-reporting","full_name":"acsone/account-financial-reporting","owner":{"login":"acsone","id":7601056,"avatar_url":"https://avatars.githubusercontent.com/u/7601056?v=3","gravatar_id":"","url":"https://api.github.com/users/acsone","html_url":"https://github.com/acsone","followers_url":"https://api.github.com/users/acsone/followers","following_url":"https://api.github.com/users/acsone/following{/other_user}","gists_url":"https://api.github.com/users/acsone/gists{/gist_id}","starred_url":"https://api.github.com/users/acsone/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/acsone/subscriptions","organizations_url":"https://api.github.com/users/acsone/orgs","repos_url":"https://api.github.com/users/acsone/repos","events_url":"https://api.github.com/users/acsone/events{/privacy}","received_events_url":"https://api.github.com/users/acsone/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/acsone/account-financial-reporting","description":"","fork":true,"url":"https://api.github.com/repos/acsone/account-financial-reporting","forks_url":"https://api.github.com/repos/acsone/account-financial-reporting/forks","keys_url":"https://api.github.com/repos/acsone/account-financial-reporting/keys{/key_id}","collaborators_url":"https://api.github.com/repos/acsone/account-financial-reporting/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/acsone/account-financial-reporting/teams","hooks_url":"https://api.github.com/repos/acsone/account-financial-reporting/hooks","issue_events_url":"https://api.github.com/repos/acsone/account-financial-reporting/issues/events{/number}","events_url":"https://api.github.com/repos/acsone/account-financial-reporting/events","assignees_url":"https://api.github.com/repos/acsone/account-financial-reporting/assignees{/user}","branches_url":"https://api.github.com/repos/acsone/account-financial-reporting/branches{/branch}","tags_url":"https://api.github.com/repos/acsone/account-financial-reporting/tags","blobs_url":"https://api.github.com/repos/acsone/account-financial-reporting/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/acsone/account-financial-reporting/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/acsone/account-financial-reporting/git/refs{/sha}","trees_url":"https://api.github.com/repos/acsone/account-financial-reporting/git/trees{/sha}","statuses_url":"https://api.github.com/repos/acsone/account-financial-reporting/statuses/{sha}","languages_url":"https://api.github.com/repos/acsone/account-financial-reporting/languages","stargazers_url":"https://api.github.com/repos/acsone/account-financial-reporting/stargazers","contributors_url":"https://api.github.com/repos/acsone/account-financial-reporting/contributors","subscribers_url":"https://api.github.com/repos/acsone/account-financial-reporting/subscribers","subscription_url":"https://api.github.com/repos/acsone/account-financial-reporting/subscription","commits_url":"https://api.github.com/repos/acsone/account-financial-reporting/commits{/sha}","git_commits_url":"https://api.github.com/repos/acsone/account-financial-reporting/git/commits{/sha}","comments_url":"https://api.github.com/repos/acsone/account-financial-reporting/comments{/number}","issue_comment_url":"https://api.github.com/repos/acsone/account-financial-reporting/issues/comments{/number}","contents_url":"https://api.github.com/repos/acsone/account-financial-reporting/contents/{+path}","compare_url":"https://api.github.com/repos/acsone/account-financial-reporting/compare/{base}...{head}","merges_url":"https://api.github.com/repos/acsone/account-financial-reporting/merges","archive_url":"https://api.github.com/repos/acsone/account-financial-reporting/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/acsone/account-financial-reporting/downloads","issues_url":"https://api.github.com/repos/acsone/account-financial-reporting/issues{/number}","pulls_url":"https://api.github.com/repos/acsone/account-financial-reporting/pulls{/number}","milestones_url":"https://api.github.com/repos/acsone/account-financial-reporting/milestones{/number}","notifications_url":"https://api.github.com/repos/acsone/account-financial-reporting/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/acsone/account-financial-reporting/labels{/name}","releases_url":"https://api.github.com/repos/acsone/account-financial-reporting/releases{/id}","created_at":"2014-07-18T14:40:00Z","updated_at":"2015-04-20T07:43:58Z","pushed_at":"2015-04-24T15:32:54Z","git_url":"git://github.com/acsone/account-financial-reporting.git","ssh_url":"git@github.com:acsone/account-financial-reporting.git","clone_url":"https://github.com/acsone/account-financial-reporting.git","svn_url":"https://github.com/acsone/account-financial-reporting","homepage":null,"size":3988,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"8.0"}},"_links":{"self":{"href":"https://api.github.com/repos/acsone/account-financial-reporting/pulls/2"},"html":{"href":"https://github.com/acsone/account-financial-reporting/pull/2"},"issue":{"href":"https://api.github.com/repos/acsone/account-financial-reporting/issues/2"},"comments":{"href":"https://api.github.com/repos/acsone/account-financial-reporting/issues/2/comments"},"review_comments":{"href":"https://api.github.com/repos/acsone/account-financial-reporting/pulls/2/comments"},"review_comment":{"href":"https://api.github.com/repos/acsone/account-financial-reporting/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/acsone/account-financial-reporting/pulls/2/commits"},"statuses":{"href":"https://api.github.com/repos/acsone/account-financial-reporting/statuses/9b0334c4d55d6b6280f6790b8b40be28e85174f3"}}}}