Search code examples
pythonodooodoo-12odoo-rpc

Odoo API: invoice has "paid" status after validation


I am working on a Python script that will import all my existing invoices to an Odoo 12 instance. I am using odoorpc library to simplify RPC calls to my Odoo instance.

I achieved to create an invoice using the API, registering it in "draft" state. Then, I want to "validate" it and update its state into "open". Unfortunately, using the "Validate" button in Odoo UI or calling the action from the RPC API do the same: invoice state is changed to "paid". I don't understand this behavior, since I didn't register any payment (it will be my next goal).

Here is a simplified version of my script that can be used to reproduce the issue :

import odoorpc

import settings
"""settings module contains various constants used
to connect with Odoo on my VPS"""


if __name__ == "__main__":
    odoo = odoorpc.ODOO(settings.ODOO_HOST, port=settings.ODOO_PORT, timeout=10)
    odoo.login(settings.ODOO_DB, settings.ODOO_USER, settings.ODOO_PASSWORD)

    Partner = odoo.env["res.partner"]
    # This partner already exists in DB
    customer = Partner.browse([22])

    Invoice = odoo.env["account.invoice"]
    invoice_id = Invoice.create({
        'partner_id' : customer.id,
        'state': 'draft',
        # This is ID for "Customers Invoices" journal
        'journal_id': 1,
        'account_id': customer.property_account_receivable_id.id,
        # This is ID for default bank account, already registered
        'partner_bank_id': 1,
        'payment_term_id': odoo.env.ref("account.account_payment_term_net").id,
    })

    InvoiceLine = odoo.env["account.invoice.line"]
    InvoiceLine.create({
        "invoice_id": invoice_id,
        "name": "A basic product",
        "quantity": 6,
        "price_unit": 100.0,
        # Not sure about this one:
        "uom_id": 1,
        # No tax
        "invoice_line_tax_ids": [],
        'journal_id': 1,
        'account_id': customer.property_account_receivable_id.id,
    })

    inv = Invoice.browse([invoice_id])
    print("Before validating:", inv.state)

    inv.action_invoice_open()

    inv = Invoice.browse([invoice_id])
    print("After validating:", inv.state)

result:

Before validating: draft
After validating: paid

I think there is something missing or wrong in my invoice creation, but I didn't find what exactly should be modified to have an invoice created the same way it would be from the UI. Can anybody help me to find what's wrong in my script ?


Solution

  • I found myself a solution. It seems the account_id must be different for invoice and invoice line. To fix the issue, I retrieved the account.journal instance with ID 1 (for "Customers Invoices" journal), then used it to fill invoice line's account_id based on the journal's default_credit_account_id field:

    cust_invoices_journal = odoo.env["account.journal"].browse([1])
    # [...]
    invoice_id = Invoice.create({
        # [...]
        'journal_id': cust_invoices_journal.id,
        'account_id': customer.property_account_receivable_id.id,
        # [...]
    })
    # [...]
    InvoiceLine.create({
        # [...]
        'account_id': cust_invoices_journal.default_credit_account_id.id,
        # [...]
    })