Repository: fossasia/open-event-server

Issue:
Change language of date and time based on user choice
The language for date and time is not changed in messages even if the message is not in English.


Discussion:
please assign me this issue,I'll fix it within an hour or so.
We don't assign issues to external contributors. Please comment that you're working on the issue after checking that no one else is, and then send a pull request for it. Thank You!
 I am working on the issue, after checking that no one else is.

@sourav-mishra-889 - No need to assign the issue, you can start working
@mariobehling we have to make this change in invoice and mails, right?

Resolving patch:
diff --git a/app/api/helpers/mail.py b/app/api/helpers/mail.py
--- a/app/api/helpers/mail.py
+++ b/app/api/helpers/mail.py
@@ -21,6 +21,11 @@
 from app.models.user import User
 from app.settings import get_settings
 from app.models.order import OrderTicket
+from babel.dates import (
+    format_date,
+    format_time,
+    format_datetime
+)
 
 logger = logging.getLogger(__name__)
 # pytype: disable=attribute-error
@@ -379,11 +384,11 @@ def send_email_announce_event(event, group, emails):
 
     event_name = event.name
     group_name = group.name
-    event_date = event.starts_at.strftime('%d %B %Y')
+    event_date = event.starts_at
     event_description = event.description
     event_url = event.site_link
     event_location = event.normalized_location
-    event_time = event.starts_at.strftime("%H:%M (%Z)")
+    event_time = event.starts_at
     group_url = group.view_page_link
     app_name = get_settings()['app_name']
 
@@ -395,7 +400,7 @@ def send_email_announce_event(event, group, emails):
                 subject=mail['subject'].format(
                     event_name=event_name,
                     group_name=group_name,
-                    event_date=event_date,
+                    event_date=convert_to_user_locale(email, date=event_date),
                 ),
                 html=render_template(
                     mail['template'],
@@ -403,8 +408,12 @@ def send_email_announce_event(event, group, emails):
                     event_description=event_description,
                     event_url=event_url,
                     event_location=event_location,
-                    event_date=event_date,
-                    event_time=event_time,
+                    event_date=convert_to_user_locale(email, date=event_date),
+                    event_time=convert_to_user_locale(
+                        email,
+                        time=event_time,
+                        tz=event.timezone
+                    ),
                     group_name=group_name,
                     group_url=group_url,
                     app_name=app_name,
@@ -506,7 +515,7 @@ def send_email_change_user_email(user, email):
         base64.b64encode(bytes(serializer.dumps([email, str_generator()]), 'utf-8')),
         'utf-8',
     )
-    app_name=get_settings()['app_name']
+    app_name = get_settings()['app_name']
     link = make_frontend_url('/email/verify', {'token': hash_})
     send_email_with_action(
         user.email,
@@ -514,7 +523,7 @@ def send_email_change_user_email(user, email):
         'user_confirm',
         email=user.email,
         link=link,
-        app_name=app_name
+        app_name=app_name,
     )
     send_email_with_action(
         email,
@@ -548,20 +557,35 @@ def send_email_to_attendees(order):
     )
     email_group = groupby(attendees, lambda a: a.email)
 
+    buyer_email = order.user.email
+    event_date = convert_to_user_locale(
+        buyer_email,
+        date=order.event.starts_at,
+    )
+    event_end_date = convert_to_user_locale(
+        buyer_email,
+        date_time=order.event.ends_at,
+        tz=order.event.timezone,
+    )
+    event_time = convert_to_user_locale(
+        buyer_email,
+        time=order.event.starts_at,
+        tz=order.event.timezone,
+    )
+
     context = dict(
         order=order,
+        starts_at=convert_to_user_locale(
+            buyer_email,
+            date_time=order.event.starts_at,
+            tz=order.event.timezone,
+        ),
+        ends_at=event_end_date,
+        event_time=event_time,
         settings=get_settings(),
         order_view_url=order.site_view_link,
     )
 
-    event_date = convert_to_event_timezone(
-        order.event.starts_at, order.event.timezone, format='%d %B %Y'
-    )
-    event_time = convert_to_event_timezone(
-        order.event.starts_at, order.event.timezone, format='%H:%M (%Z%z)'
-    )
-
-    buyer_email = order.user.email
     action = MailType.TICKET_PURCHASED
     mail = MAILS[action]
     send_email(
@@ -606,6 +630,8 @@ def send_email_to_attendees(order):
 def send_order_purchase_organizer_email(order, recipients):
 
     order_tickets = OrderTicket.query.filter_by(order_id=order.id).all()
+    emails = list({organizer.email for organizer in recipients})
+    print(emails[0])
 
     context = dict(
         buyer_email=order.user.email,
@@ -615,14 +641,21 @@ def send_order_purchase_organizer_email(order, recipients):
         frontend_url=get_settings()['frontend_url'],
         site_link=order.event.site_link,
         order_url=order.site_view_link,
-        event_date=convert_to_event_timezone(
-            order.event.starts_at, order.event.timezone, format='%d %B %Y'
+        event_date=convert_to_user_locale(
+            order.user.email,
+            date=order.event.starts_at,
         ),
-        event_time=convert_to_event_timezone(
-            order.event.starts_at, order.event.timezone, format='%H:%M (%Z%z)'
+        event_time=convert_to_user_locale(
+            order.user.email,
+            time=order.event.starts_at,
+            tz=order.event.timezone,
         ),
         timezone=order.event.timezone,
-        purchase_time=order.completed_at,
+        purchase_time=convert_to_user_locale(
+            emails[0],
+            date_time=order.completed_at,
+            tz=order.event.timezone
+        ),
         payment_mode=order.payment_mode,
         payment_status=order.status,
         order_amount=order.amount,
@@ -638,7 +671,6 @@ def send_order_purchase_organizer_email(order, recipients):
         buyer_tax_id=order.tax_business_info,
         app_name=get_settings()['app_name'],
     )
-    emails = list({organizer.email for organizer in recipients})
     if emails:
         send_email_with_action(
             emails[0],
@@ -765,10 +797,7 @@ def send_email_after_event(email, event_name):
     send_email(
         to=email,
         action=action,
-        subject=mail['subject'].format(
-            event_name=event_name,
-            app_name=app_name
-        ),
+        subject=mail['subject'].format(event_name=event_name, app_name=app_name),
         html=render_template(
             mail['template'],
             app_name=app_name,
@@ -794,11 +823,35 @@ def send_email_after_event_speaker(email, event_name):
     )
 
 
-def convert_to_event_timezone(date, timezone=None, format='%B %d, %Y %H:%M (%Z%z)'):
-    if not date:
-        return None
-    if timezone:
-        date = date.replace(tzinfo=pytz.timezone('UTC')).astimezone(
-            pytz.timezone(timezone)
-        )
-    return date.strftime(format)
+def convert_to_user_locale(email, date_time=None, date=None, time=None, tz=None):
+    """
+    Convert date and time to user selected language
+    :return        : datetime/date/time translated to user locale
+    """
+    if email:
+        user = User.query.filter(User.email == email).first()
+        user_locale = 'en'
+
+        if user and user.language_prefrence:
+            user_locale = user.language_prefrence
+
+        if date_time and tz:
+            return format_datetime(
+                date_time,
+                'full',
+                tzinfo=pytz.timezone(tz),
+                locale=user_locale
+            )
+        
+        if date:
+            return format_date(date, 'd MMMM Y', locale=user_locale)
+        
+        if time and tz:
+            return format_time(
+                time,
+                'HH:mm (zzzz)',
+                tzinfo=pytz.timezone(tz),
+                locale=user_locale
+            )
+
+    return None
diff --git a/app/api/helpers/order.py b/app/api/helpers/order.py
--- a/app/api/helpers/order.py
+++ b/app/api/helpers/order.py
@@ -19,6 +19,7 @@
     notify_ticket_purchase_attendee,
     notify_ticket_purchase_organizer,
 )
+from app.api.helpers.mail import convert_to_user_locale
 from app.api.helpers.storage import UPLOAD_PATHS
 from app.models import db
 from app.models.order import OrderTicket
@@ -76,9 +77,25 @@ def create_pdf_tickets_for_holder(order):
     Create tickets and invoices for the holders of an order.
     :param order: The order for which to create tickets for.
     """
+    starts_at = convert_to_user_locale(
+        order.user.email,
+        date_time=order.event.starts_at,
+        tz=order.event.timezone
+    )
+    ends_at = convert_to_user_locale(
+        order.user.email,
+        date_time=order.event.ends_at,
+        tz=order.event.timezone
+    )
+
     if order.status == 'completed' or order.status == 'placed':
         pdf = create_save_pdf(
-            render_template('pdf/ticket_purchaser.html', order=order),
+            render_template(
+                'pdf/ticket_purchaser.html',
+                order=order,
+                starts_at=starts_at,
+                ends_at=ends_at
+            ),
             UPLOAD_PATHS['pdf']['tickets_all'],
             dir_path='/static/uploads/pdf/tickets/',
             identifier=order.identifier,
@@ -89,9 +106,25 @@ def create_pdf_tickets_for_holder(order):
         order.tickets_pdf_url = pdf
 
         for holder in order.ticket_holders:
+            starts_at = convert_to_user_locale(
+                holder.email,
+                date_time=order.event.starts_at,
+                tz=order.event.timezone
+            )
+            ends_at = convert_to_user_locale(
+                holder.email,
+                date_time=order.event.ends_at,
+                tz=order.event.timezone
+            )
+
             # create attendee pdf for every ticket holder
             pdf = create_save_pdf(
-                render_template('pdf/ticket_attendee.html', order=order, holder=holder),
+                render_template(
+                    'pdf/ticket_attendee.html',
+                    order=order,
+                    starts_at=starts_at,
+                    ends_at=ends_at,
+                    holder=holder),
                 UPLOAD_PATHS['pdf']['tickets_all'],
                 dir_path='/static/uploads/pdf/tickets/',
                 identifier=order.identifier,
@@ -125,8 +158,14 @@ def create_pdf_tickets_for_holder(order):
                 event=order.event,
                 tax=order.event.tax,
                 order_tickets=order_tickets,
-                event_starts_at=order.event.starts_at_tz.strftime('%d %B %Y'),
-                created_at=order.created_at.strftime('%d %B %Y'),
+                event_starts_at=convert_to_user_locale(
+                    order.user.email,
+                    date=order.event.starts_at_tz,
+                ),
+                created_at=convert_to_user_locale(
+                    order.user.email,
+                    date=order.created_at,
+                ),
                 admin_info=admin_info,
                 order_amount=order_amount
             ),


Test patch: