Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
80 changes: 80 additions & 0 deletions om_aed_currency_symbol/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
=======================
UAE Dirham Symbol (AED)
=======================

A bridge until Odoo supports the sign.

The UAE Dirham sign (U+20C3) is new: it joined Unicode in version 18.0, and Odoo still shows 'AED' by default.

This module displays the official sign today, using a small font for devices that don't support it yet.

Once Odoo supports the sign natively, we'll announce it here and discontinue this module.

Uninstalling the module restores 'AED', or Odoo's own sign if supported, without changing anything else in your database.

Features
========

Shows the UAE Dirham sign (U+20C3 UAE DIRHAM SIGN, Unicode 18.0) for the AED currency in the Odoo
backend, PDF reports, website, customer portal and Point of Sale.

* Uses the official Unicode character, so copied amounts keep the real sign.
* The sign is placed before the amount. A symbol typed by the user is kept; the button *Use UAE
Dirham Sign* on the currency form switches to the sign.
* Symbols set by older workarounds (for example U+1D01) are replaced automatically.
* Works with every report layout font (Lato, Roboto, Open Sans, Montserrat, Oswald, Raleway,
Tajawal, Fira Mono), regular and bold.
* No element's ``font-family`` is changed: interface fonts, report fonts and code editors
(Ace/CodeMirror monospace) keep their own fonts.

How it works
============

* On install, the AED currency symbol becomes U+20C3, placed before the amount.
* A tiny web font (one glyph, regular and bold, in ``static/src/fonts``) is declared with
``@font-face`` rules restricted with ``unicode-range: U+20C3`` and added to font families that
already exist in Odoo's stacks (``Odoo Unicode Support Noto``, and the report layout fonts in the
report bundle).
* The CSS references the font files by URL instead of embedding them, so each font file is
downloaded once and cached, and the report stylesheet stays small.
* On uninstall, the symbol of AED is set back to ``AED``, placed after the amount, but only if it is
still the Dirham sign set by this module. A symbol typed by the user is never changed. If Odoo's own
currency data already uses U+20C3 (a future Odoo version), the symbol is left untouched.

Font origin and license
=======================

The font files in ``static/src/fonts`` contain a single glyph, U+20C3 UAE DIRHAM SIGN, in a regular
and a bold weight (TTF, WOFF, WOFF2).

* **Creator:** the glyph outline (``om_uae_dirham.svg``) was drawn for this module by Akshay Manoj,
with the help of an AI tool, and the fonts were built from it. It is not taken from any third-party
font.
* **License:** LGPL-3, the same license as the module (also recorded in the copyright field of the
font files). No third-party font software is included.
* **Design:** the glyph follows the official sign published by the Central Bank of the UAE.

Tests
=====

::

odoo-bin -d <db> -i om_aed_currency_symbol,web_tour --test-enable --test-tags=/om_aed_currency_symbol

Credits
=======

Contributors
------------

Akshay Manoj

Author & Maintainer
-------------------

This module is maintained by the Odoo Mates <odoomates@gmail.com>

License
=======

LGPL-3
13 changes: 13 additions & 0 deletions om_aed_currency_symbol/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Part of om_aed_currency_symbol (Odoo Mates). License: LGPL-3.
from . import models
from .models.res_currency import DIRHAM_SIGN


def post_init_hook(env):
"""Show the UAE Dirham sign for AED (all companies share the currency record)."""
env['res.currency']._om_set_dirham_sign()


