Mbonea commited on
Commit
6a3e1a1
·
1 Parent(s): 4aa1d81
App/Android/Android.py CHANGED
@@ -49,6 +49,16 @@ class AndroidClient:
49
  response = await self.client.post(f"/logout/{phone}")
50
  return APIResponse(**response.json())
51
 
 
 
 
 
 
 
 
 
 
 
52
  @require_base_url
53
  async def get_active_users(self) -> APIResponse:
54
  """Retrieve all active users."""
@@ -57,8 +67,15 @@ class AndroidClient:
57
  return APIResponse(**response.json())
58
 
59
  @require_base_url
60
- async def disable_user(self, request: SetUserStatusRequest) -> APIResponse:
61
  """Enable or disable a user."""
 
 
 
 
 
 
 
62
  path = f"/users/{request.phone}/disable"
63
  response = await self.client.post(path, json=None)
64
  return APIResponse(**response.json())
@@ -112,3 +129,9 @@ class AndroidClient:
112
  await self.enable_user(request=request)
113
  # Replace this with actual API call logic
114
  return {"status": "success", "message": "User activated."}
 
 
 
 
 
 
 
49
  response = await self.client.post(f"/logout/{phone}")
50
  return APIResponse(**response.json())
51
 
52
+ @require_base_url
53
+ async def is_user_active(self, phone_number):
54
+ """Retrieve all active users."""
55
+ response = await self.client.get("/users/active")
56
+ active_users = response.json()["active_users"]
57
+
58
+ for user in active_users:
59
+ if phone_number == user["phone"]:
60
+ return True
61
+
62
  @require_base_url
63
  async def get_active_users(self) -> APIResponse:
64
  """Retrieve all active users."""
 
67
  return APIResponse(**response.json())
68
 
69
  @require_base_url
70
+ async def remove_session(self, phone_number) -> APIResponse:
71
  """Enable or disable a user."""
72
+ path = f"/users/{phone_number}/remove-session"
73
+ response = await self.client.post(path, json=None)
74
+ return APIResponse(**response.json())
75
+
76
+ @require_base_url
77
+ async def disable_user(self, request: SetUserStatusRequest) -> APIResponse:
78
+ """disable a user."""
79
  path = f"/users/{request.phone}/disable"
80
  response = await self.client.post(path, json=None)
81
  return APIResponse(**response.json())
 
129
  await self.enable_user(request=request)
130
  # Replace this with actual API call logic
131
  return {"status": "success", "message": "User activated."}
132
+
133
+ async def deactivate_user(self, phone_number: str):
134
+ request = SetUserStatusRequest(phone=phone_number, disabled=False)
135
+ await self.disable_user(request=request)
136
+ # Replace this with actual API call logic
137
+ return {"status": "success", "message": "User activated."}
App/Subscriptions/SubscriptionRoutes.py CHANGED
@@ -145,13 +145,29 @@ async def update_usage(subscription_id: str, request: UpdateUsageRequest):
145
  "/subscription/{subscription_id}/deactivate", response_model=BaseResponse
146
  )
147
  async def deactivate_subscription(subscription_id: str):
 
148
  subscription = await Subscription.get_or_none(id=subscription_id)
149
  if not subscription:
150
  raise HTTPException(
151
  status_code=status.HTTP_404_NOT_FOUND, detail="Subscription not found"
152
  )
153
 
 
 
 
 
 
 
 
 
 
 
154
  subscription.active = False
155
  await subscription.save()
156
 
157
- return BaseResponse(code=200, message="Subscription deactivated successfully")
 
 
 
 
 
 
145
  "/subscription/{subscription_id}/deactivate", response_model=BaseResponse
146
  )
147
  async def deactivate_subscription(subscription_id: str):
148
+ # Fetch the subscription by ID
149
  subscription = await Subscription.get_or_none(id=subscription_id)
150
  if not subscription:
151
  raise HTTPException(
152
  status_code=status.HTTP_404_NOT_FOUND, detail="Subscription not found"
153
  )
154
 
155
+ # Fetch the associated user
156
+ user = await subscription.user
157
+ plan = await subscription.plan
158
+ if not user:
159
+ raise HTTPException(
160
+ status_code=status.HTTP_404_NOT_FOUND,
161
+ detail="User not found for subscription",
162
+ )
163
+
164
+ # Deactivate the subscription
165
  subscription.active = False
166
  await subscription.save()
167
 
168
+ # Deactivate the user associated with this subscription
169
+ await user.deactivate_user()
170
+ await user.send_subcription_expired_message(plan=plan)
171
+ return BaseResponse(
172
+ code=200, message="Subscription and user deactivated successfully"
173
+ )
App/Templates/Templates.py CHANGED
@@ -61,5 +61,8 @@ class MessageTemplate:
61
  def balance_assigned_message(self, amount: Decimal, new_balance: Decimal) -> str:
62
  return f"Habari! Salio la {amount} limeongezwa kwa mafanikio kwenye akaunti yako. Salio lako jipya ni {new_balance}."
63
 
64
-
65
-
 
 
 
 
61
  def balance_assigned_message(self, amount: Decimal, new_balance: Decimal) -> str:
