Skip to content

Commit

Permalink
G2P-2411 G2P-2381 Fixed display name and resolved odoo server error d…
Browse files Browse the repository at this point in the history
…uring entitlement approval
  • Loading branch information
shivamg9 committed May 28, 2024
1 parent 5e55b64 commit 0031cda
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 86 deletions.
2 changes: 1 addition & 1 deletion src/openg2p_portal_api/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ class Initializer(Initializer):
def initialize(self, **kwargs):
super().initialize()
# Initialize all Services, Controllers, any utils here.
PartnerService()
MembershipService()
ProgramService()
FormService()
PartnerService()

DiscoveryController().post_init()
ProgramController().post_init()
Expand Down
23 changes: 11 additions & 12 deletions src/openg2p_portal_api/controllers/auth_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from openg2p_fastapi_auth.controllers.auth_controller import AuthController
from openg2p_fastapi_auth.models.orm.login_provider import LoginProvider
from openg2p_fastapi_common.errors.http_exceptions import UnauthorizedError
from sqlalchemy.exc import IntegrityError

from ..config import Settings
from ..dependencies import JwtBearerAuth
Expand All @@ -16,7 +17,7 @@
PartnerPhoneNoORM,
)
from ..models.orm.reg_id_orm import RegIDORM, RegIDTypeORM
from ..models.profile import Profile
from ..models.profile import GetProfile, UpdateProfile
from ..services.partner_service import PartnerService

_config = Settings.get_config()
Expand All @@ -37,13 +38,12 @@ def __init__(self, **kwargs):
self.router.add_api_route(
"/profile",
self.get_profile,
responses={200: {"model": Profile}},
responses={200: {"model": GetProfile}},
methods=["GET"],
)
self.router.add_api_route(
"/profile",
self.update_profile,
responses={200: {"model": Profile}},
methods=["PUT"],
)

Expand Down Expand Up @@ -125,7 +125,7 @@ async def get_profile(
}
)

