Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[To Main] DESENG-515: Multi-language - Create event, subcribe_item, poll, timeline widget translation tables & API routes #2421

Merged
merged 21 commits into from
Mar 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
1e49d85
DESENG-515: Models and Test
ratheesh-aot Mar 11, 2024
db7fbc3
Merge remote-tracking branch 'upstream/main' into DESENG-515-MultiLan…
ratheesh-aot Mar 11, 2024
75285f6
DESENG-515: Correcting migration file
ratheesh-aot Mar 11, 2024
dfd795e
DESENG-515: Updating function name
ratheesh-aot Mar 11, 2024
55e4ce3
DESENG-515 : Added API, Service and Tests for Poll answer translation
ratheesh-aot Mar 11, 2024
3479b16
DESENG-515: Poll answer translation api and test
ratheesh-aot Mar 12, 2024
c9f8e41
DESENG-515 : Event item translation api and test
ratheesh-aot Mar 12, 2024
d9024d9
Merge pull request #2414 from ratheesh-aot/DESENG-515-MultiLangEvent
ratheesh-aot Mar 13, 2024
1aa7380
DESENG-515: Fixing comments and tests
ratheesh-aot Mar 13, 2024
9d2cab9
DESENG-515: Subscribe item and Timeline event translation API
ratheesh-aot Mar 14, 2024
e891b83
DESENG-515: Fixing lint findings
ratheesh-aot Mar 14, 2024
bd05c9a
DESENG-515: Fixing review comments
ratheesh-aot Mar 14, 2024
1ef48d7
Merge pull request #2416 from ratheesh-aot/DESENG-515-MultiLangEvent
ratheesh-aot Mar 14, 2024
7ad17b2
Merge remote-tracking branch 'upstream/main' into DESENG-515-MultiLan…
ratheesh-aot Mar 15, 2024
b46281a
DESENG-515: Fixed migration version based on main
ratheesh-aot Mar 15, 2024
58469bc
DESENG-515: Updated changelog
ratheesh-aot Mar 15, 2024
1c946c4
Merge pull request #2418 from ratheesh-aot/DESENG-515-MultiLangEvent
ratheesh-aot Mar 15, 2024
1045b42
DESENG-515: Fixing code cov comments
ratheesh-aot Mar 15, 2024
09e929a
Merge remote-tracking branch 'origin/DESENG-515-MultiLangEvent' into …
ratheesh-aot Mar 15, 2024
51f15e7
DESENG-515: Isort fix
ratheesh-aot Mar 15, 2024
4b8c52c
Merge remote-tracking branch 'origin/DESENG-515-MultiLangEvent' into …
ratheesh-aot Mar 15, 2024
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
11 changes: 10 additions & 1 deletion CHANGELOG.MD
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
## March 15, 2024

