# © 2013-2014 ACSONE SA (). # © 2014 Serv. Tecnol. Avanzados - Pedro M. Baeza # © 2016 Akretion (Alexis de Lattre ) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). from flectra import api, fields, models, _ from flectra.exceptions import UserError class AccountInvoice(models.Model): _inherit = 'account.invoice' payment_order_ok = fields.Boolean( compute="_compute_payment_order_ok", ) @api.depends('payment_mode_id', 'move_id', 'move_id.line_ids', 'move_id.line_ids.payment_mode_id') def _compute_payment_order_ok(self): for invoice in self: payment_mode = ( invoice.move_id.line_ids.filtered( lambda x: not x.reconciled ).mapped('payment_mode_id')[:1] ) if not payment_mode: payment_mode = invoice.payment_mode_id invoice.payment_order_ok = payment_mode.payment_order_ok @api.model def _get_reference_type(self): rt = super(AccountInvoice, self)._get_reference_type() rt.append(('structured', _('Structured Reference'))) return rt @api.model def line_get_convert(self, line, part): """Copy supplier bank account from invoice to account move line""" res = super(AccountInvoice, self).line_get_convert(line, part) if line.get('type') == 'dest' and line.get('invoice_id'): invoice = self.browse(line['invoice_id']) if invoice.type in ('in_invoice', 'in_refund'): res['partner_bank_id'] = invoice.partner_bank_id.id or False return res @api.multi def _prepare_new_payment_order(self, payment_mode=None): self.ensure_one() if payment_mode is None: payment_mode = self.env['account.payment.mode'] vals = { 'payment_mode_id': payment_mode.id or self.payment_mode_id.id, } # other important fields are set by the inherit of create # in account_payment_order.py return vals @api.multi def create_account_payment_line(self): apoo = self.env['account.payment.order'] result_payorder_ids = [] action_payment_type = 'debit' for inv in self: if inv.state != 'open': raise UserError(_( "The invoice %s is not in Open state") % inv.number) if not inv.move_id: raise UserError(_( "No Journal Entry on invoice %s") % inv.number) applicable_lines = inv.move_id.line_ids.filtered( lambda x: ( not x.reconciled and x.payment_mode_id.payment_order_ok and x.account_id.internal_type in ('receivable', 'payable') and not any(p_state in ('draft', 'open', 'generated') for p_state in x.payment_line_ids.mapped('state')) ) ) if not applicable_lines: raise UserError(_( 'No Payment Line created for invoice %s because ' 'it already exists or because this invoice is ' 'already paid.') % inv.number) payment_modes = applicable_lines.mapped('payment_mode_id') if not payment_modes: raise UserError(_( "No Payment Mode on invoice %s") % inv.number) for payment_mode in payment_modes: payorder = apoo.search([ ('payment_mode_id', '=', payment_mode.id), ('state', '=', 'draft') ], limit=1) new_payorder = False if not payorder: payorder = apoo.create(inv._prepare_new_payment_order( payment_mode )) new_payorder = True result_payorder_ids.append(payorder.id) action_payment_type = payorder.payment_type count = 0 for line in applicable_lines.filtered( lambda x: x.payment_mode_id == payment_mode ): line.create_payment_line_from_move_line(payorder) count += 1 if new_payorder: inv.message_post(body=_( '%s payment lines added to the new draft payment ' 'order %s which has been automatically created.') % (count, payorder.name)) else: inv.message_post(body=_( '%s payment lines added to the existing draft ' 'payment order %s.') % (count, payorder.name)) action = self.env['ir.actions.act_window'].for_xml_id( 'account_payment_order', 'account_payment_order_%s_action' % action_payment_type) if len(result_payorder_ids) == 1: action.update({ 'view_mode': 'form,tree,pivot,graph', 'res_id': payorder.id, 'views': False, }) else: action.update({ 'view_mode': 'tree,form,pivot,graph', 'domain': "[('id', 'in', %s)]" % result_payorder_ids, 'views': False, }) return action