def uninstall_hook(env):
"""Give AED its standard symbol back (unless Odoo's own data already uses the Dirham sign)."""
env['res.currency']._om_restore_aed_symbol()
64 changes: 64 additions & 0 deletions om_aed_currency_symbol/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Part of om_aed_currency_symbol (Odoo Mates). License: LGPL-3.
{
'name': 'Odoo 20 UAE Dirham Symbol (AED)',
'version': '1.0',
'author': 'Odoo Mates',
'maintainer': 'Odoo Mates',
'support': 'odoomates@gmail.com',
'category': 'Accounting/Localizations',
'summary': 'UAE Dirham Symbol, New AED Currency Sign, Dirham Sign in Invoices, Reports, POS and Website, '
'AED Symbol, UAE Currency Symbol, Emirati Dirham Sign',
'description': """
UAE Dirham Symbol (AED)
=======================

A bridge until Odoo supports the sign.

The UAE Dirham sign (U+20C3) is new: it joined Unicode in version 18.0, and Odoo still shows 'AED' by
default.

This module displays the official sign today, using a small font for devices that don't support it yet.

Once Odoo supports the sign natively, we'll announce it here and discontinue this module.

Uninstalling the module restores 'AED', or Odoo's own sign if supported, without changing anything else in
your database.

Shows the new UAE Dirham sign (U+20C3, Unicode 18.0) instead of "AED" everywhere Odoo prints an
amount in dirhams: backend, PDF reports (invoices, quotations, payslips...), website, portal and
Point of Sale.

* Uses the official Unicode character, so copied amounts keep the real sign.
* A small web font draws the sign until operating systems ship it; nothing else changes:
your interface fonts, report fonts and code editors keep their own fonts.
* Works with every report layout font (Lato, Roboto, Open Sans, Montserrat, Oswald, Raleway,
Tajawal, Fira Mono), regular and bold.
* Symbol placed before the amount; uninstalling restores "AED" (or Odoo's own sign, once supported).

Contributor: Akshay Manoj.
""",
'license': 'LGPL-3',
'depends': ['web'],
'data': [
'views/res_currency_views.xml',
],
'assets': {
'web.assets_backend': [
'om_aed_currency_symbol/static/src/css/om_aed_symbol.css',
],
'web.assets_frontend': [
'om_aed_currency_symbol/static/src/css/om_aed_symbol.css',
],
'web.report_assets_common': [
'om_aed_currency_symbol/static/src/css/om_aed_symbol_report.css',
],
'point_of_sale._assets_pos': [
'om_aed_currency_symbol/static/src/css/om_aed_symbol_report.css',
],
},
'images': ['static/description/banner.png'],
'post_init_hook': 'post_init_hook',
'uninstall_hook': 'uninstall_hook',
'installable': True,
'application': False,
}
1 change: 1 addition & 0 deletions om_aed_currency_symbol/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import res_currency
76 changes: 76 additions & 0 deletions om_aed_currency_symbol/models/res_currency.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Part of om_aed_currency_symbol (Odoo Mates). License: LGPL-3.
import logging

from lxml import etree

from odoo import api, models
from odoo.tools import file_open

_logger = logging.getLogger(__name__)

# U+20C3 UAE DIRHAM SIGN (Unicode 18.0), unveiled by the Central Bank of the UAE in March 2025.
DIRHAM_SIGN = '⃃'
STANDARD_SYMBOL = 'AED'
# Symbols other modules or users used for AED; they are replaced by the real sign.
REPLACEABLE_SYMBOLS = {STANDARD_SYMBOL, 'Dhs', 'DH', 'Dh', 'د.إ', 'دإ', 'ᴁ', 'Æ', ''}


class ResCurrency(models.Model):
_inherit = 'res.currency'

@api.model
def _om_aed_currency(self):
currency = self.env.ref('base.AED', raise_if_not_found=False)
if not currency:
currency = self.with_context(active_test=False).search([('name', '=', 'AED')], limit=1)
return currency.sudo()

@api.model
def _om_set_dirham_sign(self, force=False):
"""Set U+20C3 as the AED symbol, placed before the amount.

A symbol that a user typed on purpose (not in the known list) is kept unless ``force``.
"""
currency = self._om_aed_currency()
if not currency:
_logger.info('om_aed_currency_symbol: no AED currency found, nothing to do.')
return False
if currency.symbol == DIRHAM_SIGN and currency.position == 'before':
return True
if force or currency.symbol in REPLACEABLE_SYMBOLS or currency.symbol == DIRHAM_SIGN:
currency.write({'symbol': DIRHAM_SIGN, 'position': 'before'})
return True
_logger.info('om_aed_currency_symbol: AED symbol %r kept (custom value).', currency.symbol)
return False

@api.model
def _om_native_aed_symbol(self):
"""Symbol that Odoo's own currency data gives to AED, or None if it cannot be read.

This module is a bridge until Odoo supports U+20C3 natively. Once Odoo's data uses the sign
itself, uninstalling the module must not overwrite it.
"""
try:
with file_open('base/data/res_currency_data.xml', 'rb') as data_file:
nodes = etree.parse(data_file).xpath("//record[@id='AED']/field[@name='symbol']")
except (OSError, etree.XMLSyntaxError, ValueError):
_logger.info('om_aed_currency_symbol: could not read the native AED symbol of Odoo.')
return None
return nodes[0].text if nodes else None

@api.model
def _om_restore_aed_symbol(self):
"""Give AED its standard symbol back, unless Odoo itself already uses the Dirham sign."""
currency = self._om_aed_currency()
if not currency or currency.symbol != DIRHAM_SIGN:
return True
if self._om_native_aed_symbol() == DIRHAM_SIGN:
# Odoo's own data already uses U+20C3: leave the symbol exactly as Odoo defines it.
return True
currency.write({'symbol': STANDARD_SYMBOL, 'position': 'after'})
return True

