diff --git a/addons/account/data/account_data.xml b/addons/account/data/account_data.xml
index 900e7fdead454e4adf9b1339efda2cc5872524db..f7fa31bd517e5a9801d0b063c8d7270b4bb55d41 100644
--- a/addons/account/data/account_data.xml
+++ b/addons/account/data/account_data.xml
@@ -2,6 +2,15 @@
 <odoo>
     <data noupdate="1">
 
+        <!-- Open Settings from Purchase Journal to configure mail servers -->
+        <record id="action_open_settings" model="ir.actions.act_window">
+            <field name="name">Settings</field>
+            <field name="res_model">res.config.settings</field>
+            <field name="view_mode">form</field>
+            <field name="target">inline</field>
+            <field name="context" eval="{'module': 'general_settings'}"/>
+        </record>
+
         <!-- TAGS FOR CASH FLOW STATEMENT -->
 
         <record id="account_tag_operating" model="account.account.tag">
diff --git a/addons/account/models/account.py b/addons/account/models/account.py
index 87b4ffc2765e93f7fbea43d4cfdb593bc1957270..c8ec7e289ffec6154c90620925870dc1f90a85b6 100644
--- a/addons/account/models/account.py
+++ b/addons/account/models/account.py
@@ -2,6 +2,7 @@
 
 import time
 import math
+import re
 
 from odoo.osv import expression
 from odoo.tools.float_utils import float_round as round
@@ -427,10 +428,21 @@ class AccountJournal(models.Model):
     bank_acc_number = fields.Char(related='bank_account_id.acc_number')
     bank_id = fields.Many2one('res.bank', related='bank_account_id.bank_id')
 
+    # alias configuration for 'purchase' type journals
+    alias_id = fields.Many2one('mail.alias', string='Alias')
+    alias_domain = fields.Char('Alias domain', compute='_compute_alias_domain', default=lambda self: self.env["ir.config_parameter"].sudo().get_param("mail.catchall.domain"))
+    alias_name = fields.Char('Alias Name for Vendor Bills', related='alias_id.alias_name', help="It creates draft vendor bill by sending an email.")
+
     _sql_constraints = [
         ('code_company_uniq', 'unique (code, name, company_id)', 'The code and name of the journal must be unique per company !'),
     ]
 
+    @api.multi
+    def _compute_alias_domain(self):
+        alias_domain = self.env["ir.config_parameter"].sudo().get_param("mail.catchall.domain")
+        for record in self:
+            record.alias_domain = alias_domain
+
     @api.multi
     # do not depend on 'sequence_id.date_range_ids', because
     # sequence_id._get_current_sequence() may invalidate it!
@@ -509,6 +521,19 @@ class AccountJournal(models.Model):
         if not self.default_debit_account_id:
             self.default_debit_account_id = self.default_credit_account_id
 
+    @api.multi
+    def _get_alias_values(self, alias_name=None):
+        if not alias_name:
+            alias_name = self.name
+            if self.company_id != self.env.ref('base.main_company'):
+                alias_name += '-' + str(self.company_id.name)
+        return {
+            'alias_defaults': {'type': 'in_invoice'},
+            'alias_user_id': self.env.user.id,
+            'alias_parent_thread_id': self.id,
+            'alias_name': re.sub(r'[^\w]+', '-', alias_name)
+        }
+
     @api.multi
     def unlink(self):
         bank_accounts = self.env['res.partner.bank'].browse()
@@ -516,6 +541,7 @@ class AccountJournal(models.Model):
             accounts = self.search([('bank_account_id', '=', bank_account.id)])
             if accounts <= self:
                 bank_accounts += bank_account
+        self.mapped('alias_id').unlink()
         ret = super(AccountJournal, self).unlink()
         bank_accounts.unlink()
         return ret
@@ -529,6 +555,19 @@ class AccountJournal(models.Model):
             name=_("%s (copy)") % (self.name or ''))
         return super(AccountJournal, self).copy(default)
 
