{"action":"created","comment":{"url":"https://api.github.com/repos/odoo/odoo/pulls/comments/43582795","id":43582795,"diff_hunk":"@@ -0,0 +1,1178 @@\n+# -*- coding: utf-8 -*-\n+# Part of Odoo. See LICENSE file for full copyright and licensing details.\n+\n+from datetime import timedelta\n+from dateutil.relativedelta import relativedelta\n+from operator import itemgetter\n+\n+from odoo import api, fields, models, tools, _\n+from odoo.tools import email_re, email_split\n+from odoo.exceptions import UserError, AccessError\n+\n+from odoo.addons.crm.models import crm_stage\n+from odoo.addons.base.res.res_partner import format_address\n+\n+\n+CRM_LEAD_FIELDS_TO_MERGE = [\n+    'name',\n+    'partner_id',\n+    'campaign_id',\n+    'company_id',\n+    'country_id',\n+    'team_id',\n+    'state_id',\n+    'stage_id',\n+    'medium_id',\n+    'source_id',\n+    'user_id',\n+    'title',\n+    'city',\n+    'contact_name',\n+    'description',\n+    'email',\n+    'fax',\n+    'mobile',\n+    'partner_name',\n+    'phone',\n+    'probability',\n+    'planned_revenue',\n+    'street',\n+    'street2',\n+    'zip',\n+    'create_date',\n+    'date_action_last',\n+    'date_action_next',\n+    'email_from',\n+    'email_cc',\n+    'partner_name']\n+\n+\n+class CrmLead(format_address, models.Model):\n+    \"\"\" CRM Lead Case \"\"\"\n+    _name = \"crm.lead\"\n+    _description = \"Lead/Opportunity\"\n+    _order = \"priority desc,date_action,id desc\"\n+    _inherit = ['mail.thread', 'ir.needaction_mixin', 'utm.mixin']\n+    _mail_mass_mailing = _('Leads / Opportunities')\n+\n+    def _default_get_stage_id(self):\n+        \"\"\" Gives default stage_id \"\"\"\n+        team = self.env['crm.team'].sudo()._get_default_team_id(user_id=self.env.uid)\n+        return self.stage_find(team.id, [('fold', '=', False)])\n+\n+    partner_id = fields.Many2one('res.partner', string='Partner', track_visibility='onchange',\n+            index=True, help=\"Linked partner (optional). Usually created when converting the lead.\")\n+\n+    name = fields.Char(string='Opportunity', required=True, index=True)\n+    active = fields.Boolean(default=True)\n+    date_action_last = fields.Datetime(string='Last Action', readonly=True)\n+    date_action_next = fields.Datetime(string='Next Action', readonly=True)\n+    email_from = fields.Char(string='Email', size=128, help=\"Email address of the contact\", index=True)\n+    team_id = fields.Many2one('crm.team', string='Sales Team', oldname='section_id', default=lambda self: self.env['crm.team'].sudo()._get_default_team_id(user_id=self.env.uid),\n+                        index=True, track_visibility='onchange', help='When sending mails, the default email address is taken from the sales team.')\n+    create_date = fields.Datetime(string='Creation Date', readonly=True)\n+    email_cc = fields.Text(string='Global CC', help=\"These email addresses will be added to the CC field of all inbound and outbound emails for this record before being sent. Separate multiple email addresses with a comma\")\n+    description = fields.Text(string='Notes')\n+    write_date = fields.Datetime(string='Update Date', readonly=True)\n+    tag_ids = fields.Many2many('crm.lead.tag', 'crm_lead_tag_rel', 'lead_id', 'tag_id', string='Tags', help=\"Classify and analyze your lead/opportunity categories like: Training, Service\")\n+    contact_name = fields.Char(string='Contact Name')\n+    partner_name = fields.Char(string=\"Customer Name\", help='The name of the future partner company that will be created while converting the lead into opportunity', index=True)\n+    opt_out = fields.Boolean(string='Opt-Out', oldname='optout',\n+            help=\"If opt-out is checked, this contact has refused to receive emails for mass mailing and marketing campaign. \"\n+                    \"Filter 'Available for Mass Mailing' allows users to filter the leads when performing mass mailing.\")\n+    lead_type = fields.Selection(\n+            [('lead', 'Lead'), ('opportunity', 'Opportunity')],\n+            string='Lead Type', index=True, required=True, default=lambda self: 'lead' if self.env['res.users'].has_group('crm.group_use_lead') else 'opportunity',\n+            help=\"Lead Type is used to separate Leads and Opportunities\", oldname='type')\n+    priority = fields.Selection(crm_stage.AVAILABLE_PRIORITIES, string='Rating', index=True, default=lambda *a: crm_stage.AVAILABLE_PRIORITIES[0][0])\n+    date_closed = fields.Datetime(string='Closed', readonly=True, copy=False)\n+    stage_id = fields.Many2one('crm.stage', string='Stage', track_visibility='onchange', index=True,\n+                        domain=\"['&', ('team_ids', '=', team_id), '|', ('stage_type', '=', lead_type), ('stage_type', '=', 'both')]\", default=lambda self: self._default_get_stage_id())\n+    user_id = fields.Many2one('res.users', string='Salesperson', index=True, track_visibility='onchange', default=lambda self: self.env.user)\n+    referred = fields.Char(string='Referred By')\n+    date_open = fields.Datetime(string='Assigned', readonly=True)\n+    day_open = fields.Float(compute='_compute_day', string='Days to Assign', store=True)\n+    day_close = fields.Float(compute='_compute_day', string='Days to Close', store=True)\n+    date_last_stage_update = fields.Datetime(string='Last Stage Update', index=True, default=fields.Datetime.now)\n+    date_conversion = fields.Datetime(string='Conversion Date', readonly=True)\n+\n+    # Messaging and marketing\n+    message_bounce = fields.Integer('Bounce', help=\"Counter of the number of bounced emails for this contact\")\n+    # Only used for type opportunity\n+    probability = fields.Float(group_operator=\"avg\", default=10)\n+    planned_revenue = fields.Float(string='Expected Revenue', track_visibility='always')\n+    phone = fields.Char()\n+    date_deadline = fields.Date(string='Expected Closing', help=\"Estimate of the date on which the opportunity will be won.\")\n+        # CRM Actions\n+    last_activity_id = fields.Many2one(\"crm.activity\", string=\"Last Activity\", index=True)\n+    next_activity_id = fields.Many2one(\"crm.activity\", string=\"Next Activity\", index=True)\n+    next_activity_1 = fields.Char(related=\"last_activity_id.activity_1_id.name\", string=\"Next Activity 1\")\n+    next_activity_2 = fields.Char(related=\"last_activity_id.activity_2_id.name\", string=\"Next Activity 2\")\n+    next_activity_3 = fields.Char(related=\"last_activity_id.activity_3_id.name\", string=\"Next Activity 3\")\n+    date_action = fields.Date(string='Next Activity Date', index=True)\n+    title_action = fields.Char(string='Next Activity Summary')\n+\n+    color = fields.Integer(string='Color Index', default=0)\n+    partner_address_name = fields.Char(related='partner_id.name', string='Partner Contact Name', readonly=True)\n+    partner_address_email = fields.Char(related='partner_id.email', string='Partner Contact Email', readonly=True)\n+    company_currency = fields.Many2one(related='company_id.currency_id', string='Currency', readonly=True, relation=\"res.currency\")\n+    user_email = fields.Char(related='user_id.email', string='User Email', readonly=True)\n+    user_login = fields.Char(related='user_id.login', string='User Login', readonly=True)\n+\n+    # Fields for address, due to separation from crm and res.partner\n+    street = fields.Char()\n+    street2 = fields.Char()\n+    zip = fields.Char(change_default=True, size=24)\n+    city = fields.Char()\n+    state_id = fields.Many2one(\"res.country.state\", string='State')\n+    country_id = fields.Many2one('res.country', string='Country')\n+    phone = fields.Char()\n+    fax = fields.Char()\n+    mobile = fields.Char()\n+    function = fields.Char()\n+    title = fields.Many2one('res.partner.title')\n+    company_id = fields.Many2one('res.company', string='Company', index=True, default=lambda self: self.env.user.company_id.id)\n+    meeting_count = fields.Integer(compute='_compute_meeting_count', string='# Meetings')\n+    lost_reason = fields.Many2one('crm.lost.reason', string='Lost Reason', index=True, track_visibility='onchange')\n+\n+    _sql_constraints = [\n+        ('check_probability', 'check(probability >= 0 and probability <= 100)', 'The probability of closing the deal should be between 0% and 100%!')\n+    ]\n+\n+    @api.depends('date_open', 'date_closed')\n+    def _compute_day(self):\n+        \"\"\"\n+        Compute difference between current date and log date\n+        \"\"\"\n+        for lead in self:\n+            if lead.date_open:\n+                date_create = fields.Datetime.from_string(lead.create_date)\n+                date_open = fields.Datetime.from_string(lead.date_open)\n+                ans = date_open - date_create\n+                lead.day_open = abs(int(ans.days))\n+\n+            if lead.date_closed:\n+                date_create = fields.Datetime.from_string(lead.create_date)\n+                date_close = fields.Datetime.from_string(lead.date_closed)\n+                ans = date_close - date_create\n+                lead.day_close = abs(int(ans.days))\n+\n+    def _compute_meeting_count(self):\n+        self.meeting_count = self.env['calendar.event'].search_count([('opportunity_id', '=', self.id)])\n+\n+    @api.onchange('partner_id')\n+    def on_change_partner_id(self):\n+        partner = self.partner_id\n+        self.partner_name = partner.parent_id.name or partner.is_company and partner.name\n+        self.contact_name = (not partner.is_company and partner.name) or False\n+        self.title = partner.title\n+        self.street = partner.street\n+        self.street2 = partner.street2\n+        self.city = partner.city\n+        self.state_id = partner.state_id.id\n+        self.country_id = partner.country_id.id\n+        self.email_from = partner.email\n+        self.phone = partner.phone\n+        self.mobile = partner.mobile\n+        self.fax = partner.fax\n+        self.zip = partner.zip\n+        self.function = partner.function\n+\n+    @api.onchange('user_id')\n+    def on_change_user(self):\n+        \"\"\" When changing the user, also set a team_id or restrict team id\n+            to the ones user_id is member of. \"\"\"\n+        self.team_id = self.env['crm.team']._get_default_team_id(user_id=self.user_id.id)\n+\n+    @api.onchange('state_id')\n+    def onchange_state(self):\n+        self.country_id = self.state_id.country_id.id\n+\n+    @api.onchange('next_activity_id')\n+    def onchange_next_activity_id(self):\n+        activity = self.next_activity_id\n+        self.next_activity_1 = activity.activity_1_id.name\n+        self.next_activity_2 = activity.activity_2_id.name\n+        self.next_activity_3 = activity.activity_3_id.name\n+        self.title_action = activity.description\n+        self.date_action = fields.Datetime.to_string(fields.Datetime.from_string(fields.Datetime.now()) + timedelta(days=activity.days)) if activity.days else False\n+        self.last_activity_id = False\n+\n+    @api.multi\n+    def onchange_stage_id(self, stage_id=False):\n+        if not stage_id:\n+            return\n+        stage = self.env['crm.stage'].browse(stage_id)\n+        if not stage.on_change:\n+            return\n+        for lead in self:\n+            lead.probability = stage.probability\n+\n+    @api.model\n+    def fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False):\n+        opportunity_id = self.env.context.get('opportunity_id')\n+        if opportunity_id:\n+            action = self._get_formview_action(opportunity_id)\n+            if action.get('views') and any(view_id for view_id in action['views'] if view_id[1] == view_type):\n+                view_id = next(view_id[0] for view_id in action['views'] if view_id[1] == view_type)\n+        res = super(CrmLead, self).fields_view_get(view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu)\n+        if view_type == 'form':\n+            res['arch'] = self.fields_view_get_address(res['arch'])\n+        return res\n+\n+    @api.model\n+    def create(self, vals):\n+        ctx = dict(self.env.context)\n+        if vals.get('lead_type') and not ctx.get('default_lead_type'):\n+            ctx['default_lead_type'] = vals.get('lead_type')\n+        if vals.get('team_id') and not ctx.get('default_team_id'):\n+            ctx['default_team_id'] = vals.get('team_id')\n+        if vals.get('user_id') and 'date_open' not in vals:\n+            vals['date_open'] = fields.Datetime.now()\n+\n+        # context: no_log, because subtype already handle this\n+        ctx['mail_create_nolog'] = True\n+        return super(CrmLead, self.with_context(ctx)).create(vals)\n+\n+    @api.multi\n+    def write(self, vals):\n+        # stage change: update date_last_stage_update\n+        if 'stage_id' in vals:\n+            vals['date_last_stage_update'] = fields.Datetime.now()\n+        if vals.get('user_id') and 'date_open' not in vals:\n+            vals['date_open'] = fields.Datetime.now()\n+        # stage change with new stage: update probability and date_closed\n+        if vals.get('stage_id') and 'probability' not in vals:\n+            self.onchange_stage_id(vals.get('stage_id'))\n+        if vals.get('probability') >= 100 or not vals.get('active', True):\n+            vals['date_closed'] = fields.Datetime.now()\n+        return super(CrmLead, self).write(vals)\n+\n+    @api.one\n+    def copy(self, default=None):\n+        if not default:\n+            default = {}\n+        if self.lead_type == 'opportunity':\n+            default['date_open'] = fields.Datetime.now()\n+        else:\n+            default['date_open'] = False\n+        return super(CrmLead, self.with_context(default_lead_type=self.lead_type, default_team_id=self.team_id.id)).copy(default=default)\n+\n+    @api.multi\n+    def redirect_opportunity_view(self):\n+        # Get opportunity views\n+        self.ensure_one()\n+        form_view = self.env.ref('crm.crm_case_form_view_oppor')\n+        tree_view = self.env.ref('crm.crm_case_tree_view_oppor')\n+        return {\n+            'name': _('Opportunity'),\n+            'view_type': 'form',\n+            'view_mode': 'tree, form',\n+            'res_model': 'crm.lead',\n+            'domain': [('lead_type', '=', 'opportunity')],\n+            'res_id': self.id,\n+            'view_id': False,\n+            'views': [(form_view.id, 'form'),\n+                      (tree_view.id, 'tree'), (False, 'kanban'),\n+                      (False, 'calendar'), (False, 'graph')],\n+            'type': 'ir.actions.act_window',\n+            'context': {'default_lead_type': 'opportunity'}\n+        }\n+\n+    @api.multi\n+    def redirect_lead_view(self):\n+        # Get lead views\n+        self.ensure_one()\n+        form_view = self.env.ref('crm.crm_case_form_view_leads')\n+        tree_view = self.env.ref('crm.crm_case_tree_view_leads')\n+        return {\n+            'name': _('Lead'),\n+            'view_type': 'form',\n+            'view_mode': 'tree, form',\n+            'res_model': 'crm.lead',\n+            'domain': [('lead_type', '=', 'lead')],\n+            'res_id': self.id,\n+            'view_id': False,\n+            'views': [(form_view.id, 'form'),\n+                      (tree_view.id, 'tree'),\n+                      (False, 'calendar'), (False, 'graph')],\n+            'type': 'ir.actions.act_window',\n+        }\n+\n+    @api.multi\n+    def action_schedule_meeting(self):\n+        \"\"\"\n+        Open meeting's calendar view to schedule meeting on current opportunity.\n+        :return dict: dictionary value for created Meeting view\n+        \"\"\"\n+        self.ensure_one()\n+        res = self.env['ir.actions.act_window'].for_xml_id('calendar', 'action_calendar_event')\n+        partner_ids = [self.env.user.partner_id.id]\n+        if self.partner_id:\n+            partner_ids.append(self.partner_id.id)\n+        res['context'] = {\n+            'search_default_opportunity_id': self.lead_type == 'opportunity' and self.id or False,\n+            'default_opportunity_id': self.lead_type == 'opportunity' and self.id or False,\n+            'default_partner_id': self.partner_id.id,\n+            'default_partner_ids': partner_ids,\n+            'default_team_id': self.team_id.id,\n+            'default_name': self.name,\n+        }\n+        return res\n+\n+    @api.multi\n+    def action_set_lost(self):\n+        \"\"\" Lost semantic: probability = 0, active = False \"\"\"\n+        return self.write({'probability': 0, 'active': False})\n+    # Backward compatibility\n+    case_mark_lost = action_set_lost\n+\n+    @api.multi\n+    def action_set_active(self):\n+        return self.write({'active': True})\n+\n+    @api.multi\n+    def action_set_unactive(self):\n+        return self.write({'active': False})\n+\n+    @api.multi\n+    def action_set_won(self):\n+        \"\"\" Won semantic: probability = 100 (active untouched) \"\"\"\n+        stages_leads = {}\n+        for lead in self:\n+            stage_id = lead.stage_find(lead.team_id.id or False, [('probability', '=', 100.0), ('on_change', '=', True)])","path":"addons/crm/models/crm_lead.py","position":343,"original_position":343,"commit_id":"e96763db94a25c902652fab5ba20df9574bc221e","original_commit_id":"e96763db94a25c902652fab5ba20df9574bc221e","user":{"login":"atp-odoo","id":7599410,"avatar_url":"https://avatars.githubusercontent.com/u/7599410?v=3","gravatar_id":"","url":"https://api.github.com/users/atp-odoo","html_url":"https://github.com/atp-odoo","followers_url":"https://api.github.com/users/atp-odoo/followers","following_url":"https://api.github.com/users/atp-odoo/following{/other_user}","gists_url":"https://api.github.com/users/atp-odoo/gists{/gist_id}","starred_url":"https://api.github.com/users/atp-odoo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/atp-odoo/subscriptions","organizations_url":"https://api.github.com/users/atp-odoo/orgs","repos_url":"https://api.github.com/users/atp-odoo/repos","events_url":"https://api.github.com/users/atp-odoo/events{/privacy}","received_events_url":"https://api.github.com/users/atp-odoo/received_events","type":"User","site_admin":false},"body":"no need to use False, team_id is recordset(s).\r\nlike this way: \r\n  lead.stage_find(lead.team_id.id,  [('probability', '=', 100.0), ('on_change', '=', True)])","created_at":"2015-11-01T13:53:47Z","updated_at":"2015-11-01T13:53:47Z","html_url":"https://github.com/odoo/odoo/pull/8955#discussion_r43582795","pull_request_url":"https://api.github.com/repos/odoo/odoo/pulls/8955","_links":{"self":{"href":"https://api.github.com/repos/odoo/odoo/pulls/comments/43582795"},"html":{"href":"https://github.com/odoo/odoo/pull/8955#discussion_r43582795"},"pull_request":{"href":"https://api.github.com/repos/odoo/odoo/pulls/8955"}}},"pull_request":{"url":"https://api.github.com/repos/odoo/odoo/pulls/8955","id":47127025,"html_url":"https://github.com/odoo/odoo/pull/8955","diff_url":"https://github.com/odoo/odoo/pull/8955.diff","patch_url":"https://github.com/odoo/odoo/pull/8955.patch","issue_url":"https://api.github.com/repos/odoo/odoo/issues/8955","number":8955,"state":"open","locked":false,"title":"CRM: migrate into new api","user":{"login":"hmo-odoo","id":6368068,"avatar_url":"https://avatars.githubusercontent.com/u/6368068?v=3","gravatar_id":"","url":"https://api.github.com/users/hmo-odoo","html_url":"https://github.com/hmo-odoo","followers_url":"https://api.github.com/users/hmo-odoo/followers","following_url":"https://api.github.com/users/hmo-odoo/following{/other_user}","gists_url":"https://api.github.com/users/hmo-odoo/gists{/gist_id}","starred_url":"https://api.github.com/users/hmo-odoo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hmo-odoo/subscriptions","organizations_url":"https://api.github.com/users/hmo-odoo/orgs","repos_url":"https://api.github.com/users/hmo-odoo/repos","events_url":"https://api.github.com/users/hmo-odoo/events{/privacy}","received_events_url":"https://api.github.com/users/hmo-odoo/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-10-08T08:59:40Z","updated_at":"2015-11-01T13:53:47Z","closed_at":null,"merged_at":null,"merge_commit_sha":"7dfed7e8c854cd9f4868afd0a90665e30d2f8556","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/odoo/odoo/pulls/8955/commits","review_comments_url":"https://api.github.com/repos/odoo/odoo/pulls/8955/comments","review_comment_url":"https://api.github.com/repos/odoo/odoo/pulls/comments{/number}","comments_url":"https://api.github.com/repos/odoo/odoo/issues/8955/comments","statuses_url":"https://api.github.com/repos/odoo/odoo/statuses/e96763db94a25c902652fab5ba20df9574bc221e","head":{"label":"odoo-dev:master-crm-new-api-apa","ref":"master-crm-new-api-apa","sha":"e96763db94a25c902652fab5ba20df9574bc221e","user":{"login":"odoo-dev","id":7466976,"avatar_url":"https://avatars.githubusercontent.com/u/7466976?v=3","gravatar_id":"","url":"https://api.github.com/users/odoo-dev","html_url":"https://github.com/odoo-dev","followers_url":"https://api.github.com/users/odoo-dev/followers","following_url":"https://api.github.com/users/odoo-dev/following{/other_user}","gists_url":"https://api.github.com/users/odoo-dev/gists{/gist_id}","starred_url":"https://api.github.com/users/odoo-dev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/odoo-dev/subscriptions","organizations_url":"https://api.github.com/users/odoo-dev/orgs","repos_url":"https://api.github.com/users/odoo-dev/repos","events_url":"https://api.github.com/users/odoo-dev/events{/privacy}","received_events_url":"https://api.github.com/users/odoo-dev/received_events","type":"Organization","site_admin":false},"repo":{"id":19853934,"name":"odoo","full_name":"odoo-dev/odoo","owner":{"login":"odoo-dev","id":7466976,"avatar_url":"https://avatars.githubusercontent.com/u/7466976?v=3","gravatar_id":"","url":"https://api.github.com/users/odoo-dev","html_url":"https://github.com/odoo-dev","followers_url":"https://api.github.com/users/odoo-dev/followers","following_url":"https://api.github.com/users/odoo-dev/following{/other_user}","gists_url":"https://api.github.com/users/odoo-dev/gists{/gist_id}","starred_url":"https://api.github.com/users/odoo-dev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/odoo-dev/subscriptions","organizations_url":"https://api.github.com/users/odoo-dev/orgs","repos_url":"https://api.github.com/users/odoo-dev/repos","events_url":"https://api.github.com/users/odoo-dev/events{/privacy}","received_events_url":"https://api.github.com/users/odoo-dev/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/odoo-dev/odoo","description":"RD Dev Repository","fork":true,"url":"https://api.github.com/repos/odoo-dev/odoo","forks_url":"https://api.github.com/repos/odoo-dev/odoo/forks","keys_url":"https://api.github.com/repos/odoo-dev/odoo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/odoo-dev/odoo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/odoo-dev/odoo/teams","hooks_url":"https://api.github.com/repos/odoo-dev/odoo/hooks","issue_events_url":"https://api.github.com/repos/odoo-dev/odoo/issues/events{/number}","events_url":"https://api.github.com/repos/odoo-dev/odoo/events","assignees_url":"https://api.github.com/repos/odoo-dev/odoo/assignees{/user}","branches_url":"https://api.github.com/repos/odoo-dev/odoo/branches{/branch}","tags_url":"https://api.github.com/repos/odoo-dev/odoo/tags","blobs_url":"https://api.github.com/repos/odoo-dev/odoo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/odoo-dev/odoo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/odoo-dev/odoo/git/refs{/sha}","trees_url":"https://api.github.com/repos/odoo-dev/odoo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/odoo-dev/odoo/statuses/{sha}","languages_url":"https://api.github.com/repos/odoo-dev/odoo/languages","stargazers_url":"https://api.github.com/repos/odoo-dev/odoo/stargazers","contributors_url":"https://api.github.com/repos/odoo-dev/odoo/contributors","subscribers_url":"https://api.github.com/repos/odoo-dev/odoo/subscribers","subscription_url":"https://api.github.com/repos/odoo-dev/odoo/subscription","commits_url":"https://api.github.com/repos/odoo-dev/odoo/commits{/sha}","git_commits_url":"https://api.github.com/repos/odoo-dev/odoo/git/commits{/sha}","comments_url":"https://api.github.com/repos/odoo-dev/odoo/comments{/number}","issue_comment_url":"https://api.github.com/repos/odoo-dev/odoo/issues/comments{/number}","contents_url":"https://api.github.com/repos/odoo-dev/odoo/contents/{+path}","compare_url":"https://api.github.com/repos/odoo-dev/odoo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/odoo-dev/odoo/merges","archive_url":"https://api.github.com/repos/odoo-dev/odoo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/odoo-dev/odoo/downloads","issues_url":"https://api.github.com/repos/odoo-dev/odoo/issues{/number}","pulls_url":"https://api.github.com/repos/odoo-dev/odoo/pulls{/number}","milestones_url":"https://api.github.com/repos/odoo-dev/odoo/milestones{/number}","notifications_url":"https://api.github.com/repos/odoo-dev/odoo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/odoo-dev/odoo/labels{/name}","releases_url":"https://api.github.com/repos/odoo-dev/odoo/releases{/id}","created_at":"2014-05-16T11:16:19Z","updated_at":"2015-10-13T05:17:28Z","pushed_at":"2015-10-30T19:38:43Z","git_url":"git://github.com/odoo-dev/odoo.git","ssh_url":"git@github.com:odoo-dev/odoo.git","clone_url":"https://github.com/odoo-dev/odoo.git","svn_url":"https://github.com/odoo-dev/odoo","homepage":"https://www.odoo.com","size":1452470,"stargazers_count":62,"watchers_count":62,"language":null,"has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":24,"mirror_url":null,"open_issues_count":0,"forks":24,"open_issues":0,"watchers":62,"default_branch":"master"}},"base":{"label":"odoo:master","ref":"master","sha":"a588fbf8dce324371c80f29d80d5f151daa6de7e","user":{"login":"odoo","id":6368483,"avatar_url":"https://avatars.githubusercontent.com/u/6368483?v=3","gravatar_id":"","url":"https://api.github.com/users/odoo","html_url":"https://github.com/odoo","followers_url":"https://api.github.com/users/odoo/followers","following_url":"https://api.github.com/users/odoo/following{/other_user}","gists_url":"https://api.github.com/users/odoo/gists{/gist_id}","starred_url":"https://api.github.com/users/odoo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/odoo/subscriptions","organizations_url":"https://api.github.com/users/odoo/orgs","repos_url":"https://api.github.com/users/odoo/repos","events_url":"https://api.github.com/users/odoo/events{/privacy}","received_events_url":"https://api.github.com/users/odoo/received_events","type":"Organization","site_admin":false},"repo":{"id":19745004,"name":"odoo","full_name":"odoo/odoo","owner":{"login":"odoo","id":6368483,"avatar_url":"https://avatars.githubusercontent.com/u/6368483?v=3","gravatar_id":"","url":"https://api.github.com/users/odoo","html_url":"https://github.com/odoo","followers_url":"https://api.github.com/users/odoo/followers","following_url":"https://api.github.com/users/odoo/following{/other_user}","gists_url":"https://api.github.com/users/odoo/gists{/gist_id}","starred_url":"https://api.github.com/users/odoo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/odoo/subscriptions","organizations_url":"https://api.github.com/users/odoo/orgs","repos_url":"https://api.github.com/users/odoo/repos","events_url":"https://api.github.com/users/odoo/events{/privacy}","received_events_url":"https://api.github.com/users/odoo/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/odoo/odoo","description":"Odoo (formerly OpenERP). Open Source Apps To Grow Your Business.","fork":false,"url":"https://api.github.com/repos/odoo/odoo","forks_url":"https://api.github.com/repos/odoo/odoo/forks","keys_url":"https://api.github.com/repos/odoo/odoo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/odoo/odoo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/odoo/odoo/teams","hooks_url":"https://api.github.com/repos/odoo/odoo/hooks","issue_events_url":"https://api.github.com/repos/odoo/odoo/issues/events{/number}","events_url":"https://api.github.com/repos/odoo/odoo/events","assignees_url":"https://api.github.com/repos/odoo/odoo/assignees{/user}","branches_url":"https://api.github.com/repos/odoo/odoo/branches{/branch}","tags_url":"https://api.github.com/repos/odoo/odoo/tags","blobs_url":"https://api.github.com/repos/odoo/odoo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/odoo/odoo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/odoo/odoo/git/refs{/sha}","trees_url":"https://api.github.com/repos/odoo/odoo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/odoo/odoo/statuses/{sha}","languages_url":"https://api.github.com/repos/odoo/odoo/languages","stargazers_url":"https://api.github.com/repos/odoo/odoo/stargazers","contributors_url":"https://api.github.com/repos/odoo/odoo/contributors","subscribers_url":"https://api.github.com/repos/odoo/odoo/subscribers","subscription_url":"https://api.github.com/repos/odoo/odoo/subscription","commits_url":"https://api.github.com/repos/odoo/odoo/commits{/sha}","git_commits_url":"https://api.github.com/repos/odoo/odoo/git/commits{/sha}","comments_url":"https://api.github.com/repos/odoo/odoo/comments{/number}","issue_comment_url":"https://api.github.com/repos/odoo/odoo/issues/comments{/number}","contents_url":"https://api.github.com/repos/odoo/odoo/contents/{+path}","compare_url":"https://api.github.com/repos/odoo/odoo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/odoo/odoo/merges","archive_url":"https://api.github.com/repos/odoo/odoo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/odoo/odoo/downloads","issues_url":"https://api.github.com/repos/odoo/odoo/issues{/number}","pulls_url":"https://api.github.com/repos/odoo/odoo/pulls{/number}","milestones_url":"https://api.github.com/repos/odoo/odoo/milestones{/number}","notifications_url":"https://api.github.com/repos/odoo/odoo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/odoo/odoo/labels{/name}","releases_url":"https://api.github.com/repos/odoo/odoo/releases{/id}","created_at":"2014-05-13T15:38:58Z","updated_at":"2015-11-01T12:43:21Z","pushed_at":"2015-11-01T02:04:07Z","git_url":"git://github.com/odoo/odoo.git","ssh_url":"git@github.com:odoo/odoo.git","clone_url":"https://github.com/odoo/odoo.git","svn_url":"https://github.com/odoo/odoo","homepage":"https://www.odoo.com","size":1625181,"stargazers_count":3320,"watchers_count":3320,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2958,"mirror_url":null,"open_issues_count":2726,"forks":2958,"open_issues":2726,"watchers":3320,"default_branch":"9.0"}},"_links":{"self":{"href":"https://api.github.com/repos/odoo/odoo/pulls/8955"},"html":{"href":"https://github.com/odoo/odoo/pull/8955"},"issue":{"href":"https://api.github.com/repos/odoo/odoo/issues/8955"},"comments":{"href":"https://api.github.com/repos/odoo/odoo/issues/8955/comments"},"review_comments":{"href":"https://api.github.com/repos/odoo/odoo/pulls/8955/comments"},"review_comment":{"href":"https://api.github.com/repos/odoo/odoo/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/odoo/odoo/pulls/8955/commits"},"statuses":{"href":"https://api.github.com/repos/odoo/odoo/statuses/e96763db94a25c902652fab5ba20df9574bc221e"}}}}