@@ -139,13 +139,12 @@ def create_invitation(invite_data):
139139 account_id = invite_data .get ('account_id' )
140140 role_name = invite_data .get ('role_name' )
141141 proponent_id = invite_data .get ('proponent_id' )
142- project_ids = invite_data .get ('project_ids' )
143142
144143 role = InvitationService ._validate_fetch_role (role_name )
145144
146145 with session_scope () as session :
147146 account = InvitationService ._get_or_create_account (
148- account_id , proponent_id , project_ids , session )
147+ account_id , proponent_id , session )
149148 session .flush ()
150149
151150 token = InvitationService .generate_uuid_token ()
@@ -200,6 +199,10 @@ def accept_invitation(token, payload):
200199 account_user = InvitationService ._create_account_user (
201200 user .id , invitation .account_id , payload , session )
202201
202+ # Create account projects if they don't exist (handles concurrent invitations gracefully)
203+ InvitationService ._create_account_projects (
204+ invitation .account_id , invitation .project_ids , session )
205+
203206 account_projects = AccountProjectModel .get_all_in_project_ids (invitation .project_ids )
204207 roles = []
205208 for account_project in account_projects :
@@ -260,13 +263,13 @@ def _validate_invitation_access(invitation):
260263 return True
261264
262265 @staticmethod
263- def _get_or_create_account (account_id , proponent_id , project_ids , session ):
266+ def _get_or_create_account (account_id , proponent_id , session ):
264267 """Retrieve or create an account based on proponent_id or account_id."""
265268 if account_id :
266269 return InvitationService ._get_account_by_id (account_id )
267270
268271 if proponent_id :
269- return InvitationService ._get_or_create_account_by_proponent (proponent_id , project_ids , session )
272+ return InvitationService ._get_or_create_account_by_proponent (proponent_id , session )
270273
271274 raise ResourceNotFoundError ("No valid account found for the provided data." )
272275
@@ -281,14 +284,12 @@ def _get_proponent_by_id(proponent_id):
281284 return ProponentModel .find_by_id (proponent_id )
282285
283286 @staticmethod
284- def _get_or_create_account_by_proponent (proponent_id , project_ids , session ):
287+ def _get_or_create_account_by_proponent (proponent_id , session ):
285288 """Retrieve or create an account by proponent_id."""
286289 account = AccountModel .get_by_proponent_id (proponent_id )
287290 if not account :
288291 account_data = {'proponent_id' : proponent_id }
289292 account = AccountModel .create_account (account_data , session )
290- InvitationService ._create_account_projects (
291- account .id , project_ids , session )
292293 return account
293294
294295 @staticmethod
@@ -313,7 +314,7 @@ def _create_invitation_record(invite_data, role, account, token, session):
313314 role_id = role .id ,
314315 package_ids = invite_data .get ('package_ids' ),
315316 original_package_ids = invite_data .get ('original_package_ids' ),
316- expiry_date = datetime .datetime .utcnow ( ) + datetime .timedelta (days = expiry_days ),
317+ expiry_date = datetime .datetime .now ( datetime . timezone . utc ) + datetime .timedelta (days = expiry_days ),
317318 is_first_time = is_first_time
318319 )
319320 session .add (invitation )
@@ -396,7 +397,12 @@ def get_valid_invitation(token):
396397 if invitation .status != InvitationStatus .PENDING .value :
397398 return {"error" : "Invitation is not valid" }, False
398399
399- if invitation .expiry_date < datetime .datetime .utcnow ():
400+ # Ensure expiry_date is timezone-aware for comparison
401+ expiry_date = invitation .expiry_date
402+ if expiry_date .tzinfo is None :
403+ expiry_date = expiry_date .replace (tzinfo = datetime .timezone .utc )
404+
405+ if expiry_date < datetime .datetime .now (datetime .timezone .utc ):
400406 return {"error" : "Invitation has expired" }, False
401407
402408 # Update proponent status
@@ -428,7 +434,7 @@ def resend_invitation(token):
428434 InvitationService ._check_action_authorized (invitation .project_ids )
429435
430436 # Extend expiry date by 1 week from current date
431- invitation .expiry_date = datetime .datetime .utcnow ( ) + datetime .timedelta (weeks = 1 )
437+ invitation .expiry_date = datetime .datetime .now ( datetime . timezone . utc ) + datetime .timedelta (weeks = 1 )
432438
433439 InvitationService ._create_email_queue_record (
434440 invitation .id , session )
0 commit comments