+    def _update_mail_alias(self, vals):
+        self.ensure_one()
+        alias_values = self._get_alias_values(alias_name=vals.get('alias_name'))
+        if self.alias_id:
+            self.alias_id.write(alias_values)
+        else:
+            self.alias_id = self.env['mail.alias'].with_context(alias_model_name='account.invoice',
+                alias_parent_model_name='account.journal').create(alias_values)
+
+        if vals.get('alias_name'):
+            # remove alias_name to avoid useless write on alias
+            del(vals['alias_name'])
+
     @api.multi
     def write(self, vals):
         for journal in self:
@@ -564,7 +603,8 @@ class AccountJournal(models.Model):
                     bank_account = self.env['res.partner.bank'].browse(vals['bank_account_id'])
                     if bank_account.partner_id != company.partner_id:
                         raise UserError(_("The partners of the journal's company and the related bank account mismatch."))
-
+            if vals.get('type') == 'purchase':
+                self._update_mail_alias(vals)
         result = super(AccountJournal, self).write(vals)
 
         # Create the bank_account_id if necessary
@@ -676,8 +716,10 @@ class AccountJournal(models.Model):
             vals.update({'sequence_id': self.sudo()._create_sequence(vals).id})
         if vals.get('type') in ('sale', 'purchase') and vals.get('refund_sequence') and not vals.get('refund_sequence_id'):
             vals.update({'refund_sequence_id': self.sudo()._create_sequence(vals, refund=True).id})
-
         journal = super(AccountJournal, self).create(vals)
+        if journal.type == 'purchase':
+            # create a mail alias for purchase journals (always, deactivated if alias_name isn't set)
+            journal._update_mail_alias(vals)
 
         # Create the bank_account_id if necessary
         if journal.type == 'bank' and not journal.bank_account_id and vals.get('bank_acc_number'):
diff --git a/addons/account/models/account_invoice.py b/addons/account/models/account_invoice.py
index a4407c557aff008db7d1f73e89510fd5919c4363..3999980159aa84d54df0ab32e428bd7d3c9e533a 100644
--- a/addons/account/models/account_invoice.py
+++ b/addons/account/models/account_invoice.py
@@ -10,7 +10,7 @@ from dateutil.relativedelta import relativedelta
 from werkzeug.urls import url_encode
 
 from odoo import api, exceptions, fields, models, _
-from odoo.tools import float_is_zero, float_compare, pycompat
+from odoo.tools import email_re, email_split, email_escape_char, float_is_zero, float_compare, pycompat
 from odoo.tools.misc import formatLang
 
 from odoo.exceptions import AccessError, UserError, RedirectWarning, ValidationError, Warning
@@ -241,7 +241,7 @@ class AccountInvoice(models.Model):
             ('in_invoice','Vendor Bill'),
             ('out_refund','Customer Credit Note'),
             ('in_refund','Vendor Credit Note'),
-        ], readonly=True, index=True, change_default=True,
+        ], readonly=True, states={'draft': [('readonly', False)]}, index=True, change_default=True,
         default=lambda self: self._context.get('type', 'out_invoice'),
         track_visibility='always')
     access_token = fields.Char(
@@ -284,7 +284,7 @@ class AccountInvoice(models.Model):
              "term is not set on the invoice. If you keep the Payment terms and the due date empty, it "
              "means direct payment.")
     partner_id = fields.Many2one('res.partner', string='Partner', change_default=True,
-        required=True, readonly=True, states={'draft': [('readonly', False)]},
+        readonly=True, states={'draft': [('readonly', False)]},
         track_visibility='always')
     vendor_bill_id = fields.Many2one('account.invoice', string='Vendor Bill',
         help="Auto-complete from a past bill.")
@@ -299,7 +299,7 @@ class AccountInvoice(models.Model):
         readonly=True, states={'draft': [('readonly', False)]})
 
     account_id = fields.Many2one('account.account', string='Account',
-        required=True, readonly=True, states={'draft': [('readonly', False)]},
+        readonly=True, states={'draft': [('readonly', False)]},
         domain=[('deprecated', '=', False)], help="The partner account used for this invoice.")
     invoice_line_ids = fields.One2many('account.invoice.line', 'invoice_id', string='Invoice Lines', oldname='invoice_line',
         readonly=True, states={'draft': [('readonly', False)]}, copy=True)
@@ -370,10 +370,24 @@ class AccountInvoice(models.Model):
     sequence_number_next = fields.Char(string='Next Number', compute="_get_sequence_number_next", inverse="_set_sequence_next")
     sequence_number_next_prefix = fields.Char(string='Next Number Prefix', compute="_get_sequence_prefix")
 