return Profile(
return GetProfile(
id=partner_data.id,
ids=partner_ids,
email=partner_data.email,
Expand All @@ -142,7 +142,7 @@ async def get_profile(

async def update_profile(
self,
userdata: Profile,
userdata: UpdateProfile,
auth: Annotated[AuthCredentials, Depends(JwtBearerAuth())],
):
"""
Expand All @@ -158,14 +158,13 @@ async def update_profile(
Confirmation or updated profile data after the update.
"""
if userdata.id is None or userdata.id != auth.partner_id:
raise UnauthorizedError(
message="Unauthorized. Partner Not Found in Registry."
try:
await self.partner_service.update_partner_info(
auth.partner_id, userdata.model_dump(exclude={"id"})
)

return await self.partner_service.update_partner_data(
auth.partner_id, userdata.model_dump(exclude={"id"})
)
except IntegrityError:
return "Could not add to registrant to program!!"
return "Updated the partner info"

async def get_login_providers_db(self) -> List[LoginProvider]:
return [
Expand Down
2 changes: 1 addition & 1 deletion src/openg2p_portal_api/models/orm/partner_orm.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class PartnerORM(BaseORMModelWithId):
birth_place: Mapped[str] = mapped_column()
phone: Mapped[str] = mapped_column()
company_id: Mapped[Optional[int]] = mapped_column()
registration_date: Mapped[date] = mapped_column(Date())
registration_date: Mapped[date] = mapped_column(Date(), default=date.today)
reg_ids: Mapped[Optional[List[RegIDORM]]] = relationship(back_populates="partner")

create_date: Mapped[datetime] = mapped_column(DateTime(), default=datetime.utcnow)
Expand Down
17 changes: 11 additions & 6 deletions src/openg2p_portal_api/models/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,22 @@ class PhoneNumber(BaseModel):


class Profile(BaseModel):
model_config = ConfigDict()

id: Optional[int] = None
ids: List[RegistrantID]
ids: Optional[List[RegistrantID]] = None
email: Optional[str] = None
gender: Optional[str] = None
# address: Optional[dict] = {}
bank_ids: List[BankDetails]
bank_ids: Optional[List[BankDetails]] = None
addl_name: Optional[str] = None
given_name: Optional[str] = None
family_name: Optional[str] = None
birthdate: Optional[date] = None
phone_numbers: List[PhoneNumber]
phone_numbers: Optional[List[PhoneNumber]] = None
birth_place: Optional[str] = None


class UpdateProfile(Profile):
pass


class GetProfile(Profile):
id: Optional[int] = None
57 changes: 14 additions & 43 deletions src/openg2p_portal_api/services/form_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,24 @@

from openg2p_fastapi_common.context import dbengine
from openg2p_fastapi_common.service import BaseService
from sqlalchemy import text
from sqlalchemy.exc import IntegrityError
from sqlalchemy.ext.asyncio import async_sessionmaker

from ..context import partner_fields_cache
from ..models.form import ProgramForm
from ..models.orm.partner_orm import PartnerORM
from ..models.orm.program_orm import ProgramORM
from ..models.orm.program_registrant_info_orm import (
ProgramRegistrantInfoDraftORM,
ProgramRegistrantInfoORM,
)
from .membership_service import MembershipService
from .partner_service import PartnerService


class FormService(BaseService):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.membership_service = MembershipService.get_component()
self.partner_service = PartnerService.get_component()

async def get_program_form(self, program_id: int, registrant_id: int):
response_dict = {}
Expand Down Expand Up @@ -107,17 +106,12 @@ async def submit_application_form(
application_id = self._compute_application_id()
create_date = datetime.now()

partner_info = await PartnerORM.get_partner_data(registrant_id)
if partner_info:
updated_partner_info = await self.update_partner_info(
session, partner_info, form_data.program_registrant_info
)

cleaned_program_registrant_info = self.clean_program_registrant_info(
form_data.program_registrant_info, updated_partner_info
)
else:
cleaned_program_registrant_info = form_data.program_registrant_info
updated_partner_info = await self.partner_service.update_partner_info(
registrant_id, form_data.program_registrant_info, session=session
)
cleaned_program_registrant_info = self.clean_program_registrant_info(
form_data.program_registrant_info, updated_partner_info
)

program_registrant_info = ProgramRegistrantInfoORM(
program_id=program_id,
Expand Down Expand Up @@ -151,38 +145,15 @@ def _compute_application_id(self):
random_number = str(random.randint(1, 100000))
return d + m + y + random_number.zfill(5)

async def update_partner_info(self, session, partner_info, program_registrant_info):
# Update partner_info with fields from program_registrant_info
updated_fields = {}
partner_fields = await self.get_partner_fields()
for key, value in program_registrant_info.items():
# if hasattr(partner_info, key) and getattr(partner_info, key) != value:
if key in partner_fields:
updated_fields[key] = value
if updated_fields:
set_clause = ", ".join(
[f"{key} = '{value}'" for key, value in updated_fields.items()]
)
await session.execute(
text(
f"UPDATE {PartnerORM.__tablename__} SET {set_clause} WHERE id='{partner_info.id}'"
)
)
return updated_fields

def clean_program_registrant_info(self, program_registrant_info, updated_fields):
def clean_program_registrant_info(
self, program_registrant_info, updated_partner_fields
):
# Remove updated fields from program_registrant_info
if not updated_partner_fields:
return program_registrant_info
cleaned_info = {
key: value
for key, value in program_registrant_info.items()
if key not in updated_fields
if key not in updated_partner_fields
}
return cleaned_info

async def get_partner_fields(self):
partner_field = partner_fields_cache.get()
if partner_field:
return partner_field
partner_field = await PartnerORM.get_partner_fields()
partner_fields_cache.set(partner_field)
return partner_field
75 changes: 52 additions & 23 deletions src/openg2p_portal_api/services/partner_service.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import logging
from datetime import datetime

import orjson
from openg2p_fastapi_common.context import dbengine
from openg2p_fastapi_common.errors.http_exceptions import InternalServerError
from openg2p_fastapi_common.service import BaseService
from sqlalchemy import text
from sqlalchemy.exc import IntegrityError
from sqlalchemy.ext.asyncio import async_sessionmaker

from ..config import Settings
from ..context import partner_fields_cache
from ..models.orm.auth_oauth_provider import AuthOauthProviderORM
from ..models.orm.partner_orm import PartnerORM, PartnerPhoneNoORM
from ..models.orm.reg_id_orm import RegIDORM

_config = Settings.get_config(strict=False)
_logger = logging.getLogger(_config.logging_default_logger_name)


class PartnerService(BaseService):
Expand Down Expand Up @@ -74,7 +78,9 @@ async def check_and_create_partner(
)
)

async_session_maker = async_sessionmaker(dbengine.get())
async_session_maker = async_sessionmaker(
dbengine.get(), expire_on_commit=False
)
async with async_session_maker() as session:
try:
partner = PartnerORM(**partner_dict)
Expand All @@ -92,34 +98,41 @@ async def check_and_create_partner(
session.add(phone_number)

await session.commit()
await self.create_partner_add_display_name(partner, session)
except IntegrityError as e:
raise InternalServerError(
message=f"Could not create partner. {repr(e)}",
) from e

async def update_partner_data(self, id, data: dict):
async_session_maker = async_sessionmaker(dbengine.get())
async with async_session_maker() as session:
partner = await PartnerORM.get_partner_data(id)
if partner:
for field_name in partner.__dict__:
if field_name in data:
setattr(partner, field_name, data[field_name])

partner.name = (
data["given_name"]
+ " "
+ data["family_name"]
+ " "
+ data["addl_name"]
async def update_partner_info(self, partner_id, data, session=None):
# Update partner_info with fields from program_registrant_info
is_create_session = False
if not session:
session = async_sessionmaker(dbengine.get())()
is_create_session = True
updated_fields = {}
partner_fields = await self.get_partner_fields()
for key, value in data.items():
# if hasattr(partner_info, key) and getattr(partner_info, key) != value:
# TODO: handle deleted values

if key in partner_fields and data.get(key, None):
updated_fields[key] = value
# TODO: handle the name change
# name=self.create_partner_process_name(data["family_name"],data["given_name"],data["addl_name"])
if updated_fields:
set_clause = ", ".join(
[f"{key} = '{value}'" for key, value in updated_fields.items()]
)
await session.execute(
text(
f"UPDATE {PartnerORM.__tablename__} SET {set_clause} WHERE id='{partner_id}'"
)

try:
session.add(partner)
await session.commit()
except IntegrityError:
return "Could not add to registrant to program!!"
return "Updated the partner info"
)
await session.commit()
if is_create_session:
await session.close()
return updated_fields

def create_partner_process_gender(self, gender):
return gender.capitalize()
Expand Down Expand Up @@ -157,3 +170,19 @@ def create_partner_process_other_fields(self, validation: dict, mapping: str):
else:
res[key] = value
return res

async def create_partner_add_display_name(self, partner, session):
try:
await self.update_partner_info(
partner.id, {"display_name": partner.name}, session=session
)
except IntegrityError:
_logger.warning("Failed to insert display name. Odoo version maybe 17.0")

async def get_partner_fields(self):
partner_field = partner_fields_cache.get()
if partner_field:
return partner_field
partner_field = await PartnerORM.get_partner_fields()
partner_fields_cache.set(partner_field)
return partner_field

0 comments on commit 0031cda

Please sign in to comment.