'Create and post an account.payment for the invoice self, which creates a journal entry that reconciles the invoice.
:param pay_journal: journal in which the payment entry will be created
:param pay_amount: amount of the payment to register, defaults to the residual of the invoice
:param date: payment date, defaults to fields.Date.context_today(self)
:param writeoff_acc: account in which to create a writeoff if pay_amount < self.residual, so that the invoice is fully paid'

@api.multi
def pay_and_reconcile(self, pay_journal, pay_amount=None, date=None, writeoff_acc=None):

    if isinstance(pay_journal, (int, long)):
        pay_journal = self.env['account.journal'].browse([pay_journal])
    assert (len(self) == 1), 'Can    only    pay    one    invoice    at    a    time.'
    payment_type = (((self.type in ('out_invoice', 'in_refund')) and 'inbound') or 'outbound')
    if (payment_type == 'inbound'):
        payment_method = self.env.ref('account.account_payment_method_manual_in')
        journal_payment_methods = pay_journal.inbound_payment_method_ids
    else:
        payment_method = self.env.ref('account.account_payment_method_manual_out')
        journal_payment_methods = pay_journal.outbound_payment_method_ids
    if (payment_method not in journal_payment_methods):
        raise UserError((_('No    appropriate    payment    method    enabled    on    journal    %s') % pay_journal.name))
    communication = (((self.type in ('in_invoice', 'in_refund')) and self.reference) or self.number)
    if self.origin:
        communication = ('%s    (%s)' % (communication, self.origin))
    payment = self.env['account.payment'].create({'invoice_ids': [(6, 0, self.ids)], 'amount': (pay_amount or self.residual), 'payment_date': (date or fields.Date.context_today(self)), 'communication': communication, 'partner_id': self.partner_id.id, 'partner_type': (((self.type in ('out_invoice', 'out_refund')) and 'customer') or 'supplier'), 'journal_id': pay_journal.id, 'payment_type': payment_type, 'payment_method_id': payment_method.id, 'payment_difference_handling': ((writeoff_acc and 'reconcile') or 'open'), 'writeoff_account_id': ((writeoff_acc and writeoff_acc.id) or False)})
    payment.post()
    return True
