{"action":"created","comment":{"url":"https://api.github.com/repos/odoo/odoo/pulls/comments/185498906","pull_request_review_id":116899162,"id":185498906,"diff_hunk":"@@ -399,55 +399,110 @@ def message_new(self, msg_dict, custom_values=None):\n             custom_values = {}\n \n         email_address = email_split(msg_dict.get('email_from', False))[0]\n-\n         employee = self.env['hr.employee'].search([\n             '|',\n             ('work_email', 'ilike', email_address),\n             ('user_id.email', 'ilike', email_address)\n         ], limit=1)\n \n         expense_description = msg_dict.get('subject', '')\n+        vals = self._parse_expense_subject(expense_description, employee)\n+        custom_values.update(vals)\n \n-        # Match the first occurence of '[]' in the string and extract the content inside it\n-        # Example: '[foo] bar (baz)' becomes 'foo'. This is potentially the product code\n-        # of the product to encode on the expense. If not, take the default product instead\n-        # which is 'Fixed Cost'\n-        default_product = self.env.ref('hr_expense.product_product_fixed_cost')\n-        pattern = '\\[([^)]*)\\]'\n-        product_code = re.search(pattern, expense_description)\n-        if product_code is None:\n-            product = default_product\n-        else:\n-            expense_description = expense_description.replace(product_code.group(), '')\n-            products = self.env['product.product'].search([('default_code', 'ilike', product_code.group(1))]) or default_product\n-            product = products.filtered(lambda p: p.default_code == product_code.group(1)) or products[0]\n-\n-        pattern = '[-+]?(\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?'\n-        # Match the last occurence of a float in the string\n-        # Example: '[foo] 50.3 bar 34.5' becomes '34.5'. This is potentially the price\n-        # to encode on the expense. If not, take 1.0 instead\n-        expense_price = re.findall(pattern, expense_description)\n-        # TODO: International formatting\n-        if not expense_price:\n-            price = 1.0\n+        expense = super(HrExpense, self).message_new(msg_dict, custom_values)\n+        self._send_expense_success_mail(msg_dict, expense)\n+        return expense\n+\n+    @api.model\n+    def _parse_expense_subject(self, expense_description, employee):\n+        \"\"\" Fetch product, price and currency info from mail subject.\n+\n+            Product can be identified based on product name or product code.\n+            It can be passed between [] or it can be placed at start.\n+\n+            If multi currencies is activated then this will allow all active\n+            currencies else only company currency is allowed. This will fetch\n+            currency in symbol($) or ISO name (USD).\n+\n+            Some valid examples:\n+                Travel by Air [TICKET] USD 1205.91\n+                TICKET $1205.91 Travel by Air\n+                Extra expenses 29.10EUR [EXTRA]\n+        \"\"\"\n+        vals = {\n+            'employee_id': employee.id,\n+            'company_id': employee.company_id.id\n+        }\n+\n+        # Fetch product from subject\n+        product_pattern = '\\[([^)]*)\\]'\n+        product_code = re.search(product_pattern, expense_description)\n+        if product_code:\n+            product = self.env['product.product'].search([('can_be_expensed', '=', True), '|', ('name', '=ilike', product_code.group(1)), ('default_code', '=ilike', product_code.group(1))], limit=1)\n+            if product:\n+                expense_description = expense_description.replace(product_code.group(), '')\n         else:\n-            price = expense_price[-1][0]\n-            expense_description = expense_description.replace(price, '')\n+            # to select first word from string\n+            product_to_search = expense_description.split(' ')[0]\n+            product = self.env['product.product'].search([('can_be_expensed', '=', True), '|', ('name', '=ilike', product_to_search), ('default_code', '=ilike', product_to_search)], limit=1)\n+            if product:\n+                expense_description = expense_description.replace(product_to_search, '')\n+        product = product or self.env.ref('hr_expense.product_product_fixed_cost')\n+        vals.update({\n+            'product_id': product.id,\n+            'product_uom_id': product.uom_id.id,\n+        })\n+\n+        # Fetch price and currency from subject  (TODO: International formatting)\n+        price, currency_id = False, employee.company_id.currency_id\n+        symbols, symbols_pattern, float_pattern = [], '', '(\\d+(?:\\.\\d+)?|\\.\\d+)'","path":"addons/hr_expense/models/hr_expense.py","position":null,"original_position":85,"commit_id":"b7e9bcb424d25069f23b7e2d8ba85c1c4af88f85","original_commit_id":"4e9a7d67d54e791aa0602834c818be00b548e885","user":{"login":"pga-odoo","id":7629089,"avatar_url":"https://avatars2.githubusercontent.com/u/7629089?v=4","gravatar_id":"","url":"https://api.github.com/users/pga-odoo","html_url":"https://github.com/pga-odoo","followers_url":"https://api.github.com/users/pga-odoo/followers","following_url":"https://api.github.com/users/pga-odoo/following{/other_user}","gists_url":"https://api.github.com/users/pga-odoo/gists{/gist_id}","starred_url":"https://api.github.com/users/pga-odoo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pga-odoo/subscriptions","organizations_url":"https://api.github.com/users/pga-odoo/orgs","repos_url":"https://api.github.com/users/pga-odoo/repos","events_url":"https://api.github.com/users/pga-odoo/events{/privacy}","received_events_url":"https://api.github.com/users/pga-odoo/received_events","type":"User","site_admin":false},"body":"Before it was part of regex but it was not accepting it ","created_at":"2018-05-02T13:40:51Z","updated_at":"2018-05-02T13:40:51Z","html_url":"https://github.com/odoo/odoo/pull/22168#discussion_r185498906","pull_request_url":"https://api.github.com/repos/odoo/odoo/pulls/22168","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/odoo/odoo/pulls/comments/185498906"},"html":{"href":"https://github.com/odoo/odoo/pull/22168#discussion_r185498906"},"pull_request":{"href":"https://api.github.com/repos/odoo/odoo/pulls/22168"}},"in_reply_to_id":185446559},"pull_request":{"url":"https://api.github.com/repos/odoo/odoo/pulls/22168","id":162348788,"html_url":"https://github.com/odoo/odoo/pull/22168","diff_url":"https://github.com/odoo/odoo/pull/22168.diff","patch_url":"https://github.com/odoo/odoo/pull/22168.patch","issue_url":"https://api.github.com/repos/odoo/odoo/issues/22168","number":22168,"state":"open","locked":false,"title":"[hr_expense] Smooth email flow to record an expense","user":{"login":"rop-odoo","id":10609000,"avatar_url":"https://avatars3.githubusercontent.com/u/10609000?v=4","gravatar_id":"","url":"https://api.github.com/users/rop-odoo","html_url":"https://github.com/rop-odoo","followers_url":"https://api.github.com/users/rop-odoo/followers","following_url":"https://api.github.com/users/rop-odoo/following{/other_user}","gists_url":"https://api.github.com/users/rop-odoo/gists{/gist_id}","starred_url":"https://api.github.com/users/rop-odoo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rop-odoo/subscriptions","organizations_url":"https://api.github.com/users/rop-odoo/orgs","repos_url":"https://api.github.com/users/rop-odoo/repos","events_url":"https://api.github.com/users/rop-odoo/events{/privacy}","received_events_url":"https://api.github.com/users/rop-odoo/received_events","type":"User","site_admin":false},"body":"Task: https://www.odoo.com/web?#id=35093&view_type=form&model=project.task&action=327&menu_id=4720\r\nPad: https://pad.odoo.com/p/r.9efc2b24d8595bc156b5fe1088a0682e\r\nDescription of the issue/feature this PR addresses:\r\n\r\nCurrent behavior before PR:\r\n\r\nDesired behavior after PR is merged:\r\n\r\n\r\n--\r\nI confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr\r\n","created_at":"2018-01-11T10:47:13Z","updated_at":"2018-05-02T13:40:51Z","closed_at":null,"merged_at":null,"merge_commit_sha":"5111e9998e974ffbdf983d9467da4f17855203c0","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":106173385,"url":"https://api.github.com/repos/odoo/odoo/labels/RD","name":"RD","color":"5319e7","default":false},{"id":620800901,"url":"https://api.github.com/repos/odoo/odoo/labels/Services","name":"Services","color":"c2e0c6","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/odoo/odoo/pulls/22168/commits","review_comments_url":"https://api.github.com/repos/odoo/odoo/pulls/22168/comments","review_comment_url":"https://api.github.com/repos/odoo/odoo/pulls/comments{/number}","comments_url":"https://api.github.com/repos/odoo/odoo/issues/22168/comments","statuses_url":"https://api.github.com/repos/odoo/odoo/statuses/b7e9bcb424d25069f23b7e2d8ba85c1c4af88f85","head":{"label":"odoo-dev:master-hr-expense-smooth-email-rop","ref":"master-hr-expense-smooth-email-rop","sha":"b7e9bcb424d25069f23b7e2d8ba85c1c4af88f85","user":{"login":"odoo-dev","id":7466976,"avatar_url":"https://avatars0.githubusercontent.com/u/7466976?v=4","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://avatars0.githubusercontent.com/u/7466976?v=4","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}","deployments_url":"https://api.github.com/repos/odoo-dev/odoo/deployments","created_at":"2014-05-16T11:16:19Z","updated_at":"2018-04-11T11:21:01Z","pushed_at":"2018-05-02T13:40:06Z","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":2063757,"stargazers_count":78,"watchers_count":78,"language":null,"has_issues":false,"has_projects":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":39,"mirror_url":null,"archived":false,"open_issues_count":0,"license":null,"forks":39,"open_issues":0,"watchers":78,"default_branch":"master"}},"base":{"label":"odoo:master","ref":"master","sha":"635932fe0900e3c2146c1c83501997a5ca2cc4ae","user":{"login":"odoo","id":6368483,"avatar_url":"https://avatars2.githubusercontent.com/u/6368483?v=4","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://avatars2.githubusercontent.com/u/6368483?v=4","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. 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}","deployments_url":"https://api.github.com/repos/odoo/odoo/deployments","created_at":"2014-05-13T15:38:58Z","updated_at":"2018-05-02T13:40:51Z","pushed_at":"2018-05-02T13:40:04Z","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":2021345,"stargazers_count":9462,"watchers_count":9462,"language":"Python","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":8041,"mirror_url":null,"archived":false,"open_issues_count":1650,"license":{"key":"other","name":"Other","spdx_id":null,"url":null},"forks":8041,"open_issues":1650,"watchers":9462,"default_branch":"11.0"}},"_links":{"self":{"href":"https://api.github.com/repos/odoo/odoo/pulls/22168"},"html":{"href":"https://github.com/odoo/odoo/pull/22168"},"issue":{"href":"https://api.github.com/repos/odoo/odoo/issues/22168"},"comments":{"href":"https://api.github.com/repos/odoo/odoo/issues/22168/comments"},"review_comments":{"href":"https://api.github.com/repos/odoo/odoo/pulls/22168/comments"},"review_comment":{"href":"https://api.github.com/repos/odoo/odoo/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/odoo/odoo/pulls/22168/commits"},"statuses":{"href":"https://api.github.com/repos/odoo/odoo/statuses/b7e9bcb424d25069f23b7e2d8ba85c1c4af88f85"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"pga-odoo"}}