+    #fields related to vendor bills automated creation by email
+    source_email = fields.Char(string='Source Email', track_visibility='onchange')
+    vendor_display_name = fields.Char(compute='_get_vendor_display_info', store=True)  # store=True to enable sorting on that column
+    invoice_icon = fields.Char(compute='_get_vendor_display_info', store=False)
+
     _sql_constraints = [
         ('number_uniq', 'unique(number, company_id, journal_id, type)', 'Invoice Number must be unique per Company!'),
     ]
 
+    @api.depends('partner_id', 'source_email')
+    def _get_vendor_display_info(self):
+        for invoice in self:
+            vendor_display_name = invoice.partner_id.name
+            if not vendor_display_name and invoice.source_email:
+                vendor_display_name = _('From: ') + invoice.source_email
+            invoice.vendor_display_name = vendor_display_name
+            invoice.invoice_icon = invoice.source_email and '@' or ''
+
     # Load all Vendor Bill lines
     @api.onchange('vendor_bill_id')
     def _onchange_vendor_bill(self):
@@ -479,8 +493,6 @@ class AccountInvoice(models.Model):
                 for field in changed_fields:
                     if field not in vals and invoice[field]:
                         vals[field] = invoice._fields[field].convert_to_write(invoice[field], invoice)
-        if not vals.get('account_id',False):
-            raise UserError(_('No account was found to create the invoice, be sure you have installed a chart of account.'))
 
         invoice = super(AccountInvoice, self.with_context(mail_create_nolog=True)).create(vals)
 
@@ -611,6 +623,82 @@ class AccountInvoice(models.Model):
             self.filtered(lambda inv: not inv.sent).write({'sent': True})
         return super(AccountInvoice, self.with_context(mail_post_autofollow=True)).message_post(**kwargs)
 
+    @api.model
+    def message_new(self, msg_dict, custom_values=None):
+        """ Overrides mail_thread message_new(), called by the mailgateway through message_process,
+            to complete values for vendor bills created by mails.
+        """
+        # Split `From` and `CC` email address from received email to look for related partners to subscribe on the invoice
+        subscribed_emails = email_split((msg_dict.get('from') or '') + ',' + (msg_dict.get('cc') or ''))
+        subscribed_partner_ids = [pid for pid in self._find_partner_from_emails(subscribed_emails) if pid]
+
+        # Detection of the partner_id of the invoice:
+        # 1) check if the email_from correspond to a supplier
+        email_from = msg_dict.get('from') or ''
+        email_from = email_escape_char(email_split(email_from)[0])
+        partner_id = self._search_on_partner(email_from, extra_domain=[('supplier', '=', True)])
+
+        # 2) otherwise, if the email sender is from odoo internal users then it is likely that the vendor sent the bill
+        # by mail to the internal user who, inturn, forwarded that email to the alias to automatically generate the bill
+        # on behalf of the vendor.
+        if not partner_id:
+            user_partner_id = self._search_on_user(email_from)
+            if user_partner_id and user_partner_id in self.env.ref('base.group_user').users.mapped('partner_id').ids:
+                # In this case, we will look for the vendor's email address in email's body and assume if will come first
+                email_addresses = email_re.findall(msg_dict.get('body'))
+                if email_addresses:
+                    partner_ids = [pid for pid in self._find_partner_from_emails([email_addresses[0]], force_create=False) if pid]
+                    partner_id = partner_ids and partner_ids[0]
+            # otherwise, there's no fallback on the partner_id found for the regular author of the mail.message as we want
+            # the partner_id to stay empty
+
+        # If the partner_id can be found, subscribe it to the bill, otherwise it's left empty to be manually filled
+        if partner_id:
+            subscribed_partner_ids.append(partner_id)
+
+        # Find the right purchase journal based on the "TO" email address
+        destination_emails = email_split((msg_dict.get('to') or '') + ',' + (msg_dict.get('cc') or ''))
+        alias_names = [mail_to.split('@')[0] for mail_to in destination_emails]
+        journal = self.env['account.journal'].search([
+            ('type', '=', 'purchase'), ('alias_name', 'in', alias_names)
+        ], limit=1)
+
+        # Create the message and the bill.
+        values = dict(custom_values or {}, partner_id=partner_id, source_email=email_from)
+        if journal:
+            values['journal_id'] = journal.id
+        # Passing `type` in context so that _default_journal(...) can correctly set journal for new vendor bill
+        invoice = super(AccountInvoice, self.with_context(type=values.get('type'))).message_new(msg_dict, values)
+
+        # Subscribe people on the newly created bill
+        if subscribed_partner_ids:
+            invoice.message_subscribe(subscribed_partner_ids)
+        return invoice
+
+    @api.model
+    def complete_empty_list_help(self):
+        # add help message about email alias in vendor bills empty lists
+        Journal = self.env['account.journal']
+        journals = Journal.browse(self._context.get('default_journal_id')) or Journal.search([('type', '=', 'purchase')])
+
+        if journals:
+            links = ''
+            alias_count = 0
+            for journal in journals.filtered(lambda j: j.alias_domain and j.alias_id.alias_name):
+                email = format(journal.alias_id.alias_name) + "@" + format(journal.alias_domain)
+                links += "<a id='o_mail_test' href='mailto:{}'>{}</a>".format(email, email) + ", "
+                alias_count += 1
+            if links and alias_count == 1:
+                help_message = _('Or share the email %s to your vendors: bills will be created automatically upon mail reception.') % (links[:-2])
+            elif links:
+                help_message = _('Or share the emails %s to your vendors: bills will be created automatically upon mail reception.') % (links[:-2])
+            else:
+                help_message = _('''Or set an <a data-oe-id=%s data-oe-model="account.journal" href=#id=%s&model=account.journal>email alias</a> '''
+                                              '''to allow draft vendor bills to be created upon reception of an email.''') % (journals[0].id, journals[0].id)
+        else:
+            help_message = _('<p>You can control the invoice from your vendor based on what you purchased or received.</p>')
+        return help_message
+
     @api.multi
     def compute_taxes(self):
         """Function used in other module to compute the taxes on a fresh invoice created (onchanges did not applied)"""