def action_om_use_dirham_sign(self):
"""Button on the currency form: use the Dirham sign even if a custom symbol was set."""
self._om_set_dirham_sign(force=True)
return True
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
56 changes: 56 additions & 0 deletions om_aed_currency_symbol/static/description/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<section class="oe_container" style="padding: 24px 0;">
<div class="oe_row" style="max-width: 960px; margin: 0 auto; text-align: center;">
<h2 style="color: #0e6e48; font-weight: 700;">UAE Dirham Symbol (AED)</h2>
<h3 style="color: #555;">The new UAE Dirham sign everywhere Odoo shows an amount in dirhams</h3>
<img src="banner.png" alt="UAE Dirham Symbol" style="max-width: 100%; border-radius: 8px; margin: 16px 0;"/>
</div>
</section>

<section class="oe_container" style="padding: 8px 0;">
<div class="oe_row" style="max-width: 960px; margin: 0 auto; background: #f3f8f5; border-left: 4px solid #0e6e48; padding: 12px 20px;">
<h3 style="color: #0e6e48; margin-top: 0;">A bridge until Odoo supports the sign</h3>
<p style="font-size: 15px;">The UAE Dirham sign (U+20C3) is new: it joined Unicode in version 18.0, and Odoo still shows 'AED' by default.</p>
<p style="font-size: 15px;">This module displays the official sign today, using a small font for devices that don't support it yet.</p>
<p style="font-size: 15px;">Once Odoo supports the sign natively, we'll announce it here and discontinue this module.</p>
<p style="font-size: 15px; margin-bottom: 0;">Uninstalling the module restores 'AED', or Odoo's own sign if supported, without changing anything else in your database.</p>
</div>
</section>

<section class="oe_container" style="padding: 8px 0;">
<div class="oe_row" style="max-width: 960px; margin: 0 auto;">
<h3 style="color: #0e6e48;">Key Features</h3>
<ul style="font-size: 15px; line-height: 1.8;">
<li>Replaces <b>"AED"</b> with the new <b>UAE Dirham sign</b> unveiled by the Central Bank of the UAE.</li>
<li>Uses the <b>official Unicode character U+20C3</b> (Unicode 18.0): copied amounts keep the real sign.</li>
<li>Shown in the <b>backend</b>, <b>PDF reports</b> (invoices, quotations, purchase orders, payslips...), <b>website</b>, <b>customer portal</b> and <b>Point of Sale</b>.</li>
<li>Works with <b>every report layout font</b> (Lato, Roboto, Open Sans, Montserrat, Oswald, Raleway, Tajawal, Fira Mono) in regular and bold.</li>
<li><b>Nothing else changes</b>: interface fonts, report fonts and code editors keep their own fonts. Only the dirham sign uses the small embedded font.</li>
<li>Symbol placed <b>before the amount</b>. Change it any time in Accounting &gt; Configuration &gt; Currencies.</li>
<li>Replaces symbols set by older workarounds automatically; a symbol you typed yourself is kept (button <i>Use UAE Dirham Sign</i> on the currency to switch).</li>
<li>Uninstall restores <b>"AED"</b> (or Odoo's own sign once supported). No configuration, no dependency other than the web client.</li>
</ul>
</div>
</section>

<section class="oe_container" style="padding: 8px 0;">
<div class="oe_row" style="max-width: 960px; margin: 0 auto;">
<h3 style="color: #0e6e48;">Invoice</h3>
<img src="screenshots/invoice_form.png" alt="Invoice with the UAE Dirham sign" style="max-width: 100%; border: 1px solid #ddd; border-radius: 6px;"/>
<h3 style="color: #0e6e48; margin-top: 24px;">PDF Report</h3>
<img src="screenshots/invoice_pdf.png" alt="PDF invoice with the UAE Dirham sign" style="max-width: 100%; border: 1px solid #ddd; border-radius: 6px;"/>
<h3 style="color: #0e6e48; margin-top: 24px;">List Views</h3>
<img src="screenshots/invoice_list.png" alt="Invoice list with the UAE Dirham sign" style="max-width: 100%; border: 1px solid #ddd; border-radius: 6px;"/>
</div>
</section>

<section class="oe_container" style="padding: 8px 0 32px;">
<div class="oe_row" style="max-width: 960px; margin: 0 auto;">
<h3 style="color: #0e6e48;">Good to Know</h3>
<ul style="font-size: 15px; line-height: 1.8;">
<li>Inside Odoo the sign is drawn by the module. In e-mails, Excel or CSV exports opened elsewhere, it depends on the reader's device: devices without a font for U+20C3 (Unicode 18.0) show a placeholder until their system adds it.</li>
<li>The sign is applied to the AED currency, shared by all companies of the database.</li>
</ul>
<p style="text-align: center; font-size: 15px;">Support: <a href="mailto:odoomates@gmail.com">odoomates@gmail.com</a></p>
<p style="text-align: center; font-size: 13px; color: #888;">Contributor: Akshay Manoj</p>
</div>
</section>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading