diff options
| author | Christophe Simonis <chs@odoo.com> | 2019-09-24 16:59:15 +0000 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2019-09-24 17:45:37 +0000 |
| commit | d67b2483e5bfa5d8c1e6ef1a64fb933f5e080ad5 (patch) | |
| tree | 25a7fd39ac993f3c04c5d8408beb628b3c9948ce /addons | |
| parent | 38d8b0526f0fccc32df5a11f5d086a3522ed5fcf (diff) | |
| parent | 9ed4872ea03f28012118ed48a43d0800617a84f3 (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')
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 |
