Hp137 commited on
Commit
310c607
·
1 Parent(s): 198a2e8

fix:payslip bug

Browse files
queries/Query.sql ADDED
File without changes
src/payslip/router.py CHANGED
@@ -39,39 +39,40 @@ async def gmail_connect_url(user_id: uuid.UUID):
39
  return {"auth_url": f"{settings.AUTH_BASE}?{urlencode(params)}"}
40
 
41
 
42
- @router.get("/gmail/callback", response_class=HTMLResponse)
43
  async def gmail_callback(
44
- code: str,
45
- state: str,
46
- session: AsyncSession = Depends(get_async_session),
47
  ):
48
- """
49
- Google redirects here with ?code & ?state=user_id.
50
- We:
51
- - exchange code for tokens
52
- - verify the Google email matches our user's email
53
- - store refresh_token into payslip_requests table
54
- """
55
  user_id = uuid.UUID(state)
56
  user = await session.get(Users, user_id)
57
 
58
  if not user:
59
- raise HTTPException(400, "User not found for given state")
 
 
60
 
61
- token_data = exchange_code_for_tokens(code)
62
- google_email = extract_email_from_id_token(token_data["id_token"])
 
 
 
 
 
63
 
 
64
  if google_email.lower() != user.email_id.lower():
65
- raise HTTPException(
66
- 400,
67
- f"Please select your registered email: {user.email_id}",
68
  )
69
 
70
  refresh_token = token_data.get("refresh_token")
71
  if not refresh_token:
72
- raise HTTPException(400, "No refresh token received from Google")
 
 
73
 
74
- # Check if this user already has any payslip row
75
  q = (
76
  select(PayslipRequest)
77
  .where(PayslipRequest.user_id == user_id)
@@ -80,29 +81,23 @@ async def gmail_callback(
80
  existing = (await session.execute(q)).scalar_one_or_none()
81
 
82
  if existing:
83
- # Update the latest row with new refresh token
84
  existing.refresh_token = refresh_token
85
- # Do NOT change requested_at or status here;
86
- # this endpoint is only for (re)connecting Gmail.
87
  session.add(existing)
88
  else:
89
- # First time ever connecting Gmail -> create a "connection row"
90
- connection_row = PayslipRequest(
91
- user_id=user_id,
92
- refresh_token=refresh_token,
93
- status=PayslipStatus.PENDING, # not an actual request yet
94
- # requested_at default is now; one_request_per_day ignores PENDING rows
95
  )
96
- session.add(connection_row)
97
 
98
  await session.commit()
99
 
100
- return """
101
- <html><body>
102
- <h1>Gmail Connected Successfully ✔</h1>
103
- <p>You may now request your payslip.</p>
104
- </body></html>
105
- """
106
 
107
 
108
  @router.post("/request")
 
39
  return {"auth_url": f"{settings.AUTH_BASE}?{urlencode(params)}"}
40
 
41
 
42
+ @router.get("/gmail/callback")
43
  async def gmail_callback(
44
+ code: str, state: str, session: AsyncSession = Depends(get_async_session)
 
 
45
  ):
46
+ from fastapi.responses import RedirectResponse
47
+
 
 
 
 
 
48
  user_id = uuid.UUID(state)
49
  user = await session.get(Users, user_id)
50
 
51
  if not user:
52
+ return RedirectResponse(
53
+ "yuvabe://gmail/callback?success=false&error=user_not_found&message=No such user exists"
54
+ )
55
 
56
+ try:
57
+ token_data = exchange_code_for_tokens(code)
58
+ google_email = extract_email_from_id_token(token_data["id_token"])
59
+ except Exception:
60
+ return RedirectResponse(
61
+ "yuvabe://gmail/callback?success=false&error=invalid_code&message=OAuth code exchange failed"
62
+ )
63
 
64
+ # --- GMAIL MISMATCH ERROR ---
65
  if google_email.lower() != user.email_id.lower():
66
+ return RedirectResponse(
67
+ "yuvabe://gmail/callback?success=false&error=email_mismatch&message=Google account does not match registered email"
 
68
  )
69
 
70
  refresh_token = token_data.get("refresh_token")
71
  if not refresh_token:
72
+ return RedirectResponse(
73
+ "yuvabe://gmail/callback?success=false&error=no_refresh_token&message=No refresh token returned from Google"
74
+ )
75
 
 
76
  q = (
77
  select(PayslipRequest)
78
  .where(PayslipRequest.user_id == user_id)
 
81
  existing = (await session.execute(q)).scalar_one_or_none()
82
 
83
  if existing:
 
84
  existing.refresh_token = refresh_token
 
 
85
  session.add(existing)
86
  else:
87
+ session.add(
88
+ PayslipRequest(
89
+ user_id=user_id,
90
+ refresh_token=refresh_token,
91
+ status=PayslipStatus.PENDING,
92
+ )
93
  )
 
94
 
95
  await session.commit()
96
 
97
+ # --- SUCCESS MESSAGE ---
98
+ return RedirectResponse(
99
+ "yuvabe://gmail/callback?success=true&message=gmail_connected_successfully"
100
+ )
 
 
101
 
102
 
103
  @router.post("/request")
src/payslip/utils.py CHANGED
@@ -35,9 +35,10 @@ def _parse_month(month_str: str) -> date:
35
 
36
  def validate_join_date(join_date: Optional[str], period_start: date):
37
  if not join_date:
38
- return
 
 
39
 
40
- join = datetime.strptime(join_date, "%Y-%m-%d").date()
41
  if period_start < join:
42
  raise HTTPException(
43
  400,
 
35
 
36
  def validate_join_date(join_date: Optional[str], period_start: date):
37
  if not join_date:
38
+ join = date(2020, 4, 1)
39
+ else:
40
+ join = datetime.strptime(join_date, "%Y-%m-%d").date()
41
 
 
42
  if period_start < join:
43
  raise HTTPException(
44
  400,
src/profile/router.py CHANGED
@@ -505,6 +505,7 @@ async def get_profile_details(
505
  "team_name": team.name,
506
  "mentor_name": ", ".join(mentor_names),
507
  "mentor_email": ", ".join(mentor_emails),
 
508
  },
509
  )
510
 
 
505
  "team_name": team.name,
506
  "mentor_name": ", ".join(mentor_names),
507
  "mentor_email": ", ".join(mentor_emails),
508
+ "join_date": user.join_date,
509
  },
510
  )
511