diff --git a/addons/account/i18n/account.pot b/addons/account/i18n/account.pot
index 43deedf6f9d..1ea910942bf 100644
--- a/addons/account/i18n/account.pot
+++ b/addons/account/i18n/account.pot
@@ -3855,6 +3855,12 @@ msgid ""
"balance."
msgstr ""
+#. module: account
+#: code:addons/account/models/account_move.py:408
+#, python-format
+msgid "Difference debit - credit: "
+msgstr ""
+
#. module: account
#: model:ir.model,name:account.model_digest_digest
msgid "Digest"
diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py
index 8a6de4e1ccf..b0f559a283b 100644
--- a/addons/account/models/account_move.py
+++ b/addons/account/models/account_move.py
@@ -1224,10 +1224,15 @@ class AccountMove(models.Model):
lang_env = move.with_context(lang=move.partner_id.lang).env
tax_lines = move.line_ids.filtered(lambda line: line.tax_line_id)
res = {}
+ # There are as many tax line as there are repartition lines
+ done_taxes = set()
for line in tax_lines:
res.setdefault(line.tax_line_id.tax_group_id, {'base': 0.0, 'amount': 0.0})
res[line.tax_line_id.tax_group_id]['amount'] += line.price_subtotal
- res[line.tax_line_id.tax_group_id]['base'] += line.tax_base_amount
+ if line.tax_line_id.id not in done_taxes:
+ # The base should be added ONCE
+ res[line.tax_line_id.tax_group_id]['base'] += line.tax_base_amount
+ done_taxes.add(line.tax_line_id.id)
res = sorted(res.items(), key=lambda l: l[0].sequence)
move.amount_by_group = [(
group.name, amounts['amount'],
@@ -1304,7 +1309,7 @@ class AccountMove(models.Model):
# are already done. Then, this query MUST NOT depend of computed stored fields (e.g. balance).
# It happens as the ORM makes the create with the 'no_recompute' statement.
self._cr.execute('''
- SELECT line.move_id
+ SELECT line.move_id, ROUND(SUM(debit - credit), currency.decimal_places)
FROM account_move_line line
JOIN account_move move ON move.id = line.move_id
JOIN account_journal journal ON journal.id = move.journal_id
@@ -1318,7 +1323,8 @@ class AccountMove(models.Model):
query_res = self._cr.fetchall()
if query_res:
ids = [res[0] for res in query_res]
- raise UserError(_("Cannot create unbalanced journal entry. Ids: %s") % str(ids))
+ sums = [res[1] for res in query_res]
+ raise UserError(_("Cannot create unbalanced journal entry. Ids: %s\nDifferences debit - credit: %s") % (ids, sums))
@api.multi
def _check_fiscalyear_lock_date(self):
diff --git a/addons/account/models/account_reconcile_model.py b/addons/account/models/account_reconcile_model.py
index 6c7b28d89c7..43651c74bcd 100644
--- a/addons/account/models/account_reconcile_model.py
+++ b/addons/account/models/account_reconcile_model.py
@@ -229,6 +229,7 @@ class AccountReconcileModel(models.Model):
'analytic_tag_ids': [(6, 0, self.analytic_tag_ids.ids)],
'debit': line_balance > 0 and line_balance or 0,
'credit': line_balance < 0 and -line_balance or 0,
+ 'reconcile_model_id': self.id,
}
new_aml_dicts.append(writeoff_line)
@@ -243,7 +244,11 @@ class AccountReconcileModel(models.Model):
# Second write-off line.
if self.has_second_line and self.second_account_id:
- line_balance = balance - sum(aml['debit'] - aml['credit'] for aml in new_aml_dicts)
+ remaining_balance = balance - sum(aml['debit'] - aml['credit'] for aml in new_aml_dicts)
+ if self.second_amount_type == 'percentage':
+ line_balance = remaining_balance * (self.second_amount / 100.0)
+ else:
+ line_balance = self.second_amount * (1 if remaining_balance > 0.0 else -1)
second_writeoff_line = {
'name': self.second_label or st_line.name,
'account_id': self.second_account_id.id,
@@ -251,6 +256,7 @@ class AccountReconcileModel(models.Model):
'analytic_tag_ids': [(6, 0, self.second_analytic_tag_ids.ids)],
'debit': line_balance > 0 and line_balance or 0,
'credit': line_balance < 0 and -line_balance or 0,
+ 'reconcile_model_id': self.id,
}
new_aml_dicts.append(second_writeoff_line)
diff --git a/addons/account/models/reconciliation_widget.py b/addons/account/models/reconciliation_widget.py
index 85a755c2920..0544a413acd 100644
--- a/addons/account/models/reconciliation_widget.py
+++ b/addons/account/models/reconciliation_widget.py
@@ -522,22 +522,16 @@ class AccountReconciliation(models.AbstractModel):
])
domain = expression.OR([domain_reconciliation, domain_matching])
- partner_domain = []
if partner_id:
- partner_domain = [('partner_id', '=', partner_id)]
- domain = expression.AND([domain, partner_domain])
+ domain = expression.AND([domain, [('partner_id', '=', partner_id)]])
# Domain factorized for all reconciliation use cases
if search_str:
str_domain = self._domain_move_lines(search_str=search_str)
- if not partner_id:
- partner_domain = [('partner_id.name', 'ilike', search_str)]
-
str_domain = expression.OR([
str_domain,
- partner_domain,
+ [('partner_id.name', 'ilike', search_str)]
])
-
domain = expression.AND([
domain,
str_domain
@@ -553,7 +547,6 @@ class AccountReconciliation(models.AbstractModel):
if st_line.company_id.account_bank_reconciliation_start:
domain = expression.AND([domain, [('date', '>=', st_line.company_id.account_bank_reconciliation_start)]])
-
return domain
@api.model
diff --git a/addons/account/models/res_users.py b/addons/account/models/res_users.py
index 013acde54ff..cc423c2d3a5 100644
--- a/addons/account/models/res_users.py
+++ b/addons/account/models/res_users.py
@@ -13,8 +13,12 @@ class Users(models.Model):
def _check_one_user_type(self):
super(Users, self)._check_one_user_type()
- g1 = self.env.ref('account.group_show_line_subtotals_tax_included')
- g2 = self.env.ref('account.group_show_line_subtotals_tax_excluded')
+ g1 = self.env.ref('account.group_show_line_subtotals_tax_included', False)
+ g2 = self.env.ref('account.group_show_line_subtotals_tax_excluded', False)
+
+ if not g1 or not g2:
+ # A user cannot be in a non-existant group
+ return
if self._has_multiple_groups([g1.id, g2.id]):
raise ValidationError(_("A user cannot have both Tax B2B and Tax B2C.\n"
diff --git a/addons/account/tests/test_reconciliation_widget.py b/addons/account/tests/test_reconciliation_widget.py
index a588fccd42c..ebd23ddd434 100644
--- a/addons/account/tests/test_reconciliation_widget.py
+++ b/addons/account/tests/test_reconciliation_widget.py
@@ -57,6 +57,7 @@ class TestReconciliationWidget(TestReconciliation):
def test_filter_partner1(self):
inv1 = self.create_invoice(currency_id=self.currency_euro_id)
inv2 = self.create_invoice(currency_id=self.currency_euro_id)
+ partner = inv1.partner_id
receivable1 = inv1.line_ids.filtered(lambda l: l.account_id.internal_type == 'receivable')
receivable2 = inv2.line_ids.filtered(lambda l: l.account_id.internal_type == 'receivable')
@@ -75,7 +76,31 @@ class TestReconciliationWidget(TestReconciliation):
'date': time.strftime('%Y-07-15'),
})
- # This is like opening the widget, and type "deco" in the filter
+ # This is like input a partner in the widget
+ mv_lines_rec = self.env['account.reconciliation.widget'].get_move_lines_for_bank_statement_line(
+ bank_stmt_line.id,
+ partner_id=partner.id,
+ excluded_ids=[],
+ search_str=False
+ )
+ mv_lines_ids = [l['id'] for l in mv_lines_rec]
+
+ self.assertTrue(receivable1.id in mv_lines_ids)
+ self.assertTrue(receivable2.id in mv_lines_ids)
+
+ # With a partner set, type the invoice reference in the filter
+ mv_lines_rec = self.env['account.reconciliation.widget'].get_move_lines_for_bank_statement_line(
+ bank_stmt_line.id,
+ partner_id=partner.id,
+ excluded_ids=[],
+ search_str=inv1.invoice_payment_ref,
+ )
+ mv_lines_ids = [l['id'] for l in mv_lines_rec]
+
+ self.assertTrue(receivable1.id in mv_lines_ids)
+ self.assertFalse(receivable2.id in mv_lines_ids)
+
+ # Without a partner set, type "deco" in the filter
mv_lines_rec = self.env['account.reconciliation.widget'].get_move_lines_for_bank_statement_line(
bank_stmt_line.id,
partner_id=False,
@@ -87,8 +112,7 @@ class TestReconciliationWidget(TestReconciliation):
self.assertTrue(receivable1.id in mv_lines_ids)
self.assertTrue(receivable2.id in mv_lines_ids)
- # This is like clicking on the first receivable
- partner = inv1.partner_id
+ # With a partner set, type "deco" in the filter and click on the first receivable
mv_lines_rec = self.env['account.reconciliation.widget'].get_move_lines_for_bank_statement_line(
bank_stmt_line.id,
partner_id=partner.id,
diff --git a/addons/account/views/account_view.xml b/addons/account/views/account_view.xml
index c70b70e7dc9..c709897ca69 100644
--- a/addons/account/views/account_view.xml
+++ b/addons/account/views/account_view.xml
@@ -1128,7 +1128,7 @@ action = model.setting_init_bank_account_action()
-
+
diff --git a/addons/auth_signup/models/res_partner.py b/addons/auth_signup/models/res_partner.py
index c041ffd3ccf..6f484117fa0 100644
--- a/addons/auth_signup/models/res_partner.py
+++ b/addons/auth_signup/models/res_partner.py
@@ -113,7 +113,7 @@ class ResPartner(models.Model):
allow_signup = self.env['res.users']._get_signup_invitation_scope() == 'b2c'
for partner in self:
- if allow_signup and not partner.user_ids:
+ if allow_signup and not partner.sudo().user_ids:
partner = partner.sudo()
partner.signup_prepare()
res[partner.id]['auth_signup_token'] = partner.signup_token
diff --git a/addons/digest/data/res_config_settings_data.xml b/addons/digest/data/res_config_settings_data.xml
index cbd93e4fef0..cacc318daf0 100644
--- a/addons/digest/data/res_config_settings_data.xml
+++ b/addons/digest/data/res_config_settings_data.xml
@@ -1,10 +1,10 @@
-
-
+
+
digest.default_digest_emails
True
-
+
digest.default_digest_id
diff --git a/addons/event/controllers/main.py b/addons/event/controllers/main.py
index f844e6a5d51..723d30aaa51 100644
--- a/addons/event/controllers/main.py
+++ b/addons/event/controllers/main.py
@@ -10,8 +10,6 @@ class EventController(Controller):
@route(['''/event//ics'''], type='http', auth="public")
def event_ics_file(self, event, **kwargs):
- if not event or not event.registration_ids:
- return request.not_found()
files = event._get_ics_file()
if not event.id in files:
return NotFound()
diff --git a/addons/l10n_fr/data/account_fiscal_position_template_data.xml b/addons/l10n_fr/data/account_fiscal_position_template_data.xml
index c1b3663520f..c82d89442e7 100644
--- a/addons/l10n_fr/data/account_fiscal_position_template_data.xml
+++ b/addons/l10n_fr/data/account_fiscal_position_template_data.xml
@@ -54,6 +54,11 @@
+
+
+
+
+
@@ -64,6 +69,11 @@
+
+
+
+
+
@@ -146,11 +156,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -168,22 +198,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -203,11 +253,21 @@
+
+
+
+
+
+
+
+
+
+
@@ -280,6 +340,11 @@
+
+
+
+
+
@@ -291,12 +356,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/l10n_fr/data/account_tax_data.xml b/addons/l10n_fr/data/account_tax_data.xml
index 3f72c43b63e..41fc79e15a1 100644
--- a/addons/l10n_fr/data/account_tax_data.xml
+++ b/addons/l10n_fr/data/account_tax_data.xml
@@ -46,6 +46,47 @@
]"/>
+
+
+ TVA à l'encaissement (vente) 10,0%
+ TVA 10%
+
+ percent
+ on_payment
+
+
+ sale
+
+
+
+
+
TVA à l'encaissement (vente) 20,0%
@@ -367,6 +408,48 @@
]"/>
+
+
+ TVA à l'encaissement (vente) 10,0% TTC
+ TVA 10% TTC
+
+
+ percent
+ on_payment
+
+
+ sale
+
+
+
+
+
TVA à l'encaissement (vente) 20,0% TTC
@@ -693,6 +776,88 @@
]"/>
+
+
+ TVA à l'encaissement (achat) 20,0%
+ TVA 20%
+
+ percent
+ on_payment
+
+
+ purchase
+
+
+
+
+
+
+
+ TVA à l'encaissement (achat) 10,0%
+ TVA 10%
+
+ percent
+ on_payment
+
+
+ purchase
+
+
+
+
+
TVA déductible (achat) 8,5%
@@ -810,6 +975,47 @@
]"/>
+
+
+ TVA à l'encaissement (achat) 5,5%
+ TVA 5,5%
+
+ percent
+ on_payment
+
+
+ purchase
+
+
+
+
+
TVA déductible (achat) 2,1%
@@ -851,6 +1057,47 @@
+
+
+ TVA à l'encaissement (achat) 2,1%
+ TVA 2,1%
+
+ percent
+ on_payment
+
+
+ purchase
+
+
+
+
+
TVA déductible (achat) 20,0% TTC
@@ -891,6 +1138,48 @@
]"/>
+
+
+ TVA à l'encaissement (achat) 20,0% TTC
+ TVA 20% TTC
+
+
+ percent
+ on_payment
+
+
+ purchase
+
+
+
+
+
TVA déductible (achat) 8,5% TTC
@@ -931,6 +1220,48 @@
]"/>
+
+
+ TVA à l'encaissement (achat) 10,0% TTC
+ TVA 10% TTC
+
+
+ percent
+ on_payment
+
+
+ purchase
+
+
+
+
+
TVA déductible (achat) 10,0% TTC
@@ -1011,6 +1342,48 @@
]"/>
+
+
+ TVA à l'encaissement (achat) 5,5% TTC
+ TVA 5,5% TTC
+
+
+ percent
+ on_payment
+
+
+ purchase
+
+
+
+
+
TVA déductible (achat) 2,1% TTC
@@ -1051,6 +1424,48 @@
]"/>
+
+
+ TVA à l'encaissement (achat) 2,1% TTC
+ TVA 2,1% TTC
+
+
+ percent
+ on_payment
+
+
+ purchase
+
+
+
+
+
diff --git a/addons/l10n_in/data/account_data.xml b/addons/l10n_in/data/account_data.xml
index c1fb9299c1e..c20cfa8839f 100644
--- a/addons/l10n_in/data/account_data.xml
+++ b/addons/l10n_in/data/account_data.xml
@@ -3,6 +3,12 @@
+
+ SGST
+
+
+ CGST
+
IGST
diff --git a/addons/l10n_in/data/account_tax_template_data.xml b/addons/l10n_in/data/account_tax_template_data.xml
index 6c0d3b8892e..374628bb05d 100644
--- a/addons/l10n_in/data/account_tax_template_data.xml
+++ b/addons/l10n_in/data/account_tax_template_data.xml
@@ -459,14 +459,14 @@ if tax > result:result=tax
-
- GST 1%
- GST 1%
- sale
+
+ SGST Sale 0.5%
+ SGST 0.5%
+ none
percent
- 1.0
+ 0.5
-
+
+
+
+
+ CGST Sale 0.5%
+ CGST 0.5%
+ none
+ percent
+ 0.5
+
+
+
+
+
+
+
+ GST 1%
+ GST 1%
+ sale
+ group
+ 1.0
+
+
+
+
+
+
+ SGST Sale 1%
+ SGST 1%
+ none
+ percent
+ 1
+
+
+
+
+
+
+
+ CGST Sale 1%
+ CGST 1%
+ none
+ percent
+ 1
+
+
+
+
@@ -511,10 +614,21 @@ if tax > result:result=tax
GST 2%
GST 2%
sale
- percent
+ group
2.0
+
+
+
+
+ SGST Sale 14%
+ SGST 14%
+ none
+ percent
+ 14
+
+
+
+
+
+ CGST Sale 14%
+ CGST 14%
+ none
+ percent
+ 14
+
+
+
+
@@ -559,10 +695,21 @@ if tax > result:result=tax
GST 28%
GST 28%
sale
- percent
+ group
28.0
+
+
+
+
+ SGST Sale 9%
+ SGST 9%
+ none
+ percent
+ 9
+
+
+
+
+
+ CGST Sale 9%
+ CGST 9%
+ none
+ percent
+ 9
+
+
+
+
@@ -607,43 +776,74 @@ if tax > result:result=tax
GST 18%
GST 18%
sale
- percent
+ group
18.0
+
+
+
+
+ SGST Sale 6%
+ SGST 6%
+ none
+ percent
+ 6
+
+
+
+
+
+ CGST Sale 6%
+ CGST 6%
+ none
+ percent
+ 6
+
+
+
+ GST 12%
GST 12%
sale
- percent
+ group
12.0
+
+
+
+
+ SGST Sale 2.5%
+ SGST 2.5%
+ none
+ percent
+ 2.5
+
+
+
+
+
+ CGST Sale 2.5%
+ CGST 2.5%
+ none
+ percent
+ 2.5
+
+
+
+
@@ -703,49 +936,12 @@ if tax > result:result=tax
GST 5%
GST 5%
sale
- percent
+ group
5.0
0
-
-
+
@@ -1166,31 +1362,25 @@ if tax > result:result=tax
-
- GST 1%
- GST 1%
- purchase
+
+ SGST Purchase 0.5%
+ SGST 0.5%
+ none
percent
- 1.0
+ 0.5
-
+
+
+
+
+ CGST Purchase 0.5%
+ CGST 0.5%
+ none
+ percent
+ 0.5
+
+
+
+
+
+ GST 1%
+ GST 1%
+ purchase
+ group
+ 1.0
+
+
+
+
+
+
+ SGST Purchase 1%
+ SGST 1%
+ none
+ percent
+ 1
+
+
+
+
+
+
+
+ CGST Purchase 1%
+ CGST 1%
+ none
+ percent
+ 1
+
+
+
+
+
+
+
GST 2%
GST 2%
purchase
- percent
+ group
2.0
+
+
+
+
+ SGST Purchase 14%
+ SGST 14%
+ none
+ percent
+ 14
+
+
+
+
+
+ CGST Purchase 14%
+ CGST 14%
+ none
+ percent
+ 14
+
+
+
+
@@ -1264,10 +1595,21 @@ if tax > result:result=tax
GST 28%
GST 28%
purchase
- percent
+ group
28.0
+
+
+
+
+ SGST Purchase 9%
+ SGST 9%
+ none
+ percent
+ 9
+
+
+
+
+
+ CGST Purchase 9%
+ CGST 9%
+ none
+ percent
+ 9
+
+
+
+
@@ -1312,10 +1676,21 @@ if tax > result:result=tax
GST 18%
GST 18%
purchase
- percent
+ group
18.0
+
+
+
+
+ SGST Purchase 6%
+ SGST 6%
+ none
+ percent
+ 6
+
+
+
+
+
+
+ CGST Purchase 6%
+ CGST 6%
+ none
+ percent
+ 6
+
+
+
@@ -1360,10 +1757,21 @@ if tax > result:result=tax
GST 12%
GST 12%
purchase
- percent
+ group
12.0
+
+
+
+
+ SGST Purchase 2.5%
+ SGST 2.5%
+ none
+ percent
+ 2.5
+
+
+
+
+
+ CGST Purchase 2.5%
+ CGST 2.5%
+ none
+ percent
+ 2.5
+
+
+
+
@@ -1408,49 +1838,12 @@ if tax > result:result=tax
GST 5%
GST 5%
purchase
- percent
+ group
5.0
0
-
-
+
diff --git a/addons/l10n_it_edi/models/account_invoice.py b/addons/l10n_it_edi/models/account_invoice.py
index 3a8d8361b95..77185ea4e3d 100644
--- a/addons/l10n_it_edi/models/account_invoice.py
+++ b/addons/l10n_it_edi/models/account_invoice.py
@@ -110,7 +110,7 @@ class AccountMove(models.Model):
raise UserError(_("%s must have a country.") % (seller.display_name))
# <1.4.1>
- if not buyer.vat and not buyer.l10n_it_codice_fiscale and buyer.country_id.code != 'IT':
+ if not buyer.vat and not buyer.l10n_it_codice_fiscale and buyer.country_id.code == 'IT':
raise UserError(_("The buyer, %s, or his company must have either a VAT number either a tax code (Codice Fiscale).") % (buyer.display_name))
# <1.4.2>
@@ -273,11 +273,12 @@ class AccountMove(models.Model):
'body': _('Sending file: %s to ES: %s') % (self.l10n_it_einvoice_id.name, self.env.company.l10n_it_address_recipient_fatturapa),
'author_id': self.env.user.partner_id.id,
'email_from': self.env.company.l10n_it_address_send_fatturapa,
+ 'reply_to': self.env.company.l10n_it_address_send_fatturapa,
'mail_server_id': self.env.company.l10n_it_mail_pec_server_id.id,
'attachment_ids': [(6, 0, self.l10n_it_einvoice_id.ids)],
})
- mail_fattura = self.env['mail.mail'].create({
+ mail_fattura = self.env['mail.mail'].with_context(wo_return_path=True).create({
'mail_message_id': message.id,
'email_to': self.env.company.l10n_it_address_recipient_fatturapa,
})
diff --git a/addons/l10n_it_edi/models/ir_mail_server.py b/addons/l10n_it_edi/models/ir_mail_server.py
index 581274ac404..18c4a66af3c 100644
--- a/addons/l10n_it_edi/models/ir_mail_server.py
+++ b/addons/l10n_it_edi/models/ir_mail_server.py
@@ -355,3 +355,17 @@ class FetchmailServer(models.Model):
if descrizione:
output_str += "
Errore %s: %s" % (element[0].text, descrizione)
return output_str + ""
+
+class IrMailServer(models.Model):
+ _name = "ir.mail_server"
+ _inherit = "ir.mail_server"
+
+ def build_email(self, email_from, email_to, subject, body, email_cc=None, email_bcc=None, reply_to=False,
+ attachments=None, message_id=None, references=None, object_id=False, subtype='plain', headers=None,
+ body_alternative=None, subtype_alternative='plain'):
+
+ if self.env.context.get('wo_return_path') and headers:
+ headers.pop('Return-Path', False)
+ return super(IrMailServer, self).build_email(email_from, email_to, subject, body, email_cc=email_cc, email_bcc=email_bcc, reply_to=reply_to,
+ attachments=attachments, message_id=message_id, references=references, object_id=object_id, subtype=subtype, headers=headers,
+ body_alternative=body_alternative, subtype_alternative=subtype_alternative)
diff --git a/addons/mail/static/src/js/discuss.js b/addons/mail/static/src/js/discuss.js
index 6eeeaecf7c3..de5ce88b742 100644
--- a/addons/mail/static/src/js/discuss.js
+++ b/addons/mail/static/src/js/discuss.js
@@ -280,6 +280,8 @@ var Discuss = AbstractAction.extend({
this.options.channelQuickSearchThreshold = 20;
}
+ this._isMessagingReady = this.call('mail_service', 'isReady');
+ this._isStarted = false;
this._threadsScrolltop = {};
this._composerStates = {};
this._defaultThreadID = this.options.active_id ||
@@ -291,68 +293,20 @@ var Discuss = AbstractAction.extend({
this._updateThreads.bind(this), 100, { leading: false });
this.controlPanelParams.modelName = 'mail.message';
- },
- /**
- * @override
- */
- willStart: function () {
- return Promise.all([this._super(), this.call('mail_service', 'isReady')]);
+ this.call('mail_service', 'getMailBus').on('messaging_ready', this, this._onMessagingReady);
},
/**
* @override
*/
start: function () {
var self = this;
-
- this._basicComposer = new BasicComposer(this, {
- mentionPartnersRestricted: true,
- showTyping: true,
+ this._isStarted = true;
+ return this._super.apply(this, arguments).then(function () {
+ if (!self._isMessagingReady) {
+ return;
+ }
+ return self._initRender();
});
- this._extendedComposer = new ExtendedComposer(this, {
- mentionPartnersRestricted: true,
- showTyping: true,
- });
- this._basicComposer
- .on('post_message', this, this._onPostMessage)
- .on('input_focused', this, this._onComposerFocused);
- this._extendedComposer
- .on('post_message', this, this._onPostMessage)
- .on('input_focused', this, this._onComposerFocused);
- this._renderButtons();
-
- var defs = [];
- defs.push(
- this._renderThread()
- );
- defs.push(
- this._basicComposer.appendTo(this.$('.o_mail_discuss_content')));
- defs.push(
- this._extendedComposer.appendTo(this.$('.o_mail_discuss_content')));
- defs.push(this._super.apply(this, arguments));
-
- return Promise.all(defs)
- .then(function () {
- return self._setThread(self._defaultThreadID);
- })
- .then(function () {
- self._initThreads();
- self._startListening();
- self._threadWidget.$el.on('scroll', null, _.debounce(function () {
- if (
- self._threadWidget.getScrolltop() < 20 &&
- !self._threadWidget.$('.o_mail_no_content').length &&
- !self._thread.isAllHistoryLoaded(self.domain)
- ) {
- self._loadMoreMessages();
- }
- if (
- self._threadWidget.isAtBottom() &&
- self._thread.getType() !== 'mailbox'
- ) {
- self._thread.markAsRead();
- }
- }, 100));
- });
},
/**
* @override
@@ -381,8 +335,8 @@ var Discuss = AbstractAction.extend({
this.call('mail_service', 'getMailBus').trigger('discuss_open', true);
if (this._thread) {
this._threadWidget.scrollToPosition(this._threadsScrolltop[this._thread.getID()]);
+ this._loadEnoughMessages();
}
- this._loadEnoughMessages();
},
/**
* @override
@@ -546,6 +500,60 @@ var Discuss = AbstractAction.extend({
}
}
},
+ /**
+ * @private
+ */
+ _initRender: function () {
+ var self = this;
+ this._basicComposer = new BasicComposer(this, {
+ mentionPartnersRestricted: true,
+ showTyping: true,
+ });
+ this._extendedComposer = new ExtendedComposer(this, {
+ mentionPartnersRestricted: true,
+ showTyping: true,
+ });
+ this._basicComposer
+ .on('post_message', this, this._onPostMessage)
+ .on('input_focused', this, this._onComposerFocused);
+ this._extendedComposer
+ .on('post_message', this, this._onPostMessage)
+ .on('input_focused', this, this._onComposerFocused);
+ this._renderButtons();
+
+ var defs = [];
+ defs.push(
+ this._renderThread()
+ );
+ defs.push(
+ this._basicComposer.appendTo(this.$('.o_mail_discuss_content')));
+ defs.push(
+ this._extendedComposer.appendTo(this.$('.o_mail_discuss_content')));
+
+ return Promise.all(defs)
+ .then(function () {
+ return self._setThread(self._defaultThreadID);
+ })
+ .then(function () {
+ self._initThreads();
+ self._startListening();
+ self._threadWidget.$el.on('scroll', null, _.debounce(function () {
+ if (
+ self._threadWidget.getScrolltop() < 20 &&
+ !self._threadWidget.$('.o_mail_no_content').length &&
+ !self._thread.isAllHistoryLoaded(self.domain)
+ ) {
+ self._loadMoreMessages();
+ }
+ if (
+ self._threadWidget.isAtBottom() &&
+ self._thread.getType() !== 'mailbox'
+ ) {
+ self._thread.markAsRead();
+ }
+ }, 100));
+ });
+ },
/**
* Renders the mainside bar with current threads
*
@@ -1400,6 +1408,20 @@ var Discuss = AbstractAction.extend({
this._fetchAndRenderThread();
}
},
+ /**
+ * @private
+ */
+ _onMessagingReady: function () {
+ if (this._isMessagingReady) {
+ return;
+ }
+ this._isMessagingReady = true;
+ if (!this._isStarted) {
+ return;
+ }
+ this.$('.o_mail_discuss_loading').remove();
+ this._initRender();
+ },
/**
* @private
* @param {MouseEvent} ev
diff --git a/addons/mail/static/src/js/services/mail_document_thread_manager.js b/addons/mail/static/src/js/services/mail_document_thread_manager.js
index 6bb66b1b439..652567baf14 100644
--- a/addons/mail/static/src/js/services/mail_document_thread_manager.js
+++ b/addons/mail/static/src/js/services/mail_document_thread_manager.js
@@ -34,7 +34,7 @@ MailManager.include({
this.call('local_storage', 'getItem', key);
}
}
- this.isReady().then(this._updateDocumentThreadWindows.bind(this, this._documentThreadWindowStates));
+ this._mailBus.on('messaging_ready', this, this._updateDocumentThreadWindows.bind(this, this._documentThreadWindowStates));
// listen to localStorage changes to synchronize DocumentThread's
// windows between tabs
this.call('local_storage', 'onStorage', this, this._onStorage);
diff --git a/addons/mail/static/src/js/services/mail_manager.js b/addons/mail/static/src/js/services/mail_manager.js
index 3ed4031abeb..950ac8c5cd6 100644
--- a/addons/mail/static/src/js/services/mail_manager.js
+++ b/addons/mail/static/src/js/services/mail_manager.js
@@ -46,6 +46,7 @@ var PREVIEW_MSG_MAX_SIZE = 350; // optimal for native english speakers
var MailManager = AbstractService.extend({
dependencies: ['ajax', 'bus_service', 'local_storage'],
+ _isReady: false,
_ODOOBOT_ID: ["ODOOBOT", "ODOOBOT"], // authorID for transient messages
/**
@@ -294,7 +295,7 @@ var MailManager = AbstractService.extend({
* This is the case when it has fetched the initial state from the server,
* by means of the route 'mail/init_messaging'
*
- * @returns {Promise}
+ * @returns {boolean}
*/
isReady: function () {
return this._isReady;
@@ -636,7 +637,7 @@ var MailManager = AbstractService.extend({
*/
_fetchMailStateFromServer: function () {
var self = this;
- this._isReady = session.is_bound.then(function () {
+ session.is_bound.then(function () {
var context = _.extend(
{ isMobile: config.device.isMobile },
session.user_context
@@ -648,6 +649,8 @@ var MailManager = AbstractService.extend({
}).then(function (result) {
self._updateInternalStateFromServer(result);
self.call('bus_service', 'startPolling');
+ self._isReady = true;
+ self._mailBus.trigger('messaging_ready');
});
},
/**
diff --git a/addons/mail/static/src/js/systray/systray_activity_menu.js b/addons/mail/static/src/js/systray/systray_activity_menu.js
index 641ff4be1bc..8afa88d7e20 100644
--- a/addons/mail/static/src/js/systray/systray_activity_menu.js
+++ b/addons/mail/static/src/js/systray/systray_activity_menu.js
@@ -19,9 +19,6 @@ var ActivityMenu = Widget.extend({
'click .o_mail_preview': '_onActivityFilterClick',
'show.bs.dropdown': '_onActivityMenuShow',
},
- willStart: function () {
- return Promise.resolve(this.call('mail_service', 'isReady'));
- },
start: function () {
this._$activitiesPreview = this.$('.o_mail_systray_dropdown_items');
this.call('mail_service', 'getMailBus').on('activity_updated', this, this._updateCounter);
diff --git a/addons/mail/static/src/js/systray/systray_messaging_menu.js b/addons/mail/static/src/js/systray/systray_messaging_menu.js
index f4c4eb48f39..1093a22d27a 100644
--- a/addons/mail/static/src/js/systray/systray_messaging_menu.js
+++ b/addons/mail/static/src/js/systray/systray_messaging_menu.js
@@ -27,12 +27,6 @@ var MessagingMenu = Widget.extend({
'click .o_thread_window_expand': '_onClickExpand',
'show.bs.dropdown': '_onShowDropdown',
},
- /**
- * @override
- */
- willStart: function () {
- return Promise.all([this._super.apply(this, arguments), this.call('mail_service', 'isReady')]);
- },
/**
* @override
*/
@@ -40,8 +34,10 @@ var MessagingMenu = Widget.extend({
this._$filterButtons = this.$('.o_filter_button');
this._$previews = this.$('.o_mail_systray_dropdown_items');
this._filter = false;
+ this._isMessagingReady = this.call('mail_service', 'isReady');
this._updateCounter();
var mailBus = this.call('mail_service', 'getMailBus');
+ mailBus.on('messaging_ready', this, this._onMessagingReady);
mailBus.on('update_needaction', this, this._updateCounter);
mailBus.on('new_channel', this, this._updateCounter);
mailBus.on('update_thread_unread_counter', this, this._updateCounter);
@@ -207,6 +203,9 @@ var MessagingMenu = Widget.extend({
_updatePreviews: function () {
// Display spinner while waiting for conversations preview
this._$previews.html(QWeb.render('Spinner'));
+ if (!this._isMessagingReady) {
+ return;
+ }
this._getPreviews()
.then(this._renderPreviews.bind(this));
},
@@ -229,7 +228,11 @@ var MessagingMenu = Widget.extend({
* @private
*/
_updateCounter: function () {
+ if (!this._isMessagingReady) {
+ return;
+ }
var counter = this._computeCounter();
+ this.$('.o_mail_messaging_menu_icon').removeClass('fa-spinner fa-spin');
this.$('.o_notification_counter').text(counter);
this.$el.toggleClass('o_no_notification', !counter);
if (this._isShown()) {
@@ -338,6 +341,16 @@ var MessagingMenu = Widget.extend({
}
}
},
+ /**
+ * @private
+ */
+ _onMessagingReady: function () {
+ if (this._isMessagingReady) {
+ return;
+ }
+ this._isMessagingReady = true;
+ this._updateCounter();
+ },
});
// Systray menu items display order matches order in the list
diff --git a/addons/mail/static/src/js/thread_field.js b/addons/mail/static/src/js/thread_field.js
index ab8023b06ad..c8a59850016 100644
--- a/addons/mail/static/src/js/thread_field.js
+++ b/addons/mail/static/src/js/thread_field.js
@@ -20,23 +20,21 @@ var ThreadField = AbstractField.extend({
*/
init: function () {
this._super.apply(this, arguments);
+ this._isMessagingReady = this.call('mail_service', 'isReady');
+ this._isStarted = false;
+ this.call('mail_service', 'getMailBus').on('messaging_ready', this, this._onMessagingReady);
// Used to automatically mark document thread as read at the moment we
// access the document and render the thread.
this._markAsReadOnNextRender = false;
this._setDocumentThread();
},
- /**
- * @override
- */
- willStart: function () {
- return this.alive(this.call('mail_service', 'isReady'));
- },
/**
* @override
*/
start: function () {
var self = this;
+ this._isStarted = true;
this.dp = new concurrency.DropPrevious();
this._threadWidget = new ThreadWidget(this, {
@@ -159,6 +157,9 @@ var ThreadField = AbstractField.extend({
* If it is a new document in create mode, unset the document thread.
*/
_setDocumentThread: function () {
+ if (!this._isMessagingReady) {
+ return;
+ }
var params = {
messageIDs: this.value.res_ids,
name: this.recordData.display_name,
@@ -185,6 +186,19 @@ var ThreadField = AbstractField.extend({
_onLoadMoreMessages: function () {
this._fetchAndRenderThread({ forceFetch: true });
},
+ /**
+ * @private
+ */
+ _onMessagingReady: function () {
+ if (this._isMessagingReady) {
+ return;
+ }
+ this._isMessagingReady = true;
+ if (!this._isStarted) {
+ return;
+ }
+ this._setDocumentThread();
+ },
/**
* @private
* @param {mail.model.Message}
diff --git a/addons/mail/static/src/scss/discuss.scss b/addons/mail/static/src/scss/discuss.scss
index 8284fdc70b5..4cb902e4539 100644
--- a/addons/mail/static/src/scss/discuss.scss
+++ b/addons/mail/static/src/scss/discuss.scss
@@ -7,6 +7,18 @@
height: 100%;
overflow: hidden;
+ .o_mail_discuss_loading {
+ display: flex;
+ flex: 1 1 auto;
+ align-items: center;
+ justify-content: center;
+ min-height: 100%;
+
+ > i {
+ margin-right: 5px;
+ }
+ }
+
.o_mail_discuss_sidebar {
width: $o-mail-chat-sidebar-width;
height: 100%;
diff --git a/addons/mail/static/src/xml/discuss.xml b/addons/mail/static/src/xml/discuss.xml
index afee3a84da2..781a03c016d 100644
--- a/addons/mail/static/src/xml/discuss.xml
+++ b/addons/mail/static/src/xml/discuss.xml
@@ -8,8 +8,15 @@
-->
diff --git a/addons/mail/static/src/xml/systray.xml b/addons/mail/static/src/xml/systray.xml
index 7bcda0fb273..204af3700e4 100644
--- a/addons/mail/static/src/xml/systray.xml
+++ b/addons/mail/static/src/xml/systray.xml
@@ -7,7 +7,7 @@
-
+