@@ -799,10 +887,14 @@ class AccountInvoice(models.Model):
     def action_invoice_open(self):
         # lots of duplicate calls to action_invoice_open, so we remove those already open
         to_open_invoices = self.filtered(lambda inv: inv.state != 'open')
+        for inv in to_open_invoices.filtered(lambda inv: not inv.partner_id):
+            raise UserError(_("The field Vendor is required, please complete it to validate the Vendor Bill."))
         if to_open_invoices.filtered(lambda inv: inv.state != 'draft'):
             raise UserError(_("Invoice must be in draft state in order to validate it."))
         if to_open_invoices.filtered(lambda inv: inv.amount_total < 0):
             raise UserError(_("You cannot validate an invoice with a negative total amount. You should create a credit note instead."))
+        if to_open_invoices.filtered(lambda inv: not inv.account_id):
+            raise UserError(_('No account was found to create the invoice, be sure you have installed a chart of account.'))
         to_open_invoices.action_date_assign()
         to_open_invoices.action_move_create()
         return to_open_invoices.invoice_validate()
diff --git a/addons/account/models/account_journal_dashboard.py b/addons/account/models/account_journal_dashboard.py
index cb58e37df92c35560e7fffecfe019a886ddc260e..af8e26b27ab1d69755c8f3cc7029ba3bf026b32c 100644
--- a/addons/account/models/account_journal_dashboard.py
+++ b/addons/account/models/account_journal_dashboard.py
@@ -324,7 +324,7 @@ class account_journal(models.Model):
             elif self.type == 'sale':
                 action_name = 'action_invoice_tree1'
             elif self.type == 'purchase':
-                action_name = 'action_invoice_tree2'
+                action_name = 'action_vendor_bill_template'
             else:
                 action_name = 'action_move_journal_line'
 
@@ -354,11 +354,14 @@ class account_journal(models.Model):
         action['context'] = ctx
         action['domain'] = self._context.get('use_domain', [])
         account_invoice_filter = self.env.ref('account.view_account_invoice_filter', False)