62
  return f"Habari! Salio la {amount} limeongezwa kwa mafanikio kwenye akaunti yako. Salio lako jipya ni {new_balance}."
63
 
64
+ def subscription_expired_message(
65
+ self, user_name: str, plan_name: str, business_name=BUSINESS
66
+ ) -> str:
67
+ """Generates a message when the subscription is over."""
68
+ return f"Habari {user_name}, Bando lako la {plan_name}, limeisha. "
App/Users/Model.py CHANGED
@@ -318,3 +318,41 @@ class User(models.Model):
318
  except Exception as e:
319
  logger.error(f"Error activating user {self.phoneNumber}: {str(e)}")
320
  return False
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
318
  except Exception as e:
319
  logger.error(f"Error activating user {self.phoneNumber}: {str(e)}")
320
  return False
321
+
322
+ async def deactivate_user(self):
323
+
324
+ self.account_locked = True
325
+ await self.save()
326
+ await self.remover_user_session()
327
+
328
+ try:
329
+ await self.android_client.deactivate_user(self.phoneNumber)
330
+ except Exception as e:
331
+ logger.error(f"Failed to deactivate user {self.phoneNumber}: {e}")
332
+ raise e # Raise the error after logging
333
+
334
+ async def send_subcription_expired_message(self, plan: Plan):
335
+ try:
336
+ message = self.message_templates.subscription_expired_message(
337
+ user_name=self.name, plan_name=plan.name
338
+ )
339
+ await self.send_message(message=message)
340
+ logger.info(f"Subscription expired message sent to {self.phoneNumber}.")
341
+ except Exception as e:
342
+ logger.error(
343
+ f"Failed to send subscription expired message to {self.phoneNumber}: {e}"
344
+ )
345
+ raise e
346
+
347
+ async def is_active(self):
348
+ try:
349
+ return await self.android_client.is_user_active(self.phoneNumber)
350
+ except Exception as e:
351
+ raise e
352
+
353
+ async def remover_user_session(self):
354
+ try:
355
+ await self.android_client.remove_session(self.phoneNumber)
356
+ except Exception as e:
357
+ logger.error(f"Failed to remove session for {self.phoneNumber}: {e}")
358
+ raise e # Raise the error after logging
App/Users/UserRoutes.py CHANGED
@@ -63,10 +63,11 @@ async def register_user(request: RegisterUserRequest):
63
  )
64
  async def login_user(request: LoginUserRequest):
65
  # Find user by phone number
66
- db_user = await User.filter(phoneNumber=request.phoneNumber).first()
67
  valid_password = await db_user.verify_password(request.password)
68
  # Check if user exists and password is correct
69
  if db_user and valid_password:
 
70
  # Fetch active subscription if it exists
71
  subscription = await Subscription.filter(user=db_user, active=True).first()
72
 
@@ -75,6 +76,9 @@ async def login_user(request: LoginUserRequest):
75
  subscription.expiration_time.isoformat() if subscription else None
76
  )
77
 
 
 
 
78
  access_token = create_access_token(
79
  data={
80
  "user_name": db_user.name,
@@ -145,17 +149,17 @@ async def get_all_users():
145
  return [UserResponse.from_orm(user) for user in users]
146
 
147
 
148
- @user_router.delete(
149
- "/user/{user_id}", response_model=BaseResponse, status_code=status.HTTP_200_OK
150
- )
151
- async def delete_user(user_id: str):
152
- user = await User.filter(id=user_id).first()
153
- if not user:
154
- raise HTTPException(
155
- status_code=status.HTTP_404_NOT_FOUND, detail="User not found."
156
- )
157
- await user.delete()
158
- return BaseResponse(code=200, message="User deleted successfully.")
159
 
160
 
161
  @user_router.put(
 
63
  )
64
  async def login_user(request: LoginUserRequest):
65
  # Find user by phone number
66
+ db_user: User = await User.filter(phoneNumber=request.phoneNumber).first()
67
  valid_password = await db_user.verify_password(request.password)
68
  # Check if user exists and password is correct
69
  if db_user and valid_password:
70
+
71
  # Fetch active subscription if it exists
72
  subscription = await Subscription.filter(user=db_user, active=True).first()
73
 
 
76
  subscription.expiration_time.isoformat() if subscription else None
77
  )
78
 
79
+ is_active = await db_user.is_active()
80
+ if is_active:
81
+ await db_user.remover_user_session()
82
  access_token = create_access_token(
83
  data={
84
  "user_name": db_user.name,
 
149
  return [UserResponse.from_orm(user) for user in users]
150
 
151
 
152
+ # @user_router.delete(
153
+ # "/user/{user_id}", response_model=BaseResponse, status_code=status.HTTP_200_OK
154
+ # )
155
+ # async def delete_user(user_id: str):
156
+ # user = await User.filter(id=user_id).first()
157
+ # if not user:
158
+ # raise HTTPException(
159
+ # status_code=status.HTTP_404_NOT_FOUND, detail="User not found."
160
+ # )
161
+ # await user.delete()
162
+ # return BaseResponse(code=200, message="User deleted successfully.")
163
 
164
 
165
  @user_router.put(