Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
e496046
[FIX] account_peppol: allow accounting users to read EDI attachment w…
fd-oncodna Dec 1, 2025
5c098f1
[FIX] account_edi_ubl_cii: allow BIS 3 customers invoices without cus…
sbidoul Dec 1, 2025
309bfb3
[FIX] packaging: fix windows uninstaller
d-fence Dec 1, 2025
128f7e0
[FIX] {website_}sale_loyalty: Avoid concurrent use of a promo code
aboo-odoo Oct 21, 2025
7f31f5d
[FIX] werkzeug: parser differential url_encode
bram1000 Sep 8, 2025
4d85470
[IMP] account,l10n_ma: Add ICE number to invoicing
seifgneedy Jun 26, 2025
bfe9fab
[FIX] website: use urllib's urlencode
mwath Oct 27, 2025
fab443e
[FIX] mail: avoid trying to send scheduled notifications for deleted …
yajo Apr 22, 2025
eac66f8
[FIX] mail: hide message failures for deleted records
yajo Nov 5, 2024
97f02e9
[FIX] mail: fix management of activities on removed records
tde-banana-odoo Nov 4, 2025
7636339
[FIX] mail: handle deleted records
robodoo Dec 4, 2025
e9a8ec2
[FIX] purchase: check internal user
thle-odoo Oct 15, 2025
e040f1b
[FIX] mail: do not crash when scheduling message on 'no model'
tde-banana-odoo Dec 4, 2025
44d3a2f
[IMP] core: disable audio during tours
xmo-odoo Dec 5, 2025
a60c618
[FIX] website_event: get reCaptcha token on registration form submit
ByteMeAsap Dec 3, 2025
9a3f283
[FIX] tools: prevent editing parser rules
thle-odoo Dec 8, 2025
d02af7c
[FIX] auth_signup: Signup token invalidation
Megaaaaaa Nov 21, 2025
512ba4e
[FIX] lower_logging: support mapping args
xmo-odoo Dec 10, 2025
bb60d83
[IMP] web: verify the name of the database
mart-e Sep 26, 2025
0fb2d76
[ADD] account_add_gln,account_edi_ubl_cii: GLN number
AllePilli Dec 2, 2025
cc5dac0
[ADD] payment_worldline: backport to 16.0
dija-odoo Jun 16, 2025
eb99aa1
[IMP] core: test_module_operations reporting to runbot
xmo-odoo Dec 15, 2025
f3e32eb
[FIX] mail: author on create and write
Megaaaaaa Oct 9, 2025
ccbc9ae
[FIX] account_peppol: missing PDF in XML
svfu-odoo Dec 15, 2025
2a68a75
[FIX] web: limit number of cells written in pivot exports
beledouxdenis Oct 27, 2025
e4e20b4
[REF] account_peppol: Peppol endpoint & eas computations
AllePilli Dec 5, 2025
d9c68b7
[IMP] account_peppol: partner improvements
AllePilli Dec 16, 2025
e60da7f
[PERF] account_edi_format: Speedup product search
MohamedKasem99 Dec 5, 2025
b7dd8af
[FIX] l10n_it_edi: Correct function signature
LouisGobert Dec 19, 2025
7f45fff
[FIX] web_editor: removing icon makes paragraph unreachable
dhba-odoo Nov 27, 2025
2fb442c
[FIX] web_editor: enter before icon element
dhba-odoo Dec 18, 2025
f07949e
[FIX] web_editor: open a popover for inline document download
Jinjiu96 Nov 18, 2025
bae579f
[FIX] account_peppol: missing destructuring of loop var
svfu-odoo Jan 6, 2026
863d89a
[IMP] mail_plugin: allow the mail plugin to know the Odoo version
std-odoo Nov 17, 2025
16f4efc
[FIX] account: Remove sudo-ed returned bank
aboo-odoo Jan 8, 2026
e73b4f2
[FIX] mail: mail.message create on no user
Megaaaaaa Nov 13, 2025
70dd6b6
[FIX] website: only update menu on page creation if the menu has no page
blse-odoo Jan 12, 2026
8f92694
[FIX] mail: handle wildcard content-type
jorv-odoo Jan 6, 2026
237cd53
[IMP] account, *: backport embed multiple files peppol
roto-odoo Dec 19, 2025
967f8e0
[FIX] web: show scanned barcode for iOS
vandroogenbd Jan 13, 2026
a036689
[FIX] auth_signup: signup_cancel as sudo when writing on active
Megaaaaaa Oct 23, 2025
ec6e559
[FIX] account_edi_ubl_cii: fix duple attachment bug
AhmedElemary57 Jan 15, 2026
8d8d542
[FIX] account_peppol: safer server deregistration
antonrom1 Dec 9, 2025
1704699
[FIX] account_peppol: Fix embed attachments through peppol
roto-odoo Jan 21, 2026
fa2e79f
[FIX] account_edi_ubl_cii,account_peppol: better filter embed attachment
roto-odoo Jan 21, 2026
98dcbc8
[FIX] *: replace "Deco Addict" with "Acme Corporation"
reth-odoo Jan 22, 2026
a7f2fae
[FIX] account: make "sample" invoices demo-only
reth-odoo Jan 22, 2026
c3448d0
[FIX] l10n_fr_fec: reduce FEC export memory footprint
mograby3500 Dec 22, 2025
1d4e5e7
[FIX] tools: align policy addition API
antonrom1 Dec 8, 2025
1b300dd
[REF] mrp: init manual_consumption column (from c001d6d56b02a1e1d5ef8…
ThomasBinsfeld Jan 30, 2026
8196318
[REF] MRP: don't assign groups to default user
ThomasBinsfeld Jan 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion addons/account/models/account_bank_statement_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ def _find_or_create_bank_account(self):
'partner_id': self.partner_id.id,
'journal_id': None,
})
return bank_account.filtered(lambda x: x.company_id.id in (False, self.company_id.id))
return bank_account.filtered(lambda x: x.company_id.id in (False, self.company_id.id)).sudo(False)

