def send_mail_to_a_friend(request): """ Function to send mail to an email_id. :param request: email_id: email_id of a friend list_object or string :return: """ data = json.loads(request.body) email = data.get("email_id") event_id = data.get("event_id") testing = data.pop("testing", False) if not (event_id and email): logger.log_error("Event_id or email is missing in the request") return api_error_response(message="Please provide necessary details", status=400) if isinstance(email, str): email = [email] message = data.get("message") try: event_name = Event.objects.get(id=event_id).name except Event.DoesNotExist: logger.log_error("Invalid email id") return api_error_response(message="Invalid email id", status=400) if not testing: send_email_sms_and_notification(action_name="user_share", message=message, url=EVENT_URL + str(event_id), event_name=event_name, email_ids=email) logger.log_info( f"Mail send successfully to the friend by user {email} for event {event_id}" ) return api_success_response(message="Mail sent successfully", status=200)
def reset_password(request): """ API for forgot password, will be called after sms integration :param request: email and password as {"email": <email_id> , "password": "******"} :return: Success if password is changed """ data = json.loads(request.body) email = data.get('email') password = data.get('password') code = data.get('code') try: code_obj = VerificationCode.objects.get(email=email, is_active=True) try: user_existed = authenticate(username=email, password=password) except Exception as err: logger.log_error(str(err)) return api_error_response(message="Some internal error occur", status=500) if user_existed: logger.log_error(f"New password cannot be same as old password for reset_password request of {email}") return api_error_response(message="New password cannot be same as old password !") if code_obj and code_obj.code == code: user = User.objects.get(email=email) user.set_password(password) user.save() code_obj.is_active = False code_obj.save() logger.log_info("Password updated successfully !!!") return api_success_response(message='Password updated successfully') logger.log_error("Invalid verification code") return api_error_response(message="Invalid Code", status=400) except Exception as err: logger.log_error(str(err)) return api_error_response(message=str(err), status=500)
def post(self, request): """ :param request: email : user's email id for logging in :param request: password : user's password for logging in :return: json containing access and refresh token if the user is authenticated """ data = json.loads(request.body) email = data.get('email', None) password = data.get('password', None) try: user = authenticate(username=email, password=password) except Exception as err: logger.log_error(str(err)) return api_error_response(message=str(err), status=400) if user is None: logger.log_error(f"Invalid credentials provided for user login {email}") message = "Given credentials do not match with any registered user!" return api_error_response(message=message, status=400) token = get_token_for_user(user) user_obj = produce_object_for_user(user) if user_obj is None: logger.log_error("Error in creation of user object") return api_error_response( message='Some error is coming in returning response', status=400) token['user'] = user_obj logger.log_info(f"Login Successful for user {email} !!!") return api_success_response(data=token)
def create(self, request): """ Create api for wish list """ logger.log_info("Wishlist creation started") data = json.loads(request.body) event_id = data.get('event_id', None) token = get_authorization_header(request).split()[1] payload = jwt.decode(token, SECRET_KEY) user_id = payload['user_id'] if user_id and event_id: data = dict(user=user_id, event=event_id) wishlist = None try: event = Event.objects.get(id=event_id, is_active=True) except: logger.log_error(f"Invalid Event with id {event_id}") return api_error_response(message="Invalid Event", status=400) if event and event.event_created_by == user_id: logger.log_error("LoggedIn user is not organizer of event") return api_error_response( message="You are the Organizer of the event", status=400) try: wishlist = WishList.objects.get(user=user_id, event=event_id) except: pass if wishlist: if not wishlist.is_active: wishlist.is_active = True wishlist.save() message = "Wishlisted successfully" else: message = "Event already wishlisted" serializer = WishListSerializer(wishlist) return api_success_response(message=message, data=serializer.data, status=200) serializer = WishListSerializer(data=data) serializer.is_valid(raise_exception=True) serializer.save() logger.log_info( f"Wishlist successfully added for user_id {user_id} for event {event_id}" ) return api_success_response(data=serializer.data, message="Wishlisted successfully", status=200) logger.log_error("Request Parameters are invalid") return api_error_response(message="Request Parameters are invalid", status=400)
def post(self, request): """ API to post feedback :param request: body will contain event_id and answer of all questions in provided format :return: success response """ logger.log_info("Feedback creation starts") token = get_authorization_header(request).split()[1] payload = jwt.decode(token, SECRET_KEY) user_id = payload['user_id'] data = json.loads(request.body) event_id = data['event_id'] feedback = data['feedback'] try: user_feedback = UserFeedback.objects.get(user_id=user_id, event_id=event_id) except UserFeedback.DoesNotExist: user_feedback = UserFeedback.objects.create(user_id=user_id, event_id=event_id) for response in feedback: question_id = response.get("id", None) if not question_id: logger.log_error("No question id provided") return api_error_response( message="You must provide question id for all questions", status=400) try: question = Question.objects.get(id=question_id) except Question.DoesNotExist: logger.log_error( "Question with id {} is not valid".format(question_id)) return api_error_response( message="Question Ids are not correct", status=400) answer = response.get('answer', {}) answer_description = answer.get('description', "") image = answer.get('image', "") try: Feedback.objects.create(user_feedback=user_feedback, question=question, answer=answer_description, image=image) except Exception as err: logger.log_error(str(err)) return api_error_response(message="Some internal error occur", status=500) logger.log_info("Feedback submitted successfully !!!") return api_success_response(message="Successfully submitted", status=200)
def create(self, request, *args, **kwargs): """ Event payment method added here """ data = json.loads(request.body) card_number = data.get('card_number', None) expiry_month = data.get('expiry_month', None) expiry_year = data.get('expiry_year', None) amount = data.get('amount', None) discount_amount = data.get('discount_amount', None) total_amount = data.get('total_amount', ) no_of_tickets = data.get('no_of_tickets', None) now = datetime.datetime.now() year = now.year month = now.month token = request.headers.get('authorization', None).split()[1] payload = jwt.decode(token, DECODE_KEY, algorithms=['HS256']) user_id = payload['user_id'] if not discount_amount: discount_amount = 0 if not total_amount: if amount < 0: total_amount = amount*(-1) - discount_amount amount = amount*-1 else: total_amount = amount - discount_amount check = False if no_of_tickets < 0: check = True status = 3 else: if not amount or not card_number or not expiry_year or not expiry_month: return api_error_response(message="Request Parameters are invalid") status = 0 if isinstance(card_number, int) and len(str(card_number)) == 16 and ( expiry_year > year or (expiry_year == year and expiry_month > month)): check = True if check: data = dict(amount=amount, discount_amount=discount_amount, total_amount=total_amount, status=status, user_id=user_id) serializer = PaymentSerializer(data=data) serializer.is_valid(raise_exception=True) serializer.save() data = serializer.data return api_success_response(data=data, message="Payment SuccessFul") return api_error_response(message="Payment Failed")
def send_forget_password_mail(request): """ API for sending verification code on the giving mail :param request: email :return: Success if mail send """ data = json.loads(request.body) email = data.get('email') testing = data.pop("testing", False) try: User.objects.get(email=email) except User.DoesNotExist: logger.log_error(f"User does not exist with given email_id {email}, send mail failed") return api_error_response(message="Please provide the registered email id.", status=400) verification_code = randint(1000, 9999) VerificationCode.objects.filter(email=email, is_active=True).update(is_active=False) code = VerificationCode(email=email, code=verification_code) code.save() if not testing: send_email_sms_and_notification( action_name="forget_password", verification_code=verification_code, email_ids=[email] ) logger.log_info(f"Verification code send successfully to user {email}") return api_success_response(message="Verification code send successfully")
def destroy(self, request, *args, **kwargs): token = get_authorization_header(request).split()[1] payload = jwt.decode(token, SECRET_KEY) user_id = payload['user_id'] event_id = int(kwargs.get('pk')) data = request.data message = data.get("message", "") testing = data.pop("testing", False) logger.log_info( f"Event deletion request from user {user_id} for event {event_id}") try: event = self.queryset.get(id=event_id) except Event.DoesNotExist: logger.log_error( "Given event id {} does not exist".format(event_id)) return api_error_response( message="Given event id {} does not exist".format(event_id)) if self.queryset.get(id=event_id).event_created_by.id != user_id: logger.log_error( "Organizer with id {} is not the organizer of the event id {}". format(user_id, event_id)) return api_error_response( message="You are not the organizer of this event {}".format( event_id), status=400) user_obj = Subscription.objects.filter( event=event_id).select_related('user').annotate( email=F('user__email'), users_id=F('user__id')).values("email", "users_id") email_ids = list({_["email"] for _ in user_obj}) user_ids = list({_["users_id"] for _ in user_obj}) self.queryset.filter(id=event_id).update(is_cancelled=True) self.queryset.filter(id=event_id).update(is_active=False) if not testing: send_email_sms_and_notification(action_name="event_deleted", email_ids=email_ids, message=message, event_name=event.name, user_ids=user_ids, event_id=event_id) logger.log_info( f"Event deletion successful for event_id {event_id} by user {user_id}" ) return api_success_response(message="Event successfully deleted", status=200)
def change_user_password(request): """ Function to set current user's password :param request: password: password to be reset email: emailId as a username :return: JSON confirming password was changed or not """ data = json.loads(request.body) email = data.get('email') old_password = data.get('old_password') new_password = data.get('new_password') if email is None or old_password is None or new_password is None: logger.log_error("Email or Password field is missing for change password request") return api_error_response(message='No field can be left blank') try: user = authenticate(username=email, password=old_password) except Exception as err: logger.log_error(str(err)) return api_error_response(message=str(err), status=400) if user is None: logger.log_error("Invalid user credentials provided") message = "Given credentials does not matches with any registered user!" return api_error_response(message=message, status=400) if old_password == new_password: logger.log_error(f"New password cannot be same as old password for user {email}") return api_error_response(message="New password cannot be same as old password !", status=400) try: user.set_password(new_password) user.save() logger.log_info(f"Password change successful for user {email} ") return api_success_response(message='Password updated successfully') except Exception as err: logger.log_error(str(err)) return api_error_response(message=str(err))
def destroy(self, request, pk=None): """ Destroy api for wish list """ logger.log_info("Wishlist remove process started") event_id = pk token = get_authorization_header(request).split()[1] payload = jwt.decode(token, SECRET_KEY) user_id = payload['user_id'] if user_id and event_id: try: instance = WishList.objects.get(event=event_id, user=user_id) except: return api_error_response(message='Not wishlisted', status=400) instance.is_active = False instance.save() logger.log_info( f"Wishlist removed successfully for user_id {user_id}") return api_success_response( message='Successfully removed from wishlist', status=200) logger.log_error(f"Invalid event {event_id}") return api_error_response(message='Invalid event', status=400)
def get_feedback_questions(request): """ API to get all questions assigned for feedback :return: questions for feedback """ try: query = Question.objects.filter(is_active=True) except Exception as err: logger.log_error(str(err)) return api_error_response(message="Some internal error occur", status=500) serializer = QuestionSerializer(query, many=True) logger.log_info("Feedback questions list fetched successfully !!!") return api_success_response(message="Feedback questions list", status=200, data=serializer.data)
def list(self, request, *args, **kwargs): """ List the payment entry """ data = json.loads(request.body) list_of_payment_ids = data.get("list_of_payment_ids") token = get_authorization_header(request).split()[1] payload = jwt.decode(token, DECODE_KEY, algorithms=['HS256']) user_id = payload['user_id'] user_instance = self.queryset.filter(user_id=user_id) if not user_instance: return api_error_response(message="No entry for this user", status=400) payment_details = user_instance.filter(id__in=list_of_payment_ids) serializer = PaymentSerializer(payment_details, many=True) return api_success_response(data=serializer.data, message="Payment details")
def patch(self, request): """ Patch api method of notification """ token = get_authorization_header(request).split()[1] payload = jwt.decode(token, SECRET_KEY) user_id = payload['user_id'] list_of_ids = request.data.get('notification_ids') try: self.queryset.filter(id__in=list_of_ids).update(has_read=True) except Exception as err: logger.log_error(str(err)) return api_error_response(message="Something went wrong", status=500) logger.log_info( f"Notification status updated successfully by user_id {user_id}") return api_success_response( message="Notification updated successfully", status=200)
def create(self, request, *args, **kwargs): """ Create Api for Event """ token = get_authorization_header(request).split()[1] payload = jwt.decode(token, SECRET_KEY) user_id = payload['user_id'] logger.log_info(f"Event creation started by user {user_id}") if user_id != request.data["event_created_by"]: return api_error_response( message="You are not authorized to perform this action", status=400) request.data['type'] = request.data.pop('event_type', None) self.serializer_class = EventSerializer response = super(EventViewSet, self).create(request, *args, **kwargs) response.data['event_type'] = response.data.pop('type') response.data['images'] = \ f"https://s3.{AWS_REGION}.amazonaws.com/{BUCKET}/{response.data['images']}", response.data['self_organised'] = True response.data['event_status'] = EVENT_STATUS['default'] logger.log_info(f"Event created Successfully for user {user_id}") return response
def get(self, request): """ :param request: :return: """ event_id = request.GET.get('event_id') try: event = Event.objects.get(id=event_id) except: logger.log_error( f"Invalid event id {event_id} entered for getting presigned url" ) return api_error_response(message="Event is not valid", status=400) image_name = event.images bucket = BUCKET object_name = image_name s3 = AwsS3() presigned_url = s3.get_presigned_url( bucket_name=bucket, object_name=object_name, expiry=300, ) return api_success_response(presigned_url, status=200)
def retrieve(self, request, *args, **kwargs): token = get_authorization_header(request).split()[1] payload = jwt.decode(token, SECRET_KEY) user_logged_in = payload['user_id'] user_id = int(kwargs.get('user_id')) if user_logged_in != user_id: logger.log_error( f"Cannot fetch profile details of other user, tried by user " f"{user_logged_in} for user_id {user_id}") return api_error_response( message="You can only view your own profile", status=400) profile = self.queryset.get(user_id=user_id) curr_profile = { 'id': profile.user.id, 'name': profile.name, 'contact_number': profile.contact_number, 'address': profile.address, 'role': profile.role.id, 'organization': profile.organization } try: list_of_interest = list( UserInterest.objects.filter( user=user_id, is_active=True).values_list('event_type', flat=True)) except UserInterest.DoesNotExist: list_of_interest = [] curr_profile['interest'] = list_of_interest logger.log_info( f"User details fetched successfully for user_id {user_id}") return api_success_response(data=curr_profile, message="user details", status=200)
def list(self, request, *args, **kwargs): """ User list api created here """ token = get_authorization_header(request).split()[1] payload = jwt.decode(token, SECRET_KEY) user_id = payload['user_id'] try: user_logged_in = user_id user_role = UserProfile.objects.get( user_id=user_logged_in).role.role except Exception: return api_error_response(message="Something went wrong", status=500) data = [] for profile in self.queryset: curr_profile = { 'id': profile.user.id, 'name': profile.name, 'contact_number': profile.contact_number, 'address': profile.address, 'role': profile.role.id, 'organization': profile.organization } try: list_of_interest = list( UserInterest.objects.filter(user=profile.user.id, is_active=True).values_list( 'event_type', flat=True)) except UserInterest.DoesNotExist: list_of_interest = [] curr_profile['interests'] = list_of_interest data.append(curr_profile) return api_success_response(data=data, status=200)
def update(self, request, *args, **kwargs): """ Function to update a particular event :param request: body containing changes to be made :param kwargs: contains event id from the url given :return: changed response of an event """ token = get_authorization_header(request).split()[1] payload = jwt.decode(token, SECRET_KEY) user_id = payload['user_id'] event_id = int(kwargs.get('pk')) data = request.data testing = data.pop("testing", False) user_logged_in = user_id logger.log_info( f"Event update request started by user {user_id} for event {event_id}" ) try: user_role = UserProfile.objects.get( user_id=user_logged_in).role.role except Exception: logger.log_error( f"Event update request by user_id {user_id}: fetching of user role from object failed" ) return api_error_response( message="Not able to fetch the role of the logged in user", status=500) if user_role == 'subscriber': logger.log_error( f"Event update request by user_id {user_id}: a subscriber cannot update event details" ) return api_error_response( message="A subscriber cannot change an event details", status=500) if self.queryset.get( id=event_id).event_created_by.id != user_logged_in: logger.log_error( f"Event update request: LoggedIn user {user_id} is not the organizer of the event with id " f"{event_id} ") return api_error_response( message="You are not the organizer of this event {}".format( event_id), status=400) try: event_obj = Event.objects.get(id=event_id) prev_name = event_obj.name prev_location = event_obj.location prev_date = event_obj.date prev_time = event_obj.time except Event.DoesNotExist: logger.log_error( f"Event update request: event_id {event_id} does not exist") return api_error_response( message=f"Event with id {event_id} does not exist", status=400) try: partial = kwargs.pop('partial', False) if 'event_type' in request.data: request.data['type'] = request.data.pop('event_type') serializer = EventSerializer(event_obj, data=request.data, partial=partial) serializer.is_valid(raise_exception=True) serializer.save() serializer.data['images'] = f"https://s3.{AWS_REGION}.amazonaws.com/{BUCKET}/" \ f"{serializer.data['images']}" serializer.data['event_type'] = serializer.data.pop('type') except Exception as err: logger.log_error(str(err)) return api_error_response( message="Some internal error coming while updating the event", status=500) event_name = event_obj.name field_list = [] prev_list = [] next_list = [] if 'name' in data: field_list.append("name") prev_list.append(prev_name) next_list.append(data.get('name')) if 'location' in data: field_list.append("location") prev_list.append(prev_location) next_list.append(data.get('location')) if 'date' in data: field_list.append("date") prev_list.append(str(prev_date)) next_list.append(data.get('date')) if 'time' in data: field_list.append("time") prev_list.append(str(prev_time)) next_list.append(data.get('time')) field = ", ".join(field_list) prev_value = ", ".join(prev_list) next_value = ", ".join(next_list) user_obj = Subscription.objects.filter( event=event_id).select_related('user').annotate( email=F('user__email'), users_id=F('user__id')).values("email", "users_id") email_ids = list({_["email"] for _ in user_obj}) user_ids = list({_["users_id"] for _ in user_obj}) if field: if not testing: send_email_sms_and_notification(action_name="event_updated", email_ids=email_ids, field=field, prev_value=prev_value, next_value=next_value, event_name=event_name, user_ids=user_ids, event_id=event_id) logger.log_info("Subscribers notified for event details update") logger.log_info( f"Event with id {event_id} successfully updated by user with id {user_id}" ) return api_success_response(data=serializer.data, status=200)
def get_event_summary(request): """ API to return summary of ongoing events organized by the user :param request: organizer id :return: data object returning the event details like sold tickets, revenue etc. """ token = get_authorization_header(request).split()[1] payload = jwt.decode(token, SECRET_KEY) user_id = payload['user_id'] search_text = request.GET.get("search", None) event_status_filter = request.GET.get('event_status', EVENT_STATUS['all']) today = date.today() queryset = Event.objects.filter(event_created_by=user_id).order_by('id') queryset.filter(date__lt=str(today)).update(is_active=False) total_revenue, revenue_cancelled_events, revenue_completed_events, revenue_ongoing_events = 0, 0, 0, 0 if event_status_filter.lower() == EVENT_STATUS['completed']: queryset = queryset.filter(is_active=False, is_cancelled=False) elif event_status_filter.lower() == EVENT_STATUS['cancelled']: queryset = queryset.filter(is_active=False, is_cancelled=True) elif event_status_filter.lower() == EVENT_STATUS['default']: queryset = queryset.filter(date__gte=str(today), is_active=True) if search_text: queryset = queryset.filter( Q(location__icontains=search_text) | Q(name__icontains=search_text)) cancelled_events, completed_events, ongoing_events, total_events = 0, 0, 0, queryset.count( ) data = {'event_list': []} event_name_list = [] event_revenue_list = [] event_remaining_tickets = [] event_sold_tickets = [] try: for event in queryset: if event.subscription_fee == 0: revenue = 0 else: total_amount = Subscription.objects.filter( event=event.id, is_active=True).aggregate(Sum("amount")) if total_amount["amount__sum"]: revenue = total_amount["amount__sum"] else: revenue = 0 if event.is_cancelled: revenue = 0 total_revenue += revenue event_status = EVENT_STATUS['default'] if event.is_cancelled: event_status = EVENT_STATUS['cancelled'] revenue_cancelled_events += revenue cancelled_events += 1 if not event.is_active and not event.is_cancelled: event_status = EVENT_STATUS['completed'] revenue_completed_events += revenue completed_events += 1 if event_status == EVENT_STATUS['default']: revenue_ongoing_events += revenue ongoing_events += 1 data['event_list'].append({ 'key': event.id, 'name': event.name, 'total_tickets': event.no_of_tickets, 'sold_tickets': event.sold_tickets, 'revenue': revenue, 'location': event.location, 'status': event_status }) event_name_list.append(event.name) event_revenue_list.append(revenue) event_remaining_tickets.append(event.no_of_tickets - event.sold_tickets) event_sold_tickets.append(event.sold_tickets) data['total_revenue'] = total_revenue data['total_events'] = total_events data['ongoing_events'] = ongoing_events data['completed_events'] = completed_events data['cancelled_events'] = cancelled_events data['revenue_ongoing_events'] = revenue_ongoing_events data['revenue_completed_events'] = revenue_completed_events data['revenue_cancelled_events'] = revenue_cancelled_events data['ticket_graph_object'] = { 'name_list': event_name_list, 'revenue_list': event_revenue_list, 'remaining_tickets': event_remaining_tickets, 'sold_tickets': event_sold_tickets } monthly_data = get_month_wise_data(queryset) data['monthly_event_count'] = monthly_data['events'] data['monthly_revenue'] = monthly_data['revenue'] except Exception as err: logger.log_error(str(err)) return api_error_response(message="Some internal error occur", status=500) logger.log_info( f"Analytics successfully sent for events of organizer with user_id {user_id}" ) return api_success_response(message="Summary of all events", data=data, status=200)
def list(self, request, *args, **kwargs): """ Function to give list of Events based on different filter parameters :param request: contain the query type and it's value :return: Response contains complete list of events after the query """ search_text = request.GET.get("search", None) event_type = request.GET.get("event_type", None) start_date = request.GET.get("start_date", None) end_date = request.GET.get("end_date", None) event_created_by = request.GET.get("event_created_by", False) is_wishlisted = request.GET.get('is_wishlisted', False) event_status = request.GET.get('event_status', EVENT_STATUS['default']) subscription_type = request.GET.get('subscription_type', SUBSCRIPTION_TYPE['default']) token = get_authorization_header(request).split()[1] payload = jwt.decode(token, SECRET_KEY) user_id = payload['user_id'] logger.log_info(f"Event list request initiated by user {user_id}") try: user_logged_in = user_id user_role = UserProfile.objects.get( user_id=user_logged_in).role.role except Exception: logger.log_error( f"Fetching of user role for user_id {user_id} failed") return api_error_response( message="Not able to fetch the role of the logged in user", status=500) if event_status.lower() == EVENT_STATUS['all']: self.queryset = Event.objects.all() event_status = event_status.lower() today = date.today() self.queryset.filter(date__lt=str(today)).update(is_active=False) if event_status.lower() == EVENT_STATUS['completed']: self.queryset = Event.objects.filter(is_active=False, is_cancelled=False) if event_status.lower() == EVENT_STATUS['cancelled']: self.queryset = Event.objects.filter(is_active=False, is_cancelled=True) if event_status.lower() == EVENT_STATUS['default']: self.queryset = self.queryset.filter(date__gte=str(today)) if is_wishlisted == 'True': try: event_ids = WishList.objects.filter( user=user_id, is_active=True).values_list('event__id', flat=True) self.queryset = self.queryset.filter(id__in=event_ids) except Exception as err: logger.log_error(str(err)) return api_error_response( message= "Some internal error coming in fetching the wishlist", status=400) if subscription_type.lower() == SUBSCRIPTION_TYPE['free']: self.queryset = self.queryset.filter(subscription_fee=0) if subscription_type.lower() == SUBSCRIPTION_TYPE['paid']: self.queryset = self.queryset.filter(subscription_fee__gt=0) if search_text: self.queryset = self.queryset.filter( Q(location__icontains=search_text) | Q(name__icontains=search_text)) if event_created_by == 'True': self.queryset = self.queryset.filter(event_created_by=user_id) if event_type: self.queryset = self.queryset.filter(type=event_type) if start_date and end_date: self.queryset = self.queryset.filter( date__range=[start_date, end_date]) if len(self.queryset) > 1: self.queryset = self.queryset.annotate( diff=ExpressionWrapper(F('sold_tickets') * 100000 / F('no_of_tickets'), output_field=IntegerField())) self.queryset = self.queryset.order_by('-diff') is_subscriber = (user_role == 'subscriber') data = [] for curr_event in self.queryset: response_obj = { "id": curr_event.id, "name": curr_event.name, "date": curr_event.date, "time": curr_event.time, "location": curr_event.location, "event_type": curr_event.type.id, "description": curr_event.description, "no_of_tickets": curr_event.no_of_tickets, "sold_tickets": curr_event.sold_tickets, "subscription_fee": curr_event.subscription_fee, "images": f"https://s3.{AWS_REGION}.amazonaws.com/{BUCKET}/{curr_event.images}", "external_links": curr_event.external_links, 'is_free': curr_event.subscription_fee == 0, 'feedback_count': UserFeedback.objects.filter(event_id=curr_event.id).count(), 'event_status': event_status } if event_status == EVENT_STATUS['all']: response_obj['event_status'] = get_event_status(curr_event) if is_subscriber: # check for subscription subscription_list = Subscription.objects.filter( user_id=user_logged_in, event_id=curr_event.id, is_active=True) if subscription_list: is_subscribed = True else: is_subscribed = False response_obj['is_subscribed'] = is_subscribed try: # check if the event is wish-listed WishList.objects.get(user_id=user_logged_in, event_id=curr_event.id, is_active=True) response_obj['is_wishlisted'] = True except WishList.DoesNotExist: response_obj['is_wishlisted'] = False try: UserFeedback.objects.get(user_id=user_logged_in, event_id=curr_event.id, is_active=True) feedback_given = True except UserFeedback.DoesNotExist: feedback_given = False response_obj['feedback_given'] = feedback_given data.append(response_obj) logger.log_info( f"Event list fetched successfully by user_id {user_id}") return api_success_response(message="List of events", data=data)
def retrieve(self, request, *args, **kwargs): """ Retrieve Api for Event """ token = get_authorization_header(request).split()[1] payload = jwt.decode(token, SECRET_KEY) user_id = payload['user_id'] user_logged_in = user_id payment_access_token = payment_token(user_id) payment_access_token = payment_access_token.decode('UTF-8') try: user_role = UserProfile.objects.get( user_id=user_logged_in).role.role except Exception: logger.log_error("Fetching of user role from object failed") return api_error_response( message="Not able to fetch the role of the logged in user", status=500) event_id = int(kwargs.get('pk')) logger.log_info( f"Fetch event details request by user {user_id} for event {event_id}" ) try: curr_event = Event.objects.get(id=event_id) except Event.DoesNotExist: logger.log_error( "Invalid event_id {} provided in retrieve request".format( event_id)) return api_error_response( message="Given event {} does not exist".format(event_id)) event_status = get_event_status(curr_event) if user_role != 'subscriber': invitee_list = Invitation.objects.filter( event=curr_event.id, event__event_created_by_id=user_logged_in, is_active=True) self_organised = (curr_event.event_created_by.id == user_logged_in) invitee_data = [] for invited in invitee_list: response_obj = { 'invitation_id': invited.id, 'email': invited.email } if invited.user is not None: try: user_profile = UserProfile.objects.get( user=invited.user.id) response_obj['user'] = { 'user_id': invited.user.id, 'name': user_profile.name, 'contact_number': user_profile.contact_number, 'address': user_profile.address, 'organization': user_profile.organization } except UserProfile.DoesNotExist: pass response_obj[ 'discount_percentage'] = invited.discount_percentage invitee_data.append(response_obj) data = { "id": curr_event.id, "name": curr_event.name, "date": curr_event.date, "time": curr_event.time, "location": curr_event.location, "event_type": curr_event.type.id, "description": curr_event.description, "no_of_tickets": curr_event.no_of_tickets, "sold_tickets": curr_event.sold_tickets, "subscription_fee": curr_event.subscription_fee, "images": f"https://s3.{AWS_REGION}.amazonaws.com/{BUCKET}/{curr_event.images}", "external_links": curr_event.external_links, "invitee_list": invitee_data, "self_organised": self_organised, 'event_status': event_status, 'feedback_count': UserFeedback.objects.filter(event_id=curr_event.id).count() } logger.log_info("Event details successfully returned !!!") return api_success_response(message="event details", data=data, status=200) else: data = { "id": curr_event.id, "name": curr_event.name, "date": curr_event.date, "time": curr_event.time, "location": curr_event.location, "event_type": curr_event.type.id, "description": curr_event.description, "subscription_fee": curr_event.subscription_fee, "no_of_tickets": curr_event.no_of_tickets, "images": f"https://s3.{AWS_REGION}.amazonaws.com/{BUCKET}/{curr_event.images}", "external_links": curr_event.external_links, 'event_status': event_status } try: WishList.objects.get(user_id=user_logged_in, event_id=curr_event.id, is_active=True) wishlisted = True except WishList.DoesNotExist: wishlisted = False is_subscribed = False try: UserFeedback.objects.get(user_id=user_logged_in, event_id=event_id, is_active=True) feedback_given = True except UserFeedback.DoesNotExist: feedback_given = False try: subscription_list = Subscription.objects.filter( user_id=user_id, event_id=curr_event.id, is_active=True) if subscription_list: is_subscribed = True no_of_tickets_bought = int( sum( list( subscription_list.values_list('no_of_tickets', flat=True)))) if curr_event.subscription_fee <= 0: # Free event total_amount_paid = 0 total_discount_given = 0 discount_percentage = 0 else: # paid event payment_ids_list = Subscription.objects.filter( user=user_id, event=event_id, is_active=True).values_list("id_payment") payment_ids_list = [_[0] for _ in payment_ids_list] payment_payload = { "list_of_payment_ids": payment_ids_list } payment_response = requests.get( PAYMENT_URL, data=json.dumps(payment_payload), headers={ "Authorization": f"Bearer {payment_access_token}", "Content-type": "application/json" }) if payment_response.status_code != 200: return api_error_response( message= "Error in fetching details from payment service", status=500) payment_object = payment_response.json().get('data') total_amount_paid = sum([ item["total_amount"] if item["status"] == 0 else item["total_amount"] * (-1) for item in payment_object ]) total_discount_given = sum([ item["discount_amount"] if item["status"] == 0 else item["discount_amount"] * (-1) for item in payment_object ]) try: discount_percentage = \ Invitation.objects.get(user_id=user_id, event_id=curr_event.id, is_active=True).discount_percentage except Invitation.DoesNotExist: discount_percentage = 0 created_on = subscription_list.order_by( 'created_on')[0].created_on data["subscription_details"] = { "no_of_tickets_bought": no_of_tickets_bought, "amount_paid": total_amount_paid, "discount_given": total_discount_given, "discount_percentage": discount_percentage, "created_on": datetime.strftime(created_on, "%Y-%m-%d") } else: data["subscription_details"] = {} try: discount_allotted = \ Invitation.objects.get(user=user_id, event=curr_event.id, is_active=True).discount_percentage except Invitation.DoesNotExist: discount_allotted = 0 data['discount_percentage'] = discount_allotted except Subscription.DoesNotExist: try: discount_allotted = Invitation.objects.get( user=user_id, event=curr_event.id, is_active=True).discount_percentage except Invitation.DoesNotExist: discount_allotted = 0 data['discount_percentage'] = discount_allotted data["subscription_details"] = dict() data['is_wishlisted'] = wishlisted data["is_subscribed"] = is_subscribed data['feedback_given'] = feedback_given data[ "remaining_tickets"] = curr_event.no_of_tickets - curr_event.sold_tickets logger.log_info( f"Event details successfully returned for event {event_id}!!!") return api_success_response(message="Event details", data=data, status=200)
def post(self, request): """ :param request :return: api success response if registration is successful """ logger.log_info("User registration started") data = json.loads(request.body) email = data.get('email') name = data.get('name') contact_number = data.get('contact') address = data.get('address') password = data.get('password') organization = data.get('organization') role_name = data.get('role') testing = data.pop("testing", False) if email is None or password is None or role_name is None: logger.log_error("Email, password or role is missing in registration request") return api_error_response( message='Incomplete or incorrect credentials are provided for registration', status=400) try: # Checking if role is correct or not role_name = role_name.lower() role_obj = Role.objects.get(role=role_name) except Role.DoesNotExist: logger.log_error(f"Role name {role_name} is invalid for registering user {email}") return api_error_response( message='Role assigned is not matching with any role type', status=400) try: user = User.objects.get(email=email) except User.DoesNotExist: # if user is None then new_user will be created user = None if user is not None: logger.log_error(f'A user already exist with the given email id: {email}') return api_error_response(message='A user already exist with the given email id: {}'. format(email), status=400) try: user = User.objects.create_user(email=email, password=password) logger.log_info(f"New user created with email id {email}") user_profile_obj = UserProfile.objects.create( user=user, name=name, contact_number=contact_number, organization=organization, address=address, role=role_obj) user_profile_obj.save() logger.log_info(f"User Details successfully registered for user {email}") if role_name == 'organizer': user.is_active = False user.save() token = {} if not testing: send_email_sms_and_notification(action_name="new_organizer_created", email_ids=[ADMIN_EMAIL], user_email=email) else: token = get_token_for_user(user) token['user'] = produce_object_for_user(user) logger.log_info(f"Registration Successful of the User {email} !!!") return api_success_response(data=token, message='User created successfully', status=201) except Exception as err: logger.log_error(str(err)) return api_error_response(message=str(err), status=400)
def update(self, request, *args, **kwargs): """ User update api created here """ logger.log_info("User Profile Update Initialised") token = get_authorization_header(request).split()[1] payload = jwt.decode(token, SECRET_KEY) user_id = payload['user_id'] data = request.data interest_list = [] try: partial = kwargs.pop('partial', False) instance = self.get_object() if 'interest' in data: interests = data.pop('interest') else: interests = [] serializer = self.get_serializer(instance, data=request.data, partial=partial) serializer.is_valid(raise_exception=True) self.perform_update(serializer) try: prev_interest = list( UserInterest.objects.filter( user=user_id, is_active=True).values_list('event_type', flat=True)) if interests: interest_to_be_deleted = list( set(prev_interest).difference(interests)) UserInterest.objects.filter( event_type_id__in=interest_to_be_deleted).update( is_active=False) except Exception as err: logger.log_error(str(err)) prev_interest = [] return api_error_response(message="Something went wrong", status=500) for current in interests: try: UserInterest.objects.get(user=user_id, event_type_id=current, is_active=True) except: UserInterest.objects.create(user_id=user_id, event_type_id=current).save() interest_list.append(current) response = serializer.data if interest_list: response['interest'] = interest_list else: response['interest'] = prev_interest except Exception as err: logger.log_error(str(err)) return api_error_response(message="Something went wrong", status=500) logger.log_info( f"User Profile updated successfully for user_id {user_id}") return api_success_response(data=response, status=200)
def get(self, request): """ API to get the list of all feedback for an event :param request: in params pass event_id=<event_id> :return: Feedback list if success """ token = get_authorization_header(request).split()[1] payload = jwt.decode(token, SECRET_KEY) user_id = payload['user_id'] event_id = request.GET.get("event_id", None) if not event_id: logger.log_error("Event_id is missing in params") return api_error_response( message="You have to provide event_id in feedback details", status=400) event_id = int(event_id) try: event = Event.objects.get(id=event_id) except Exception: logger.log_error(f"Event_id {event_id} is invalid") return api_error_response(message="Provided event doesn't exist", status=400) user_role = UserProfile.objects.get(user=request.user).role.role if user_role == 'organizer' and event.event_created_by != request.user: logger.log_error( f"Organizer with id {user_id} is not the owner of the event with id {event_id}" ) return api_error_response( message="You can only see feedback for self organized events", status=400) user_feedback = UserFeedback.objects.filter(event_id=event_id) if user_role == 'subscriber': user_feedback = user_feedback.filter(user_id=user_id) data = [] for instance in user_feedback: feedback = Feedback.objects.filter( user_feedback=instance).order_by("id") current_response = { 'user': { 'id': instance.user.id, 'name': UserProfile.objects.get(user_id=instance.user.id).name, 'email': instance.user.email, 'contact': UserProfile.objects.get( user_id=instance.user.id).contact_number }, 'responses': [] } for response in feedback: image = response.image if image != '': image = f"https://s3.{AWS_REGION}.amazonaws.com/{BUCKET}/{image}" current_response['responses'].append({ 'question_id': response.question.id, 'question': response.question.question, 'answer': response.answer, 'image': image }) data.append(current_response) logger.log_info("Feedback fetched successfully !!!") return api_success_response(message="All feedback", status=200, data=data)
def create(self, request): """ Function to set subscription of a user to a particular event :param request: token, event_id, no_of_tickets, user_id, card_number, expiry_month, expiry_year, amount, discount_amount, total_amount :return: json response subscribed successful or error message """ logger.log_info("Subscription Started") data = json.loads(request.body) event_id = data.get('event_id', None) no_of_tickets = data.get('no_of_tickets', None) user_id = data.get('user_id', None) card_number = data.get('card_number', None) expiry_month = data.get('expiry_month', None) expiry_year = data.get('expiry_year', None) amount = data.get('amount', None) discount_amount = data.get('discount_amount', None) total_amount = data.get('total_amount', None) payment_id = None token = get_authorization_header(request).split()[1] payload = jwt.decode(token, SECRET_KEY) user_id = payload['user_id'] if not event_id or not no_of_tickets or not user_id: logger.log_error( "Event_id, no_of_tickets and user_id are mandatory in request") return api_error_response(message="Request Parameters are invalid") try: self.event = Event.objects.get(id=event_id, is_active=True) except Event.DoesNotExist: logger.log_error(f"Event_id {event_id} does not exist") return api_error_response("Invalid event id") if no_of_tickets < 0: instance = self.queryset.filter(user=user_id, event=event_id) tickets_data = instance.values('event').aggregate( Sum('no_of_tickets')) remaining_tickets = no_of_tickets + tickets_data[ 'no_of_tickets__sum'] if remaining_tickets < 0: logger.log_error( f"Can not cancel tickets more than purchase {no_of_tickets}" ) return api_error_response( message="Can not cancel tickets more than purchase", status=400) if amount: data = dict(card_number=card_number, expiry_month=expiry_month, expiry_year=expiry_year, amount=amount, discount_amount=discount_amount, total_amount=total_amount, no_of_tickets=no_of_tickets) payment_access_token = payment_token(user_id) payment_access_token = payment_access_token.decode('UTF-8') payment_object = requests.post( PAYMENT_URL, data=json.dumps(data), headers={ "Authorization": "Bearer {}".format(payment_access_token), "Content-type": "application/json" }) if payment_object.status_code == 200: payment_object = payment_object.json().get('data') if payment_object['status'] == 3: payment_object[ 'total_amount'] = payment_object['total_amount'] * (-1) else: return api_error_response( message="Error while fetching payment", status=500) payment_id = payment_object['id'] amount = payment_object['total_amount'] data = dict(user=user_id, event=event_id, no_of_tickets=no_of_tickets, id_payment=payment_id, amount=amount) if not payment_id and self.event.subscription_fee > 0: return api_error_response( message="Required fields are not present") if self.event.no_of_tickets - self.event.sold_tickets >= no_of_tickets: serializer = SubscriptionSerializer(data=data) serializer.is_valid(raise_exception=True) serializer.save() if serializer.instance.id_payment: success_queryset = self.queryset.filter( user=user_id, event=event_id, id_payment__isnull=False, amount__gt=0) refund_queryset = self.queryset.filter( user=user_id, event=event_id, id_payment__isnull=False, amount__lt=0) success_queryset = success_queryset.select_related('event') refund_queryset = refund_queryset.select_related('event') success_queryset = success_queryset.values('event').annotate( total_amount=Coalesce(Sum('amount'), 0), total_tickets=Coalesce(Sum('no_of_tickets'), 0), event_name=F('event__name'), event_date=F('event__date'), event_time=F('event__time'), event_location=F('event__location')) refund_queryset = refund_queryset.values('event').annotate( total_amount=Coalesce(Sum('amount'), 0), total_tickets=Coalesce(Sum('no_of_tickets'), 0)) if len(success_queryset) > 0: success_queryset = success_queryset[0] if len(refund_queryset) > 0: refund_queryset = refund_queryset[0] refund_total_amount = refund_queryset['total_amount'] refund_total_tickets = refund_queryset['total_tickets'] else: refund_total_amount = 0 refund_total_tickets = 0 data = dict( curent_payment_id=payment_id, no_of_tickets=int(success_queryset['total_tickets'] + refund_total_tickets), total_amount=success_queryset['total_amount'] + refund_total_amount, event_name=success_queryset['event_name'], event_date=success_queryset['event_date'], event_time=success_queryset['event_time'], event_location=success_queryset['event_location']) else: queryset = self.queryset.filter(event=event_id, user=user_id, id_payment=None) queryset = queryset.select_related('event') tickets_data = queryset.aggregate(Sum('no_of_tickets')) queryset = queryset.values('event').annotate( event_name=F('event__name'), event_date=F('event__date'), event_time=F('event__time'), event_location=F('event__location')) queryset = queryset.first() data = dict(no_of_tickets=int( tickets_data['no_of_tickets__sum']), event_name=queryset['event_name'], event_date=queryset['event_date'], event_time=queryset['event_time'], event_location=queryset['event_location']) logger.log_info( f"Subscription successful for user with id {user_id}") return api_success_response(message="Subscribed Successfully", data=data, status=201) logger.log_error( f"Number of tickets are invalid for subscription request of user_id {user_id}" ) return api_error_response( message="Requested number of tickets are more than available", status=400)