Skip to content

[16.0][REF] account_invoice_supplier_self_invoice: enhance self-billing footer and header logic#2256

Open
nicolas-delbovier-acsone wants to merge 7 commits intoOCA:16.0from
acsone:16.0-ref-account_invoice_supplier_self_invoice-self-invoice-report-layout
Open

[16.0][REF] account_invoice_supplier_self_invoice: enhance self-billing footer and header logic#2256
nicolas-delbovier-acsone wants to merge 7 commits intoOCA:16.0from
acsone:16.0-ref-account_invoice_supplier_self_invoice-self-invoice-report-layout

Conversation

@nicolas-delbovier-acsone
Copy link

@nicolas-delbovier-acsone nicolas-delbovier-acsone commented Feb 5, 2026

  1. The self-bill report was incorrectly swapping the positions of the
    issuer and the recipient.

In a self-billing scenario:

  • The Company (the recipient of the goods, but the issuer of the document)
    should be in the header/branding area.
  • The Vendor (the actual supplier) should be positioned in the
    address window (usually the right side) to ensure the document
    can be mailed correctly in a window envelope.

This change ensures the addresses follow standard commercial letter
formats for self-billing.

  1. Improves how footers are handled on self-billing reports and adds more granular configuration options.

Changes:

  • Add 'self_invoice_extra_infos' to Company Settings to allow global
    legal mentions etc for self-billing.
  • Update report logic to always include the standard Company footer.
  • Cumulative footer logic: The report now displays the Company footer, followed by the Company self-billing extra info, and finally the
    Partner-specific self-billing info.
  • UI/UX: The "invalid self-bill" warning message is now styled in red to clearly distinguish it from standard document notes.

Before

image

After

image
Steps to reproduce Here is some demo data you can load (note that this has to be done after module init otherwise this will not work as some account records might not be setup correctly otherwise):
<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <data>

        <record id="demo_self_invoice_partner" model="res.partner">
            <field name="name">The Mirror Vendor (Self-Bill Vendor)</field>
            <field name="supplier_rank">1</field>
            <field name="self_invoice" eval="True" />
            <field name="self_invoice_partner_prefix">MIRROR</field>
            <field name="self_invoice_report_footer">Custom self invoice footer for Mirror Vendor.</field>
            <field name="email">vendor@mirror.example.com</field>

            <field name="street">Rue du Miroir 123</field>
            <field name="city">Brussels</field>
            <field name="zip">1000</field>
            <field name="country_id" ref="base.be" />
            <field name="phone">+32 2 555 01 23</field>
            <field name="website">www.mirror-vendor.example.com</field>
        </record>

        <record id="demo_delivery_address_mirror" model="res.partner">
            <field name="name">The Mirror Warehouse</field>
            <field name="parent_id" ref="demo_self_invoice_partner" />
            <field name="type">delivery</field>
            <field name="street">Avenue de la Réflexion 45</field>
            <field name="city">Grand-Rosière</field>
            <field name="zip">1367</field>
            <field name="country_id" ref="base.be" />
            <field name="email">warehouse@mirror.example.com</field>
        </record>

        <record id="demo_expense_account" model="account.account">
            <field name="name">Self-Bill Testing Expense</field>
            <field name="code">EXP.SELF.01</field>
            <field name="account_type">expense</field>
            <field name="company_id" ref="base.main_company" />
        </record>

        <record id="demo_self_invoice_move" model="account.move">
            <field name="move_type">in_invoice</field>
            <field name="partner_id" ref="demo_self_invoice_partner" />
            <field name="invoice_date" eval="time.strftime('%Y-%m-01')" />
            <field name="company_id" ref="base.main_company" />
            <field name="journal_id"
                model="account.journal"
                search="[('type', '=', 'purchase'), ('company_id', '=', ref('base.main_company'))]" />
        </record>

        <record id="demo_self_invoice_line" model="account.move.line">
            <field name="move_id" ref="demo_self_invoice_move" />
            <field name="name">Reflective Consultancy Services</field>
            <field name="account_id" ref="demo_expense_account" />
            <field name="quantity">5.0</field>
            <field name="price_unit">120.0</field>
        </record>

    </data>
</odoo>

Alternatively, you can use play this script in an odoo shell:

import datetime

# 1. Resolve External IDs for base data
country_be = env.ref('base.be').id
main_company = env.ref('base.main_company').id

# 2. Create the Vendor Partner
partner = env['res.partner'].create({
    'name': 'The Mirror Vendor (Self-Bill Vendor)',
    'supplier_rank': 1,
    'self_invoice': True,
    'self_invoice_partner_prefix': 'MIRROR',
    'self_invoice_report_footer': 'Custom self invoice footer for Mirror Vendor.',
    'email': 'vendor@mirror.example.com',
    'street': 'Rue du Miroir 123',
    'city': 'Brussels',
    'zip': '1000',
    'country_id': country_be,
    'phone': '+32 2 555 01 23',
    'website': 'www.mirror-vendor.example.com',
})

