| Component | Approved | Translated | Unreviewed | Unfinished | Unfinished words | Unfinished characters | Untranslated | Checks | Suggestions | Comments | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| whatsapp_account BSD-2-Clause | 0% | 40% | 2 | 3 | 4 | 21 | 3 | 0 | 0 | 0 | |
| whatsapp_account_followup BSD-2-Clause | 0% | 2% | 1 | 42 | 121 | 667 | 42 | 0 | 0 | 0 | |
| whatsapp_calendar BSD-2-Clause | 0% | 8% | 1 | 11 | 30 | 189 | 11 | 0 | 0 | 0 | |
| whatsapp_event BSD-2-Clause | 0% | 76% | 10 | 3 | 13 | 71 | 3 | 0 | 0 | 0 | |
| whatsapp_hr_referral BSD-2-Clause | 0% | 42% | 3 | 4 | 21 | 173 | 4 | 0 | 0 | 0 | |
| whatsapp_payment BSD-2-Clause | 0% | 83% | 5 | 1 | 9 | 50 | 1 | 0 | 0 | 0 | |
| whatsapp_pos BSD-2-Clause | 0% | 64% | 11 | 6 | 30 | 210 | 6 | 0 | 0 | 0 | |
| whatsapp_sale BSD-2-Clause | 0% | 3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ||
| whatsapp_sign BSD-2-Clause | 0% | 0% | 0 | 29 | 129 | 868 | 29 | 0 | 0 | 0 | |
| whatsapp_stock BSD-2-Clause | 0% | 75% | 6 | 2 | 11 | 65 | 2 | 0 | 0 | 0 | |
| whatsapp_website_sale BSD-2-Clause | 0% | 7 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ||
| wine_merchant BSD-2-Clause | 0% | 26% | 48 | 131 | 1,589 | 10,795 | 131 | 0 | 0 | 0 | |
| worksheet BSD-2-Clause | 0% | 57% | 16 | 12 | 88 | 626 | 12 | 0 | 0 | 0 | |
| yoga_pilates BSD-2-Clause | 0% | 20% | 45 | 171 | 1,814 | 14,213 | 171 | 2 | 0 | 0 | |
Summary
| Project website | www.odoo.com | |
|---|---|---|
| Project reviewers41 |
|
|
| Language | Catalan | |
| Language code | ca | |
| Text direction | Left to right | |
| Case sensitivity | Case-sensitive | |
| Number of speakers | 8,218,781 | |
03/13/2026
String statistics
| Strings percent | Hosted strings | Words percent | Hosted words | Characters percent | Hosted characters | |
|---|---|---|---|---|---|---|
| Total | 116,933 | 726,566 | 5,335,089 | |||
| Approved | 1% | 28 | 1% | 3,912 | 1% | 63,115 |
| Waiting for review | 56% | 66,738 | 41% | 299,361 | 38% | 2,069,011 |
| Translated | 57% | 66,766 | 41% | 303,273 | 39% | 2,132,126 |
| Needs editing | 1% | 1 | 1% | 2 | 1% | 12 |
| Read-only | 0% | 0 | 0% | 0 | 0% | 0 |
| Failing checks | 1% | 749 | 1% | 8,311 | 1% | 55,533 |
| Strings with suggestions | 0% | 0 | 0% | 0 | 0% | 0 |
| Untranslated strings | 42% | 50,166 | 58% | 423,291 | 60% | 3,202,951 |
Quick numbers
and previous 30 days
Trends of last 30 days
+100%
Hosted words
—
+100%
Hosted strings
—
+57%
Translated
—
+100%
Contributors
—
|
Translation approved |
|
|
Translation added |
|
|
Translation approved |
|
|
Translation changed |
|
|
Translation approved |
|
|
Translation added |
|
|
Contributor joined |
Contributor joined
03/12/2026
|
|
Translation approved |
|
|
Translation changed |
|
|
Translation approved |
|
<t t-set="is_online" t-value="'appointment_type_id' in object.event_id and object.event_id.appointment_type_id"/>
<t t-set="recurrent" t-value="object.recurrence_id and not ctx.get('calendar_template_ignore_recurrence')"/>
<h1 style="font-size: 18px; font-weight: bold; color: #374151; margin-bottom: 28px;">
Reminder
<img src="/calendar/static/src/img/bell.png" style="border:0; width: 21px; height: 24px; margin-left: 10px; text-decoration:none; vertical-align: bottom;"/>
</h1>
<p style="margin: 0;">
Hello <t t-out="object.common_name or ''">Gemini Furniture</t>,<br/>
<span style="display: block; margin-top: 8px;">This is a reminder for the event below.</span>
</p>
<div style="text-align: center; padding: 16px 0px 16px 0px;">
<a t-attf-href="/calendar/{{ 'recurrence' if recurrent else 'meeting' }}/accept?token={{ object.sudo().access_token }}&id={{ object.event_id.id }}" t-attf-style="display: inline-block; padding: 7px 14px; color: {{object.event_id.user_id.company_id.email_primary_color or '#FFFFFF'}}; text-decoration: none; background-color: {{object.event_id.user_id.company_id.email_secondary_color or '#875A7B'}}; border-radius: 3px;">
Accept</a>
<a t-attf-href="/calendar/{{ 'recurrence' if recurrent else 'meeting' }}/decline?token={{ object.sudo().access_token }}&id={{ object.event_id.id }}" t-attf-style="display: inline-block; margin-left: 6px; padding: 7px 14px; color: {{object.event_id.user_id.company_id.email_primary_color or '#FFFFFF'}}; text-decoration: none; background-color: {{object.event_id.user_id.company_id.email_secondary_color or '#875A7B'}}; border-radius: 3px;">
Decline</a>
<a t-attf-href="/calendar/meeting/view?token={{ object.sudo().access_token }}&id={{ object.event_id.id }}" t-attf-style="display: inline-block; margin-left: 12px; padding: 7px 14px; color: #111827; text-decoration: none; background-color: #E7E9ED; border-radius: 3px;">
View</a>
</div>
<div style="margin: 16px 0 0;">
<h2 t-attf-style="margin-bottom: 12px; font-size: 14px; font-weight: bold; color: {{user.company_id.email_secondary_color or '#875A7B'}};">Details</h2>
<table cellpadding="0" cellspacing="0" border="0" style="font-size: 13px; color: #374151;">
<tr>
<td style="width: 100px; color: #676F7B;">Date & Time</td>
<td style="font-weight: bold;">
<t t-out="format_datetime(dt=object.event_id.start, tz=object.mail_tz if not object.event_id.allday else None, dt_format='EEEE', lang_code=object.env.lang) or ''">Tuesday</t>
<t t-out="format_datetime(dt=object.event_id.start, tz=object.mail_tz if not object.event_id.allday else None, dt_format='d', lang_code=object.env.lang) or ''">4</t>
<t t-out="format_datetime(dt=object.event_id.start, tz=object.mail_tz if not object.event_id.allday else None, dt_format='MMMM y', lang_code=object.env.lang) or ''">May 2021</t>
<t t-if="not object.event_id.allday">
<t t-out="format_time(time=object.event_id.start, tz=object.mail_tz, time_format='short', lang_code=object.env.lang) or ''">11:00 AM</t>
<t t-if="object.mail_tz">
<span style="font-size: 11px; font-weight: normal;">
(<t t-out="object.mail_tz or ''">Europe/Brussels</t>)
</span>
</t>
</t>
</td>
</tr>
<tr t-if="recurrent">
<td style="width: 100px; padding-top: 6px; color: #676F7B;">When</td>
<td style="padding-top: 6px;">
<t t-out="object.recurrence_id.get_recurrence_name() or ''">Every 1 Weeks, for 3 events</t>
</td>
</tr>
<tr t-if="not object.event_id.allday and object.event_id.duration">
<td style="width: 100px; padding-top: 6px; color: #676F7B;">Duration</td>
<td style="padding-top: 6px;">
<t t-out="('%dH%02d' % (object.event_id.duration,round(object.event_id.duration*60)%60)) or ''">0H30</t>
</td>
</tr>
<tr t-if="object.event_id.location">
<td style="width: 100px; padding-top: 6px; color: #676F7B; vertical-align: top;">Location</td>
<td style="padding-top: 6px;">
<t t-out="object.event_id.location or ''">Bruxelles</t>
<a target="_blank" t-if="not is_online or is_online and object.event_id.location != object.event_id.appointment_type_id.location_id.name" t-attf-href="http://maps.google.com/maps?oi=map&q={{object.event_id.location}}" style="margin-left: 12px; font-size: 12px; color: #008f8c; text-decoration: underline;">View Map</a>
</td>
</tr>
<tr t-if="object.event_id.videocall_location">
<td style="width: 100px; padding-top: 6px; color: #676F7B;">
<t t-if="object.get_base_url() in object.event_id.videocall_location">Join with</t>
<t t-else="">Join</t>
</td>
<td style="padding-top: 6px;">
<a t-att-href="object.event_id.videocall_location" target="_blank" style="color: #008f8c;">
<t t-if="object.get_base_url() in object.event_id.videocall_location">Odoo Discuss</t>
<t t-else="">Video meeting</t>
</a>
</td>
</tr>
</table>
</div>
<div style="margin: 32px 0 0;">
<t t-set="max_shown_attendees" t-value="20"/>
<h2 t-attf-style="margin-bottom: 12px; font-size: 14px; font-weight: bold; color: {{user.company_id.email_secondary_color or '#875A7B'}};">Attendees</h2>
<div t-foreach="object.event_id.attendee_ids[:max_shown_attendees]" t-as="attendee" style="margin-bottom: 5px;">
<img t-if="attendee.state" t-attf-src="/calendar/static/src/img/state_{{ attendee.state }}.png" style="border:0; width: 15px; height: 15px; vertical-align: text-bottom;"/>
<t t-if="attendee != object">
<span style="margin-left: 5px;" t-out="attendee.common_name or ''">Mitchell Admin</span>
</t>
<t t-else="">
<span style="margin-left: 5px;">You</span>
</t>
</div>
<div t-if="len(object.event_id.attendee_ids) > max_shown_attendees" style="margin-bottom: 5px;">
... and <t t-out="len(object.event_id.attendee_ids) - max_shown_attendees"/> more
</div>
</div>
<div t-if="not is_html_empty(object.event_id.description)" style="margin: 32px 0 0;">
<h2 t-attf-style="margin-bottom: 12px; font-size: 14px; font-weight: bold; color: {{user.company_id.email_secondary_color or '#875A7B'}};">Description of the event</h2>
<t t-out="object.event_id.description">Internal meeting for discussion for new pricing for product and services.</t>
</div>
<p style="margin: 32px 0 0;">
Thank you!
<t t-if="object.event_id.user_id.signature">
<span style="display: block; margin-top: 8px;"><t t-out="object.event_id.user_id.signature or ''">Mitchell Admin</t></span>
</t>
</p>
</div>
<t t-set="is_online" t-value="'appointment_type_id' in object.event_id and object.event_id.appointment_type_id"/>
<t t-set="recurrent" t-value="object.recurrence_id and not ctx.get('calendar_template_ignore_recurrence')"/>
<h1 style="font-size: 18px; font-weight: bold; color: #374151; margin-bottom: 28px;">
Recordatori
<img src="/calendar/static/src/img/bell.png" style="border:0; width: 21px; height: 24px; margin-left: 10px; text-decoration:none; vertical-align: bottom;"/>
</h1>
<p style="margin: 0;">
Hola, <t t-out="object.common_name or ''">Gemini Furniture</t>:<br/>
<span style="display: block; margin-top: 8px;">Aquest és un recordatori del següent esdeveniment.</span>
</p>
<div style="text-align: center; padding: 16px 0px 16px 0px;">
<a t-attf-href="/calendar/{{ 'recurrence' if recurrent else 'meeting' }}/accept?token={{ object.sudo().access_token }}&id={{ object.event_id.id }}" t-attf-style="display: inline-block; padding: 7px 14px; color: {{object.event_id.user_id.company_id.email_primary_color or '#FFFFFF'}}; text-decoration: none; background-color: {{object.event_id.user_id.company_id.email_secondary_color or '#875A7B'}}; border-radius: 3px;">
Acceptar</a>
<a t-attf-href="/calendar/{{ 'recurrence' if recurrent else 'meeting' }}/decline?token={{ object.sudo().access_token }}&id={{ object.event_id.id }}" t-attf-style="display: inline-block; margin-left: 6px; padding: 7px 14px; color: {{object.event_id.user_id.company_id.email_primary_color or '#FFFFFF'}}; text-decoration: none; background-color: {{object.event_id.user_id.company_id.email_secondary_color or '#875A7B'}}; border-radius: 3px;">
Rebutjar</a>
<a t-attf-href="/calendar/meeting/view?token={{ object.sudo().access_token }}&id={{ object.event_id.id }}" t-attf-style="display: inline-block; margin-left: 12px; padding: 7px 14px; color: #111827; text-decoration: none; background-color: #E7E9ED; border-radius: 3px;">
Veure</a>
</div>
<div style="margin: 16px 0 0;">
<h2 t-attf-style="margin-bottom: 12px; font-size: 14px; font-weight: bold; color: {{user.company_id.email_secondary_color or '#875A7B'}};">Detalls</h2>
<table cellpadding="0" cellspacing="0" border="0" style="font-size: 13px; color: #374151;">
<tr>
<td style="width: 100px; color: #676F7B;">Data i hora</td>
<td style="font-weight: bold;">
<t t-out="format_datetime(dt=object.event_id.start, tz=object.mail_tz if not object.event_id.allday else None, dt_format='EEEE', lang_code=object.env.lang) or ''">dimarts</t>
<t t-out="format_datetime(dt=object.event_id.start, tz=object.mail_tz if not object.event_id.allday else None, dt_format='d', lang_code=object.env.lang) or ''">4</t>
<t t-out="format_datetime(dt=object.event_id.start, tz=object.mail_tz if not object.event_id.allday else None, dt_format='MMMM y', lang_code=object.env.lang) or ''">de maig de 2021</t>
<t t-if="not object.event_id.allday">
<t t-out="format_time(time=object.event_id.start, tz=object.mail_tz, time_format='short', lang_code=object.env.lang) or ''">11:00 h</t>
<t t-if="object.mail_tz">
<span style="font-size: 11px; font-weight: normal;">
(<t t-out="object.mail_tz or ''">Europa/Brussel·les</t>)
</span>
</t>
</t>
</td>
</tr>
<tr t-if="recurrent">
<td style="width: 100px; padding-top: 6px; color: #676F7B;">Quan?</td>
<td style="padding-top: 6px;">
<t t-out="object.recurrence_id.get_recurrence_name() or ''">setmanalment, 3 esdeveniments</t>
</td>
</tr>
<tr t-if="not object.event_id.allday and object.event_id.duration">
<td style="width: 100px; padding-top: 6px; color: #676F7B;">Durada</td>
<td style="padding-top: 6px;">
<t t-out="('%dH%02d' % (object.event_id.duration,round(object.event_id.duration*60)%60)) or ''">0 h 30 min</t>
</td>
</tr>
<tr t-if="object.event_id.location">
<td style="width: 100px; padding-top: 6px; color: #676F7B; vertical-align: top;">Ubicació</td>
<td style="padding-top: 6px;">
<t t-out="object.event_id.location or ''">Brussel·les</t>
<a target="_blank" t-if="not is_online or is_online and object.event_id.location != object.event_id.appointment_type_id.location_id.name" t-attf-href="http://maps.google.com/maps?oi=map&q={{object.event_id.location}}" style="margin-left: 12px; font-size: 12px; color: #008f8c; text-decoration: underline;">Veure al mapa</a>
</td>
</tr>
<tr t-if="object.event_id.videocall_location">
<td style="width: 100px; padding-top: 6px; color: #676F7B;">
<t t-if="object.get_base_url() in object.event_id.videocall_location">Unir-se amb</t>
<t t-else="">Unir-se</t>
</td>
<td style="padding-top: 6px;">
<a t-att-href="object.event_id.videocall_location" target="_blank" style="color: #008f8c;">
<t t-if="object.get_base_url() in object.event_id.videocall_location">Converses d'Odoo</t>
<t t-else="">Videotrucada</t>
</a>
</td>
</tr>
</table>
</div>
<div style="margin: 32px 0 0;">
<t t-set="max_shown_attendees" t-value="20"/>
<h2 t-attf-style="margin-bottom: 12px; font-size: 14px; font-weight: bold; color: {{user.company_id.email_secondary_color or '#875A7B'}};">Participants</h2>
<div t-foreach="object.event_id.attendee_ids[:max_shown_attendees]" t-as="attendee" style="margin-bottom: 5px;">
<img t-if="attendee.state" t-attf-src="/calendar/static/src/img/state_{{ attendee.state }}.png" style="border:0; width: 15px; height: 15px; vertical-align: text-bottom;"/>
<t t-if="attendee != object">
<span style="margin-left: 5px;" t-out="attendee.common_name or ''">Mitchell Admin</span>
</t>
<t t-else="">
<span style="margin-left: 5px;">Vostè</span>
</t>
</div>
<div t-if="len(object.event_id.attendee_ids) > max_shown_attendees" style="margin-bottom: 5px;">
<t t-out="len(object.event_id.attendee_ids) - max_shown_attendees"/> i molt més
</div>
</div>
<div t-if="not is_html_empty(object.event_id.description)" style="margin: 32px 0 0;">
<h2 t-attf-style="margin-bottom: 12px; font-size: 14px; font-weight: bold; color: {{user.company_id.email_secondary_color or '#875A7B'}};">Descripció de l'esdeveniment</h2>
<t t-out="object.event_id.description">Reunió interna per parlar sobre els nous preus dels productes i dels serveis.</t>
</div>
<p style="margin: 32px 0 0;">
Gràcies!
<t t-if="object.event_id.user_id.signature">
<span style="display: block; margin-top: 8px;"><t t-out="object.event_id.user_id.signature or ''">Mitchell Admin</t></span>
</t>
</p>
</div>