diff --git a/account_payment_disperse/__manifest__.py b/account_payment_disperse/__manifest__.py index 160611ad..a66efe60 100644 --- a/account_payment_disperse/__manifest__.py +++ b/account_payment_disperse/__manifest__.py @@ -1,6 +1,6 @@ { 'name': 'Payment Disperse', - 'version': '11.0.1.0.0', + 'version': '12.0.1.0.0', 'author': 'Hibou Corp. ', 'category': 'Accounting', 'summary': 'Pay multiple invoices with one Payment', diff --git a/account_payment_disperse/models/account.py b/account_payment_disperse/models/account.py index 60ba0026..e39340a5 100644 --- a/account_payment_disperse/models/account.py +++ b/account_payment_disperse/models/account.py @@ -18,50 +18,51 @@ class AccountPayment(models.Model): return super(AccountPayment, self)._create_payment_entry(amount) def _create_payment_entry_manual_disperse(self, amount, wizard): + # When registering payments for multiple partners at the same time, without setting + # the amount again, then the payment will not match the accounting. self.amount = abs(amount) if hasattr(self, 'check_amount_in_words'): self.check_amount_in_words = self.currency_id.amount_to_text(self.amount) + aml_obj = self.env['account.move.line'].with_context(check_move_validity=False) - invoice_currency = False - if self.invoice_ids and all([x.currency_id == self.invoice_ids[0].currency_id for x in self.invoice_ids]): - # if all the invoices selected share the same currency, record the paiement in that currency too - invoice_currency = self.invoice_ids[0].currency_id - debit, credit, amount_currency, currency_id = aml_obj.with_context(date=self.payment_date)\ - .compute_amount_fields(amount, self.currency_id, self.company_id.currency_id, invoice_currency) + debit, credit, amount_currency, currency_id = aml_obj.with_context(date=self.payment_date)._compute_amount_fields(amount, self.currency_id, self.company_id.currency_id) move = self.env['account.move'].create(self._get_move_vals()) inv_lines = [] for partial_invoice in wizard.invoice_line_ids.filtered(lambda p: p.amount and p.partner_id == self.partner_id): + # Note that for customer payments, the amount will be reversed. inv_amount = partial_invoice.amount if amount > 0 else -partial_invoice.amount - i_debit, i_credit, i_amount_currency, i_currency_id = aml_obj.with_context( - date=self.payment_date).compute_amount_fields(inv_amount, self.currency_id, self.company_id.currency_id, - invoice_currency) + i_debit, i_credit, i_amount_currency, i_currency_id = aml_obj.with_context(date=self.payment_date)._compute_amount_fields(inv_amount, self.currency_id, self.company_id.currency_id) counterpart_aml_dict = self._get_shared_move_line_vals(i_debit, i_credit, i_amount_currency, move.id, False) counterpart_aml_dict.update(self._get_counterpart_move_line_vals(partial_invoice.invoice_id)) counterpart_aml_dict.update({'currency_id': currency_id}) counterpart_aml = aml_obj.create(counterpart_aml_dict) - # capture writeoff account etc. counterpart_aml |= partial_invoice.invoice_id.move_id.line_ids.filtered( lambda r: not r.reconciled and r.account_id.internal_type in ('payable', 'receivable')) inv_lines.append((counterpart_aml, partial_invoice.writeoff_acc_id)) - # Create Payment side (payment journal default accounts) + # Useful for debugging + # for aml_ids, writeoff_acc_id in inv_lines: + # _logger.warn('pair:' + (' writeoff: ' + str(writeoff_acc_id)) if writeoff_acc_id else '') + # for l in aml_ids: + # _logger.warn(' ' + str(l) + ' debit: ' + str(l.debit) + ' credit: ' + str(l.credit)) + + # Write counterpart lines if not self.currency_id.is_zero(self.amount): if not self.currency_id != self.company_id.currency_id: amount_currency = 0 liquidity_aml_dict = self._get_shared_move_line_vals(credit, debit, -amount_currency, move.id, False) liquidity_aml_dict.update(self._get_liquidity_move_line_vals(-amount)) - aml_obj.create(liquidity_aml_dict) + other = aml_obj.create(liquidity_aml_dict) + #_logger.warn('other line -- debit: ' + str(other.debit) + ' credit: ' + str(other.credit)) # validate the payment - move.post() + if not self.journal_id.post_at_bank_rec: + move.post() # reconcile the invoice receivable/payable line(s) with the payment - for inv_lines, writeoff_acc_id in inv_lines: - # _logger.warn('pair: ') - # for l in inv_lines: - # _logger.warn(' ' + str(l) + ' credit: ' + str(l.credit) + ' debit: ' + str(l.debit)) - inv_lines.reconcile(writeoff_acc_id, wizard.writeoff_journal_id) + for aml_ids, writeoff_acc_id in inv_lines: + aml_ids.reconcile(writeoff_acc_id, wizard.writeoff_journal_id) return move diff --git a/account_payment_disperse/tests/test_payment_multi.py b/account_payment_disperse/tests/test_payment_multi.py index 92c6e310..e07fcabb 100644 --- a/account_payment_disperse/tests/test_payment_multi.py +++ b/account_payment_disperse/tests/test_payment_multi.py @@ -112,6 +112,7 @@ class PaymentMultiTest(TestPayment): payment_ids = self.payment_model.search([('invoice_ids', 'in', ids)], order="id desc") self.assertEqual(len(payment_ids), 2, 'Need two payments.') + # Useful for logging amounts of payments and their accounting # for pay in payment_ids: # _logger.warn(str(pay) + ' amount: ' + str(pay.amount)) # for line in pay.move_line_ids: diff --git a/account_payment_disperse/wizard/register_payment_wizard.py b/account_payment_disperse/wizard/register_payment_wizard.py index 38861838..3153045a 100644 --- a/account_payment_disperse/wizard/register_payment_wizard.py +++ b/account_payment_disperse/wizard/register_payment_wizard.py @@ -13,8 +13,9 @@ class AccountRegisterPayments(models.TransientModel): @api.model def default_get(self, fields): rec = super(AccountRegisterPayments, self).default_get(fields) - invoice_ids = rec['invoice_ids'][0][2] - rec['invoice_line_ids'] = [(0, 0, {'invoice_id': i, 'amount': 0.0}) for i in invoice_ids] + if 'invoice_ids' in rec: + invoice_ids = rec['invoice_ids'][0][2] + rec['invoice_line_ids'] = [(0, 0, {'invoice_id': i, 'amount': 0.0}) for i in invoice_ids] return rec @api.multi @@ -63,12 +64,15 @@ class AccountRegisterPaymentsInvoiceLine(models.TransientModel): @api.depends('invoice_id', 'wizard_id.due_date_cutoff', 'invoice_id.partner_id') def _compute_balances(self): for line in self: - residual = line.invoice_id.residual + # Bug in the ORM 12.0? The invoice is set, but there is no residual + # on anything other than the first invoice/line processed. + invoice = line.invoice_id.browse(line.invoice_id.id) + residual = invoice.residual cutoff_date = line.wizard_id.due_date_cutoff total_amount = 0.0 total_reconciled = 0.0 - for move_line in line.invoice_id.move_id.line_ids.filtered(lambda r: ( + for move_line in invoice.move_id.line_ids.filtered(lambda r: ( not r.reconciled and r.account_id.internal_type in ('payable', 'receivable') and r.date_maturity <= cutoff_date @@ -79,11 +83,13 @@ class AccountRegisterPaymentsInvoiceLine(models.TransientModel): total_reconciled += partial_line.amount for partial_line in move_line.matched_credit_ids: total_reconciled += partial_line.amount - - line.residual = residual - line.residual_due = total_amount - total_reconciled - line.difference = residual - (line.amount or 0.0) - line.partner_id = line.invoice_id.partner_id + values = { + 'residual': residual, + 'residual_due': total_amount - total_reconciled, + 'difference': residual - (line.amount or 0.0), + 'partner_id': invoice.partner_id.id, + } + line.update(values) @api.onchange('amount') def _onchange_amount(self): diff --git a/account_payment_disperse/wizard/register_payment_wizard_views.xml b/account_payment_disperse/wizard/register_payment_wizard_views.xml index 0a367f68..3e428048 100644 --- a/account_payment_disperse/wizard/register_payment_wizard_views.xml +++ b/account_payment_disperse/wizard/register_payment_wizard_views.xml @@ -8,9 +8,12 @@ {'readonly': [('multi', '=', True), ('is_manual_disperse', '!=', True)]} - + + + {'invisible': ['|', ('payment_difference', '=', 0.0), ('is_manual_disperse', '=', True)]} +