summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2019-09-24 16:59:15 +0000
committerChristophe Simonis <chs@odoo.com>2019-09-24 17:45:37 +0000
commitd67b2483e5bfa5d8c1e6ef1a64fb933f5e080ad5 (patch)
tree25a7fd39ac993f3c04c5d8408beb628b3c9948ce /addons
parent38d8b0526f0fccc32df5a11f5d086a3522ed5fcf (diff)
parent9ed4872ea03f28012118ed48a43d0800617a84f3 (diff)
[MERGE] forward port branch saas-12.4 up to 9ed4872ea03
closes odoo/odoo#37372 Signed-off-by: Christophe Simonis <chs@odoo.com>
Diffstat (limited to 'addons')
-rw-r--r--addons/account/models/account_move.py17
-rw-r--r--addons/account/models/account_reconcile_model.py2
-rw-r--r--addons/account/models/reconciliation_widget.py11
-rw-r--r--addons/account/models/res_users.py8
-rw-r--r--addons/account/tests/account_test_no_chart.py4
-rw-r--r--addons/account/tests/test_account_move_entry.py1
-rw-r--r--addons/account/tests/test_account_move_partner_count.py11
-rw-r--r--addons/account/tests/test_reconciliation_widget.py32
-rw-r--r--addons/account/views/account_view.xml2
-rw-r--r--addons/auth_signup/models/res_partner.py2
-rw-r--r--addons/digest/data/res_config_settings_data.xml6
-rw-r--r--addons/event/controllers/main.py2
-rw-r--r--addons/hr_org_chart/controllers/hr_org_chart.py4
-rw-r--r--addons/l10n_fr/data/account_fiscal_position_template_data.xml80
-rw-r--r--addons/l10n_fr/data/account_tax_data.xml415
-rw-r--r--addons/l10n_in/data/account_data.xml6
-rw-r--r--addons/l10n_in/data/account_tax_template_data.xml755
-rw-r--r--addons/l10n_it_edi/models/account_invoice.py5
-rw-r--r--addons/l10n_it_edi/models/ir_mail_server.py14
-rw-r--r--addons/mail/static/src/js/discuss.js134
-rw-r--r--addons/mail/static/src/js/services/mail_document_thread_manager.js2
-rw-r--r--addons/mail/static/src/js/services/mail_manager.js7
-rw-r--r--addons/mail/static/src/js/systray/systray_activity_menu.js3
-rw-r--r--addons/mail/static/src/js/systray/systray_messaging_menu.js25
-rw-r--r--addons/mail/static/src/js/thread_field.js26
-rw-r--r--addons/mail/static/src/scss/discuss.scss12
-rw-r--r--addons/mail/static/src/xml/discuss.xml9
-rw-r--r--addons/mail/static/src/xml/systray.xml2
-rw-r--r--addons/mail/static/tests/discuss_tests.js50
-rw-r--r--addons/mail/static/tests/systray/systray_messaging_menu_tests.js47
-rw-r--r--addons/mrp/models/mrp_production.py1
-rw-r--r--addons/payment/models/payment_acquirer.py14
-rw-r--r--addons/payment_stripe/models/payment.py42
-rw-r--r--addons/product/models/product_pricelist.py6
-rw-r--r--addons/product/models/product_template.py2
-rw-r--r--addons/purchase/tests/test_purchase_order_report.py2
-rw-r--r--addons/sale/tests/test_reinvoice.py19
-rw-r--r--addons/sale/tests/test_sale_order.py1
-rw-r--r--addons/stock/models/stock_move.py7
-rw-r--r--addons/stock/models/stock_picking.py36
-rw-r--r--addons/stock/tests/test_move2.py14
-rw-r--r--addons/survey/controllers/main.py16
-rw-r--r--addons/survey/static/src/js/survey.js10
-rw-r--r--addons/web/static/src/css/reset.min.css4
-rw-r--r--addons/web/static/src/js/core/dom.js2
-rw-r--r--addons/web/static/src/js/fields/field_utils.js4
-rw-r--r--addons/web/static/src/js/fields/relational_fields.js2
-rw-r--r--addons/web/static/src/js/views/list/list_controller.js13
-rw-r--r--addons/web/static/src/js/widgets/date_picker.js8
-rw-r--r--addons/web/static/tests/fields/basic_fields_tests.js36
-rw-r--r--addons/web/static/tests/fields/field_utils_tests.js34
-rw-r--r--addons/web/static/tests/views/search_view_tests.js1
-rw-r--r--addons/website/static/src/scss/website.scss8
-rw-r--r--addons/website_event_questions/report/report_event_question_view.xml3
-rw-r--r--addons/website_sale/data/mail_template_data.xml2
-rw-r--r--addons/website_sale_wishlist/controllers/main.py2
56 files changed, 1644 insertions, 339 deletions
diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py
index e0fbfbc1873..131ca0f3a53 100644
--- a/addons/account/models/account_move.py
+++ b/addons/account/models/account_move.py
@@ -1220,10 +1220,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'],
@@ -1315,7 +1320,7 @@ class AccountMove(models.Model):
self.env['account.move.line'].flush(['debit', 'credit', 'move_id'])
self.env['account.move'].flush(['journal_id'])
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
@@ -1329,7 +1334,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))
def _check_fiscalyear_lock_date(self):
for move in self:
@@ -2060,7 +2066,6 @@ class AccountMove(models.Model):
"""
if any(not move.is_invoice(include_receipts=True) for move in self):
raise UserError(_("Only invoices could be printed."))
- self._check_tax_lock_date()
self.filtered(lambda inv: not inv.invoice_sent).write({'invoice_sent': True})
if self.user_has_groups('account.group_account_invoice'):
@@ -2309,7 +2314,7 @@ class AccountMoveLine(models.Model):
),
(
'check_accountable_required_fields',
- "CHECK(display_type IN ('line_section', 'line_note') OR account_id IS NOT NULL)",
+ "CHECK(COALESCE(display_type IN ('line_section', 'line_note'), 'f') OR account_id IS NOT NULL)",
"Missing required account on accountable invoice line."
),
(
@@ -2794,7 +2799,7 @@ class AccountMoveLine(models.Model):
currency = record.company_id.currency_id
audit_str = ''
for tag in record.tag_ids:
- tag_amount = (tag.tax_negate and -1 or 1) * (record.move_id.is_outbound() and -1 or 1) * record.balance
+ tag_amount = (tag.tax_negate and -1 or 1) * (record.move_id.is_inbound() and -1 or 1) * record.balance
if tag.tax_report_line_ids:
#Then, the tag comes from a report line, and hence has a + or - sign (also in its name)
diff --git a/addons/account/models/account_reconcile_model.py b/addons/account/models/account_reconcile_model.py
index 56a8fc81a4e..147c8334a67 100644
--- a/addons/account/models/account_reconcile_model.py
+++ b/addons/account/models/account_reconcile_model.py
@@ -265,6 +265,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)
@@ -298,6 +299,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 a52aa1ee3b3..d17d1e21ef4 100644
--- a/addons/account/models/reconciliation_widget.py
+++ b/addons/account/models/reconciliation_widget.py
@@ -556,10 +556,8 @@ 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)]])
if mode == 'rp':
domain = expression.AND([domain,
[('account_id.internal_type', 'in', ['receivable', 'payable', 'liquidity'])]
@@ -572,14 +570,10 @@ class AccountReconciliation(models.AbstractModel):
# 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
@@ -596,7 +590,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 6b379668fa3..d564746dfd6 100644
--- a/addons/account/models/res_users.py
+++ b/addons/account/models/res_users.py
@@ -12,8 +12,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/account_test_no_chart.py b/addons/account/tests/account_test_no_chart.py
index fbd895fdb46..61cbe3e47a6 100644
--- a/addons/account/tests/account_test_no_chart.py
+++ b/addons/account/tests/account_test_no_chart.py
@@ -83,12 +83,16 @@ class TestAccountNoChartCommon(SavepointCase):
'code': 'AJ-PURC',
'type': 'purchase',
'company_id': cls.env.user.company_id.id,
+ 'default_debit_account_id': cls.account_expense.id,
+ 'default_credit_account_id': cls.account_expense.id,
})
cls.journal_sale = cls.env['account.journal'].create({
'name': 'Sale Journal - Test',
'code': 'AJ-SALE',
'type': 'sale',
'company_id': cls.env.user.company_id.id,
+ 'default_debit_account_id': cls.account_income.id,
+ 'default_credit_account_id': cls.account_income.id,
})
cls.journal_general = cls.env['account.journal'].create({
'name': 'General Journal - Test',
diff --git a/addons/account/tests/test_account_move_entry.py b/addons/account/tests/test_account_move_entry.py
index 587dfc48deb..d3c3503ff5a 100644
--- a/addons/account/tests/test_account_move_entry.py
+++ b/addons/account/tests/test_account_move_entry.py
@@ -60,6 +60,7 @@ class TestAccountMove(InvoiceTestCommon):
self.env['account.move'].create(self.test_move.copy_data())
def test_misc_tax_lock_date_1(self):
+ self.test_move.post()
# Set the tax lock date after the journal entry date.
self.test_move.company_id.tax_lock_date = fields.Date.from_string('2017-01-01')
diff --git a/addons/account/tests/test_account_move_partner_count.py b/addons/account/tests/test_account_move_partner_count.py
index 7ec2b6cc410..68527cf7572 100644
--- a/addons/account/tests/test_account_move_partner_count.py
+++ b/addons/account/tests/test_account_move_partner_count.py
@@ -1,9 +1,11 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
+from odoo.tests import tagged
from odoo.tests.common import TransactionCase
+@tagged('post_install', '-at_install')
class TestAccountMovePartnerCount(TransactionCase):
def setUp(self):
@@ -14,6 +16,13 @@ class TestAccountMovePartnerCount(TransactionCase):
with self.registry.cursor() as cr:
env = self.env(cr=cr)
self.partner = self.env['res.partner'].with_env(env).create({'name': 'Lucien'})
+ user_type_income = env.ref('account.data_account_type_direct_costs')
+ self.account_income = self.env['account.account'].with_env(env).create({
+ 'code': 'TESTCOUNT42',
+ 'name': 'Sale - Test Account',
+ 'user_type_id': user_type_income.id
+ })
+
self.journal = self.env['account.journal'].with_env(env).create({
'name': 'Journal',
'code': '7775',
@@ -28,6 +37,7 @@ class TestAccountMovePartnerCount(TransactionCase):
self.line = self.env['account.move.line'].with_env(env).create({
'move_id': self.move.id,
'name': 'account move line test',
+ 'account_id': self.account_income.id,
})
def tearDown(self):
@@ -38,6 +48,7 @@ class TestAccountMovePartnerCount(TransactionCase):
move.state = 'draft'
move.unlink()
self.journal.with_env(env).unlink()
+ self.account_income.with_env(env).unlink()
self.partner.with_env(env).unlink()
def test_account_move_count(self):
diff --git a/addons/account/tests/test_reconciliation_widget.py b/addons/account/tests/test_reconciliation_widget.py
index 99769bc2f2e..0baa2c23f8b 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,33 @@ 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,
+ mode="rp",
+ )
+ mv_lines_ids = [l['id'] for l in mv_lines_rec]
+
+ self.assertIn(receivable1.id, mv_lines_ids)
+ self.assertIn(receivable2.id, 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,
+ mode="rp",
+ )
+ mv_lines_ids = [l['id'] for l in mv_lines_rec]
+
+ self.assertIn(receivable1.id, mv_lines_ids)
+ self.assertNotIn(receivable2.id, 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,
@@ -88,8 +115,7 @@ class TestReconciliationWidget(TestReconciliation):
self.assertIn(receivable1.id, mv_lines_ids)
self.assertIn(receivable2.id, 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 a488cc09ed0..07e733d0b42 100644
--- a/addons/account/views/account_view.xml
+++ b/addons/account/views/account_view.xml
@@ -1265,7 +1265,7 @@ action = model.setting_init_bank_account_action()
<field name="include_base_amount" attrs="{'invisible':[('amount_type','=', 'group')]}" />
<field name="hide_tax_exigibility" invisible="1"/>
<field name="tax_exigibility" widget="radio" attrs="{'invisible':['|', ('amount_type','=', 'group'), ('hide_tax_exigibility', '=', False)]}" groups="account.group_account_user"/>
- <field name="cash_basis_base_account_id" options="{'no_create': True}" attrs="{'invisible': [('tax_exigibility', '=', 'on_invoice')], 'required': [('tax_exigibility', '=', 'on_payment')]}" groups="account.group_account_user"/>
+ <field name="cash_basis_base_account_id" options="{'no_create': True}" attrs="{'invisible': [('tax_exigibility', '=', 'on_invoice')]}" groups="account.group_account_user"/>
<field name="cash_basis_transition_account_id" options="{'no_create': True}" attrs="{'invisible': [('tax_exigibility', '=', 'on_invoice')], 'required': [('tax_exigibility', '=', 'on_payment')]}" groups="account.group_account_user"/>
</group>
</group>
diff --git a/addons/auth_signup/models/res_partner.py b/addons/auth_signup/models/res_partner.py
index b92e5dc55f5..259a5838b30 100644
--- a/addons/auth_signup/models/res_partner.py
+++ b/addons/auth_signup/models/res_partner.py
@@ -109,7 +109,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 @@
<?xml version='1.0' encoding='utf-8'?>
-<odoo>
- <record id="default_emails_digest" model="ir.config_parameter">
+<odoo noupdate="1">
+ <record id="default_emails_digest" model="ir.config_parameter" forcecreate="0">
<field name="key">digest.default_digest_emails</field>
<field name="value">True</field>
</record>
- <record id="default_digest" model="ir.config_parameter">
+ <record id="default_digest" model="ir.config_parameter" forcecreate="0">
<field name="key">digest.default_digest_id</field>
<field name="value" ref="digest.digest_digest_default"/>
</record>
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/<model("event.event", "[('state', 'in', ('confirm', 'done'))]"):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/hr_org_chart/controllers/hr_org_chart.py b/addons/hr_org_chart/controllers/hr_org_chart.py
index 8df4c81ae40..f9160767995 100644
--- a/addons/hr_org_chart/controllers/hr_org_chart.py
+++ b/addons/hr_org_chart/controllers/hr_org_chart.py
@@ -14,8 +14,8 @@ class HrOrgChartController(http.Controller):
return None
employee_id = int(employee_id)
- if ('context' in kw and 'allowed_company_ids' in kw['context']):
- cids = kw['context']['allowed_company_ids']
+ if 'allowed_company_ids' in request.env.context:
+ cids = request.env.context['allowed_company_ids']
else:
cids = [request.env.company.id]
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 @@
<field name="tax_src_id" ref="tva_normale_ttc" />
<field name="tax_dest_id" ref="tva_intra_0" />
</record>
+ <record id="fp_tax_template_intraeub2b_vt_intermediaire_encaissement" model="account.fiscal.position.tax.template">
+ <field name="position_id" ref="fiscal_position_template_intraeub2b" />
+ <field name="tax_src_id" ref="tva_intermediaire_encaissement" />
+ <field name="tax_dest_id" ref="tva_intra_0" />
+ </record>
<record id="fp_tax_template_intraeub2b_vt_normale_encaissement" model="account.fiscal.position.tax.template">
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
<field name="tax_src_id" ref="tva_normale_encaissement" />
@@ -64,6 +69,11 @@
<field name="tax_src_id" ref="tva_normale_encaissement_ttc" />
<field name="tax_dest_id" ref="tva_intra_0" />
</record>
+ <record id="fp_tax_template_intraeub2b_vt_intermediaire_encaissement_ttc" model="account.fiscal.position.tax.template">
+ <field name="position_id" ref="fiscal_position_template_intraeub2b" />
+ <field name="tax_src_id" ref="tva_intermediaire_encaissement_ttc" />
+ <field name="tax_dest_id" ref="tva_intra_0" />
+ </record>
<!-- Taux DOM-TOM -->
<record id="fp_tax_template_intraeub2b_vt_specifique" model="account.fiscal.position.tax.template">
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
@@ -146,11 +156,31 @@
<field name="tax_src_id" ref="tva_acq_specifique" />
<field name="tax_dest_id" ref="tva_intra_specifique" />
</record>
+ <record id="fp_tax_template_intraeub2b_ha_encaissement_deduc" model="account.fiscal.position.tax.template">
+ <field name="position_id" ref="fiscal_position_template_intraeub2b" />
+ <field name="tax_src_id" ref="tva_acq_encaissement" />
+ <field name="tax_dest_id" ref="tva_intra_normale" />
+ </record>
<record id="fp_tax_template_intraeub2b_ha_specifique_acq" model="account.fiscal.position.tax.template">
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
<field name="tax_src_id" ref="tva_acq_specifique" />
<field name="tax_dest_id" ref="tva_acq_intra_specifique" />
</record>
+ <record id="fp_tax_template_intraeub2b_ha_encaissement_acq" model="account.fiscal.position.tax.template">
+ <field name="position_id" ref="fiscal_position_template_intraeub2b" />
+ <field name="tax_src_id" ref="tva_acq_encaissement" />
+ <field name="tax_dest_id" ref="tva_acq_intra_normale" />
+ </record>
+ <record id="fp_tax_template_intraeub2b_ha_encaissement_deduc" model="account.fiscal.position.tax.template">
+ <field name="position_id" ref="fiscal_position_template_intraeub2b" />
+ <field name="tax_src_id" ref="tva_acq_intermediaire_encaissement" />
+ <field name="tax_dest_id" ref="tva_intra_intermediaire" />
+ </record>
+ <record id="fp_tax_template_intraeub2b_ha_encaissement_acq" model="account.fiscal.position.tax.template">
+ <field name="position_id" ref="fiscal_position_template_intraeub2b" />
+ <field name="tax_src_id" ref="tva_acq_intermediaire_encaissement" />
+ <field name="tax_dest_id" ref="tva_acq_intra_intermediaire" />
+ </record>
<!-- Taux Intermédiaire -->
<record id="fp_tax_template_intraeub2b_ha_intermediaire_deduc" model="account.fiscal.position.tax.template">
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
@@ -168,22 +198,42 @@
<field name="tax_src_id" ref="tva_acq_reduite" />
<field name="tax_dest_id" ref="tva_intra_reduite" />
</record>
+ <record id="fp_tax_template_intraeub2b_ha_encaissement_reduite_deduc" model="account.fiscal.position.tax.template">
+ <field name="position_id" ref="fiscal_position_template_intraeub2b" />
+ <field name="tax_src_id" ref="tva_acq_encaissement_reduite" />
+ <field name="tax_dest_id" ref="tva_intra_reduite" />
+ </record>
<record id="fp_tax_template_intraeub2b_ha_reduite_acq" model="account.fiscal.position.tax.template">
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
<field name="tax_src_id" ref="tva_acq_reduite" />
<field name="tax_dest_id" ref="tva_acq_intra_reduite" />
</record>
+ <record id="fp_tax_template_intraeub2b_ha_encaissement_reduite_acq" model="account.fiscal.position.tax.template">
+ <field name="position_id" ref="fiscal_position_template_intraeub2b" />
+ <field name="tax_src_id" ref="tva_acq_encaissement_reduite" />
+ <field name="tax_dest_id" ref="tva_acq_intra_reduite" />
+ </record>
<!-- Taux super réduit -->
<record id="fp_tax_template_intraeub2b_ha_super_reduite_deduc" model="account.fiscal.position.tax.template">
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
<field name="tax_src_id" ref="tva_acq_super_reduite" />
<field name="tax_dest_id" ref="tva_intra_super_reduite" />
</record>
+ <record id="fp_tax_template_intraeub2b_ha_encaissement_super_reduite_deduc" model="account.fiscal.position.tax.template">
+ <field name="position_id" ref="fiscal_position_template_intraeub2b" />
+ <field name="tax_src_id" ref="tva_acq_encaissement_super_reduite" />
+ <field name="tax_dest_id" ref="tva_intra_super_reduite" />
+ </record>
<record id="fp_tax_template_intraeub2b_ha_super_reduite_acq" model="account.fiscal.position.tax.template">
<field name="position_id" ref="fiscal_position_template_intraeub2b" />
<field name="tax_src_id" ref="tva_acq_super_reduite" />
<field name="tax_dest_id" ref="tva_acq_intra_super_reduite" />
</record>
+ <record id="fp_tax_template_intraeub2b_ha_encaissement_super_reduite_acq" model="account.fiscal.position.tax.template">
+ <field name="position_id" ref="fiscal_position_template_intraeub2b" />
+ <field name="tax_src_id" ref="tva_acq_encaissement_super_reduite" />
+ <field name="tax_dest_id" ref="tva_acq_intra_super_reduite" />
+ </record>
<!-- Import/Export + DOM/TOM -->
<!-- ventes -->
@@ -203,11 +253,21 @@
<field name="tax_src_id" ref="tva_normale_encaissement" />
<field name="tax_dest_id" ref="tva_export_0" />
</record>
+ <record id="fp_tax_template_impexp_vt_intermediaire_encaissement" model="account.fiscal.position.tax.template">
+ <field name="position_id" ref="fiscal_position_template_import_export" />
+ <field name="tax_src_id" ref="tva_intermediaire_encaissement" />
+ <field name="tax_dest_id" ref="tva_export_0" />
+ </record>
<record id="fp_tax_template_impexp_vt_normale_encaissement_ttc" model="account.fiscal.position.tax.template">
<field name="position_id" ref="fiscal_position_template_import_export" />
<field name="tax_src_id" ref="tva_normale_encaissement_ttc" />
<field name="tax_dest_id" ref="tva_export_0" />
</record>
+ <record id="fp_tax_template_impexp_vt_intermediaire_encaissement_ttc" model="account.fiscal.position.tax.template">
+ <field name="position_id" ref="fiscal_position_template_import_export" />
+ <field name="tax_src_id" ref="tva_intermediaire_encaissement_ttc" />
+ <field name="tax_dest_id" ref="tva_export_0" />
+ </record>
<!-- Taux DOM-TOM -->
<record id="fp_tax_template_impexp_vt_specifique" model="account.fiscal.position.tax.template">
<field name="position_id" ref="fiscal_position_template_import_export" />
@@ -280,6 +340,11 @@
<field name="tax_dest_id" ref="tva_import_0" />
</record>
<!-- Taux DOM-TOM -->
+ <record id="fp_tax_template_impexp_ha_encaissement" model="account.fiscal.position.tax.template">
+ <field name="position_id" ref="fiscal_position_template_import_export" />
+ <field name="tax_src_id" ref="tva_acq_encaissement" />
+ <field name="tax_dest_id" ref="tva_import_0" />
+ </record>
<record id="fp_tax_template_impexp_ha_specifique" model="account.fiscal.position.tax.template">
<field name="position_id" ref="fiscal_position_template_import_export" />
<field name="tax_src_id" ref="tva_acq_specifique" />
@@ -291,12 +356,27 @@
<field name="tax_src_id" ref="tva_acq_intermediaire" />
<field name="tax_dest_id" ref="tva_import_0" />
</record>
+ <record id="fp_tax_template_impexp_ha_intermediaire" model="account.fiscal.position.tax.template">
+ <field name="position_id" ref="fiscal_position_template_import_export" />
+ <field name="tax_src_id" ref="tva_acq_intermediaire_encaissement" />
+ <field name="tax_dest_id" ref="tva_import_0" />
+ </record>
<!-- Taux Réduit -->
<record id="fp_tax_template_impexp_ha_reduite" model="account.fiscal.position.tax.template">
<field name="position_id" ref="fiscal_position_template_import_export" />
<field name="tax_src_id" ref="tva_acq_reduite" />
<field name="tax_dest_id" ref="tva_import_0" />
</record>
+ <record id="fp_tax_template_impexp_ha_encaissement_super_reduite" model="account.fiscal.position.tax.template">
+ <field name="position_id" ref="fiscal_position_template_import_export" />
+ <field name="tax_src_id" ref="tva_acq_encaissement_super_reduite" />
+ <field name="tax_dest_id" ref="tva_import_0" />
+ </record>
+ <record id="fp_tax_template_impexp_ha_encaissement_reduite" model="account.fiscal.position.tax.template">
+ <field name="position_id" ref="fiscal_position_template_import_export" />
+ <field name="tax_src_id" ref="tva_acq_encaissement_reduite" />
+ <field name="tax_dest_id" ref="tva_import_0" />
+ </record>
<!-- Taux super réduit -->
<record id="fp_tax_template_impexp_ha_super_reduite" model="account.fiscal.position.tax.template">
<field name="position_id" ref="fiscal_position_template_import_export" />
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 @@
]"/>
</record>
+ <record model="account.tax.template" id="tva_intermediaire_encaissement">
+ <field name="chart_template_id" ref="l10n_fr_pcg_chart_template"/>
+ <field name="name">TVA à l'encaissement (vente) 10,0%</field>
+ <field name="description">TVA 10%</field>
+ <field name="amount" eval="10.0"/>
+ <field name="amount_type">percent</field>
+ <field name="tax_exigibility">on_payment</field>
+ <field name="cash_basis_transition_account_id" ref="pcg_445712" />
+ <field name="sequence" eval="10"/>
+ <field name="type_tax_use">sale</field>
+ <field name="tax_group_id" ref="tax_group_tva_10"/>
+ <field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ 'plus_report_line_ids': [ref('l10n_fr.tax_report_base_coll_10')],
+ }),
+
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'plus_report_line_ids': [ref('l10n_fr.tax_report_tva_coll_10')],
+ 'account_id': ref('pcg_445800'),
+ }),
+ ]"/>
+ <field name="refund_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ 'minus_report_line_ids': [ref('l10n_fr.tax_report_base_coll_10')],
+ }),
+
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'minus_report_line_ids': [ref('l10n_fr.tax_report_tva_coll_10')],
+ 'account_id': ref('pcg_445712'),
+ }),
+ ]"/>
+ </record>
+
<record model="account.tax.template" id="tva_normale_encaissement">
<field name="chart_template_id" ref="l10n_fr_pcg_chart_template"/>
<field name="name">TVA à l'encaissement (vente) 20,0%</field>
@@ -367,6 +408,48 @@
]"/>
</record>
+ <record model="account.tax.template" id="tva_intermediaire_encaissement_ttc">
+ <field name="chart_template_id" ref="l10n_fr_pcg_chart_template"/>
+ <field name="name">TVA à l'encaissement (vente) 10,0% TTC</field>
+ <field name="description">TVA 10% TTC</field>
+ <field name="price_include" eval="1"/>
+ <field name="amount" eval="10"/>
+ <field name="amount_type">percent</field>
+ <field name="tax_exigibility">on_payment</field>
+ <field name="cash_basis_transition_account_id" ref="pcg_445712" />
+ <field name="sequence" eval="10"/>
+ <field name="type_tax_use">sale</field>
+ <field name="tax_group_id" ref="tax_group_tva_10"/>
+ <field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ 'plus_report_line_ids': [ref('l10n_fr.tax_report_base_coll_10')],
+ }),
+
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'plus_report_line_ids': [ref('l10n_fr.tax_report_tva_coll_10')],
+ 'account_id': ref('pcg_445800'),
+ }),
+ ]"/>
+ <field name="refund_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ 'minus_report_line_ids': [ref('l10n_fr.tax_report_base_coll_10')],
+ }),
+
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'minus_report_line_ids': [ref('l10n_fr.tax_report_tva_coll_10')],
+ 'account_id': ref('pcg_445712'),
+ }),
+ ]"/>
+ </record>
+
<record model="account.tax.template" id="tva_normale_encaissement_ttc">
<field name="chart_template_id" ref="l10n_fr_pcg_chart_template"/>
<field name="name">TVA à l'encaissement (vente) 20,0% TTC</field>
@@ -693,6 +776,88 @@
]"/>
</record>
+ <record model="account.tax.template" id="tva_acq_encaissement">
+ <field name="chart_template_id" ref="l10n_fr_pcg_chart_template"/>
+ <field name="name">TVA à l'encaissement (achat) 20,0%</field>
+ <field name="description">TVA 20%</field>
+ <field name="amount" eval="20.0"/>
+ <field name="amount_type">percent</field>
+ <field name="tax_exigibility">on_payment</field>
+ <field name="cash_basis_transition_account_id" ref="pcg_44566" />
+ <field name="sequence" eval="10"/>
+ <field name="type_tax_use">purchase</field>
+ <field name="tax_group_id" ref="tax_group_tva_20"/>
+ <field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ 'plus_report_line_ids': [ref('l10n_fr.tax_report_base_coll_20')],
+ }),
+
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'plus_report_line_ids': [ref('l10n_fr.tax_report_tva_coll_20')],
+ 'account_id': ref('pcg_445800'),
+ }),
+ ]"/>
+ <field name="refund_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ 'minus_report_line_ids': [ref('l10n_fr.tax_report_base_coll_20')],
+ }),
+
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'minus_report_line_ids': [ref('l10n_fr.tax_report_tva_coll_20')],
+ 'account_id': ref('pcg_44566'),
+ }),
+ ]"/>
+ </record>
+
+ <record model="account.tax.template" id="tva_acq_intermediaire_encaissement">
+ <field name="chart_template_id" ref="l10n_fr_pcg_chart_template"/>
+ <field name="name">TVA à l'encaissement (achat) 10,0%</field>
+ <field name="description">TVA 10%</field>
+ <field name="amount" eval="10.0"/>
+ <field name="amount_type">percent</field>
+ <field name="tax_exigibility">on_payment</field>
+ <field name="cash_basis_transition_account_id" ref="pcg_44566" />
+ <field name="sequence" eval="10"/>
+ <field name="type_tax_use">purchase</field>
+ <field name="tax_group_id" ref="tax_group_tva_10"/>
+ <field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ 'plus_report_line_ids': [ref('l10n_fr.tax_report_base_coll_10')],
+ }),
+
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'plus_report_line_ids': [ref('l10n_fr.tax_report_tva_coll_10')],
+ 'account_id': ref('pcg_445800'),
+ }),
+ ]"/>
+ <field name="refund_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ 'minus_report_line_ids': [ref('l10n_fr.tax_report_base_coll_10')],
+ }),
+
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'minus_report_line_ids': [ref('l10n_fr.tax_report_tva_coll_10')],
+ 'account_id': ref('pcg_44566'),
+ }),
+ ]"/>
+ </record>
+
<record model="account.tax.template" id="tva_acq_specifique">
<field name="chart_template_id" ref="l10n_fr_pcg_chart_template"/>
<field name="name">TVA déductible (achat) 8,5%</field>
@@ -810,6 +975,47 @@
]"/>
</record>
+ <record model="account.tax.template" id="tva_acq_encaissement_reduite">
+ <field name="chart_template_id" ref="l10n_fr_pcg_chart_template"/>
+ <field name="name">TVA à l'encaissement (achat) 5,5%</field>
+ <field name="description">TVA 5,5%</field>
+ <field name="amount" eval="5.5"/>
+ <field name="amount_type">percent</field>
+ <field name="tax_exigibility">on_payment</field>
+ <field name="cash_basis_transition_account_id" ref="pcg_44566" />
+ <field name="sequence" eval="10"/>
+ <field name="type_tax_use">purchase</field>
+ <field name="tax_group_id" ref="tax_group_tva_55"/>
+ <field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ 'plus_report_line_ids': [ref('l10n_fr.tax_report_base_coll_5_5')],
+ }),
+
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'plus_report_line_ids': [ref('l10n_fr.tax_report_tva_coll_5_5')],
+ 'account_id': ref('pcg_445800'),
+ }),
+ ]"/>
+ <field name="refund_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ 'minus_report_line_ids': [ref('l10n_fr.tax_report_base_coll_5_5')],
+ }),
+
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'minus_report_line_ids': [ref('l10n_fr.tax_report_tva_coll_5_5')],
+ 'account_id': ref('pcg_44566'),
+ }),
+ ]"/>
+ </record>
+
<record model="account.tax.template" id="tva_acq_super_reduite">
<field name="chart_template_id" ref="l10n_fr_pcg_chart_template"/>
<field name="name">TVA déductible (achat) 2,1%</field>
@@ -851,6 +1057,47 @@
<!-- ACHATS Tax included in price -->
+ <record model="account.tax.template" id="tva_acq_encaissement_super_reduite">
+ <field name="chart_template_id" ref="l10n_fr_pcg_chart_template"/>
+ <field name="name">TVA à l'encaissement (achat) 2,1% </field>
+ <field name="description">TVA 2,1%</field>
+ <field name="amount" eval="2.1"/>
+ <field name="amount_type">percent</field>
+ <field name="tax_exigibility">on_payment</field>
+ <field name="cash_basis_transition_account_id" ref="pcg_44566" />
+ <field name="sequence" eval="10"/>
+ <field name="type_tax_use">purchase</field>
+ <field name="tax_group_id" ref="tax_group_tva_21"/>
+ <field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ 'plus_report_line_ids': [ref('l10n_fr.tax_report_base_coll_2_1')],
+ }),
+
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'plus_report_line_ids': [ref('l10n_fr.tax_report_tva_coll_2_1')],
+ 'account_id': ref('pcg_445800'),
+ }),
+ ]"/>
+ <field name="refund_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ 'minus_report_line_ids': [ref('l10n_fr.tax_report_base_coll_2_1')],
+ }),
+
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'minus_report_line_ids': [ref('l10n_fr.tax_report_tva_coll_2_1')],
+ 'account_id': ref('pcg_44566'),
+ }),
+ ]"/>
+ </record>
+
<record model="account.tax.template" id="tva_acq_normale_TTC">
<field name="chart_template_id" ref="l10n_fr_pcg_chart_template"/>
<field name="name">TVA déductible (achat) 20,0% TTC</field>
@@ -891,6 +1138,48 @@
]"/>
</record>
+ <record model="account.tax.template" id="tva_acq_encaissement_TTC">
+ <field name="chart_template_id" ref="l10n_fr_pcg_chart_template"/>
+ <field name="name">TVA à l'encaissement (achat) 20,0% TTC</field>
+ <field name="description">TVA 20% TTC</field>
+ <field name="price_include" eval="1"/>
+ <field name="amount" eval="20.0"/>
+ <field name="amount_type">percent</field>
+ <field name="tax_exigibility">on_payment</field>
+ <field name="cash_basis_transition_account_id" ref="pcg_44566" />
+ <field name="sequence" eval="10"/>
+ <field name="type_tax_use">purchase</field>
+ <field name="tax_group_id" ref="tax_group_tva_20"/>
+ <field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ 'plus_report_line_ids': [ref('l10n_fr.tax_report_base_coll_20')],
+ }),
+
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'plus_report_line_ids': [ref('l10n_fr.tax_report_tva_coll_20')],
+ 'account_id': ref('pcg_445800'),
+ }),
+ ]"/>
+ <field name="refund_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ 'minus_report_line_ids': [ref('l10n_fr.tax_report_base_coll_20')],
+ }),
+
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'minus_report_line_ids': [ref('l10n_fr.tax_report_tva_coll_20')],
+ 'account_id': ref('pcg_44566'),
+ }),
+ ]"/>
+ </record>
+
<record model="account.tax.template" id="tva_acq_specifique_TTC">
<field name="chart_template_id" ref="l10n_fr_pcg_chart_template"/>
<field name="name">TVA déductible (achat) 8,5% TTC</field>
@@ -931,6 +1220,48 @@
]"/>
</record>
+ <record model="account.tax.template" id="tva_acq_intermediaire_encaissement_TTC">
+ <field name="chart_template_id" ref="l10n_fr_pcg_chart_template"/>
+ <field name="name">TVA à l'encaissement (achat) 10,0% TTC</field>
+ <field name="description">TVA 10% TTC</field>
+ <field name="price_include" eval="1"/>
+ <field name="amount" eval="10.0"/>
+ <field name="amount_type">percent</field>
+ <field name="tax_exigibility">on_payment</field>
+ <field name="cash_basis_transition_account_id" ref="pcg_44566" />
+ <field name="sequence" eval="10"/>
+ <field name="type_tax_use">purchase</field>
+ <field name="tax_group_id" ref="tax_group_tva_10"/>
+ <field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ 'plus_report_line_ids': [ref('l10n_fr.tax_report_base_coll_10')],
+ }),
+
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'plus_report_line_ids': [ref('l10n_fr.tax_report_tva_coll_10')],
+ 'account_id': ref('pcg_445800'),
+ }),
+ ]"/>
+ <field name="refund_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ 'minus_report_line_ids': [ref('l10n_fr.tax_report_base_coll_10')],
+ }),
+
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'minus_report_line_ids': [ref('l10n_fr.tax_report_tva_coll_10')],
+ 'account_id': ref('pcg_44566'),
+ }),
+ ]"/>
+ </record>
+
<record model="account.tax.template" id="tva_acq_intermediaire_TTC">
<field name="chart_template_id" ref="l10n_fr_pcg_chart_template"/>
<field name="name">TVA déductible (achat) 10,0% TTC</field>
@@ -1011,6 +1342,48 @@
]"/>
</record>
+ <record model="account.tax.template" id="tva_acq_encaissement_reduite_TTC">
+ <field name="chart_template_id" ref="l10n_fr_pcg_chart_template"/>
+ <field name="name">TVA à l'encaissement (achat) 5,5% TTC</field>
+ <field name="description">TVA 5,5% TTC</field>
+ <field name="price_include" eval="1"/>
+ <field name="amount" eval="5.5"/>
+ <field name="amount_type">percent</field>
+ <field name="tax_exigibility">on_payment</field>
+ <field name="cash_basis_transition_account_id" ref="pcg_44566" />
+ <field name="sequence" eval="10"/>
+ <field name="type_tax_use">purchase</field>
+ <field name="tax_group_id" ref="tax_group_tva_55"/>
+ <field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ 'plus_report_line_ids': [ref('l10n_fr.tax_report_base_coll_5_5')],
+ }),
+
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'plus_report_line_ids': [ref('l10n_fr.tax_report_tva_coll_5_5')],
+ 'account_id': ref('pcg_445800'),
+ }),
+ ]"/>
+ <field name="refund_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ 'minus_report_line_ids': [ref('l10n_fr.tax_report_base_coll_5_5')],
+ }),
+
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'minus_report_line_ids': [ref('l10n_fr.tax_report_tva_coll_5_5')],
+ 'account_id': ref('pcg_44566'),
+ }),
+ ]"/>
+ </record>
+
<record model="account.tax.template" id="tva_acq_super_reduite_TTC">
<field name="chart_template_id" ref="l10n_fr_pcg_chart_template"/>
<field name="name">TVA déductible (achat) 2,1% TTC</field>
@@ -1051,6 +1424,48 @@
]"/>
</record>
+ <record model="account.tax.template" id="tva_acq_encaissement_super_reduite_TTC">
+ <field name="chart_template_id" ref="l10n_fr_pcg_chart_template"/>
+ <field name="name">TVA à l'encaissement (achat) 2,1% TTC</field>
+ <field name="description">TVA 2,1% TTC</field>
+ <field name="price_include" eval="1"/>
+ <field name="amount" eval="2.1"/>
+ <field name="amount_type">percent</field>
+ <field name="tax_exigibility">on_payment</field>
+ <field name="cash_basis_transition_account_id" ref="pcg_44566" />
+ <field name="sequence" eval="10"/>
+ <field name="type_tax_use">purchase</field>
+ <field name="tax_group_id" ref="tax_group_tva_21"/>
+ <field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ 'plus_report_line_ids': [ref('l10n_fr.tax_report_base_coll_2_1')],
+ }),
+
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'plus_report_line_ids': [ref('l10n_fr.tax_report_tva_coll_2_1')],
+ 'account_id': ref('pcg_445800'),
+ }),
+ ]"/>
+ <field name="refund_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ 'minus_report_line_ids': [ref('l10n_fr.tax_report_base_coll_2_1')],
+ }),
+
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'minus_report_line_ids': [ref('l10n_fr.tax_report_tva_coll_2_1')],
+ 'account_id': ref('pcg_44566'),
+ }),
+ ]"/>
+ </record>
+
<!-- ImmoBILISATIONS (achats) -->
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 @@
<data noupdate="1">
<!-- Account Tax Group -->
+ <record id="sgst_group" model="account.tax.group">
+ <field name="name">SGST</field>
+ </record>
+ <record id="cgst_group" model="account.tax.group">
+ <field name="name">CGST</field>
+ </record>
<record id="igst_group" model="account.tax.group">
<field name="name">IGST</field>
</record>
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</field>
<!-- SGST & CGST Sales Group Tax -->
- <record id="sgst_sale_1" model="account.tax.template">
- <field name="name">GST 1%</field>
- <field name="description">GST 1%</field>
- <field name="type_tax_use">sale</field>
+ <record id="sgst_sale_0_5" model="account.tax.template">
+ <field name="name">SGST Sale 0.5%</field>
+ <field name="description">SGST 0.5%</field>
+ <field name="type_tax_use">none</field>
<field name="amount_type">percent</field>
- <field name="amount">1.0</field>
+ <field name="amount">0.5</field>
<field name="chart_template_id" ref="indian_chart_template_standard"/>
- <field name="tax_group_id" ref="gst_group"/>
+ <field name="tax_group_id" ref="sgst_group"/>
<field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
(0,0, {
'factor_percent': 100,
@@ -474,17 +474,92 @@ if tax > result:result=tax</field>
}),
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p11232'),
'plus_report_line_ids': [ref('tax_report_line_sgst')],
}),
+ ]"/>
+ <field name="refund_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ }),
+
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'account_id': ref('p10051'),
+ 'minus_report_line_ids': [ref('tax_report_line_sgst')],
+ })
+ ]"/>
+ </record>
+
+ <record id="cgst_sale_0_5" model="account.tax.template">
+ <field name="name">CGST Sale 0.5%</field>
+ <field name="description">CGST 0.5%</field>
+ <field name="type_tax_use">none</field>
+ <field name="amount_type">percent</field>
+ <field name="amount">0.5</field>
+ <field name="chart_template_id" ref="indian_chart_template_standard"/>
+ <field name="tax_group_id" ref="cgst_group"/>
+ <field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ }),
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p11233'),
'plus_report_line_ids': [ref('tax_report_line_cgst')],
+ })
+ ]"/>
+ <field name="refund_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
}),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'account_id': ref('p10052'),
+ 'minus_report_line_ids': [ref('tax_report_line_cgst')],
+ })
+ ]"/>
+ </record>
+
+ <record id="sgst_sale_1" model="account.tax.template">
+ <field name="name">GST 1%</field>
+ <field name="description">GST 1%</field>
+ <field name="type_tax_use">sale</field>
+ <field name="amount_type">group</field>
+ <field name="amount">1.0</field>
+ <field name="chart_template_id" ref="indian_chart_template_standard"/>
+ <field name="tax_group_id" ref="gst_group"/>
+ <field name="children_tax_ids" eval="[(6, 0, [ref('sgst_sale_0_5'), ref('cgst_sale_0_5'),])]"/>
+ </record>
+
+ <record id="sgst_sale_1_2" model="account.tax.template">
+ <field name="name">SGST Sale 1%</field>
+ <field name="description">SGST 1%</field>
+ <field name="type_tax_use">none</field>
+ <field name="amount_type">percent</field>
+ <field name="amount">1</field>
+ <field name="chart_template_id" ref="indian_chart_template_standard"/>
+ <field name="tax_group_id" ref="sgst_group"/>
+ <field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ }),
+
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'account_id': ref('p11232'),
+ 'plus_report_line_ids': [ref('tax_report_line_sgst')],
+ })
]"/>
<field name="refund_repartition_line_ids" eval="[(5, 0, 0),
(0,0, {
@@ -493,17 +568,45 @@ if tax > result:result=tax</field>
}),
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p10051'),
'minus_report_line_ids': [ref('tax_report_line_sgst')],
+ })
+ ]"/>
+ </record>
+
+ <record id="cgst_sale_1_2" model="account.tax.template">
+ <field name="name">CGST Sale 1%</field>
+ <field name="description">CGST 1%</field>
+ <field name="type_tax_use">none</field>
+ <field name="amount_type">percent</field>
+ <field name="amount">1</field>
+ <field name="chart_template_id" ref="indian_chart_template_standard"/>
+ <field name="tax_group_id" ref="cgst_group"/>
+ <field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ }),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'account_id': ref('p11233'),
+ 'plus_report_line_ids': [ref('tax_report_line_cgst')],
+ })
+ ]"/>
+ <field name="refund_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
}),
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p10052'),
'minus_report_line_ids': [ref('tax_report_line_cgst')],
- }),
+ })
]"/>
</record>
@@ -511,10 +614,21 @@ if tax > result:result=tax</field>
<field name="name">GST 2%</field>
<field name="description">GST 2%</field>
<field name="type_tax_use">sale</field>
- <field name="amount_type">percent</field>
+ <field name="amount_type">group</field>
<field name="amount">2.0</field>
<field name="chart_template_id" ref="indian_chart_template_standard"/>
<field name="tax_group_id" ref="gst_group"/>
+ <field name="children_tax_ids" eval="[(6, 0, [ref('sgst_sale_1_2'), ref('cgst_sale_1_2'),])]"/>
+ </record>
+
+ <record id="sgst_sale_14" model="account.tax.template">
+ <field name="name">SGST Sale 14%</field>
+ <field name="description">SGST 14%</field>
+ <field name="type_tax_use">none</field>
+ <field name="amount_type">percent</field>
+ <field name="amount">14</field>
+ <field name="chart_template_id" ref="indian_chart_template_standard"/>
+ <field name="tax_group_id" ref="sgst_group"/>
<field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
(0,0, {
'factor_percent': 100,
@@ -522,17 +636,11 @@ if tax > result:result=tax</field>
}),
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p11232'),
'plus_report_line_ids': [ref('tax_report_line_sgst')],
- }),
- (0,0, {
- 'factor_percent': 50,
- 'repartition_type': 'tax',
- 'account_id': ref('p11233'),
- 'plus_report_line_ids': [ref('tax_report_line_cgst')],
- }),
+ })
]"/>
<field name="refund_repartition_line_ids" eval="[(5, 0, 0),
(0,0, {
@@ -541,17 +649,45 @@ if tax > result:result=tax</field>
}),
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p10051'),
'minus_report_line_ids': [ref('tax_report_line_sgst')],
+ })
+ ]"/>
+ </record>
+
+ <record id="cgst_sale_14" model="account.tax.template">
+ <field name="name">CGST Sale 14%</field>
+ <field name="description">CGST 14%</field>
+ <field name="type_tax_use">none</field>
+ <field name="amount_type">percent</field>
+ <field name="amount">14</field>
+ <field name="chart_template_id" ref="indian_chart_template_standard"/>
+ <field name="tax_group_id" ref="cgst_group"/>
+ <field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ }),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'account_id': ref('p11233'),
+ 'plus_report_line_ids': [ref('tax_report_line_cgst')],
+ })
+ ]"/>
+ <field name="refund_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
}),
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p10052'),
'minus_report_line_ids': [ref('tax_report_line_cgst')],
- }),
+ })
]"/>
</record>
@@ -559,10 +695,21 @@ if tax > result:result=tax</field>
<field name="name">GST 28%</field>
<field name="description">GST 28%</field>
<field name="type_tax_use">sale</field>
- <field name="amount_type">percent</field>
+ <field name="amount_type">group</field>
<field name="amount">28.0</field>
<field name="chart_template_id" ref="indian_chart_template_standard"/>
<field name="tax_group_id" ref="gst_group"/>
+ <field name="children_tax_ids" eval="[(6, 0, [ref('sgst_sale_14'),ref('cgst_sale_14'),])]"/>
+ </record>
+
+ <record id="sgst_sale_9" model="account.tax.template">
+ <field name="name">SGST Sale 9%</field>
+ <field name="description">SGST 9%</field>
+ <field name="type_tax_use">none</field>
+ <field name="amount_type">percent</field>
+ <field name="amount">9</field>
+ <field name="chart_template_id" ref="indian_chart_template_standard"/>
+ <field name="tax_group_id" ref="sgst_group"/>
<field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
(0,0, {
'factor_percent': 100,
@@ -570,17 +717,11 @@ if tax > result:result=tax</field>
}),
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p11232'),
'plus_report_line_ids': [ref('tax_report_line_sgst')],
- }),
- (0,0, {
- 'factor_percent': 50,
- 'repartition_type': 'tax',
- 'account_id': ref('p11233'),
- 'plus_report_line_ids': [ref('tax_report_line_cgst')],
- }),
+ })
]"/>
<field name="refund_repartition_line_ids" eval="[(5, 0, 0),
(0,0, {
@@ -589,17 +730,45 @@ if tax > result:result=tax</field>
}),
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p10051'),
'minus_report_line_ids': [ref('tax_report_line_sgst')],
+ })
+ ]"/>
+ </record>
+
+ <record id="cgst_sale_9" model="account.tax.template">
+ <field name="name">CGST Sale 9%</field>
+ <field name="description">CGST 9%</field>
+ <field name="type_tax_use">none</field>
+ <field name="amount_type">percent</field>
+ <field name="amount">9</field>
+ <field name="chart_template_id" ref="indian_chart_template_standard"/>
+ <field name="tax_group_id" ref="cgst_group"/>
+ <field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
}),
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'account_id': ref('p11233'),
+ 'plus_report_line_ids': [ref('tax_report_line_cgst')],
+ })
+ ]"/>
+ <field name="refund_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ }),
+ (0,0, {
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p10052'),
'minus_report_line_ids': [ref('tax_report_line_cgst')],
- }),
+ })
]"/>
</record>
@@ -607,43 +776,74 @@ if tax > result:result=tax</field>
<field name="name">GST 18%</field>
<field name="description">GST 18%</field>
<field name="type_tax_use">sale</field>
- <field name="amount_type">percent</field>
+ <field name="amount_type">group</field>
<field name="amount">18.0</field>
<field name="chart_template_id" ref="indian_chart_template_standard"/>
<field name="tax_group_id" ref="gst_group"/>
+ <field name="children_tax_ids" eval="[(6, 0, [ref('sgst_sale_9'),ref('cgst_sale_9'),])]"/>
+ </record>
+
+ <record id="sgst_sale_6" model="account.tax.template">
+ <field name="name">SGST Sale 6%</field>
+ <field name="description">SGST 6%</field>
+ <field name="type_tax_use">none</field>
+ <field name="amount_type">percent</field>
+ <field name="amount">6</field>
+ <field name="chart_template_id" ref="indian_chart_template_standard"/>
+ <field name="tax_group_id" ref="sgst_group"/>
<field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
(0,0, {
'factor_percent': 100,
'repartition_type': 'base',
}),
-
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p11232'),
'plus_report_line_ids': [ref('tax_report_line_sgst')],
- }),
- (0,0, {
- 'factor_percent': 50,
- 'repartition_type': 'tax',
- 'account_id': ref('p11233'),
- 'plus_report_line_ids': [ref('tax_report_line_cgst')],
- }),
+ })
]"/>
<field name="refund_repartition_line_ids" eval="[(5, 0, 0),
(0,0, {
'factor_percent': 100,
'repartition_type': 'base',
}),
-
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p10051'),
'minus_report_line_ids': [ref('tax_report_line_sgst')],
+ })
+ ]"/>
+ </record>
+
+ <record id="cgst_sale_6" model="account.tax.template">
+ <field name="name">CGST Sale 6%</field>
+ <field name="description">CGST 6%</field>
+ <field name="type_tax_use">none</field>
+ <field name="amount_type">percent</field>
+ <field name="amount">6</field>
+ <field name="chart_template_id" ref="indian_chart_template_standard"/>
+ <field name="tax_group_id" ref="cgst_group"/>
+ <field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
}),
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'account_id': ref('p11233'),
+ 'plus_report_line_ids': [ref('tax_report_line_cgst')],
+ })
+ ]"/>
+ <field name="refund_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ }),
+ (0,0, {
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p10052'),
'minus_report_line_ids': [ref('tax_report_line_cgst')],
@@ -655,10 +855,21 @@ if tax > result:result=tax</field>
<field name="name">GST 12%</field>
<field name="description">GST 12%</field>
<field name="type_tax_use">sale</field>
- <field name="amount_type">percent</field>
+ <field name="amount_type">group</field>
<field name="amount">12.0</field>
<field name="chart_template_id" ref="indian_chart_template_standard"/>
<field name="tax_group_id" ref="gst_group"/>
+ <field name="children_tax_ids" eval="[(6, 0, [ref('sgst_sale_6'),ref('cgst_sale_6'),])]"/>
+ </record>
+
+ <record id="sgst_sale_2_5" model="account.tax.template">
+ <field name="name">SGST Sale 2.5%</field>
+ <field name="description">SGST 2.5%</field>
+ <field name="type_tax_use">none</field>
+ <field name="amount_type">percent</field>
+ <field name="amount">2.5</field>
+ <field name="chart_template_id" ref="indian_chart_template_standard"/>
+ <field name="tax_group_id" ref="sgst_group"/>
<field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
(0,0, {
'factor_percent': 100,
@@ -666,17 +877,11 @@ if tax > result:result=tax</field>
}),
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p11232'),
'plus_report_line_ids': [ref('tax_report_line_sgst')],
- }),
- (0,0, {
- 'factor_percent': 50,
- 'repartition_type': 'tax',
- 'account_id': ref('p11233'),
- 'plus_report_line_ids': [ref('tax_report_line_cgst')],
- }),
+ })
]"/>
<field name="refund_repartition_line_ids" eval="[(5, 0, 0),
(0,0, {
@@ -685,69 +890,60 @@ if tax > result:result=tax</field>
}),
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p10051'),
'minus_report_line_ids': [ref('tax_report_line_sgst')],
- }),
- (0,0, {
- 'factor_percent': 50,
- 'repartition_type': 'tax',
- 'account_id': ref('p10052'),
- 'minus_report_line_ids': [ref('tax_report_line_cgst')],
- }),
+ })
]"/>
</record>
- <record id="sgst_sale_5" model="account.tax.template">
- <field name="name">GST 5%</field>
- <field name="description">GST 5%</field>
- <field name="type_tax_use">sale</field>
+ <record id="cgst_sale_2_5" model="account.tax.template">
+ <field name="name">CGST Sale 2.5%</field>
+ <field name="description">CGST 2.5%</field>
+ <field name="type_tax_use">none</field>
<field name="amount_type">percent</field>
- <field name="amount">5.0</field>
+ <field name="amount">2.5</field>
<field name="chart_template_id" ref="indian_chart_template_standard"/>
- <field name="tax_group_id" ref="gst_group"/>
- <field name="sequence">0</field>
+ <field name="tax_group_id" ref="cgst_group"/>
<field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
(0,0, {
'factor_percent': 100,
'repartition_type': 'base',
}),
-
(0,0, {
- 'factor_percent': 50,
- 'repartition_type': 'tax',
- 'account_id': ref('p11232'),
- 'plus_report_line_ids': [ref('tax_report_line_sgst')],
- }),
- (0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p11233'),
'plus_report_line_ids': [ref('tax_report_line_cgst')],
- }),
+ })
]"/>
<field name="refund_repartition_line_ids" eval="[(5, 0, 0),
(0,0, {
'factor_percent': 100,
'repartition_type': 'base',
}),
-
(0,0, {
- 'factor_percent': 50,
- 'repartition_type': 'tax',
- 'account_id': ref('p10051'),
- 'minus_report_line_ids': [ref('tax_report_line_sgst')],
- }),
- (0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p10052'),
'minus_report_line_ids': [ref('tax_report_line_cgst')],
- }),
+ })
]"/>
</record>
+ <record id="sgst_sale_5" model="account.tax.template">
+ <field name="name">GST 5%</field>
+ <field name="description">GST 5%</field>
+ <field name="type_tax_use">sale</field>
+ <field name="amount_type">group</field>
+ <field name="amount">5.0</field>
+ <field name="chart_template_id" ref="indian_chart_template_standard"/>
+ <field name="tax_group_id" ref="gst_group"/>
+ <field name="sequence">0</field>
+ <field name="children_tax_ids" eval="[(6, 0, [ref('sgst_sale_2_5'), ref('cgst_sale_2_5'),])]"/>
+ </record>
+
<!-- Purchase Taxes-->
<!-- CESS Taxes -->
@@ -1166,97 +1362,232 @@ if tax > result:result=tax</field>
<!-- SGST & CGST -->
- <record id="sgst_purchase_1" model="account.tax.template">
- <field name="name">GST 1%</field>
- <field name="description">GST 1%</field>
- <field name="type_tax_use">purchase</field>
+ <record id="sgst_purchase_0_5" model="account.tax.template">
+ <field name="name">SGST Purchase 0.5%</field>
+ <field name="description">SGST 0.5%</field>
+ <field name="type_tax_use">none</field>
<field name="amount_type">percent</field>
- <field name="amount">1.0</field>
+ <field name="amount">0.5</field>
<field name="chart_template_id" ref="indian_chart_template_standard"/>
- <field name="tax_group_id" ref="gst_group"/>
+ <field name="tax_group_id" ref="sgst_group"/>
<field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
(0,0, {
'factor_percent': 100,
'repartition_type': 'base',
}),
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p10051'),
'plus_report_line_ids': [ref('tax_report_line_sgst')],
+ })
+ ]"/>
+ <field name="refund_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ }),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'account_id': ref('p11232'),
+ 'minus_report_line_ids': [ref('tax_report_line_sgst')],
+ })
+ ]"/>
+ </record>
+
+ <record id="cgst_purchase_0_5" model="account.tax.template">
+ <field name="name">CGST Purchase 0.5%</field>
+ <field name="description">CGST 0.5%</field>
+ <field name="type_tax_use">none</field>
+ <field name="amount_type">percent</field>
+ <field name="amount">0.5</field>
+ <field name="chart_template_id" ref="indian_chart_template_standard"/>
+ <field name="tax_group_id" ref="cgst_group"/>
+ <field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
}),
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p10052'),
'plus_report_line_ids': [ref('tax_report_line_cgst')],
+ })
+ ]"/>
+ <field name="refund_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
}),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'account_id': ref('p11233'),
+ 'minus_report_line_ids': [ref('tax_report_line_cgst')],
+ })
+ ]"/>
+ </record>
+
+ <record id="sgst_purchase_1" model="account.tax.template">
+ <field name="name">GST 1%</field>
+ <field name="description">GST 1%</field>
+ <field name="type_tax_use">purchase</field>
+ <field name="amount_type">group</field>
+ <field name="amount">1.0</field>
+ <field name="chart_template_id" ref="indian_chart_template_standard"/>
+ <field name="tax_group_id" ref="gst_group"/>
+ <field name="children_tax_ids" eval="[(6, 0, [ref('sgst_purchase_0_5'),ref('cgst_purchase_0_5'),])]"/>
+ </record>
+
+ <record id="sgst_purchase_1_2" model="account.tax.template">
+ <field name="name">SGST Purchase 1%</field>
+ <field name="description">SGST 1%</field>
+ <field name="type_tax_use">none</field>
+ <field name="amount_type">percent</field>
+ <field name="amount">1</field>
+ <field name="chart_template_id" ref="indian_chart_template_standard"/>
+ <field name="tax_group_id" ref="sgst_group"/>
+ <field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ }),
+
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'account_id': ref('p10051'),
+ 'plus_report_line_ids': [ref('tax_report_line_sgst')],
+ })
]"/>
<field name="refund_repartition_line_ids" eval="[(5, 0, 0),
(0,0, {
'factor_percent': 100,
'repartition_type': 'base',
}),
+
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p11232'),
'minus_report_line_ids': [ref('tax_report_line_sgst')],
+ })
+ ]"/>
+ </record>
+
+ <record id="cgst_purchase_1_2" model="account.tax.template">
+ <field name="name">CGST Purchase 1%</field>
+ <field name="description">CGST 1%</field>
+ <field name="type_tax_use">none</field>
+ <field name="amount_type">percent</field>
+ <field name="amount">1</field>
+ <field name="chart_template_id" ref="indian_chart_template_standard"/>
+ <field name="tax_group_id" ref="cgst_group"/>
+ <field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ }),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'account_id': ref('p10052'),
+ 'plus_report_line_ids': [ref('tax_report_line_cgst')],
+ })
+ ]"/>
+ <field name="refund_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
}),
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p11233'),
'minus_report_line_ids': [ref('tax_report_line_cgst')],
- }),
+ })
]"/>
+
</record>
<record id="sgst_purchase_2" model="account.tax.template">
<field name="name">GST 2%</field>
<field name="description">GST 2%</field>
<field name="type_tax_use">purchase</field>
- <field name="amount_type">percent</field>
+ <field name="amount_type">group</field>
<field name="amount">2.0</field>
<field name="chart_template_id" ref="indian_chart_template_standard"/>
<field name="tax_group_id" ref="gst_group"/>
+ <field name="children_tax_ids" eval="[(6, 0, [ref('sgst_purchase_1_2'),ref('cgst_purchase_1_2'),])]"/>
+ </record>
+
+ <record id="sgst_purchase_14" model="account.tax.template">
+ <field name="name">SGST Purchase 14%</field>
+ <field name="description">SGST 14%</field>
+ <field name="type_tax_use">none</field>
+ <field name="amount_type">percent</field>
+ <field name="amount">14</field>
+ <field name="chart_template_id" ref="indian_chart_template_standard"/>
+ <field name="tax_group_id" ref="sgst_group"/>
<field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
(0,0, {
'factor_percent': 100,
'repartition_type': 'base',
}),
-
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p10051'),
'plus_report_line_ids': [ref('tax_report_line_sgst')],
- }),
- (0,0, {
- 'factor_percent': 50,
- 'repartition_type': 'tax',
- 'account_id': ref('p10052'),
- 'plus_report_line_ids': [ref('tax_report_line_cgst')],
- }),
+ })
]"/>
<field name="refund_repartition_line_ids" eval="[(5, 0, 0),
(0,0, {
'factor_percent': 100,
'repartition_type': 'base',
}),
-
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p11232'),
'minus_report_line_ids': [ref('tax_report_line_sgst')],
+ })
+ ]"/>
+ </record>
+
+ <record id="cgst_purchase_14" model="account.tax.template">
+ <field name="name">CGST Purchase 14%</field>
+ <field name="description">CGST 14%</field>
+ <field name="type_tax_use">none</field>
+ <field name="amount_type">percent</field>
+ <field name="amount">14</field>
+ <field name="chart_template_id" ref="indian_chart_template_standard"/>
+ <field name="tax_group_id" ref="cgst_group"/>
+ <field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ }),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'account_id': ref('p10052'),
+ 'plus_report_line_ids': [ref('tax_report_line_cgst')],
+ })
+ ]"/>
+ <field name="refund_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
}),
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p11233'),
'minus_report_line_ids': [ref('tax_report_line_cgst')],
- }),
+ })
]"/>
</record>
@@ -1264,10 +1595,21 @@ if tax > result:result=tax</field>
<field name="name">GST 28%</field>
<field name="description">GST 28%</field>
<field name="type_tax_use">purchase</field>
- <field name="amount_type">percent</field>
+ <field name="amount_type">group</field>
<field name="amount">28.0</field>
<field name="chart_template_id" ref="indian_chart_template_standard"/>
<field name="tax_group_id" ref="gst_group"/>
+ <field name="children_tax_ids" eval="[(6, 0, [ref('sgst_purchase_14'),ref('cgst_purchase_14'),])]"/>
+ </record>
+
+ <record id="sgst_purchase_9" model="account.tax.template">
+ <field name="name">SGST Purchase 9%</field>
+ <field name="description">SGST 9%</field>
+ <field name="type_tax_use">none</field>
+ <field name="amount_type">percent</field>
+ <field name="amount">9</field>
+ <field name="chart_template_id" ref="indian_chart_template_standard"/>
+ <field name="tax_group_id" ref="sgst_group"/>
<field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
(0,0, {
'factor_percent': 100,
@@ -1275,17 +1617,11 @@ if tax > result:result=tax</field>
}),
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p10051'),
'plus_report_line_ids': [ref('tax_report_line_sgst')],
- }),
- (0,0, {
- 'factor_percent': 50,
- 'repartition_type': 'tax',
- 'account_id': ref('p10052'),
- 'plus_report_line_ids': [ref('tax_report_line_cgst')],
- }),
+ })
]"/>
<field name="refund_repartition_line_ids" eval="[(5, 0, 0),
(0,0, {
@@ -1294,17 +1630,45 @@ if tax > result:result=tax</field>
}),
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p11232'),
'minus_report_line_ids': [ref('tax_report_line_sgst')],
+ })
+ ]"/>
+ </record>
+
+ <record id="cgst_purchase_9" model="account.tax.template">
+ <field name="name">CGST Purchase 9%</field>
+ <field name="description">CGST 9%</field>
+ <field name="type_tax_use">none</field>
+ <field name="amount_type">percent</field>
+ <field name="amount">9</field>
+ <field name="chart_template_id" ref="indian_chart_template_standard"/>
+ <field name="tax_group_id" ref="cgst_group"/>
+ <field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
}),
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'account_id': ref('p10052'),
+ 'plus_report_line_ids': [ref('tax_report_line_cgst')],
+ })
+ ]"/>
+ <field name="refund_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ }),
+ (0,0, {
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p11233'),
'minus_report_line_ids': [ref('tax_report_line_cgst')],
- }),
+ })
]"/>
</record>
@@ -1312,10 +1676,21 @@ if tax > result:result=tax</field>
<field name="name">GST 18%</field>
<field name="description">GST 18%</field>
<field name="type_tax_use">purchase</field>
- <field name="amount_type">percent</field>
+ <field name="amount_type">group</field>
<field name="amount">18.0</field>
<field name="chart_template_id" ref="indian_chart_template_standard"/>
<field name="tax_group_id" ref="gst_group"/>
+ <field name="children_tax_ids" eval="[(6, 0, [ref('sgst_purchase_9'),ref('cgst_purchase_9'),])]"/>
+ </record>
+
+ <record id="sgst_purchase_6" model="account.tax.template">
+ <field name="name">SGST Purchase 6%</field>
+ <field name="description">SGST 6%</field>
+ <field name="type_tax_use">none</field>
+ <field name="amount_type">percent</field>
+ <field name="amount">6</field>
+ <field name="chart_template_id" ref="indian_chart_template_standard"/>
+ <field name="tax_group_id" ref="sgst_group"/>
<field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
(0,0, {
'factor_percent': 100,
@@ -1323,17 +1698,11 @@ if tax > result:result=tax</field>
}),
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p10051'),
'plus_report_line_ids': [ref('tax_report_line_sgst')],
- }),
- (0,0, {
- 'factor_percent': 50,
- 'repartition_type': 'tax',
- 'account_id': ref('p10052'),
- 'plus_report_line_ids': [ref('tax_report_line_cgst')],
- }),
+ })
]"/>
<field name="refund_repartition_line_ids" eval="[(5, 0, 0),
(0,0, {
@@ -1342,17 +1711,45 @@ if tax > result:result=tax</field>
}),
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p11232'),
'minus_report_line_ids': [ref('tax_report_line_sgst')],
+ })
+ ]"/>
+ </record>
+
+ <record id="cgst_purchase_6" model="account.tax.template">
+ <field name="name">CGST Purchase 6%</field>
+ <field name="description">CGST 6%</field>
+ <field name="type_tax_use">none</field>
+ <field name="amount_type">percent</field>
+ <field name="amount">6</field>
+ <field name="chart_template_id" ref="indian_chart_template_standard"/>
+ <field name="tax_group_id" ref="cgst_group"/>
+ <field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
}),
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
+ 'repartition_type': 'tax',
+ 'account_id': ref('p10052'),
+ 'plus_report_line_ids': [ref('tax_report_line_cgst')],
+ }),
+ ]"/>
+ <field name="refund_repartition_line_ids" eval="[(5, 0, 0),
+ (0,0, {
+ 'factor_percent': 100,
+ 'repartition_type': 'base',
+ }),
+ (0,0, {
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p11233'),
'minus_report_line_ids': [ref('tax_report_line_cgst')],
- }),
+ })
]"/>
</record>
@@ -1360,10 +1757,21 @@ if tax > result:result=tax</field>
<field name="name">GST 12%</field>
<field name="description">GST 12%</field>
<field name="type_tax_use">purchase</field>
- <field name="amount_type">percent</field>
+ <field name="amount_type">group</field>
<field name="amount">12.0</field>
<field name="chart_template_id" ref="indian_chart_template_standard"/>
<field name="tax_group_id" ref="gst_group"/>
+ <field name="children_tax_ids" eval="[(6, 0, [ref('sgst_purchase_6'),ref('cgst_purchase_6'),])]"/>
+ </record>
+
+ <record id="sgst_purchase_2_5" model="account.tax.template">
+ <field name="name">SGST Purchase 2.5%</field>
+ <field name="description">SGST 2.5%</field>
+ <field name="type_tax_use">none</field>
+ <field name="amount_type">percent</field>
+ <field name="amount">2.5</field>
+ <field name="chart_template_id" ref="indian_chart_template_standard"/>
+ <field name="tax_group_id" ref="sgst_group"/>
<field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
(0,0, {
'factor_percent': 100,
@@ -1371,17 +1779,11 @@ if tax > result:result=tax</field>
}),
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p10051'),
'plus_report_line_ids': [ref('tax_report_line_sgst')],
- }),
- (0,0, {
- 'factor_percent': 50,
- 'repartition_type': 'tax',
- 'account_id': ref('p10052'),
- 'plus_report_line_ids': [ref('tax_report_line_cgst')],
- }),
+ })
]"/>
<field name="refund_repartition_line_ids" eval="[(5, 0, 0),
(0,0, {
@@ -1390,67 +1792,58 @@ if tax > result:result=tax</field>
}),
(0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p11232'),
'minus_report_line_ids': [ref('tax_report_line_sgst')],
- }),
- (0,0, {
- 'factor_percent': 50,
- 'repartition_type': 'tax',
- 'account_id': ref('p11233'),
- 'minus_report_line_ids': [ref('tax_report_line_cgst')],
- }),
+ })
]"/>
</record>
- <record id="sgst_purchase_5" model="account.tax.template">
- <field name="name">GST 5%</field>
- <field name="description">GST 5%</field>
- <field name="type_tax_use">purchase</field>
+ <record id="cgst_purchase_2_5" model="account.tax.template">
+ <field name="name">CGST Purchase 2.5%</field>
+ <field name="description">CGST 2.5%</field>
+ <field name="type_tax_use">none</field>
<field name="amount_type">percent</field>
- <field name="amount">5.0</field>
+ <field name="amount">2.5</field>
<field name="chart_template_id" ref="indian_chart_template_standard"/>
- <field name="tax_group_id" ref="gst_group"/>
- <field name="sequence">0</field>
+ <field name="tax_group_id" ref="cgst_group"/>
<field name="invoice_repartition_line_ids" eval="[(5, 0, 0),
(0,0, {
'factor_percent': 100,
'repartition_type': 'base',
}),
-
(0,0, {
- 'factor_percent': 50,
- 'repartition_type': 'tax',
- 'account_id': ref('p10051'),
- 'plus_report_line_ids': [ref('tax_report_line_sgst')],
- }),
- (0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p10052'),
'plus_report_line_ids': [ref('tax_report_line_cgst')],
- }),
+ })
]"/>
<field name="refund_repartition_line_ids" eval="[(5, 0, 0),
(0,0, {
'factor_percent': 100,
'repartition_type': 'base',
}),
-
(0,0, {
- 'factor_percent': 50,
- 'repartition_type': 'tax',
- 'account_id': ref('p11232'),
- 'minus_report_line_ids': [ref('tax_report_line_sgst')],
- }),
- (0,0, {
- 'factor_percent': 50,
+ 'factor_percent': 100,
'repartition_type': 'tax',
'account_id': ref('p11233'),
'minus_report_line_ids': [ref('tax_report_line_cgst')],
- }),
+ })
]"/>
</record>
+ <record id="sgst_purchase_5" model="account.tax.template">
+ <field name="name">GST 5%</field>
+ <field name="description">GST 5%</field>
+ <field name="type_tax_use">purchase</field>
+ <field name="amount_type">group</field>
+ <field name="amount">5.0</field>
+ <field name="chart_template_id" ref="indian_chart_template_standard"/>
+ <field name="tax_group_id" ref="gst_group"/>
+ <field name="sequence">0</field>
+ <field name="children_tax_ids" eval="[(6, 0, [ref('sgst_purchase_2_5'),ref('cgst_purchase_2_5'),])]"/>
+ </record>
+
</odoo>
diff --git a/addons/l10n_it_edi/models/account_invoice.py b/addons/l10n_it_edi/models/account_invoice.py
index 2938c6630ff..062e7f184a2 100644
--- a/addons/l10n_it_edi/models/account_invoice.py
+++ b/addons/l10n_it_edi/models/account_invoice.py
@@ -109,7 +109,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>
@@ -270,11 +270,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 51e4a0a23a3..2d2f33540a1 100644
--- a/addons/l10n_it_edi/models/ir_mail_server.py
+++ b/addons/l10n_it_edi/models/ir_mail_server.py
@@ -360,3 +360,17 @@ class FetchmailServer(models.Model):
if descrizione:
output_str += "<li>Errore %s: %s</li>" % (element[0].text, descrizione)
return output_str + "</ul>"
+
+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._extendedComposer = new ExtendedComposer(this, {
- mentionPartnersRestricted: true,
- showTyping: true,
+ this._isStarted = true;
+ return this._super.apply(this, arguments).then(function () {
+ if (!self._isMessagingReady) {
+ return;
+ }
+ return self._initRender();
});
- 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
@@ -547,6 +501,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
*
* @private
@@ -1402,6 +1410,20 @@ var Discuss = AbstractAction.extend({
},
/**
* @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
*/
_onModerateAllClicked: function (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 27208f0edfc..015ebfa01a3 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 7dcd1ca058f..fce3247e15b 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 9a9b21fe953..4a27ed0713f 100644
--- a/addons/mail/static/src/js/systray/systray_messaging_menu.js
+++ b/addons/mail/static/src/js/systray/systray_messaging_menu.js
@@ -30,18 +30,14 @@ var MessagingMenu = Widget.extend({
/**
* @override
*/
- willStart: function () {
- return Promise.all([this._super.apply(this, arguments), this.call('mail_service', 'isReady')]);
- },
- /**
- * @override
- */
start: function () {
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);
@@ -235,6 +231,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));
},
@@ -257,7 +256,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()) {
@@ -346,6 +349,16 @@ var MessagingMenu = Widget.extend({
var $preview = $(ev.currentTarget).closest('.o_mail_preview');
this._markAsRead($preview);
},
+ /**
+ * @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 ea64d1fc9e3..218a4b552ec 100644
--- a/addons/mail/static/src/js/thread_field.js
+++ b/addons/mail/static/src/js/thread_field.js
@@ -20,6 +20,9 @@ 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;
@@ -28,15 +31,10 @@ var ThreadField = AbstractField.extend({
/**
* @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, {
@@ -160,6 +158,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,
@@ -188,6 +189,19 @@ var ThreadField = AbstractField.extend({
},
/**
* @private
+ */
+ _onMessagingReady: function () {
+ if (this._isMessagingReady) {
+ return;
+ }
+ this._isMessagingReady = true;
+ if (!this._isStarted) {
+ return;
+ }
+ this._setDocumentThread();
+ },
+ /**
+ * @private
* @param {mail.model.Message}
*/
_onNewMessage: function (message) {
diff --git a/addons/mail/static/src/scss/discuss.scss b/addons/mail/static/src/scss/discuss.scss
index 21ff765dfdb..d7a01bdf26f 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 71138ae1f24..3b21d7f230a 100644
--- a/addons/mail/static/src/xml/discuss.xml
+++ b/addons/mail/static/src/xml/discuss.xml
@@ -8,8 +8,15 @@
-->
<t t-name="mail.discuss">
<div class="o_mail_discuss">
- <div class="o_mail_discuss_sidebar"/>
+ <div class="o_mail_discuss_sidebar">
+ <div class="o_mail_discuss_loading">
+ <i class="fa fa-spinner fa-spin"/> Please wait...
+ </div>
+ </div>
<div class="o_mail_discuss_content">
+ <div class="o_mail_discuss_loading">
+ <i class="fa fa-spinner fa-spin"/> Please wait...
+ </div>
</div>
</div>
</t>
diff --git a/addons/mail/static/src/xml/systray.xml b/addons/mail/static/src/xml/systray.xml
index dfa1d02b76c..dc275079e28 100644
--- a/addons/mail/static/src/xml/systray.xml
+++ b/addons/mail/static/src/xml/systray.xml
@@ -7,7 +7,7 @@
<t t-name="mail.systray.MessagingMenu">
<li class="o_mail_systray_item">
<a class="dropdown-toggle o-no-caret" data-toggle="dropdown" data-display="static" aria-expanded="false" title="Conversations" href="#" role="button">
- <i class="fa fa-comments" role="img" aria-label="Messages"/> <span class="o_notification_counter badge badge-pill"/>
+ <i class="o_mail_messaging_menu_icon fa fa-comments fa-spinner fa-spin" role="img" aria-label="Messages"/> <span class="o_notification_counter badge badge-pill"/>
</a>
<div class="o_mail_systray_dropdown dropdown-menu dropdown-menu-right" role="menu">
<t t-if="widget.isMobile()">
diff --git a/addons/mail/static/tests/discuss_tests.js b/addons/mail/static/tests/discuss_tests.js
index 990f321a39d..8f96e8b754e 100644
--- a/addons/mail/static/tests/discuss_tests.js
+++ b/addons/mail/static/tests/discuss_tests.js
@@ -141,6 +141,56 @@ QUnit.test('basic rendering', async function (assert) {
discuss.destroy();
});
+QUnit.test('messaging not ready', async function (assert) {
+ assert.expect(9);
+
+ const messagingReadyProm = testUtils.makeTestPromise();
+ const discuss = await createDiscuss({
+ id: 1,
+ context: {},
+ params: {},
+ data: this.data,
+ services: this.services,
+ async mockRPC(route, args) {
+ if (route === '/mail/init_messaging') {
+ const _super = this._super.bind(this, ...arguments); // limitation of class.js
+ assert.step('/mail/init_messaging:pending');
+ await messagingReadyProm;
+ assert.step('/mail/init_messaging:resolved');
+ return _super();
+ }
+ return this._super(...arguments);
+ },
+ });
+
+ assert.verifySteps(['/mail/init_messaging:pending']);
+ assert.ok(
+ discuss.el,
+ "discuss should be rendered");
+ assert.strictEqual(
+ $('.o_action')[0],
+ discuss.el,
+ "should display discuss even when messaging is not ready");
+ assert.containsOnce(
+ discuss,
+ '.o_mail_discuss_sidebar .o_mail_discuss_loading',
+ "should display sidebar is loading (messaging not yet ready)");
+ assert.containsOnce(
+ discuss,
+ '.o_mail_discuss_content .o_mail_discuss_loading',
+ "should display content is loading (messaging not yet ready)");
+
+ messagingReadyProm.resolve();
+ await testUtils.nextTick();
+ assert.verifySteps(['/mail/init_messaging:resolved']);
+ assert.containsNone(
+ discuss,
+ '.o_mail_discuss_loading',
+ "should no longer display sidebar or content is loading (messaging is ready)");
+
+ discuss.destroy();
+});
+
QUnit.test('searchview options visibility', async function (assert) {
assert.expect(5);
diff --git a/addons/mail/static/tests/systray/systray_messaging_menu_tests.js b/addons/mail/static/tests/systray/systray_messaging_menu_tests.js
index 047d723a425..9281e8a3ba4 100644
--- a/addons/mail/static/tests/systray/systray_messaging_menu_tests.js
+++ b/addons/mail/static/tests/systray/systray_messaging_menu_tests.js
@@ -120,6 +120,53 @@ QUnit.test('messaging menu widget: menu with no records', async function (assert
messagingMenu.destroy();
});
+QUnit.test('messaging menu widget: messaging not ready', async function (assert) {
+ assert.expect(8);
+
+ const messagingReadyProm = testUtils.makeTestPromise();
+
+ const messagingMenu = new MessagingMenu();
+ testUtils.mock.addMockEnvironment(messagingMenu, {
+ services: this.services,
+ async mockRPC(route, args) {
+ if (route === '/mail/init_messaging') {
+ const _super = this._super.bind(this, ...arguments); // limitation of class.js
+ assert.step('/mail/init_messaging:pending');
+ await messagingReadyProm;
+ assert.step('/mail/init_messaging:resolved');
+ return _super();
+ }
+ if (args.method === 'message_fetch') {
+ return [];
+ }
+ return this._super(...arguments);
+ },
+ });
+ await messagingMenu.appendTo($('#qunit-fixture'));
+ assert.verifySteps(['/mail/init_messaging:pending']);
+ assert.ok(
+ messagingMenu.el,
+ "messaging menu should be rendered");
+ assert.strictEqual(
+ document.querySelector('.o_mail_systray_item'),
+ messagingMenu.el,
+ "should display messaging menu even when messaging is not ready");
+ assert.hasClass(
+ messagingMenu.$('.o_mail_messaging_menu_icon'),
+ 'fa-spinner',
+ "Messaging menu icon should be a spinner when messaging menu is not ready");
+
+ messagingReadyProm.resolve();
+ await testUtils.nextTick();
+ assert.verifySteps(['/mail/init_messaging:resolved']);
+ assert.doesNotHaveClass(
+ messagingMenu.$('.o_mail_messaging_menu_icon'),
+ 'fa-spinner',
+ "Messaging menu icon should no longer be a spinner when messaging menu is ready");
+
+ messagingMenu.destroy();
+});
+
QUnit.test('messaging menu widget: messaging menu with 1 record', async function (assert) {
assert.expect(3);
var messagingMenu = new MessagingMenu();
diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py
index d72caa41b24..772661d479c 100644
--- a/addons/mrp/models/mrp_production.py
+++ b/addons/mrp/models/mrp_production.py
@@ -422,6 +422,7 @@ class MrpProduction(models.Model):
self.product_qty = self.bom_id.product_qty
self.product_uom_id = self.bom_id.product_uom_id.id
self.move_raw_ids = [(2, move.id) for move in self.move_raw_ids.filtered(lambda m: m.bom_line_id)]
+ self.picking_type_id = self.bom_id.picking_type_id or self.picking_type_id
@api.onchange('date_planned_start')
def _onchange_date_planned_start(self):
diff --git a/addons/payment/models/payment_acquirer.py b/addons/payment/models/payment_acquirer.py
index d23658ffa5d..9f56664d7bd 100644
--- a/addons/payment/models/payment_acquirer.py
+++ b/addons/payment/models/payment_acquirer.py
@@ -13,6 +13,7 @@ from odoo.addons.base.models import ir_module
from odoo.exceptions import ValidationError
from odoo.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
from odoo.tools.misc import formatLang
+from odoo.http import request
_logger = logging.getLogger(__name__)
@@ -221,6 +222,19 @@ class PaymentAcquirer(models.Model):
if field_names:
raise ValidationError(_("Required fields not filled: %s") % ", ".join(field_names))
+ def get_base_url(self):
+ self.ensure_one()
+ # priority is always given to url_root
+ # from the request
+ url = ''
+ if request:
+ url = request.httprequest.url_root
+
+ if not url and 'website_id' in self and self.website_id:
+ url = self.website_id._get_http_domain()
+
+ return url or self.env['ir.config_parameter'].sudo().get_param('web.base.url')
+
def _get_feature_support(self):
"""Get advanced feature support by provider.
diff --git a/addons/payment_stripe/models/payment.py b/addons/payment_stripe/models/payment.py
index f64f1e60dcf..76191452e39 100644
--- a/addons/payment_stripe/models/payment.py
+++ b/addons/payment_stripe/models/payment.py
@@ -36,7 +36,7 @@ class PaymentAcquirerStripe(models.Model):
def stripe_form_generate_values(self, tx_values):
self.ensure_one()
- base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
+ base_url = self.get_base_url()
stripe_session_data = {
'payment_method_types[]': 'card',
'line_items[][amount]': int(tx_values['amount'] if tx_values['currency'].name in INT_CURRENCIES else float_round(tx_values['amount'] * 100, 2)),
@@ -147,6 +147,10 @@ class PaymentTransactionStripe(models.Model):
return super(PaymentTransactionStripe, self).form_feedback(data, acquirer_name)
def _stripe_create_payment_intent(self, acquirer_ref=None, email=None):
+ if not self.payment_token_id.stripe_payment_method:
+ # old token before using sca, need to fetch data from the api
+ self.payment_token_id._stripe_sca_migrate_customer()
+
charge_params = {
'amount': int(self.amount if self.currency_id.name in INT_CURRENCIES else float_round(self.amount * 100, 2)),
'currency': self.currency_id.name.lower(),
@@ -298,3 +302,39 @@ class PaymentTokenStripe(models.Model):
'acquirer_ref': cust_resp['id'],
}
return values
+
+ def _stripe_sca_migrate_customer(self):
+ """Migrate a token from the old implementation of Stripe to the SCA one.
+
+ In the old implementation, it was possible to create a valid charge just by
+ giving the customer ref to ask Stripe to use the default source (= default
+ card). Since we have a one-to-one matching between a saved card, this used to
+ work well - but now we need to specify the payment method for each call and so
+ we have to contact stripe to get the default source for the customer and save it
+ in the payment token.
+ This conversion will happen once per token, the first time it gets used following
+ the installation of the module."""
+ self.ensure_one()
+ url = "customers/%s" % (self.acquirer_ref)
+ data = self.acquirer_id._stripe_request(url, method="GET")
+ sources = data.get('sources', {}).get('data', [])
+ pm_ref = False
+ if sources:
+ if len(sources) > 1:
+ _logger.warning('stripe sca customer conversion: there should be a single saved source per customer!')
+ pm_ref = sources[0].get('id')
+ else:
+ url = 'payment_methods'
+ params = {
+ 'type': 'card',
+ 'customer': self.acquirer_ref,
+ }
+ payment_methods = self.acquirer_id._stripe_request(url, params, method='GET')
+ cards = payment_methods.get('data', [])
+ if len(cards) > 1:
+ _logger.warning('stripe sca customer conversion: there should be a single saved source per customer!')
+ pm_ref = cards and cards[0].get('id')
+ if not pm_ref:
+ raise ValidationError(_('Unable to convert Stripe customer for SCA compatibility. Is there at least one card for this customer in the Stripe backend?'))
+ self.stripe_payment_method = pm_ref
+ _logger.info('converted old customer ref to sca-compatible record for payment token %s', self.id)
diff --git a/addons/product/models/product_pricelist.py b/addons/product/models/product_pricelist.py
index dd8fa820a05..25552049c02 100644
--- a/addons/product/models/product_pricelist.py
+++ b/addons/product/models/product_pricelist.py
@@ -121,7 +121,7 @@ class Pricelist(models.Model):
""" Low-level method - Mono pricelist, multi products
Returns: dict{product_id: (price, suitable_rule) for the given pricelist}
- If date in context: Date of the pricelist (%Y-%m-%d)
+ Date in context can be a date, datetime, ...
:param products_qty_partner: list of typles products, quantity, partner
:param datetime date: validity date
@@ -129,8 +129,8 @@ class Pricelist(models.Model):
"""
self.ensure_one()
if not date:
- date = self._context.get('date') or fields.Date.context_today(self)
- date = fields.Date.to_date(date) # handwritten query below does not work with non-dates (e.g. datetimes)
+ date = self._context.get('date') or fields.Date.today()
+ date = fields.Date.to_date(date) # boundary conditions differ if we have a datetime
if not uom_id and self._context.get('uom'):
uom_id = self._context['uom']
if uom_id:
diff --git a/addons/product/models/product_template.py b/addons/product/models/product_template.py
index 105ac2f7f8f..442ecf2e90a 100644
--- a/addons/product/models/product_template.py
+++ b/addons/product/models/product_template.py
@@ -406,7 +406,7 @@ class ProductTemplate(models.Model):
def name_get(self):
# Prefetch the fields used by the `name_get`, so `browse` doesn't fetch other fields
- self.read(['name', 'default_code'])
+ self.browse(self.ids).read(['name', 'default_code'])
return [(template.id, '%s%s' % (template.default_code and '[%s] ' % template.default_code or '', template.name))
for template in self]
diff --git a/addons/purchase/tests/test_purchase_order_report.py b/addons/purchase/tests/test_purchase_order_report.py
index 9497348e3ab..0a381c46d44 100644
--- a/addons/purchase/tests/test_purchase_order_report.py
+++ b/addons/purchase/tests/test_purchase_order_report.py
@@ -56,7 +56,7 @@ class TestPurchaseOrderReport(common.TransactionCase):
})
po.button_confirm()
- f = Form(self.env['account.move'])
+ f = Form(self.env['account.move'].with_context(default_type='in_invoice'))
f.partner_id = po.partner_id
f.purchase_id = po
invoice = f.save()
diff --git a/addons/sale/tests/test_reinvoice.py b/addons/sale/tests/test_reinvoice.py
index b7640fd23e9..bc6e3457a1c 100644
--- a/addons/sale/tests/test_reinvoice.py
+++ b/addons/sale/tests/test_reinvoice.py
@@ -216,17 +216,14 @@ class TestReInvoice(TestCommonSaleNoChart):
self.sale_order.action_confirm()
# create invoice lines and validate it
- invoice_a = self.AccountMove.create({
- 'partner_id': self.partner_customer_usd.id,
- 'journal_id': self.journal_purchase.id,
- 'line_ids': [
- (0, 0, {
- 'product_id': self.product_no_expense.id,
- 'quantity': 3,
- 'analytic_account_id': self.analytic_account.id,
- }),
- ],
- })
+ move_form = Form(self.AccountMove)
+ move_form.partner_id = self.partner_customer_usd
+ move_form.journal_id = self.journal_purchase
+ with move_form.line_ids.new() as line_form:
+ line_form.product_id = self.product_no_expense
+ line_form.quantity = 3.0
+ line_form.analytic_account_id = self.analytic_account
+ invoice_a = move_form.save()
invoice_a.post()
self.assertEquals(len(self.sale_order.order_line), 1, "No SO line should have been created (or removed) when validating vendor bill")
diff --git a/addons/sale/tests/test_sale_order.py b/addons/sale/tests/test_sale_order.py
index 0b30a9c0aa0..57d9336f809 100644
--- a/addons/sale/tests/test_sale_order.py
+++ b/addons/sale/tests/test_sale_order.py
@@ -196,7 +196,6 @@ class TestSaleOrder(TestCommonSaleNoChart):
so._create_analytic_account()
inv = self.env['account.move'].with_context(default_type='in_invoice').create({
- 'type': 'in_invoice',
'partner_id': self.partner_customer_usd.id,
'invoice_line_ids': [
(0, 0, {
diff --git a/addons/stock/models/stock_move.py b/addons/stock/models/stock_move.py
index ec78b56eca9..31a03dca988 100644
--- a/addons/stock/models/stock_move.py
+++ b/addons/stock/models/stock_move.py
@@ -1078,6 +1078,7 @@ class StockMove(models.Model):
# cache invalidation when actually reserving the move.
reserved_availability = {move: move.reserved_availability for move in self}
roundings = {move: move.product_id.uom_id.rounding for move in self}
+ move_line_vals_list = []
for move in self.filtered(lambda m: m.state in ['confirmed', 'waiting', 'partially_available']):
rounding = roundings[move]
missing_reserved_uom_quantity = move.product_uom_qty - reserved_availability[move]
@@ -1086,7 +1087,7 @@ class StockMove(models.Model):
# create the move line(s) but do not impact quants
if move.product_id.tracking == 'serial' and (move.picking_type_id.use_create_lots or move.picking_type_id.use_existing_lots):
for i in range(0, int(missing_reserved_quantity)):
- self.env['stock.move.line'].create(move._prepare_move_line_vals(quantity=1))
+ move_line_vals_list.append(move._prepare_move_line_vals(quantity=1))
else:
to_update = move.move_line_ids.filtered(lambda ml: ml.product_uom_id == move.product_uom and
ml.location_id == move.location_id and
@@ -1098,7 +1099,7 @@ class StockMove(models.Model):
if to_update:
to_update[0].product_uom_qty += missing_reserved_uom_quantity
else:
- self.env['stock.move.line'].create(move._prepare_move_line_vals(quantity=missing_reserved_quantity))
+ move_line_vals_list.append(move._prepare_move_line_vals(quantity=missing_reserved_quantity))
assigned_moves |= move
else:
if not move.move_orig_ids:
@@ -1191,6 +1192,8 @@ class StockMove(models.Model):
partially_available_moves |= move
if move.product_id.tracking == 'serial':
move._update_next_serial_count()
+
+ self.env['stock.move.line'].create(move_line_vals_list)
partially_available_moves.write({'state': 'partially_available'})
assigned_moves.write({'state': 'assigned'})
self.mapped('picking_id')._check_entire_pack()
diff --git a/addons/stock/models/stock_picking.py b/addons/stock/models/stock_picking.py
index e78a9aed406..bf8b4d61160 100644
--- a/addons/stock/models/stock_picking.py
+++ b/addons/stock/models/stock_picking.py
@@ -715,21 +715,31 @@ class Picking(models.Model):
@api.depends('state', 'move_lines', 'move_lines.state', 'move_lines.package_level_id', 'move_lines.move_line_ids.package_level_id')
def _compute_move_without_package(self):
for picking in self:
- move_ids_without_package = self.env['stock.move']
- if picking.picking_type_entire_packs == False:
- move_ids_without_package = picking.move_lines
- else:
- for move in picking.move_lines:
- if not move.package_level_id:
- if move.state in ('assigned', 'done'):
- if any(not ml.package_level_id for ml in move.move_line_ids):
- move_ids_without_package |= move
- else:
- move_ids_without_package |= move
- picking.move_ids_without_package = move_ids_without_package.filtered(lambda move: not move.scrap_ids)
+ picking.move_ids_without_package = picking._get_move_ids_without_package()
def _set_move_without_package(self):
- self.move_lines |= self.move_ids_without_package
+ new_mwp = self[0].move_ids_without_package
+ for picking in self:
+ old_mwp = picking._get_move_ids_without_package()
+ picking.move_lines = (picking.move_lines - old_mwp) | new_mwp
+ moves_to_unlink = old_mwp - new_mwp
+ if moves_to_unlink:
+ moves_to_unlink.unlink()
+
+ def _get_move_ids_without_package(self):
+ self.ensure_one()
+ move_ids_without_package = self.env['stock.move']
+ if not self.picking_type_entire_packs:
+ move_ids_without_package = self.move_lines
+ else:
+ for move in self.move_lines:
+ if not move.package_level_id:
+ if move.state in ('assigned', 'done'):
+ if any(not ml.package_level_id for ml in move.move_line_ids):
+ move_ids_without_package |= move
+ else:
+ move_ids_without_package |= move
+ return move_ids_without_package.filtered(lambda move: not move.scrap_ids)
def _check_move_lines_map_quant_package(self, package):
""" This method checks that all product of the package (quant) are well present in the move_line_ids of the picking. """
diff --git a/addons/stock/tests/test_move2.py b/addons/stock/tests/test_move2.py
index e1380a8ec28..24e6e2de655 100644
--- a/addons/stock/tests/test_move2.py
+++ b/addons/stock/tests/test_move2.py
@@ -1815,6 +1815,20 @@ class TestSinglePicking(TestStockCommon):
back_order = self.env['stock.picking'].search([('backorder_id', '=', delivery_order.id)])
self.assertFalse(back_order, 'There should be no back order')
+ def test_unlink_move_1(self):
+ picking = Form(self.env['stock.picking'])
+ ptout = self.env['stock.picking.type'].browse(self.picking_type_out)
+ picking.picking_type_id = ptout
+ with picking.move_ids_without_package.new() as move:
+ move.product_id = self.productA
+ move.product_uom_qty = 10
+ picking = picking.save()
+
+ picking = Form(picking)
+ picking.move_ids_without_package.remove(0)
+ picking = picking.save()
+ self.assertEqual(len(picking.move_ids_without_package), 0)
+
def test_owner_1(self):
"""Make a receipt, set an owner and validate"""
owner1 = self.env['res.partner'].create({'name': 'owner'})
diff --git a/addons/survey/controllers/main.py b/addons/survey/controllers/main.py
index 7eabe92f733..75945503aa2 100644
--- a/addons/survey/controllers/main.py
+++ b/addons/survey/controllers/main.py
@@ -411,10 +411,11 @@ class Survey(http.Controller):
answer_tag = "%s_%s" % (survey_sudo.id, question.id)
request.env['survey.user_input_line'].sudo().save_lines(answer_sudo.id, question, post, answer_tag)
+ vals = {}
if answer_sudo.is_time_limit_reached or survey_sudo.questions_layout == 'one_page':
go_back = False
answer_sudo._mark_done()
- else:
+ elif 'button_submit' in post:
go_back = post['button_submit'] == 'previous'
next_page, last = request.env['survey.survey'].next_page_or_question(answer_sudo, page_or_question_id, go_back=go_back)
vals = {'last_displayed_page_id': page_or_question_id}
@@ -423,11 +424,16 @@ class Survey(http.Controller):
answer_sudo._mark_done()
else:
vals.update({'state': 'skip'})
- answer_sudo.write(vals)
- ret['redirect'] = '/survey/fill/%s/%s' % (survey_sudo.access_token, answer_token)
- if go_back:
- ret['redirect'] += '?prev=prev'
+ if 'breadcrumb_redirect' in post:
+ ret['redirect'] = post['breadcrumb_redirect']
+ else:
+ if vals:
+ answer_sudo.write(vals)
+
+ ret['redirect'] = '/survey/fill/%s/%s' % (survey_sudo.access_token, answer_token)
+ if go_back:
+ ret['redirect'] += '?prev=prev'
return json.dumps(ret)
diff --git a/addons/survey/static/src/js/survey.js b/addons/survey/static/src/js/survey.js
index d7092902f34..1f12c6ad2a6 100644
--- a/addons/survey/static/src/js/survey.js
+++ b/addons/survey/static/src/js/survey.js
@@ -129,6 +129,15 @@ if(!the_form.length) {
}
}
+ $('.o_survey_header .breadcrumb-item a').each(function() {
+ var $valObj = $(this);
+ $valObj.click(function(event) {
+ event.preventDefault();
+ $('<input>').attr({type: 'hidden', name: 'breadcrumb_redirect', value: $valObj.attr('href')}).appendTo('.js_surveyform');
+ $('.js_surveyform').submit();
+ });
+ });
+
// Parameters for form submission
$('.js_surveyform').ajaxForm({
url: submit_controller,
@@ -232,5 +241,4 @@ if(!the_form.length) {
display_scores();
}
});
-
});
diff --git a/addons/web/static/src/css/reset.min.css b/addons/web/static/src/css/reset.min.css
index 97c0b78b002..b6163764a5c 100644
--- a/addons/web/static/src/css/reset.min.css
+++ b/addons/web/static/src/css/reset.min.css
@@ -55,10 +55,6 @@ ul ul {
list-style: circle;
}
-blockquote, q {
- quotes: none;
-}
-
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
diff --git a/addons/web/static/src/js/core/dom.js b/addons/web/static/src/js/core/dom.js
index f260478da1e..d2fdb41fefc 100644
--- a/addons/web/static/src/js/core/dom.js
+++ b/addons/web/static/src/js/core/dom.js
@@ -537,7 +537,7 @@ var dom = {
menuItemsWidth += computeFloatOuterWidthWithMargins($extraItemsToggle[0]);
do {
menuItemsWidth -= computeFloatOuterWidthWithMargins($items.eq(--nbItems)[0]);
- } while (!(maxWidth - menuItemsWidth >= -0.001));
+ } while (!(maxWidth - menuItemsWidth >= -0.001) && (nbItems > 0));
var $extraItems = $items.slice(nbItems).detach();
$extraItems.removeClass('nav-item');
diff --git a/addons/web/static/src/js/fields/field_utils.js b/addons/web/static/src/js/fields/field_utils.js
index 782f76d6b10..e6bde45e1f5 100644
--- a/addons/web/static/src/js/fields/field_utils.js
+++ b/addons/web/static/src/js/fields/field_utils.js
@@ -415,7 +415,7 @@ function parseDate(value, field, options) {
if (options && options.isUTC) {
date = moment.utc(value);
} else {
- date = moment.utc(value, [datePattern, datePatternWoZero, moment.ISO_8601], true);
+ date = moment.utc(value, [datePattern, datePatternWoZero, moment.ISO_8601]);
}
if (date.isValid()) {
if (date.year() === 0) {
@@ -459,7 +459,7 @@ function parseDateTime(value, field, options) {
// phatomjs crash if we don't use this format
datetime = moment.utc(value.replace(' ', 'T') + 'Z');
} else {
- datetime = moment.utc(value, [pattern1, pattern2, moment.ISO_8601], true);
+ datetime = moment.utc(value, [pattern1, pattern2, moment.ISO_8601]);
if (options && options.timezone) {
datetime.add(-session.getTZOffset(datetime), 'minutes');
}
diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js
index 9ef8241f9f3..54e4d89478a 100644
--- a/addons/web/static/src/js/fields/relational_fields.js
+++ b/addons/web/static/src/js/fields/relational_fields.js
@@ -828,6 +828,8 @@ var ListFieldMany2One = FieldMany2One.extend({
}),
/**
+ * Should never be allowed to be opened while in readonly mode in a list
+ *
* @override
*/
init: function () {
diff --git a/addons/web/static/src/js/views/list/list_controller.js b/addons/web/static/src/js/views/list/list_controller.js
index b90d903739b..1047bf8d592 100644
--- a/addons/web/static/src/js/views/list/list_controller.js
+++ b/addons/web/static/src/js/views/list/list_controller.js
@@ -54,6 +54,19 @@ var ListController = BasicController.extend({
this.selectedRecords = params.selectedRecords || [];
this.multipleRecordsSavingPromise = null;
this.fieldChangedPrevented = false;
+ this._onMouseupWindowDiscard = null;
+ },
+
+ /**
+ * Overriden to properly unbind any mouseup listeners still bound to the window
+ *
+ * @override
+ */
+ destroy: function () {
+ if (this._onMouseupWindowDiscard) {
+ window.removeEventListener('mouseup', this._onMouseupWindowDiscard, true);
+ }
+ return this._super.apply(this, arguments);
},
//--------------------------------------------------------------------------
diff --git a/addons/web/static/src/js/widgets/date_picker.js b/addons/web/static/src/js/widgets/date_picker.js
index 06d329282c8..95908433fec 100644
--- a/addons/web/static/src/js/widgets/date_picker.js
+++ b/addons/web/static/src/js/widgets/date_picker.js
@@ -91,6 +91,13 @@ var DateWidget = Widget.extend({
* set datetime value
*/
changeDatetime: function () {
+ if (this.__libInput > 0) {
+ if (this.options.warn_future) {
+ this._warnFuture(this.getValue());
+ }
+ this.trigger("datetime_changed");
+ return;
+ }
var oldValue = this.getValue();
if (this.isValid()) {
this._setValueFromUi();
@@ -253,6 +260,7 @@ var DateWidget = Widget.extend({
*/
_onDateTimePickerHide: function () {
this.__isOpen = false;
+ this.changeDatetime();
if (this._onScroll) {
window.removeEventListener('scroll', this._onScroll, true);
}
diff --git a/addons/web/static/tests/fields/basic_fields_tests.js b/addons/web/static/tests/fields/basic_fields_tests.js
index 1d91f581317..e8db402ec49 100644
--- a/addons/web/static/tests/fields/basic_fields_tests.js
+++ b/addons/web/static/tests/fields/basic_fields_tests.js
@@ -511,6 +511,42 @@ QUnit.module('basic_fields', {
form.destroy();
});
+ QUnit.test('float field in list view no widget', async function (assert) {
+ assert.expect(5);
+
+ var form = await createView({
+ View: FormView,
+ model: 'partner',
+ data: this.data,
+ arch:'<form string="Partners">' +
+ '<sheet>' +
+ '<field name="qux" digits="[5,3]"/>' +
+ '</sheet>' +
+ '</form>',
+ res_id: 2,
+ });
+
+ assert.doesNotHaveClass(form.$('.o_field_widget'), 'o_field_empty',
+ 'Float field should be considered set for value 0.');
+ assert.strictEqual(form.$('.o_field_widget').first().text(), '0.000',
+ 'The value should be displayed properly.');
+
+ await testUtils.form.clickEdit(form);
+ assert.strictEqual(form.$('input[name=qux]').val(), '0.000',
+ 'The value should be rendered with correct precision.');
+
+ await testUtils.fields.editInput(form.$('input[name=qux]'), '108.2458938598598');
+ assert.strictEqual(form.$('input[name=qux]').val(), '108.2458938598598',
+ 'The value should not be formated yet.');
+
+ await testUtils.fields.editInput(form.$('input[name=qux]'), '18.8958938598598');
+ await testUtils.form.clickSave(form);
+ assert.strictEqual(form.$('.o_field_widget').first().text(), '18.896',
+ 'The new value should be rounded properly.');
+
+ form.destroy();
+ });
+
QUnit.test('float field in form view', async function (assert) {
assert.expect(5);
diff --git a/addons/web/static/tests/fields/field_utils_tests.js b/addons/web/static/tests/fields/field_utils_tests.js
index c4281b38c87..e0b9564d13c 100644
--- a/addons/web/static/tests/fields/field_utils_tests.js
+++ b/addons/web/static/tests/fields/field_utils_tests.js
@@ -353,5 +353,39 @@ QUnit.test('parse datetime', function (assert) {
core._t.database.parameters = originalParameters;
});
+QUnit.test('parse date without separator', function (assert) {
+ assert.expect(8);
+
+ var originalParameters = _.clone(core._t.database.parameters);
+
+ _.extend(core._t.database.parameters, {date_format: '%d.%m/%Y'});
+ var dateFormat = "DD.MM/YYYY";
+
+ assert.throws(function () {fieldUtils.parse.date("1197")}, /is not a correct/, "Wrongly formated dates should be invalid");
+ assert.throws(function () {fieldUtils.parse.date("0131")}, /is not a correct/, "Wrongly formated dates should be invalid");
+ assert.throws(function () {fieldUtils.parse.date("970131")}, /is not a correct/, "Wrongly formated dates should be invalid");
+ assert.equal(fieldUtils.parse.date("3101").format(dateFormat), "31.01/" + moment.utc().year());
+ assert.equal(fieldUtils.parse.date("31.01").format(dateFormat), "31.01/" + moment.utc().year());
+ assert.equal(fieldUtils.parse.date("310197").format(dateFormat), "31.01/1997");
+ assert.equal(fieldUtils.parse.date("310117").format(dateFormat), "31.01/2017");
+ assert.equal(fieldUtils.parse.date("31011985").format(dateFormat), "31.01/1985");
+
+ core._t.database.parameters = originalParameters;
+});
+
+QUnit.test('parse datetime without separator', function (assert) {
+ assert.expect(3);
+
+ var originalParameters = _.clone(core._t.database.parameters);
+
+ _.extend(core._t.database.parameters, {date_format: '%d.%m/%Y', time_format: '%H:%M/%S'});
+ var dateTimeFormat = "DD.MM/YYYY HH:mm/ss";
+
+ assert.equal(fieldUtils.parse.datetime("3101198508").format(dateTimeFormat), "31.01/1985 08:00/00");
+ assert.equal(fieldUtils.parse.datetime("310119850833").format(dateTimeFormat), "31.01/1985 08:33/00");
+ assert.equal(fieldUtils.parse.datetime("31/01/1985 08").format(dateTimeFormat), "31.01/1985 08:00/00");
+
+ core._t.database.parameters = originalParameters;
+});
});
});
diff --git a/addons/web/static/tests/views/search_view_tests.js b/addons/web/static/tests/views/search_view_tests.js
index 2664aca2bf5..43645318f6c 100644
--- a/addons/web/static/tests/views/search_view_tests.js
+++ b/addons/web/static/tests/views/search_view_tests.js
@@ -701,6 +701,7 @@ QUnit.module('Search View', {
// DateTime case
$autocomplete = $('.o_searchview_input');
await stringToEvent($autocomplete, '07/15/1983 00:00:00');
+ await testUtils.fields.triggerKey('down', $autocomplete, 'down');
await testUtils.fields.triggerKey('up', $autocomplete, 'enter');
assert.equal($('.o_searchview_facet .o_facet_values').text().trim(), '07/15/1983 00:00:00',
diff --git a/addons/website/static/src/scss/website.scss b/addons/website/static/src/scss/website.scss
index e2866e56a89..79f516fed64 100644
--- a/addons/website/static/src/scss/website.scss
+++ b/addons/website/static/src/scss/website.scss
@@ -362,9 +362,11 @@ table.table_desc tr td {
// Title
.s_title {
.s_title_boxed {
- display: inline-block;
- padding: $grid-gutter-width;
- border: 1px solid;
+ > * {
+ display: inline-block;
+ padding: $grid-gutter-width;
+ border: 1px solid;
+ }
}
.s_title_lines {
overflow: hidden;
diff --git a/addons/website_event_questions/report/report_event_question_view.xml b/addons/website_event_questions/report/report_event_question_view.xml
index 7d8f7d9298e..a495d66fc7d 100644
--- a/addons/website_event_questions/report/report_event_question_view.xml
+++ b/addons/website_event_questions/report/report_event_question_view.xml
@@ -40,6 +40,9 @@
<filter string="Event" name="group_by_event" context="{'group_by': 'event_id'}" />
<filter string="Question" name="group_by_question" context="{'group_by': 'question_id'}"/>
<filter string="Answer" name="group_by_answer" context="{'group_by': 'answer_id'}" />
+ <filter name="exclude_cancelled"
+ string="Exclude cancelled registrations"
+ domain="[('attendee_id.state', '!=', 'cancel')]" />
</group>
</search>
</field>
diff --git a/addons/website_sale/data/mail_template_data.xml b/addons/website_sale/data/mail_template_data.xml
index b766cdf9b41..25ccc2e3c7e 100644
--- a/addons/website_sale/data/mail_template_data.xml
+++ b/addons/website_sale/data/mail_template_data.xml
@@ -38,7 +38,7 @@
<h1 style="color:#A9A9A9;">THERE'S SOMETHING IN YOUR CART.</h1>
Would you like to complete your purchase?<br/><br/>
% if object.order_line:
- % for line in object.order_line:
+ % for line in object.website_order_line:
<hr/>
<table width="100%">
<tr>
diff --git a/addons/website_sale_wishlist/controllers/main.py b/addons/website_sale_wishlist/controllers/main.py
index 09bd5f90b17..b494aeb927d 100644
--- a/addons/website_sale_wishlist/controllers/main.py
+++ b/addons/website_sale_wishlist/controllers/main.py
@@ -55,5 +55,5 @@ class WebsiteSaleWishlist(WebsiteSale):
request.session.modified = True
wish.sudo().unlink()
else:
- wish.active = False
+ wish.unlink()
return True