def _get_amounts_with_currencies(self):
"""
Expand Down
2 changes: 1 addition & 1 deletion addons/account/views/bill_preview_template.xml

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions addons/account/views/report_invoice.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
<t t-if="o.company_id.account_fiscal_country_id.vat_label" t-esc="o.company_id.account_fiscal_country_id.vat_label" id="inv_tax_id_label"/>
<t t-else="">Tax ID</t>: <span t-field="o.partner_id.vat"/>
</div>
<div t-if="o.partner_id.country_code == 'MA' and o.partner_id.company_registry">
ICE: <a t-field="o.partner_id.company_registry"/>
</div>
</t>
</div>
</t>
Expand All @@ -33,6 +36,9 @@
<t t-if="o.company_id.account_fiscal_country_id.vat_label" t-esc="o.company_id.account_fiscal_country_id.vat_label" id="inv_tax_id_label"/>
<t t-else="">Tax ID</t>: <span t-field="o.partner_id.vat"/>
</div>
<div t-if="o.partner_id.country_code == 'MA' and o.partner_id.company_registry">
ICE: <a t-field="o.partner_id.company_registry"/>
</div>
</t>
</div>
</t>
Expand All @@ -44,6 +50,9 @@
<t t-if="o.company_id.account_fiscal_country_id.vat_label" t-esc="o.company_id.account_fiscal_country_id.vat_label" id="inv_tax_id_label"/>
<t t-else="">Tax ID</t>: <span t-field="o.partner_id.vat"/>
</div>
<div t-if="o.partner_id.country_code == 'MA' and o.partner_id.company_registry">
ICE: <a t-field="o.partner_id.company_registry"/>
</div>
</t>
</div>
</t>
Expand Down
15 changes: 15 additions & 0 deletions addons/account/wizard/account_invoice_send.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ class AccountInvoiceSend(models.TransientModel):
compute='_compute_move_types',
readonly=True)

# Technical field to display or not the attachment button
display_attachment_fields = fields.Boolean(compute='_compute_display_attachment_fields')
# Technical field to display or not a warning icon besides attachments not supported
attachments_not_supported = fields.Json(compute='_compute_attachments_not_supported')

@api.model
def default_get(self, fields):
res = super(AccountInvoiceSend, self).default_get(fields)
Expand Down Expand Up @@ -112,6 +117,16 @@ def _compute_invoice_without_email(self):
else:
wizard.invoice_without_email = False

@api.depends('is_email', 'composition_mode')
def _compute_display_attachment_fields(self):
for wizard in self:
wizard.display_attachment_fields = wizard.is_email and wizard.composition_mode != 'mass_mail'

@api.depends('display_attachment_fields', 'attachment_ids')
def _compute_attachments_not_supported(self):
for wizard in self:
wizard.attachments_not_supported = {}

def _send_email(self):
if self.is_email:
# with_context : we don't want to reimport the file we just exported.
Expand Down
15 changes: 12 additions & 3 deletions addons/account/wizard/account_invoice_send_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
<field name="invoice_ids" invisible="1"/>
<field name="email_from" invisible="1" />
<field name="mail_server_id" invisible="1"/>
<field name="display_attachment_fields" invisible="1"/>
<field name="attachments_not_supported" invisible="1"/>
<div name="option_print">
<field name="is_print" />
<b><label for="is_print"/></b>
Expand Down Expand Up @@ -53,16 +55,23 @@
<field name="body" class="oe-bordered-editor" options="{'style-inline': true}"/>
</div>
<group>
<group attrs="{'invisible': [('composition_mode', '=', 'mass_mail')]}">
<field name="attachment_ids" widget="many2many_binary" string="Attach a file" nolabel="1" colspan="2" attrs="{'invisible': [('composition_mode', '=', 'mass_mail')]}"/>
</group>
<group>
<field name="template_id" options="{'no_create': True, 'no_edit': True}"
context="{'default_model': 'account.move'}"/>
</group>
</group>
</div>

<group attrs="{'invisible': [('display_attachment_fields', '=', False)]}">
<field name="attachment_ids"
widget="many2many_binary"
string="Attach a file"
nolabel="1"
colspan="2"
attrs="{'invisible': [('display_attachment_fields', '=', False)]}"
options="{'attachments_not_supported_field': 'attachments_not_supported' }"/>
</group>

<footer>
<button string="Send &amp; Print"
attrs="{'invisible': ['|', ('is_email', '=', False), ('is_print', '=', False)]}" data-hotkey="q"
Expand Down
13 changes: 5 additions & 8 deletions addons/account/wizard/account_tour_upload_bill.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class AccountTourUploadBill(models.TransientModel):

selection = fields.Selection(
selection=lambda self: self._selection_values(),
default="sample"
default=lambda self: 'sample' if self.env.ref('base.res_partner_2', raise_if_not_found=False) else 'upload'
)

preview_invoice = fields.Html(
Expand Down Expand Up @@ -50,7 +50,9 @@ def _selection_values(self):
journal_alias = self.env['account.journal'] \
.search([('type', '=', 'purchase'), ('company_id', '=', self.env.company.id)], limit=1)

values = [('sample', _('Try a sample vendor bill')), ('upload', _('Upload your own bill'))]
# We don't want people putting demo data in their database if they didn't launch it in demo mode
values = [('sample', _('Try a sample vendor bill'))] if self.env.ref('base.res_partner_2', raise_if_not_found=False) else []
values.append(('upload', _('Upload your own bill')))
if journal_alias.alias_name and journal_alias.alias_domain:
values.append(('email', _('Or send a bill to %s@%s', journal_alias.alias_name, journal_alias.alias_domain)))
return values
Expand Down Expand Up @@ -78,12 +80,7 @@ def apply(self):
return purchase_journal.with_context(default_journal_id=purchase_journal.id, default_move_type='in_invoice').create_document_from_attachment(attachment_ids=self.attachment_ids.ids)
elif self.selection == 'sample':
invoice_date = fields.Date.today() - timedelta(days=12)
partner = self.env['res.partner'].search([('name', '=', 'Deco Addict')], limit=1)
if not partner:
partner = self.env['res.partner'].create({
'name': 'Deco Addict',
'is_company': True,
})
partner = self.env.ref('base.res_partner_2')
bill = self.env['account.move'].create({
'move_type': 'in_invoice',
'partner_id': partner.id,
Expand Down
1 change: 1 addition & 0 deletions addons/account_add_gln/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
13 changes: 13 additions & 0 deletions addons/account_add_gln/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
'name': "Add Partner GLN",
'summary': "This module adds the Global Location Number to the partner. Used on delivery addresses, it is used to identify stock locations and is mandatory on the UBL/CII eInvoices (but not only). The module is intended be merged with account, later on, in master",
'category': 'Accounting/Accounting',
'version': '1.0',
'depends': ['account'],
'installable': True,
'auto_install': True,
'data': [
'views/res_partner_views.xml',
],
'license': 'LGPL-3',
}
1 change: 1 addition & 0 deletions addons/account_add_gln/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import res_partner
7 changes: 7 additions & 0 deletions addons/account_add_gln/models/res_partner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from odoo import fields, models


class ResPartner(models.Model):
_inherit = 'res.partner'

global_location_number = fields.Char(string="GLN", help="Global Location Number")
17 changes: 17 additions & 0 deletions addons/account_add_gln/views/res_partner_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="account_add_gln.view_partner_form_inherit" model="ir.ui.view">
<field name="name">res.partner.form.inherit.account_peppol_partner_extra_fields</field>
<field name="model">res.partner</field>
<field name="priority">15</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<xpath expr=".//page[@name='sales_purchases']//group[@name='misc']" position="inside">
<field name="global_location_number" attrs="{'invisible': [('type', '!=', 'delivery')]}"/>
</xpath>
<xpath expr=".//page[@name='contact_addresses']/field[@name='child_ids']/form//field[@name='mobile']" position="after">
<field name="global_location_number" attrs="{'invisible': [('type', '!=', 'delivery')]}"/>
</xpath>
</field>
</record>
</odoo>
23 changes: 12 additions & 11 deletions addons/account_edi/models/account_edi_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -516,17 +516,18 @@ def _retrieve_product(self, name=None, default_code=None, barcode=None):
domains.append([('default_code', '=', default_code)])
if name:
domains += [[('name', '=', name)], [('name', 'ilike', name)]]
products = self.env['product.product'].search(
expression.AND([
expression.OR(domains),
[('company_id', 'in', [False, self.env.company.id])],
]),
)
if products:
for domain in domains:
products_by_domain = products.filtered_domain(domain)
if products_by_domain:
return products_by_domain[0]

for domain in domains:
product = self.env['product.product'].search(
expression.AND([
domain,
[('company_id', 'in', [False, self.env.company.id])],
]),
limit=1
)
# We need a single product. Exit early if one is found (implements the priority logic).
if product:
return product
return self.env['product.product']

def _retrieve_tax(self, amount, type_tax_use):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,6 @@ def _make_request(self, url, params=False):
self._renew_token()
self.env.cr.commit() # We do not want to lose it if in the _make_request below something goes wrong
return self._make_request(url, params)
if error_code == 'no_such_user':
# This error is also raised if the user didn't exchange data and someone else claimed the edi_identificaiton.
self.sudo().active = False
raise AccountEdiProxyError(error_code, proxy_error['message'] or False)

return response['result']
Expand Down
2 changes: 2 additions & 0 deletions addons/account_edi_ubl_cii/data/ubl_20_templates.xml
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,8 @@
<cac:Delivery>
<cbc:ActualDeliveryDate t-out="foreach_vals.get('actual_delivery_date')"/>
<cac:DeliveryLocation>
<cbc:ID t-att-schemeID="foreach_vals.get('delivery_location_vals', {}).get('delivery_location_scheme_id')"
t-out="foreach_vals.get('delivery_location_vals', {}).get('delivery_location_id')"/>
<cac:Address>
<t t-call="{{AddressType_template}}">
<t t-set="vals"
Expand Down
36 changes: 24 additions & 12 deletions addons/account_edi_ubl_cii/models/account_edi_xml_ubl_bis3.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,6 @@ def _get_delivery_vals_list(self, invoice):
and supplier.country_id.code in economic_area
and supplier.country_id != customer.country_id)

if not intracom_delivery:
return []

# [BR-IC-12]-In an Invoice with a VAT breakdown (BG-23) where the VAT category code (BT-118) is
# "Intra-community supply" the Deliver to country code (BT-80) shall not be blank.

Expand All @@ -194,12 +191,31 @@ def _get_delivery_vals_list(self, invoice):
else:
partner_shipping = customer

return [{
'actual_delivery_date': invoice.invoice_date,
'delivery_location_vals': {
# TODO master: clean that code a bit hacky, when the module account_add_gln is merged with account
gln = 'global_location_number' in partner_shipping._fields and partner_shipping.global_location_number

if not intracom_delivery and not gln:
return []

delivery_vals = {
'delivery_location_vals': {},
}

if intracom_delivery:
delivery_vals.update({
'actual_delivery_date': invoice.invoice_date,
})
delivery_vals['delivery_location_vals'].update({
'delivery_address_vals': self._get_partner_address_vals(partner_shipping),
},
}]
})

if gln:
delivery_vals['delivery_location_vals'].update({
'delivery_location_scheme_id': '0088',
'delivery_location_id': partner_shipping.global_location_number,
})

return [delivery_vals]

def _get_partner_address_vals(self, partner):
# EXTENDS account.edi.xml.ubl_21
Expand Down Expand Up @@ -435,10 +451,6 @@ def _invoice_constraints_peppol_en16931_ubl(self, invoice, vals):
'peppol_en16931_ubl_seller_endpoint': self._check_required_fields(
vals['supplier'], 'vat'
),
# PEPPOL-EN16931-R010: Buyer electronic address MUST be provided
'peppol_en16931_ubl_buyer_endpoint': self._check_required_fields(
vals['customer'], 'vat'
),
# PEPPOL-EN16931-R003: A buyer reference or purchase order reference MUST be provided.
'peppol_en16931_ubl_buyer_ref_po_ref':
"A buyer reference or purchase order reference must be provided." if self._check_required_fields(
Expand Down
Loading