-        if action_name in ['action_invoice_tree1', 'action_invoice_tree2']:
+        if action_name in ['action_invoice_tree1', 'action_vendor_bill_template']:
             action['search_view_id'] = account_invoice_filter and account_invoice_filter.id or False
         if action_name in ['action_bank_statement_tree', 'action_view_bank_statement_tree']:
             action['views'] = False
             action['view_id'] = False
+        if self.type == 'purchase':
+            new_help = self.env['account.invoice'].with_context(ctx).complete_empty_list_help()
+            action.update({'help': action.get('help', '') + new_help})
         return action
 
     @api.multi
diff --git a/addons/account/static/src/css/account.css b/addons/account/static/src/css/account.css
index 923ea75efe31f9f387dfef91fbfd3010399ee705..217e74f757145b782e9ad4e0751435028377d54d 100644
--- a/addons/account/static/src/css/account.css
+++ b/addons/account/static/src/css/account.css
@@ -23,4 +23,3 @@
     font-style: italic;
     color: grey;
 }
-
diff --git a/addons/account/views/account_invoice_view.xml b/addons/account/views/account_invoice_view.xml
index 0ce2d057a5bd36b55476d8565aa4549a8bfd49a4..8345b94ac5825bf3ed716fcda604f14bd27389b8 100644
--- a/addons/account/views/account_invoice_view.xml
+++ b/addons/account/views/account_invoice_view.xml
@@ -190,8 +190,11 @@
             <field name="name">account.invoice.supplier.tree</field>
             <field name="model">account.invoice</field>
             <field name="arch" type="xml">
-                <tree decoration-info="state == 'draft'" decoration-muted="state == 'cancel'" string="Invoice">
-                    <field name="partner_id" groups="base.group_user" string="Vendor"/>
+                <tree decoration-info="state == 'draft'" decoration-muted="state == 'cancel'" decoration-bf="not partner_id" string="Vendor Bill">
+                    <field name="partner_id" invisible="1"/>
+                    <field name="source_email" invisible="1"/>
+                    <field name="invoice_icon" string=" "/>
+                    <field name="vendor_display_name" groups="base.group_user" string="Vendor"/>
                     <field name="date_invoice" string="Bill Date"/>
                     <field name="number"/>
                     <field name="reference"/>
@@ -250,7 +253,7 @@
                         <group>
                             <field string="Vendor" name="partner_id"
                               context="{'default_customer': 0, 'search_default_supplier': 1, 'default_supplier': 1, 'default_company_type': 'company'}"
-                              domain="[('supplier', '=', True)]"/>
+                              domain="[('supplier', '=', True)]" required="1"/>
                             <field name="reference" string="Vendor Reference"/>
                             <field name="vendor_bill_id" attrs="{'invisible': [('state','not in',['draft'])]}"
                               domain="[('partner_id','child_of', [partner_id]), ('state','in',('open','paid')), ('type','=','in_invoice')]"
@@ -259,6 +262,7 @@
                         </group>
                         <group>
                             <field name="origin" attrs="{'invisible': [('origin', '=', False)]}"/>
+                            <field name="source_email" widget="email" groups="base.group_no_one" attrs="{'invisible': [('source_email', '=', False)]}"/>
                             <field name="date_invoice" string="Bill Date"/>
                             <field name="date_due" attrs="{'readonly': ['|',('payment_term_id','!=',False), ('state', 'in', ['open', 'paid'])]}" force_save="1"/>
                             <field name="move_name" invisible="1"/>
@@ -348,7 +352,7 @@
                         </page>
                     </notebook>
                 </sheet>
-                <div class="o_attachment_preview" attrs="{'invisible': ['|',('type', '!=', 'in_invoice'),('state', '!=', 'draft')]}"/>
+                <div class="o_attachment_preview" attrs="{'invisible': ['|',('type', '!=', 'in_invoice'),('state', '!=', 'draft')]}" options="{'preview_priority_type': 'pdf'}"/>
                 <div class="oe_chatter">
                     <field name="message_follower_ids" widget="mail_followers"/>
                     <field name="activity_ids" widget="mail_activity"/>
@@ -402,7 +406,7 @@
                             <field string="Customer" name="partner_id"
                                 context="{'search_default_customer':1, 'show_address': 1, 'default_company_type': 'company'}"
                                 options='{"always_reload": True, "no_quick_create": True}'
