diff --git a/addons/account/models/account.py b/addons/account/models/account.py index 9f6c7071950..c83c5350431 100644 --- a/addons/account/models/account.py +++ b/addons/account/models/account.py @@ -1358,7 +1358,7 @@ class AccountTax(models.Model): base = recompute_base(base, incl_fixed_amount, incl_percent_amount, incl_division_amount) incl_fixed_amount = incl_percent_amount = incl_division_amount = 0 store_included_tax_total = True - if tax.price_include: + if tax.price_include or self._context.get('force_price_include'): if tax.amount_type == 'percent': incl_percent_amount += tax.amount elif tax.amount_type == 'division': @@ -1387,7 +1387,7 @@ class AccountTax(models.Model): cumulated_tax_included_amount = 0 for tax in taxes: #compute the tax_amount - if tax.price_include and total_included_checkpoints.get(i): + if (self._context.get('force_price_include') or tax.price_include) and total_included_checkpoints.get(i): # We know the total to reach for that tax, so we make a substraction to avoid any rounding issues tax_amount = total_included_checkpoints[i] - (base + cumulated_tax_included_amount) cumulated_tax_included_amount = 0 @@ -1426,7 +1426,7 @@ class AccountTax(models.Model): 'sequence': tax.sequence, 'account_id': tax.cash_basis_transition_account_id.id if tax.tax_exigibility == 'on_payment' else repartition_line.account_id.id, 'analytic': tax.analytic, - 'price_include': tax.price_include, + 'price_include': tax.price_include or self._context.get('force_price_include'), 'tax_exigibility': tax.tax_exigibility, 'tax_repartition_line_id': repartition_line.id, 'tag_ids': (repartition_line.tag_ids + subsequent_tags).ids, diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index 1309145169c..91f9fc8a38f 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -1024,7 +1024,7 @@ class AccountMove(models.Model): vendor_display_name = _('From: ') + move.invoice_source_email move.invoice_vendor_icon = '@' else: - vendor_display_name = ('Created by: ') + move.create_uid.name + vendor_display_name = ('Created by: ') + move.sudo().create_uid.name move.invoice_vendor_icon = '#' move.invoice_vendor_display_name = vendor_display_name @@ -1877,6 +1877,9 @@ class AccountMove(models.Model): for move in self: if move.auto_post and move.date > fields.Date.today(): raise UserError(_("This move is configured to be auto-posted on {}".format(move.date.strftime(self.env['res.lang']._lang_get(self.env.user.lang).date_format)))) + + move.message_subscribe([p.id for p in [move.partner_id, move.commercial_partner_id] if p not in move.message_partner_ids]) + to_write = {'state': 'posted'} if move.name == '/': @@ -2091,6 +2094,18 @@ class AccountMove(models.Model): ]) records.post() + # offer the possibility to duplicate thanks to a button instead of a hidden menu, which is more visible + @api.multi + def action_duplicate(self): + self.ensure_one() + action = self.env.ref('account.action_move_journal_line').read()[0] + action['context'] = dict(self.env.context) + action['context']['form_view_initial_mode'] = 'edit' + action['context']['view_no_maturity'] = False + action['views'] = [(self.env.ref('account.view_move_form').id, 'form')] + action['res_id'] = self.copy().id + return action + class AccountMoveLine(models.Model): _name = "account.move.line" @@ -3536,19 +3551,6 @@ class AccountMoveLine(models.Model): tables, where_clause, where_clause_params = query.get_sql() return tables, where_clause, where_clause_params - # FIXME: Clarify me and change me in master - @api.multi - def action_duplicate(self): - self.ensure_one() - action = self.env.ref('account.action_move_journal_line').read()[0] - action['target'] = 'inline' - action['context'] = dict(self.env.context) - action['context']['form_view_initial_mode'] = 'edit' - action['context']['view_no_maturity'] = False - action['views'] = [(self.env.ref('account.view_move_form').id, 'form')] - action['res_id'] = self.copy().id - return action - def _reconciled_lines(self): ids = [] for aml in self.filtered('account_id.reconcile'): diff --git a/addons/account/models/account_reconcile_model.py b/addons/account/models/account_reconcile_model.py index 67523d4e562..2834791ec38 100644 --- a/addons/account/models/account_reconcile_model.py +++ b/addons/account/models/account_reconcile_model.py @@ -174,19 +174,23 @@ class AccountReconcileModel(models.Model): tax = self.env['account.tax'].browse(tax_res['id']) new_aml_dicts.append({ - 'account_id': tax.account_id and tax.account_id.id or base_line_dict['account_id'], - 'name': tax.name, + 'account_id': tax_res['account_id'] or base_line_dict['account_id'], + 'name': tax_res['name'], 'partner_id': base_line_dict.get('partner_id'), 'debit': tax_res['amount'] > 0 and tax_res['amount'] or 0, 'credit': tax_res['amount'] < 0 and -tax_res['amount'] or 0, 'analytic_account_id': tax.analytic and base_line_dict['analytic_account_id'], 'analytic_tag_ids': tax.analytic and base_line_dict['analytic_tag_ids'], - 'tax_exigible': tax.tax_exigibility == 'on_payment', + 'tax_exigible': tax_res['tax_exigibility'], + 'tax_repartition_line_id': tax_res['tax_repartition_line_id'], + 'tax_ids': tax_res['tax_ids'], + 'tag_ids': tax_res['tag_ids'] }) # Handle price included taxes. base_line_dict['debit'] = tax_res['base'] > 0 and tax_res['base'] or base_line_dict['debit'] base_line_dict['credit'] = tax_res['base'] < 0 and -tax_res['base'] or base_line_dict['credit'] + base_line_dict['tag_ids'] = [(6, 0, res['base_tags'])] return new_aml_dicts @api.multi diff --git a/addons/account/models/partner.py b/addons/account/models/partner.py index 42e8da47d36..483e1142fab 100644 --- a/addons/account/models/partner.py +++ b/addons/account/models/partner.py @@ -262,9 +262,9 @@ class ResPartner(models.Model): LEFT JOIN account_move_line aml ON aml.partner_id = partner.id RIGHT JOIN account_account acc ON aml.account_id = acc.id WHERE acc.internal_type = %s - AND NOT acc.deprecated + AND NOT acc.deprecated AND acc.company_id = %s GROUP BY partner.id - HAVING %s * COALESCE(SUM(aml.amount_residual), 0) ''' + operator + ''' %s''', (account_type, sign, operand)) + HAVING %s * COALESCE(SUM(aml.amount_residual), 0) ''' + operator + ''' %s''', (account_type, self.env.user.company_id.id, sign, operand)) res = self._cr.fetchall() if not res: return [('id', '=', '0')] @@ -282,7 +282,6 @@ class ResPartner(models.Model): def _invoice_total(self): account_invoice_report = self.env['account.invoice.report'] if not self.ids: - self.total_invoiced = 0.0 return True user_currency_id = self.env.company.currency_id.id diff --git a/addons/account/report/account_aged_partner_balance.py b/addons/account/report/account_aged_partner_balance.py index 85a6f4bfcfb..b58d0c6376f 100644 --- a/addons/account/report/account_aged_partner_balance.py +++ b/addons/account/report/account_aged_partner_balance.py @@ -215,7 +215,8 @@ class ReportAgedPartnerBalance(models.AbstractModel): total[(i + 1)] += values['total'] values['partner_id'] = partner['partner_id'] if partner['partner_id']: - browsed_partner = self.env['res.partner'].browse(partner['partner_id']) + #browse the partner name and trust field in sudo, as we may not have full access to the record (but we still have to see it in the report) + browsed_partner = self.env['res.partner'].sudo().browse(partner['partner_id']) values['name'] = browsed_partner.name and len(browsed_partner.name) >= 45 and browsed_partner.name[0:40] + '...' or browsed_partner.name values['trust'] = browsed_partner.trust else: diff --git a/addons/account/tests/test_reconciliation_matching_rules.py b/addons/account/tests/test_reconciliation_matching_rules.py index b9e9e7d465d..f6b79a26280 100644 --- a/addons/account/tests/test_reconciliation_matching_rules.py +++ b/addons/account/tests/test_reconciliation_matching_rules.py @@ -94,6 +94,12 @@ class TestReconciliationMatchingRules(AccountingTestCase): 'sequence': 1, }) + self.tax21 = self.env['account.tax'].create({ + 'name': '21%', + 'type_tax_use': 'purchase', + 'amount': 21, + }) + def test_matching_fields(self): ''' Test all fields used to restrict the rules's applicability.''' @@ -300,6 +306,34 @@ class TestReconciliationMatchingRules(AccountingTestCase): {'partner_id': self.partner_2.id, 'debit': 0.0, 'credit': 1000.0}, ]) + def test_auto_reconcile_with_tax(self): + ''' Test auto reconciliation with a tax amount included in the bank statement line''' + + self.rule_1.write({ + 'auto_reconcile': True, + 'force_tax_included': True, + 'tax_ids': [(6, 0, self.tax21.ids)], + 'rule_type': 'writeoff_suggestion', + }) + + self.bank_line_2.unlink() + self.bank_line_1.amount = -121 + + self._check_statement_matching( + self.rule_1, + { + self.bank_line_1.id: {'aml_ids': [], 'model': self.rule_1, 'status': 'reconciled'}, + }, + self.bank_st + ) + + # Check first line has been well reconciled. + self.assertRecordValues(self.bank_line_1.journal_entry_ids, [ + {'partner_id': self.partner_1.id, 'debit': 100.0, 'credit': 0.0, 'tax_ids': [self.tax21.id]}, + {'partner_id': self.partner_1.id, 'debit': 21.0, 'credit': 0.0, 'tax_line_id': self.tax21.id}, + {'partner_id': self.partner_1.id, 'debit': 0.0, 'credit': 121.0}, + ]) + def test_reverted_move_matching(self): AccountMove = self.env['account.move'] move = AccountMove.create({ diff --git a/addons/account/views/account_move_views.xml b/addons/account/views/account_move_views.xml index 7d3cd61e1e1..0a2bf22c90d 100644 --- a/addons/account/views/account_move_views.xml +++ b/addons/account/views/account_move_views.xml @@ -761,6 +761,26 @@ + +
+ + + + + + + + + + + + + + + + + +
- {'journal_type':'general', 'search_default_group_by_move': 1, 'group_by':'move_id', 'search_default_posted':1, 'search_default_sales':1, 'name_groupby':1} Journal Items + {'journal_type':'general', 'search_default_group_by_move': 1, 'search_default_posted':1, 'search_default_sales':1, 'name_groupby':1} + Journal Items account.move.line [('display_type', 'not in', ('line_section', 'line_note'))] @@ -937,7 +958,7 @@ - {'journal_type':'sales', 'search_default_group_by_move': 1, 'group_by':'move_id', 'search_default_posted':1, 'search_default_sales':1, 'name_groupby':1} + {'journal_type':'sales', 'search_default_group_by_move': 1, 'search_default_posted':1, 'search_default_sales':1, 'name_groupby':1} Sales account.move.line [('display_type', 'not in', ('line_section', 'line_note'))] @@ -946,7 +967,7 @@ - {'journal_type':'purchase', 'search_default_group_by_move': 1, 'group_by':'move_id', 'search_default_posted':1, 'search_default_purchases':1, 'name_groupby':1} + {'journal_type':'purchase', 'search_default_group_by_move': 1, 'search_default_posted':1, 'search_default_purchases':1, 'name_groupby':1} Purchase account.move.line [('display_type', 'not in', ('line_section', 'line_note'))] @@ -955,7 +976,7 @@ - {'journal_type':'bank', 'search_default_group_by_move': 1, 'group_by':'move_id', 'search_default_posted':1, 'search_default_bank':1, 'search_default_cash':1, 'name_groupby':1} + {'journal_type':'bank', 'search_default_group_by_move': 1, 'search_default_posted':1, 'search_default_bank':1, 'search_default_cash':1, 'name_groupby':1} Bank and Cash account.move.line [('display_type', 'not in', ('line_section', 'line_note'))] @@ -964,7 +985,7 @@ - {'journal_type':'general', 'search_default_group_by_move': 1, 'group_by':'move_id', 'search_default_posted':1, 'search_default_misc_filter':1, 'name_groupby':1} + {'journal_type':'general', 'search_default_group_by_move': 1, 'search_default_posted':1, 'search_default_misc_filter':1, 'name_groupby':1} Miscellaneous account.move.line [('display_type', 'not in', ('line_section', 'line_note'))] @@ -973,7 +994,7 @@ - {'journal_type':'general', 'search_default_group_by_account': 1, 'group_by':'account_id', 'search_default_posted':1} + {'journal_type':'general', 'search_default_group_by_account': 1, 'search_default_posted':1} General Ledger account.move.line [('display_type', 'not in', ('line_section', 'line_note'))] @@ -982,7 +1003,7 @@ - {'journal_type':'general', 'search_default_group_by_partner': 1, 'group_by':'partner_id', 'search_default_posted':1, 'search_default_payable':1, 'search_default_receivable':1, 'search_default_unreconciled':1} + {'journal_type':'general', 'search_default_group_by_partner': 1, 'search_default_posted':1, 'search_default_payable':1, 'search_default_receivable':1, 'search_default_unreconciled':1} Partner Ledger account.move.line [('display_type', 'not in', ('line_section', 'line_note'))] @@ -991,7 +1012,7 @@ - {'journal_type':'bank', 'search_default_group_by_move': 1, 'group_by':'move_id', 'search_default_posted':1, 'search_default_bank':1, 'search_default_cash':1, 'name_groupby':1} + {'journal_type':'bank', 'search_default_group_by_move': 1, 'search_default_posted':1, 'search_default_bank':1, 'search_default_cash':1, 'name_groupby':1} Bank and Cash account.move.line [('display_type', 'not in', ('line_section', 'line_note'))] @@ -1000,7 +1021,7 @@ - {'journal_type':'general', 'search_default_group_by_move': 1, 'group_by':'move_id', 'search_default_posted':1, 'search_default_misc_filter':1, 'name_groupby':1} + {'journal_type':'general', 'search_default_group_by_move': 1, 'search_default_posted':1, 'search_default_misc_filter':1, 'name_groupby':1} Miscellaneous account.move.line [('display_type', 'not in', ('line_section', 'line_note'))] @@ -1009,7 +1030,7 @@ - {'journal_type':'general', 'search_default_group_by_account': 1, 'group_by':'account_id', 'search_default_posted':1} + {'journal_type':'general', 'search_default_group_by_account': 1, 'search_default_posted':1} General Ledger account.move.line [('display_type', 'not in', ('line_section', 'line_note'))] @@ -1018,7 +1039,7 @@ - {'journal_type':'general', 'search_default_group_by_partner': 1, 'group_by':'partner_id', 'search_default_posted':1, 'search_default_payable':1, 'search_default_receivable':1, 'search_default_unreconciled':1} + {'journal_type':'general', 'search_default_group_by_partner': 1, 'search_default_posted':1, 'search_default_payable':1, 'search_default_receivable':1, 'search_default_unreconciled':1} Partner Ledger account.move.line [('display_type', 'not in', ('line_section', 'line_note'))] diff --git a/addons/account/wizard/account_invoice_send_views.xml b/addons/account/wizard/account_invoice_send_views.xml index 3ed9afdabea..28d4f03de25 100644 --- a/addons/account/wizard/account_invoice_send_views.xml +++ b/addons/account/wizard/account_invoice_send_views.xml @@ -13,6 +13,7 @@ +
diff --git a/addons/account_payment/models/payment.py b/addons/account_payment/models/payment.py index 02d52d25eb3..8dd98f98285 100644 --- a/addons/account_payment/models/payment.py +++ b/addons/account_payment/models/payment.py @@ -20,7 +20,7 @@ class PaymentTransaction(models.Model): values.update(render_values) return self.acquirer_id.with_context(submit_class='btn btn-primary', submit_txt=submit_txt or _('Pay Now')).sudo().render( self.reference, - invoice.residual_signed, + invoice.amount_residual_signed, invoice.currency_id.id, values=values, ) diff --git a/addons/account_payment/views/account_portal_templates.xml b/addons/account_payment/views/account_portal_templates.xml index bdc9c9da488..4f8c00964d6 100644 --- a/addons/account_payment/views/account_portal_templates.xml +++ b/addons/account_payment/views/account_portal_templates.xml @@ -7,7 +7,7 @@ - Pay Now @@ -16,16 +16,16 @@ - + Waiting for Payment - + Authorized - + Pending - + Paid @@ -36,7 +36,7 @@