- **Task**: Multi-language - Create event, subcribe_item, poll, timeline widget translation tables & API routes [DESENG-515](https://apps.itsm.gov.bc.ca/jira/browse/DESENG-515)
- Added Poll answer translation API.
- Added Timeline Event translation API.
- Added Subscribe Item translation API.
- Added Event item translation API
- Added Unit tests.

## March 08, 2024

- **Task**Multi-language - Create engagement translation table & API routes [DESENG-510](https://apps.itsm.gov.bc.ca/jira/browse/DESENG-510)
- **Task**: Multi-language - Create engagement translation table & API routes [DESENG-510](https://apps.itsm.gov.bc.ca/jira/browse/DESENG-510)
- Added Engagement translation model.
- Added Engagement translation API.
- Added Unit tests.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
"""event_subscribe_poll_timeline_widget_translation

Revision ID: f3842579261c
Revises: 274a2774607b
Create Date: 2024-03-08 10:59:03.021386

"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = 'f3842579261c'
down_revision = 'c4f7189494ed'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('event_item_translation',
sa.Column('created_date', sa.DateTime(), nullable=False),
sa.Column('updated_date', sa.DateTime(), nullable=True),
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('language_id', sa.Integer(), nullable=False),
sa.Column('event_item_id', sa.Integer(), nullable=False),
sa.Column('description', sa.String(length=500), nullable=True),
sa.Column('location_name', sa.String(length=50), nullable=True),
sa.Column('location_address', sa.String(length=100), nullable=True, comment='The address of the location'),
sa.Column('url', sa.String(length=500), nullable=True),
sa.Column('url_label', sa.String(length=100), nullable=True, comment='Label to show for href links'),
sa.Column('created_by', sa.String(length=50), nullable=True),
sa.Column('updated_by', sa.String(length=50), nullable=True),
sa.ForeignKeyConstraint(['event_item_id'], ['event_item.id'], ondelete='CASCADE'),
sa.ForeignKeyConstraint(['language_id'], ['language.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('event_item_id', 'language_id', name='_event_item_language_uc')
)
op.create_table('poll_answer_translation',
sa.Column('created_date', sa.DateTime(), nullable=False),
sa.Column('updated_date', sa.DateTime(), nullable=True),
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('poll_answer_id', sa.Integer(), nullable=False),
sa.Column('language_id', sa.Integer(), nullable=False),
sa.Column('answer_text', sa.String(length=255), nullable=False),
sa.Column('created_by', sa.String(length=50), nullable=True),
sa.Column('updated_by', sa.String(length=50), nullable=True),
sa.ForeignKeyConstraint(['language_id'], ['language.id'], ),
sa.ForeignKeyConstraint(['poll_answer_id'], ['poll_answers.id'], ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('poll_answer_id', 'language_id', name='_poll_answer_language_uc')
)
op.create_table('subscribe_item_translation',
sa.Column('created_date', sa.DateTime(), nullable=False),
sa.Column('updated_date', sa.DateTime(), nullable=True),
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('language_id', sa.Integer(), nullable=False),
sa.Column('subscribe_item_id', sa.Integer(), nullable=False),
sa.Column('description', sa.String(length=500), nullable=True),
sa.Column('rich_description', sa.Text(), nullable=True),
sa.Column('call_to_action_text', sa.String(length=25), nullable=True),
sa.Column('created_by', sa.String(length=50), nullable=True),
sa.Column('updated_by', sa.String(length=50), nullable=True),
sa.ForeignKeyConstraint(['language_id'], ['language.id'], ),
sa.ForeignKeyConstraint(['subscribe_item_id'], ['subscribe_item.id'], ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('subscribe_item_id', 'language_id', name='_subscribe_item_language_uc')
)
op.create_table('timeline_event_translation',
sa.Column('created_date', sa.DateTime(), nullable=False),
sa.Column('updated_date', sa.DateTime(), nullable=True),
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('language_id', sa.Integer(), nullable=False),
sa.Column('timeline_event_id', sa.Integer(), nullable=False),
sa.Column('description', sa.Text(), nullable=True),
sa.Column('time', sa.String(length=255), nullable=True),
sa.Column('created_by', sa.String(length=50), nullable=True),
sa.Column('updated_by', sa.String(length=50), nullable=True),
sa.ForeignKeyConstraint(['language_id'], ['language.id'], ),
sa.ForeignKeyConstraint(['timeline_event_id'], ['timeline_event.id'], ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('timeline_event_id', 'language_id', name='_timeline_event_language_uc')
)
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('timeline_event_translation')
op.drop_table('subscribe_item_translation')
op.drop_table('poll_answer_translation')
op.drop_table('event_item_translation')
# ### end Alembic commands ###
4 changes: 4 additions & 0 deletions met-api/src/met_api/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,8 @@
from .language import Language
from .widget_translation import WidgetTranslation
from .survey_translation import SurveyTranslation
from .event_item_translation import EventItemTranslation
from .poll_answer_translation import PollAnswerTranslation
from .timeline_event_translation import TimelineEventTranslation
from .subscribe_item_translation import SubscribeItemTranslation
from .engagement_translation import EngagementTranslation
123 changes: 123 additions & 0 deletions met-api/src/met_api/models/event_item_translation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
"""Event item translation model class.

Manages the translations for Event Items.
"""

from __future__ import annotations

from sqlalchemy import UniqueConstraint
from sqlalchemy.sql.schema import ForeignKey

from .base_model import BaseModel
from .db import db


class EventItemTranslation(BaseModel):
"""Event Items Translation table."""

__tablename__ = 'event_item_translation'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
language_id = db.Column(
db.Integer, ForeignKey('language.id'), nullable=False
)
event_item_id = db.Column(
db.Integer,
ForeignKey('event_item.id', ondelete='CASCADE'),
nullable=False,
)
description = db.Column(db.String(500))
location_name = db.Column(db.String(50), nullable=True)
location_address = db.Column(
db.String(100), comment='The address of the location', nullable=True
)
url = db.Column(db.String(500))
url_label = db.Column(
db.String(100), comment='Label to show for href links'
)

# An Event item has only one version in a particular language
__table_args__ = (
UniqueConstraint(
'event_item_id',
'language_id',
name='_event_item_language_uc',
),
)

@staticmethod
def get_by_item_and_language(event_item_id=None, language_id=None):
"""
Get event item translation by item ID and language ID.

:param event_item_id (int): ID of the event item
:param language_id (int): ID of the language
:return: list: List of EventItemTranslation objects
"""
query = EventItemTranslation.query
if event_item_id is not None:
query = query.filter_by(event_item_id=event_item_id)
if language_id is not None:
query = query.filter_by(language_id=language_id)

event_item_translation_records = query.all()
return event_item_translation_records

@classmethod
def create_event_item_translation(cls, data):
"""
Insert a new EventItemTranslation record.

:param data: Dictionary containing the fields for EventItemTranslation
:return: EventItemTranslation instance
"""
event_item_translation = EventItemTranslation(
event_item_id=data['event_item_id'],
language_id=data['language_id'],
description=data.get(
'description'
),
location_name=data.get(
'location_name'
),
location_address=data.get(
'location_address'
),
url=data.get(
'url'
),
url_label=data.get(
'url_label'
)
)
event_item_translation.save()
return event_item_translation

@classmethod
def update_event_item_translation(cls, translation_id, data):
"""
Update an existing EventItemTranslation record.

:param translation_id: ID of the EventItemTranslation to update
:param data: Dictionary of fields to update
:return: Updated EventItemTranslation instance
"""
event_item_translation = cls.find_by_id(translation_id)
if event_item_translation:
for key, value in data.items():
setattr(event_item_translation, key, value)
event_item_translation.save()
return event_item_translation

@classmethod
def delete_event_item_translation(cls, translation_id):
"""
Delete an EventItemTranslation record.

:param translation_id: ID of the EventItemTranslation to delete
:return: None
"""
event_item_translation = cls.find_by_id(translation_id)
if event_item_translation:
event_item_translation.delete()
return True
return False
104 changes: 104 additions & 0 deletions met-api/src/met_api/models/poll_answer_translation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
"""
PollAnswers translation model class.

Manages the translation of Poll answers
"""

from __future__ import annotations

from sqlalchemy.sql.schema import ForeignKey
from sqlalchemy import UniqueConstraint
from .base_model import BaseModel
from .db import db


class PollAnswerTranslation(BaseModel):
"""Definition of the PollAnswerTranslation entity."""

__tablename__ = 'poll_answer_translation'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
poll_answer_id = db.Column(
db.Integer,
ForeignKey('poll_answers.id', ondelete='CASCADE'),
nullable=False,
)
language_id = db.Column(
db.Integer, ForeignKey('language.id'), nullable=False
)
answer_text = db.Column(db.String(255), nullable=False)

# A poll answer has only one version in a particular language
__table_args__ = (
UniqueConstraint(
'poll_answer_id', 'language_id', name='_poll_answer_language_uc'
),
)

@staticmethod
def get_by_answer_and_language(
poll_answer_id=None, language_id=None
):
"""
Get poll answer translation by answer ID and language ID.

:param poll_answer_id (int): ID of the poll answer
:param language_id (int): ID of the language
:return: list: List of PollAnswerTranslation objects
"""
query = PollAnswerTranslation.query
if poll_answer_id is not None:
query = query.filter_by(poll_answer_id=poll_answer_id)
if language_id is not None:
query = query.filter_by(language_id=language_id)

poll_answer_translation_records = query.all()
return poll_answer_translation_records

@classmethod
def create_poll_answer_translation(cls, data):
"""
Insert a new PollAnswerTranslation record.

:param data: Dictionary containing the fields for PollAnswerTranslation
:return: PollAnswerTranslation instance
"""
poll_answer_translation = PollAnswerTranslation(
poll_answer_id=data['poll_answer_id'],
language_id=data['language_id'],
answer_text=data.get(
'answer_text'
), # Returns `None` if 'answer_text' is not in `data` as its optional
)

poll_answer_translation.save()
return poll_answer_translation

@classmethod
def update_poll_answer_translation(cls, translation_id, data):
"""
Update an existing PollAnswerTranslation record.

:param translation_id: ID of the PollAnswerTranslation to update
:param data: Dictionary of fields to update
:return: Updated PollAnswerTranslation instance
"""
poll_answer_translation = cls.find_by_id(translation_id)
if poll_answer_translation:
for key, value in data.items():
setattr(poll_answer_translation, key, value)
poll_answer_translation.save()
return poll_answer_translation

@classmethod
def delete_poll_answer_translation(cls, translation_id):
"""
Delete a PollAnswerTranslation record.

:param translation_id: ID of the PollAnswerTranslation to delete
:return: None
"""
poll_answer_translation = cls.find_by_id(translation_id)
if poll_answer_translation:
poll_answer_translation.delete()
return True
return False
Loading
Loading