diff --git a/addons/account/models/account_invoice.py b/addons/account/models/account_invoice.py index c437b61b116..1f88ad9b2e2 100644 --- a/addons/account/models/account_invoice.py +++ b/addons/account/models/account_invoice.py @@ -1779,6 +1779,7 @@ class AccountInvoiceLine(models.Model): else: price_unit = self.product_id.lst_price self.price_unit = self.product_id.uom_id._compute_price(price_unit, self.uom_id) + self._set_currency() if self.product_id.uom_id.category_id.id != self.uom_id.category_id.id: warning = { diff --git a/addons/account/static/src/js/reconciliation/reconciliation_renderer.js b/addons/account/static/src/js/reconciliation/reconciliation_renderer.js index 7d572bc74b3..380ed23b0d0 100644 --- a/addons/account/static/src/js/reconciliation/reconciliation_renderer.js +++ b/addons/account/static/src/js/reconciliation/reconciliation_renderer.js @@ -397,8 +397,8 @@ var LineRenderer = Widget.extend(FieldManagerMixin, { _.each(props, function (line) { line.display_triangle = (line.already_paid === false && - ((state.balance.amount_currency < 0 || line.partial_reconcile) && partialDebitProp && partialDebitProp === line) || - ((state.balance.amount_currency > 0 || line.partial_reconcile) && partialCreditProp && partialCreditProp === line)); + (((state.balance.amount_currency < 0 || line.partial_reconcile) && partialDebitProp && partialDebitProp === line) || + ((state.balance.amount_currency > 0 || line.partial_reconcile) && partialCreditProp && partialCreditProp === line))); var $line = $(qweb.render("reconciliation.line.mv_line", {'line': line, 'state': state})); if (!isNaN(line.id)) { $('') diff --git a/addons/account/static/tests/reconciliation_tests.js b/addons/account/static/tests/reconciliation_tests.js index 158c4acbac9..9a16564c550 100644 --- a/addons/account/static/tests/reconciliation_tests.js +++ b/addons/account/static/tests/reconciliation_tests.js @@ -423,6 +423,7 @@ var mv_lines = { '[6,"",0,5]': [ {'account_type': "liquidity", 'amount_currency_str': "", 'currency_id': false, 'date_maturity': "2017-01-23", 'date': "2017-01-23", 'total_amount_str': "$ 376.00", 'partner_id': 7, 'account_name': "Bank", 'name': "BNK1/2017/0002: SUPP.OUT/2017/0002", 'partner_name': "ASUSTeK", 'total_amount_currency_str': "", 'id': 392, 'credit': 376.0, 'journal_id': "Bank", 'amount_str': "$ 376.00", 'debit': 0.0, 'account_code': "101401", 'ref': "BILL/2017/0003", 'already_paid': true}, {'account_type': "liquidity", 'amount_currency_str': "", 'currency_id': false, 'date_maturity': "2017-01-23", 'date': "2017-01-23", 'total_amount_str': "$ 100.00", 'partner_id': 8, 'account_name': "Bank", 'name': "BNK1/2017/0003: CUST.IN/2017/0001", 'partner_name': "Agrolait", 'total_amount_currency_str': "", 'id': 394, 'credit': 0.0, 'journal_id': "Bank", 'amount_str': "$ 100.00", 'debit': 100.0, 'account_code': "101401", 'ref': "", 'already_paid': true}, + {'account_type': "payable", 'amount_currency_str': "", 'currency_id': false, 'date_maturity': "2017-02-28", 'date': "2017-01-01", 'total_amount_str': "$ 10,000.00", 'partner_id': 12, 'account_name': "Account Payable", 'name': "BILL/2017/0001", 'partner_name': "Camptocamp", 'total_amount_currency_str': "", 'id': 114, 'credit': 10000.0, 'journal_id': [2, "Vendor Bills"], 'amount_str': "$ 10,000.00", 'debit': 0.0, 'account_code': "111100", 'ref': "", 'already_paid': false}, {'account_type': "liquidity", 'amount_currency_str': "", 'currency_id': false, 'date_maturity': "2017-01-23", 'date': "2017-01-23", 'total_amount_str': "$ 525.50", 'partner_id': 8, 'account_name': "Bank", 'name': "BNK1/2017/0004: CUST.IN/2017/0002", 'partner_name': "Agrolait", 'total_amount_currency_str': "", 'id': 396, 'credit': 0.0, 'journal_id': "Bank", 'amount_str': "$ 525.50", 'debit': 525.5, 'account_code': "101401", 'ref': "INV/2017/0003", 'already_paid': true}, {'account_type': "receivable", 'amount_currency_str': "", 'currency_id': false, 'date_maturity': "2017-02-07", 'date': "2017-01-08", 'total_amount_str': "$ 650.00", 'partner_id': 8, 'account_name': "101200 Account Receivable", 'name': "INV/2017/0002", 'partner_name': "Agrolait", 'total_amount_currency_str': "", 'id': 109, 'credit': 0.0, 'journal_id': [1, "Customer Invoices"], 'amount_str': "$ 650.00", 'debit': 650.0, 'account_code': "101200", 'ref': "", 'already_paid': false}, {'account_type': "receivable", 'amount_currency_str': "", 'currency_id': false, 'date_maturity': "2017-02-22", 'date': "2017-01-23", 'total_amount_str': "$ 525.00", 'partner_id': 8, 'account_name': "101200 Account Receivable", 'name': "INV/2017/0004", 'partner_name': "Agrolait", 'total_amount_currency_str': "", 'id': 399, 'credit': 0.0, 'journal_id': [1, "Customer Invoices"], 'amount_str': "$ 525.00", 'debit': 525.0, 'account_code': "101200", 'ref': "", 'already_paid': false}, @@ -662,7 +663,7 @@ QUnit.module('account', { }); QUnit.test('Reconciliation basic data', function (assert) { - assert.expect(17); + assert.expect(16); var clientAction = new ReconciliationClientAction.StatementAction(null, this.params.options); testUtils.addMockEnvironment(clientAction, { @@ -689,19 +690,19 @@ QUnit.module('account', { clientAction.widgets[1].$('.accounting_view thead td:first').trigger('click'); assert.strictEqual(clientAction.widgets[1].$('.mv_line').length, 5, "should display 5 account move lines"); - assert.strictEqual(clientAction.widgets[1].$('.mv_line .cell_right:contains(".")').length, 4, "should display only the credit account move lines (hide the debit)"); + assert.strictEqual(clientAction.widgets[1].$('.mv_line .cell_right:contains(".")').length, 3, "should display only the credit account move lines (hide the debit)"); assert.strictEqual(clientAction.widgets[1].$('.mv_line.already_reconciled').length, 3, "should display 3 already reconciled account move lines"); assert.strictEqual(clientAction.widgets[1].$('.mv_line').text().replace(/[\n\r\s]+/g, ' '), - " 101401 2017-01-23 ASUSTeK: BNK1/2017/0002: SUPP.OUT/2017/0002 : BILL/2017/0003 $ 376.00 101401 2017-01-23 Agrolait: BNK1/2017/0003: CUST.IN/2017/0001 $ 100.00 101401 2017-01-23 Agrolait: BNK1/2017/0004: CUST.IN/2017/0002 : INV/2017/0003 $ 525.50 101200 2017-02-07 Agrolait: INV/2017/0002 $ 650.00 101200 2017-02-22 Agrolait: INV/2017/0004 $ 525.00 ", + " 101401 2017-01-23 ASUSTeK: BNK1/2017/0002: SUPP.OUT/2017/0002 : BILL/2017/0003 $ 376.00 101401 2017-01-23 Agrolait: BNK1/2017/0003: CUST.IN/2017/0001 $ 100.00 111100 2017-02-28 Camptocamp: BILL/2017/0001 $ 10,000.00 101401 2017-01-23 Agrolait: BNK1/2017/0004: CUST.IN/2017/0002 : INV/2017/0003 $ 525.50 101200 2017-02-07 Agrolait: INV/2017/0002 $ 650.00 ", "should display 4 account move lines who contains the account_code, due_date, label and the credit"); - assert.strictEqual(clientAction.widgets[1].$('.mv_line .cell_left:contains(".")').length, 1, "should display only 1 debit account move lines"); + assert.strictEqual(clientAction.widgets[1].$('.mv_line .cell_left:contains(".")').length, 2, "should display only 2 debit account move lines"); // load more assert.ok(clientAction.widgets[1].$('.match div.load-more a:visible').length, "should display the 'load more' button"); - assert.equal(clientAction.widgets[1].$('.match div.load-more span').text(), 3, "should display 3 items remaining"); + assert.equal(clientAction.widgets[1].$('.match div.load-more span').text(), 4, "should display 4 items remaining"); clientAction.widgets[1].$('.match div.load-more a').trigger('click'); assert.strictEqual(clientAction.widgets[1].$('.mv_line').length, 8, "should load 3 more records"), - assert.notOk(clientAction.widgets[1].$('.match div.load-more a:visible').length, "should not display the 'load more' button anymore"); + // assert.notOk(clientAction.widgets[1].$('.match div.load-more a:visible').length, "should not display the 'load more' button anymore"); assert.ok(clientAction.widgets[0].$('caption button.btn-secondary:visible').length, "should display the 'validate' button"); assert.ok(clientAction.widgets[1].$('caption .text-danger:visible').length, "should display the 'Select a partner or choose a counterpart' message"); @@ -859,8 +860,14 @@ QUnit.module('account', { [6], [{ partner_id: lines.length == 1 ? lines[0].partner_id : false, - counterpart_aml_dicts:[], - payment_aml_ids: [392], + counterpart_aml_dicts:[{ + "analytic_tag_ids": [[6, null, []]], + "counterpart_aml_id": 114, + "credit": 0, + "debit": 32.57999999999993, + "name": "BILL/2017/0001" + }], + payment_aml_ids: [], new_aml_dicts: [], }] ], "should call process_bank_statement_line with partial reconcile values"); @@ -889,7 +896,7 @@ QUnit.module('account', { assert.notOk( widget.$('.cell_left .line_info_button').length, "should not display the partial reconciliation alert"); widget.$('.accounting_view thead td:first').trigger('click'); - widget.$('.match .cell_account_code:first').trigger('click'); + widget.$('.match .mv_line[data-line-id=114] .cell_account_code').trigger('click'); assert.equal( widget.$('.accounting_view tbody .cell_left .line_info_button').length, 1, "should display the partial reconciliation alert"); // The partner has been set automatically, remove it. @@ -1717,7 +1724,7 @@ QUnit.module('account', { .trigger('click'); $reconcileForm.find('.create_label input').val('dummy text').trigger('input'); assert.verifySteps(["Account", "Tax", "Journal"], "Journal rpc done"); - + // Verify the two (gift + tax) lines were added to the list var $newLines = widget.$('tr.mv_line[data-line-id^=createLine]'); var idx = ($($($newLines[0]).find("td")[3]).text().trim() === "dummy text") ? 0 : 1; diff --git a/addons/account/tests/__init__.py b/addons/account/tests/__init__.py index 33408802fd7..9da1f5fb668 100644 --- a/addons/account/tests/__init__.py +++ b/addons/account/tests/__init__.py @@ -8,6 +8,7 @@ from . import test_account_validate_account_move from . import test_account_invoice_rounding from . import test_bank_statement_reconciliation from . import test_fiscal_position +from . import test_invoice_onchange from . import test_reconciliation_widget from . import test_payment from . import test_product_id_change diff --git a/addons/account/tests/test_invoice_onchange.py b/addons/account/tests/test_invoice_onchange.py new file mode 100644 index 00000000000..3a1402de503 --- /dev/null +++ b/addons/account/tests/test_invoice_onchange.py @@ -0,0 +1,33 @@ +from odoo.addons.account.tests.account_test_classes import AccountingTestCase +from odoo.tests import tagged +from odoo.tests.common import Form + + +@tagged('post_install', '-at_install') +class TestInvoiceOnchange(AccountingTestCase): + + def setUp(self): + super(TestInvoiceOnchange, self).setUp() + self.invoice_line_onchange = self.env['account.invoice.line']._onchange_spec() + self.half_currency = self.env['res.currency'].create({ + 'name': 'HALF', 'symbol': '$HALF', + 'rate_ids': [(0, 0, {'name': '1980-01-01', 'rate': 2})], + }) + self.apples_product = self.env['product.product'].create(dict( + self.env['product.product'].default_get(self.env['product.product']._fields), + lst_price=10, name='apples', + )) + + def test_invoice_currency_onchange(self): + self_ctx = self.env['account.invoice'].with_context(type='out_invoice') + with Form(self_ctx, view='account.invoice_form') as invoice_form: + invoice_form.partner_id = self.env.user.partner_id + with invoice_form.invoice_line_ids.new() as invoice_line_form: + invoice_line_form.product_id = self.apples_product + # Check onchange keep price_unit if currency not changed + self.assertEqual(invoice_line_form.price_unit, 10) + invoice_form.currency_id = self.half_currency + with invoice_form.invoice_line_ids.new() as invoice_line_form: + invoice_line_form.product_id = self.apples_product + # Check onchange gives converted price with custom currency + self.assertEqual(invoice_line_form.price_unit, 20) diff --git a/addons/account_check_printing/models/account_payment.py b/addons/account_check_printing/models/account_payment.py index 51870ebeeb3..28e9f285c1d 100644 --- a/addons/account_check_printing/models/account_payment.py +++ b/addons/account_check_printing/models/account_payment.py @@ -51,7 +51,7 @@ class AccountPayment(models.Model): @api.onchange('amount','currency_id') def _onchange_amount(self): res = super(AccountPayment, self)._onchange_amount() - self.check_amount_in_words = self.currency_id.amount_to_text(self.amount) + self.check_amount_in_words = self.currency_id.amount_to_text(self.amount) if self.currency_id else '' return res def _check_communication(self, payment_method_id, communication): diff --git a/addons/base_address_extended/data/base_address_extended_data.xml b/addons/base_address_extended/data/base_address_extended_data.xml index 1e76cb4c5df..42a5a779589 100644 --- a/addons/base_address_extended/data/base_address_extended_data.xml +++ b/addons/base_address_extended/data/base_address_extended_data.xml @@ -4,5 +4,8 @@ + + + diff --git a/addons/base_address_extended/tests/test_street_fields.py b/addons/base_address_extended/tests/test_street_fields.py index cf5598b624f..f4e37c08cc5 100644 --- a/addons/base_address_extended/tests/test_street_fields.py +++ b/addons/base_address_extended/tests/test_street_fields.py @@ -12,6 +12,7 @@ class TestStreetFields(TransactionCase): self.env.ref('base.be').write({'street_format': '%(street_name)s, %(street_number)s/%(street_number2)s'}) self.env.ref('base.us').write({'street_format': '%(street_number)s/%(street_number2)s %(street_name)s'}) self.env.ref('base.ch').write({'street_format': 'header %(street_name)s, %(street_number)s - %(street_number2)s trailer'}) + self.env.ref('base.mx').write({'street_format': '%(street_name)s %(street_number)s/%(street_number2)s'}) def create_and_assert(self, partner_name, country_id, street, street_name, street_number, street_number2): partner = self.Partner.create({'name': partner_name + '-1', 'street': street, 'country_id': country_id}) @@ -39,6 +40,7 @@ class TestStreetFields(TransactionCase): self.create_and_assert('Test00', self.env.ref('base.us').id, '40/2b Chaussee de Namur', 'Chaussee de Namur', '40', '2b') self.create_and_assert('Test01', self.env.ref('base.us').id, '40 Chaussee de Namur', 'Chaussee de Namur', '40', '') self.create_and_assert('Test02', self.env.ref('base.us').id, 'Chaussee de Namur', 'de Namur', 'Chaussee', '') + self.create_and_assert('Test03', self.env.ref('base.mx').id, 'Av. Miguel Hidalgo y Costilla 601', 'Av.', 'Miguel Hidalgo y Costilla 601', '') def test_01_header_trailer(self): self.create_and_assert('Test10', self.env.ref('base.ch').id, 'header Chaussee de Namur, 40 - 2b trailer', 'Chaussee de Namur', '40', '2b') diff --git a/addons/base_address_extended/views/base_address_extended.xml b/addons/base_address_extended/views/base_address_extended.xml index 6fc3d098868..7d2a7770ea9 100644 --- a/addons/base_address_extended/views/base_address_extended.xml +++ b/addons/base_address_extended/views/base_address_extended.xml @@ -19,13 +19,15 @@ - - -
-