# 3. Create the Delivery Address
env['res.partner'].create({
    'name': 'The Mirror Warehouse',
    'parent_id': partner.id,
    'type': 'delivery',
    'street': 'Avenue de la Réflexion 45',
    'city': 'Grand-Rosière',
    'zip': '1367',
    'country_id': country_be,
    'email': 'warehouse@mirror.example.com',
})

# 4. Create the Expense Account
account = env['account.account'].create({
    'name': 'Self-Bill Testing Expense',
    'code': 'EXP.SELF.01',
    'account_type': 'expense',
    'company_id': main_company,
})

# 5. Find the Purchase Journal
journal = env['account.journal'].search([
    ('type', '=', 'purchase'), 
    ('company_id', '=', main_company)
], limit=1)

# 6. Create the Invoice (account.move)
move = env['account.move'].create({
    'move_type': 'in_invoice',
    'partner_id': partner.id,
    'invoice_date': datetime.date.today().replace(day=1), # First of current month
    'company_id': main_company,
    'journal_id': journal.id,
})

# 7. Create the Invoice Line
# Note: In Odoo 16, lines can be created directly via 'invoice_line_ids' on the move,
# but to follow your XML structure exactly:
env['account.move.line'].create({
    'move_id': move.id,
    'name': 'Reflective Consultancy Services',
    'account_id': account.id,
    'quantity': 5.0,
    'price_unit': 120.0,
})


print("Demo data created successfully.")
  1. Define some company footer:
image
  1. Define some self-billing extra infos
image
  1. Add some customer specific self-billing footer
image
  1. Generate the report using the report endpoint:
    http://localhost:8069/report/pdf/account.report_invoice_with_payments/<move_id>

…ioning

The self-bill report was incorrectly swapping the positions of the
issuer and the recipient.

In a self-billing scenario:
- The Company (the recipient of the goods, but the issuer of the document)
  should be in the header/branding area.
- The Vendor (the actual supplier) should be positioned in the
  address window (usually the right side) to ensure the document
  can be mailed correctly in a window envelope.

This change ensures the addresses follow standard commercial letter
formats for self-billing.
…ter logic

This commit improves how footers are handled on self-billing reports
and adds more granular configuration options.

Changes:
- Add 'self_invoice_extra_infos' to Company Settings to allow global
  legal mentions etc for self-billing.
- Update report logic to always include the standard Company footer.
- Cumulative footer logic: The report now displays the Company footer,
  followed by the Company self-billing extra info, and finally the
  Partner-specific self-billing info.
- UI/UX: The "invalid self-bill" warning message is now styled in
  red to clearly distinguish it from standard document notes.
@nicolas-delbovier-acsone
Copy link
Author

@jbaudoux

@nicolas-delbovier-acsone nicolas-delbovier-acsone changed the title [REF] account_invoice_supplier_self_invoice: enhance self-billing footer logic [16.0][REF] account_invoice_supplier_self_invoice: enhance self-billing footer logic Feb 5, 2026
@jbaudoux
Copy link

jbaudoux commented Feb 5, 2026

cc @Shide

@nicolas-delbovier-acsone nicolas-delbovier-acsone changed the title [16.0][REF] account_invoice_supplier_self_invoice: enhance self-billing footer logic [16.0][REF] account_invoice_supplier_self_invoice: enhance self-billing footer and header logic Feb 5, 2026
…infos to body

The report footer is structurally limited; overflowing content can lead to
layout breakage or overlapping text.

This commit moves the self-invoice extra information from the page footer
into the main content area of the report. It is now rendered alongside
standard metadata like "Payment Method" or "Bank Account" to ensure
consistent layout and better visibility.
@Shide
Copy link
Contributor

Shide commented Feb 16, 2026

Well the position of the partners I think it's correct.
It's a self-invoice, so the invoice generated is like if the partner generated it.
The positions are changed and I'm not sure if it's correct this approach. @rafaelbn please check.

The extra infos can be customized in the footer of the partner. So no need to add an extra infos directly into the report. Maybe if you use the default on the partner to get the company default texts (translated) to the lang of the recipient could be better.

Also, changing Self-Bill for Self-Billed makes no sense to me.

@jbaudoux
Copy link

Well the position of the partners I think it's correct. It's a self-invoice, so the invoice generated is like if the partner generated it. The positions are changed and I'm not sure if it's correct this approach. @rafaelbn please check.

The extra infos can be customized in the footer of the partner. So no need to add an extra infos directly into the report. Maybe if you use the default on the partner to get the company default texts (translated) to the lang of the recipient could be better.

Also, changing Self-Bill for Self-Billed makes no sense to me.

It's a self-billed invoice that is generated by the company towards the partner (with agreement from the partner). The document is emitted by the company and needs the header/footer of the company. The company is the legal issuer of the document. Like a customer invoice. The document number is provided by the company corresponding to the sequence in the journal of the company and is the unique document identifier.

You need to send the document to the partner, so you need the partner in the enveloppe window.

As it's managed as a supplier invoice, there is no equivalent of the fiscal position you have on a customer invoice to put the legal required text. That why I asked to add an additional text configurable on the company.

Process is self-billing, document is self-billed invoice / credit note.

This allowed us to be compliant with https://docs.peppol.eu/poacc/self-billing/3.0/bis-sb/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants