diff --git a/addons/account/models/account.py b/addons/account/models/account.py index beab40c9ddb..9e7d2a59a0d 100644 --- a/addons/account/models/account.py +++ b/addons/account/models/account.py @@ -721,7 +721,7 @@ class AccountTaxGroup(models.Model): class AccountTax(models.Model): _name = 'account.tax' _description = 'Tax' - _order = 'sequence' + _order = 'sequence,id' @api.model def _default_tax_group(self): diff --git a/addons/account/models/account_bank_statement.py b/addons/account/models/account_bank_statement.py index a0b2a7441e6..bfb4667bf9c 100644 --- a/addons/account/models/account_bank_statement.py +++ b/addons/account/models/account_bank_statement.py @@ -895,7 +895,7 @@ class AccountBankStatementLine(models.Model): total = self.amount for aml_rec in payment_aml_rec: total -= aml_rec.debit - aml_rec.credit - aml_rec.write({'statement_line_id': self.id}) + aml_rec.with_context(check_move_validity=False).write({'statement_line_id': self.id}) counterpart_moves = (counterpart_moves | aml_rec.move_id) # Create move line(s). Either matching an existing journal entry (eg. invoice), in which diff --git a/addons/account/models/account_journal_dashboard.py b/addons/account/models/account_journal_dashboard.py index 66c8bb9f4a4..26cb462b356 100644 --- a/addons/account/models/account_journal_dashboard.py +++ b/addons/account/models/account_journal_dashboard.py @@ -201,18 +201,19 @@ class account_journal(models.Model): (number_draft, sum_draft) = self._count_results_and_sum_amounts(query_results_drafts, currency) (number_late, sum_late) = self._count_results_and_sum_amounts(late_query_results, currency) + difference = currency.round(last_balance-account_sum) + 0.0 return { 'number_to_reconcile': number_to_reconcile, - 'account_balance': formatLang(self.env, account_sum, currency_obj=self.currency_id or self.company_id.currency_id), - 'last_balance': formatLang(self.env, last_balance, currency_obj=self.currency_id or self.company_id.currency_id), - 'difference': (last_balance-account_sum) and formatLang(self.env, last_balance-account_sum, currency_obj=self.currency_id or self.company_id.currency_id) or False, + 'account_balance': formatLang(self.env, currency.round(account_sum) + 0.0, currency_obj=currency), + 'last_balance': formatLang(self.env, currency.round(last_balance) + 0.0, currency_obj=currency), + 'difference': formatLang(self.env, difference, currency_obj=currency) if difference else False, 'number_draft': number_draft, 'number_waiting': number_waiting, 'number_late': number_late, - 'sum_draft': formatLang(self.env, sum_draft or 0.0, currency_obj=self.currency_id or self.company_id.currency_id), - 'sum_waiting': formatLang(self.env, sum_waiting or 0.0, currency_obj=self.currency_id or self.company_id.currency_id), - 'sum_late': formatLang(self.env, sum_late or 0.0, currency_obj=self.currency_id or self.company_id.currency_id), - 'currency_id': self.currency_id and self.currency_id.id or self.company_id.currency_id.id, + 'sum_draft': formatLang(self.env, currency.round(sum_draft) + 0.0, currency_obj=currency), + 'sum_waiting': formatLang(self.env, currency.round(sum_waiting) + 0.0, currency_obj=currency), + 'sum_late': formatLang(self.env, currency.round(sum_late) + 0.0, currency_obj=currency), + 'currency_id': currency.id, 'bank_statements_source': self.bank_statements_source, 'title': title, } diff --git a/addons/account/models/chart_template.py b/addons/account/models/chart_template.py index ca835a6222a..eaacb3721cc 100644 --- a/addons/account/models/chart_template.py +++ b/addons/account/models/chart_template.py @@ -40,8 +40,7 @@ def migrate_tags_on_taxes(cr, registry): ('type_tax_use', '=', tax_template.type_tax_use), ('description', '=', tax_template.description) ]) - if len(tax_id.ids) == 1: - tax_id.sudo().write({'tag_ids': [(6, 0, tax_template.tag_ids.ids)]}) + tax_id.sudo().write({'tag_ids': [(6, 0, tax_template.tag_ids.ids)]}) def preserve_existing_tags_on_taxes(cr, registry, module): ''' This is a utility function used to preserve existing previous tags during upgrade of the module.''' diff --git a/addons/account/models/partner.py b/addons/account/models/partner.py index e48aa2e3b38..4482b4e1c4c 100644 --- a/addons/account/models/partner.py +++ b/addons/account/models/partner.py @@ -297,10 +297,16 @@ class ResPartner(models.Model): partner.total_invoiced = sum(price['total'] for price in price_totals if price['partner_id'] in child_ids) @api.multi - def _journal_item_count(self): + def _compute_journal_item_count(self): + AccountMoveLine = self.env['account.move.line'] for partner in self: - partner.journal_item_count = self.env['account.move.line'].search_count([('partner_id', '=', partner.id)]) - partner.contracts_count = self.env['account.analytic.account'].search_count([('partner_id', '=', partner.id)]) + partner.journal_item_count = AccountMoveLine.search_count([('partner_id', '=', partner.id)]) + + @api.multi + def _compute_contracts_count(self): + AccountAnalyticAccount = self.env['account.analytic.account'] + for partner in self: + partner.contracts_count = AccountAnalyticAccount.search_count([('partner_id', '=', partner.id)]) def get_followup_lines_domain(self, date, overdue_only=False, only_unblocked=False): domain = [('reconciled', '=', False), ('account_id.deprecated', '=', False), ('account_id.internal_type', '=', 'receivable'), '|', ('debit', '!=', 0), ('credit', '!=', 0), ('company_id', '=', self.env.user.company_id.id)] @@ -374,9 +380,8 @@ class ResPartner(models.Model): groups='account.group_account_invoice') currency_id = fields.Many2one('res.currency', compute='_get_company_currency', readonly=True, string="Currency", help='Utility field to express amount currency') - - contracts_count = fields.Integer(compute='_journal_item_count', string="Contracts", type='integer') - journal_item_count = fields.Integer(compute='_journal_item_count', string="Journal Items", type="integer") + contracts_count = fields.Integer(compute='_compute_contracts_count', string="Contracts", type='integer') + journal_item_count = fields.Integer(compute='_compute_journal_item_count', string="Journal Items", type="integer") property_account_payable_id = fields.Many2one('account.account', company_dependent=True, string="Account Payable", oldname="property_account_payable", domain="[('internal_type', '=', 'payable'), ('deprecated', '=', False)]", diff --git a/addons/account_payment/models/payment.py b/addons/account_payment/models/payment.py index b0dfeb691bb..0ad11d39788 100644 --- a/addons/account_payment/models/payment.py +++ b/addons/account_payment/models/payment.py @@ -71,7 +71,19 @@ class PaymentTransaction(models.Model): _logger.warning('<%s> transaction STATE INCORRECT for invoice %s (ID %s, state %s)', self.acquirer_id.provider, self.account_invoice_id.number, self.account_invoice_id.id, self.account_invoice_id.state) return 'pay_invoice_invalid_doc_state' if not float_compare(self.amount, self.account_invoice_id.amount_total, 2) == 0: - _logger.warning('<%s> transaction AMOUNT MISMATCH for invoice %s (ID %s)', self.acquirer_id.provider, self.account_invoice_id.number, self.account_invoice_id.id) + _logger.warning( + '<%s> transaction AMOUNT MISMATCH for invoice %s (ID %s): expected %r, got %r', + self.acquirer_id.provider, self.account_invoice_id.number, self.account_invoice_id.id, + self.account_invoice_id.amount_total, self.amount, + ) + self.account_invoice_id.message_post( + subject=_("Amount Mismatch (%s)") % self.acquirer_id.provider, + body=_("The invoice was not confirmed despite response from the acquirer (%s): invoice amount is %r but acquirer replied with %r.") % ( + self.acquirer_id.provider, + self.account_invoice_id.amount_total, + self.amount, + ) + ) return 'pay_invoice_tx_amount' if self.state == 'authorized' and self.acquirer_id.capture_manually: diff --git a/addons/event_sale/models/sale_order.py b/addons/event_sale/models/sale_order.py index 44801880267..7a2dcd8a745 100644 --- a/addons/event_sale/models/sale_order.py +++ b/addons/event_sale/models/sale_order.py @@ -42,7 +42,7 @@ class SaleOrderLine(models.Model): registrations linked to this line. This method update existing registrations and create new one for missing one. """ Registration = self.env['event.registration'] - registrations = Registration.search([('sale_order_line_id', 'in', self.ids)]) + registrations = Registration.search([('sale_order_line_id', 'in', self.ids), ('state', '!=', 'cancel')]) for so_line in self.filtered('event_id'): existing_registrations = registrations.filtered(lambda self: self.sale_order_line_id.id == so_line.id) if confirm: diff --git a/addons/hr_expense/models/hr_expense.py b/addons/hr_expense/models/hr_expense.py index 84f8e41c703..f68f6225321 100644 --- a/addons/hr_expense/models/hr_expense.py +++ b/addons/hr_expense/models/hr_expense.py @@ -591,3 +591,10 @@ class HrExpenseSheet(models.Model): employee_ids = self.expense_line_ids.mapped('employee_id') if len(employee_ids) > 1 or (len(employee_ids) == 1 and employee_ids != self.employee_id): raise ValidationError(_('You cannot add expense lines of another employee.')) + + @api.one + @api.constrains('expense_line_ids') + def _check_payment_mode(self): + payment_mode = set(self.expense_line_ids.mapped('payment_mode')) + if len(payment_mode) > 1: + raise ValidationError(_('You cannot report expenses with different payment modes.')) \ No newline at end of file diff --git a/addons/hr_expense/views/hr_expense_views.xml b/addons/hr_expense/views/hr_expense_views.xml index 566648c560e..05a7c50952c 100644 --- a/addons/hr_expense/views/hr_expense_views.xml +++ b/addons/hr_expense/views/hr_expense_views.xml @@ -432,7 +432,7 @@