-                                domain="[('customer', '=', True)]"/>
+                                domain="[('customer', '=', True)]" required="1"/>
                             <field name="payment_term_id"/>
                             <field name="cash_rounding_id" groups="account.group_cash_rounding"/>
                         </group>
@@ -707,7 +711,7 @@
                   parent="menu_finance_receivables_documents"
                   sequence="1"/>
 
-        <record id="action_invoice_tree2" model="ir.actions.act_window">
+        <record id="action_vendor_bill_template" model="ir.actions.act_window">
             <field name="name">Vendor Bills</field>
             <field name="res_model">account.invoice</field>
             <field name="view_type">form</field>
@@ -719,25 +723,36 @@
             <field name="help" type="html">
               <p class="o_view_nocontent_smiling_face">
                 Record a new vendor bill
-              </p><p>
-                You can control the invoice from your vendor based on
-                what you purchased or received.
               </p>
             </field>
         </record>
+        <!--
+            server action opening the vendor bills and returning the right help tooltip
+        -->
+        <record id="action_invoice_tree2" model="ir.actions.server">
+            <field name="name">Vendor Bills</field>
+            <field name="model_id" ref="model_account_invoice"/>
+            <field name="state">code</field>
+            <field name="code">
+action_values = env.ref('account.action_vendor_bill_template').read()[0]
+new_help = model.complete_empty_list_help()
+action_values.update({'help': action_values.get('help', '') + new_help})
+action = action_values
+            </field>
+        </record>
 
         <record id="action_invoice_supplier_tree1_view1" model="ir.actions.act_window.view">
             <field eval="1" name="sequence"/>
             <field name="view_mode">tree</field>
             <field name="view_id" ref="invoice_supplier_tree"/>
-            <field name="act_window_id" ref="action_invoice_tree2"/>
+            <field name="act_window_id" ref="action_vendor_bill_template"/>
         </record>
 
         <record id="action_invoice__supplier_tree1_view2" model="ir.actions.act_window.view">
             <field eval="2" name="sequence"/>
             <field name="view_mode">form</field>
             <field name="view_id" ref="invoice_supplier_form"/>
-            <field name="act_window_id" ref="action_invoice_tree2"/>
+            <field name="act_window_id" ref="action_vendor_bill_template"/>
         </record>
 
         <menuitem action="action_invoice_tree2" id="menu_action_invoice_tree2" parent="menu_finance_payables_documents" sequence="1"/>
diff --git a/addons/account/views/account_view.xml b/addons/account/views/account_view.xml
index 4d6a7e5a51b6b05e145a27622785452df00555da..6e22ba8b77aae7364b9cfaf6309603fcb6417035 100644
--- a/addons/account/views/account_view.xml
+++ b/addons/account/views/account_view.xml
@@ -333,6 +333,18 @@
                                         <field name="loss_account_id" attrs="{'invisible': [('type', '!=', 'cash')]}"/>
                                         <field name="show_on_dashboard" groups="base.group_no_one"/>
                                     </group>
+                                    <group name="group_alias" string="Email your Vendor Bills" attrs="{'invisible': [('type', '!=',  'purchase')]}">
+                                        <label string="Email Alias" attrs="{'invisible': [('alias_domain', '=', False)]}"/>
+                                        <div name="alias_def" attrs="{'invisible': [('alias_domain', '=', False)]}">
+                                            <field name="alias_id" class="oe_read_only oe_inline"/>
+                                            <div class="oe_edit_only oe_inline" name="edit_alias" style="display: inline;" >
+                                                <field name="alias_name" class="oe_inline"/>@<field name="alias_domain" class="oe_inline" readonly="1"/>
+                                            </div>
+                                        </div>
+                                        <div class="content-group" attrs="{'invisible': [('alias_domain', '!=', False)]}">
+                                            <a type='action' name='%(action_open_settings)d' class="btn btn-sm btn-link"><i class="fa fa-fw o_button_icon fa-arrow-right"/> Configure Email Servers</a>
+                                    </div>
+                                    </group>
                                 </group>
                             </page>
                             <page name="bank_account" string="Bank Account" attrs="{'invisible': [('type', '!=', 'bank')]}">