def get(self): _user_id = g.current_user.id _user = User.query.get(_user_id) if not _user: return moov_errors('User does not exist', 404) _notifications = Notification.query.filter(Notification.recipient_id==_user.id).order_by(desc(Notification.created_at)).limit(20).all() _notifications_data = [] if _notifications: for _notification in _notifications: _notification_to_append, _ = notification_schema.dump(_notification) _notification_to_append["icon"] = "" if _notification.transaction_icon_id: _notification_to_append["icon"] = str(_notification.notification_icon.icon) _notifications_data.append(_notification_to_append) _user_type = (_user.user_type.title).lower() if _user_type == "admin": return moov_errors('Unauthorized access', 401) _user_data, _ = user_schema.dump(_user) _user_data['wallet_amount'] = _user.wallet_user[0].wallet_amount _user_data["school"] = str(_user.school_information.name) _user_data["user_type"] = _user_type _user_data.pop('password', None) _user_data.pop('user_id', None) return jsonify({"status": "success", "data": { "message": "Basic information successfully retrieved", "user": _user_data, "notifications": _notifications_data } })
def delete(self): json_input = request.get_json() if "email" not in json_input: return moov_errors("Please provide email of user to delete", 400) keys = ['email'] if validate_input_data(json_input, keys): return validate_input_data(json_input, keys) _current_user_id = g.current_user.id _current_user = User.query.get(_current_user_id) _user_to_delete = User.query.filter(User.email==json_input["email"]).first() if not _current_user or not _user_to_delete: return moov_errors("User does not exist", 404) if _user_to_delete.user_type.title == "super_admin" or \ _user_to_delete.user_type.title == "admin" or \ _user_to_delete.user_type.title == "school" or \ _user_to_delete.user_type.title == "car_owner" or \ _user_to_delete.user_type.title == "moov": return moov_errors("Unauthorized, you cannot create a/an {0}".format(_user_to_delete.user_type.title), 401) if str(_current_user.email) != str(_user_to_delete.email) and \ str(_current_user.user_type.title) not in ["admin", "super_admin"]: return moov_errors("Unauthorized access. You cannot delete this user", 401) _user_to_delete.delete() return { 'status': 'success', 'data': None }, 200
def post(self): json_input = request.get_json() keys = ['free_ride_type'] if validate_input_data(json_input, keys): return validate_input_data(json_input, keys) _user_id = g.current_user.id _user = User.query.get(_user_id) if not _user: return moov_errors('User does not exist', 404) _free_ride_type = json_input["free_ride_type"] if str(_free_ride_type) not in ["social_share_type"]: return moov_errors('Free ride type does not exist', 400) if str(_free_ride_type) == "social_share_type": if not has_free_ride( user_id=_user_id, free_ride_type=FreeRideType.social_share_type): moov_email = os.environ.get("MOOV_EMAIL") moov_user = User.query.filter(User.email == moov_email).first() if not moov_user: return not_found_errors(moov_email) _transaction_icon = "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973461_1280.png" transaction_icon = Icon.query.filter( Icon.operation_type == "free_ride_operation").first() if transaction_icon: _transaction_icon_id = transaction_icon.id token = generate_free_ride_token(user_email=_user.email) description = "{0} generated to {1} for publisicing moov app".format( token, _user.email) message = "Congrats, you got a free ride token {0} for sharing our app".format( token) save_notification(recipient_id=_user_id, sender_id=moov_user.id, message=message, transaction_icon_id=_transaction_icon_id) _data, _ = save_free_ride_token( free_ride_type=FreeRideType.social_share_type, token=token, description=description, user_id=_user_id) return {'status': 'success', 'data': {'free_ride': _data}}, 201 # cases that don't meet any of the free ride conditions # cases that the user has collected a free ride for a particular free_ride_type return moov_errors("Free ride collection denied", 400)
def put(self): json_input = request.get_json() keys = [ 'location_latitude', 'location_longitude', 'destination_latitude', 'destination_longitude', 'car_slots', 'status', 'car_model', 'left_image', 'right_image', 'front_image', 'back_image', 'plate_number', 'bank_name', 'account_number', 'admission_type' ] if validate_input_data(json_input, keys): return validate_input_data(json_input, keys) _driver_id = g.current_user.id _driver = DriverInfo.query.filter( DriverInfo.driver_id == _driver_id).first() if not _driver: return moov_errors("Driver does not exist", 404) if is_empty_request_fields(json_input): return moov_errors( "Empty strings are not allowed, exception for image urls", 400) for key in json_input.keys(): if str(key) == "admission_type": _admission_type = AdmissionType.query.filter( AdmissionType.admission_type == str( json_input[key])).first() if not _admission_type: return moov_errors("Admission type does not exist", 400) _driver.__setitem__("admission_type_id", _admission_type.id) if str(key) == "car_slots": _driver.__setitem__("available_car_slots", json_input["car_slots"]) if str(key) not in ["admission_type"]: _driver.__setitem__(key, json_input[key]) _driver.save() _data, _ = driver_info_schema.dump(_driver) return { 'status': 'success', 'data': { 'driver': _data, 'message': 'Driver information updated succesfully', } }, 200
def get(self): _data = {} _user_id = g.current_user.id _user = User.query.get(_user_id) if not _user: return moov_errors('User does not exist', 404) user_type = _user.user_type.title if user_type == "super_admin" or \ user_type == "admin" or \ user_type == "school" or \ user_type == "car_owner" or \ user_type == "moov": return moov_errors("Unauthorized access", 401) # handle driver users if user_type == "driver": driver_info = DriverInfo.query.filter(DriverInfo.driver_id==_user_id).first() driver_info_data, _ = driver_info_schema.dump(driver_info) driver_info_data["driver_location"] = [driver_info_data["location_latitude"], driver_info_data["location_longitude"]] driver_info_data["driver_destination"] = [driver_info_data["destination_latitude"], driver_info_data["destination_longitude"]] for key in ['bank_name', 'account_number', 'driver_id', 'admission_type_id', 'location_latitude', \ 'location_longitude', 'destination_latitude', 'destination_longitude']: driver_info_data.pop(key, None) _data, _ = user_schema.dump(_user) _data["driver_info"] = driver_info_data else: _data, _ = user_schema.dump(_user) _data['wallet_amount'] = _user.wallet_user[0].wallet_amount _data["school"] = str(_user.school_information.name) _data["user_type"] = user_type _data.pop('password', None) _data.pop('user_id', None) return { 'status': 'success', 'data': { 'message': 'User has been successfully retrieved', 'user': _data } }, 200
def get(self): _user_id = g.current_user.id _user = User.query.get(_user_id) if not _user: return moov_errors('User does not exist', 404) _page = request.args.get('page') _limit = request.args.get('limit') page = int(_page or current_app.config['DEFAULT_PAGE']) limit = int(_limit or current_app.config['PAGE_LIMIT']) _transactions = Transaction.query.filter( or_(Transaction.sender_id == _user_id, Transaction.receiver_id == _user_id)).order_by( Transaction.transaction_date.desc()) transaction_count = len(_transactions.all()) _transactions = _transactions.paginate(page=page, per_page=limit, error_out=False) transactions = [] for _transaction in _transactions.items: _data, _ = transaction_schema.dump(_transaction) transactions.append(_data) previous_url = None next_url = None if _transactions.has_next: next_url = url_for(request.endpoint, limit=limit, page=page + 1, _external=True) if _transactions.has_prev: previous_url = url_for(request.endpoint, limit=limit, page=page - 1, _external=True) return { 'status': 'success', 'data': { 'message': 'Transactions successfully retrieved', 'all_count': transaction_count, 'current_count': len(transactions), 'transactions': transactions, 'next_url': next_url, 'previous_url': previous_url, 'current_page': _transactions.page, 'all_pages': _transactions.pages } }, 200
def put(self): json_input = request.get_json() keys = [ 'user_type', 'email', 'firstname', 'lastname', 'image_url', 'mobile_number', 'authorization_code', 'password' ] if validate_input_data(json_input, keys): return validate_input_data(json_input, keys) _user_id = g.current_user.id _user = User.query.get(_user_id) if not _user: return moov_errors("User does not exist", 404) if is_empty_request_fields(json_input): return moov_errors("Empty strings are not allowed, exception for image urls", 400) unauthorized_list = ["super_admin", "admin", "school", "car_owner", "moov"] if is_user_type_authorized(unauthorized_list, _user.user_type.title): return moov_errors("Unauthorized access", 401) for key in json_input.keys(): if key == 'user_type': return moov_errors('Unauthorized access, you cannot update user types', 401) if key == 'email': return moov_errors('Unauthorized access, you cannot update emails', 401) if key == 'password': if _user.check_password(json_input['password']): return moov_errors('Unauthorized, you cannot update with the same password', 401) if key == 'authorization_code': _user.__setitem__("authorization_code_status", True) _user.__setitem__(key, json_input[key]) _user.save() _data, _ = user_schema.dump(_user) _data["user_type"] = _user.user_type.title _data["school"] = str(_user.school_information.name) _data.pop('password', None) _data.pop('user_id', None) return { 'status': 'success', 'data': { 'user': _data, 'message': 'User information updated succesfully', } }, 200
def get(self): _current_user_id = g.current_user.id _current_user = User.query.get(_current_user_id) if not _current_user: return moov_errors("User does not exist", 404) _data = {} _data['user_id'] = _current_user_id _data['authorization_code'] = _data['authorization_code'] = _current_user.authorization_code _data['authorization_code_status'] = _current_user.authorization_code_status _data.pop('password', None) _data.pop('user_id', None) return jsonify({"status": "success", "data": { "data": _data } })
def get(self): _user_id = g.current_user.id _user = User.query.get(_user_id) if not _user: return moov_errors('User does not exist', 404) _user_location_name = request.args.get('user_location_name') _user_destination_name = request.args.get('user_destination_name') _user_location = request.args.get('user_location') _user_destination = request.args.get('user_destination') _slots = request.args.get('slots') _fare_charge = request.args.get('fare_charge') _school = request.args.get('school') if not _user_location or \ not _user_destination or \ not _user_location_name or \ not _user_destination_name or \ not _slots or \ not _fare_charge or \ not _school or \ validate_empty_string(_user_location) or \ validate_empty_string(_user_destination) or \ validate_empty_string(_user_location_name) or \ validate_empty_string(_user_destination_name) or \ validate_empty_string(_slots) or \ validate_empty_string(_fare_charge) or \ validate_empty_string(_school): return moov_errors( "Parameters user_destination_name, user_location_name, user_destination, user_location, slots, fare_charge and school are required", 400) try: _user_location = _user_location.split(',') _user_destination = _user_destination.split(',') # confirm if locations contains both latitude and longitude if len(_user_location) != 2 or len(_user_destination) != 2: return moov_errors( "User destination and location should contain latitude and longitude separated by comma(,)", 400) # cast the parameters _user_location_name = str(_user_location_name) _user_destination_name = str(_user_destination_name) _user_location_latitude = float(_user_location[0]) _user_location_longitude = float(_user_location[1]) _user_destination_latitude = float(_user_destination[0]) _user_destination_longitude = float(_user_destination[1]) _slots = int(_slots) _fare_charge = float(_fare_charge) _school = str(_school) except ValueError as error: return moov_errors( "Parameters should have valid types ({0})".format(error), 400) # handles mischief if _slots <= 0: return moov_errors( "Number of slots cannot be less than or equal to zero", 400) # checks if user is not currently on any ride if _user.current_ride: return moov_errors( "Sorry, you cannot make another request if you already requested or are currently on a ride", 400) # check school school = get_school(name=_school.lower()) if not school: return moov_errors("School ({0}) not found".format(_school), 404) _user_wallet = _user.wallet_user[0].wallet_amount if _user_wallet < _fare_charge: return moov_errors( "Request denied. Wallet amount not sufficient for this trip", 400) _driver = None _empty_slot_drivers = [] _available_slot_drivers = [] drivers = DriverInfo.query.filter( (DriverInfo.admin_confirmed == True) & (DriverInfo.status == True) & (DriverInfo.available_car_slots >= _slots)).all() # handle case where no driver was found if not drivers: return moov_errors("No driver available, please try again", 404) # sift the result to get empty slot drivers and available drivers for driver in drivers: # make certain the driver is for the requested school if str(driver.driver_information.school_id) == str(school.id): _available_slot_drivers.append(driver) if driver.on_trip_with == None: _empty_slot_drivers.append(driver) if _available_slot_drivers: # handle case where there are available slot drivers if len(_available_slot_drivers) == 1: _driver = _available_slot_drivers[0] else: nearest_location_drivers = get_nearest_or_furthest_drivers( driver_list=_available_slot_drivers, user_latitude=_user_location_latitude, user_longitude=_user_location_longitude, number_of_drivers=5, operation="nearest") nearest_destination_driver = get_nearest_or_furthest_drivers( driver_list=nearest_location_drivers, user_latitude=_user_destination_latitude, user_longitude=_user_destination_longitude, number_of_drivers=1, operation="nearest") _driver = nearest_destination_driver[0] elif _empty_slot_drivers: # handle case where there are empty slot drivers _driver = _empty_slot_drivers[0] _driver.available_car_slots = _driver.car_slots _driver.on_trip_with = {} _driver.save() else: # handle case no driver was found for the school at all return moov_errors( "No driver available for this school ({0})".format(_school), 404) _driver.add_to_trip(_driver.driver_id, str(_user.email), _slots) _driver_data, _ = driver_info_schema.dump(_driver) _driver_data["driver_location"] = [ _driver_data["location_latitude"], _driver_data["location_longitude"] ] _driver_data["driver_destination"] = [ _driver_data["destination_latitude"], _driver_data["destination_longitude"] ] # remove all irrelevant info for drivers for key in ['bank_name', 'account_number', 'admission_type_id', 'driver_id', 'location_latitude', \ 'location_longitude', 'destination_latitude', 'destination_longitude']: _driver_data.pop(key, None) # append other driver's information from the user's model _driver_user_data, _ = user_schema.dump(_driver.driver_information) for key in _driver_user_data.keys(): if key not in ["id", "user_type_id", "user_id", "password", "authorization_code", \ "authorization_code_status", "reset_password", "number_of_rides", "user_type"]: _driver_data[key] = _driver_user_data[key] # User Aspect # remove all irrelevant info for drivers for key in [ 'on_trip_with', 'created_at', 'modified_at', 'current_ride', 'authentication_type' ]: _driver_data.pop(key, None) # add to user's current ride _user.add_current_ride( user_email=_user.email, driver_info=_driver_data, user_location_name=_user_location_name, user_destination_name=_user_destination_name, user_location=[_user_location_latitude, _user_location_longitude], user_destination=[ _user_destination_latitude, _user_destination_longitude ]) # send notification to driver save_notification( recipient_id=_driver_user_data['id'], sender_id=_user_id, message="{0} ({1}) has requested to ride with you from {2} to {3}" \ .format(_user.firstname.title(), _user.email, _user_location_name, _user_destination_name) ) return { 'status': 'success', 'data': { 'driver': _driver_data, 'message': 'Driver information retrieved succesfully', } }, 200
def post(self): json_input = request.get_json() _driver_id = g.current_user.id _driver = DriverInfo.query.filter( DriverInfo.driver_id == _driver_id).first() if not _driver: return moov_errors("Driver does not exist", 404) keys = ['confirmation_type', 'user_email'] if validate_input_data(json_input, keys): return validate_input_data(json_input, keys) if 'confirmation_type' not in json_input or 'user_email' not in json_input: return moov_errors('Confirmation type and user email are required', 400) _confirmation_type = str(json_input['confirmation_type']).lower() if _confirmation_type not in ['accept', 'reject']: return moov_errors( 'Confirmation type can only be accept or reject', 400) _user_email = str(json_input['user_email']).strip().lower() _user = User.query.filter(User.email == _user_email).first() if not _user: return moov_errors('User email is not valid', 400) # confirm if user was assigned/requested for this driver confirm_request = False if _driver.on_trip_with: for key in _driver.on_trip_with: if key == _user.email: confirm_request = True if not confirm_request: return moov_errors( '{0} did not request a ride with current driver'.format( _user_email), 400) if _confirmation_type == "reject": _driver.remove_from_trip(_driver_id, str(_user.email)) _user.remove_current_ride(str(_user.email)) # send notification to user save_notification( recipient_id=_user.id, sender_id=_driver_id, message="{0} has rejected your request for a ride".format( _driver.driver_information.firstname.title())) return { 'status': 'success', 'data': { 'message': 'Ride successfully rejected' } }, 200 # send notification to user save_notification( recipient_id=_user.id, sender_id=_driver_id, message="{0} has accepted your request for a ride".format( _driver.driver_information.firstname.title())) return { 'status': 'success', 'data': { 'message': 'Ride successfully accepted' } }, 200
def post(self): set_temporary_password = False json_input = request.get_json() keys = ['email', 'password'] if validate_input_data(json_input, keys): return validate_input_data(json_input, keys) data, errors = user_login_schema.load(json_input) if errors: return moov_errors(errors, 422) _user = User.query.filter(User.email.like(json_input['email'])).first() if not _user: return moov_errors('User does not exist', 404) if _user.reset_password: temp_password = ForgotPassword.query.filter( ForgotPassword.user_id==_user.id ).order_by( ForgotPassword.created_at.desc() ).first() # Precautions if (not temp_password) or (temp_password and temp_password.temp_password != json_input['password']): return moov_errors("Invalid password", 400) if temp_password.used: return moov_errors("Sorry, this password has been used to reset forgotten password details", 400) if not datetime.datetime.utcnow() <= (temp_password.created_at + timedelta(days=1)): return moov_errors("Temporary password expired", 400) set_temporary_password = True temp_password.used = True _user.reset_password = False temp_password.save() _user.save() else: if not _user.check_password(json_input['password']): return moov_errors("Invalid email/password", 401) _user_wallet = Wallet.query.filter(Wallet.user_id==_user.id).first() token_date = datetime.datetime.utcnow() payload = { "id": _user.id, "stamp": str(token_date) } _token = jwt.encode(payload, os.getenv("TOKEN_KEY"), algorithm='HS256') _data, _ = user_schema.dump(_user) _data["wallet_amount"] = _user_wallet.wallet_amount if _user_wallet else "Unavailable" _data["school"] = str(_user.school_information.name) _data["user_type"] = _user.user_type.title _data["set_temporary_password"] = set_temporary_password _data.pop('password', None) _data.pop('user_id', None) return jsonify({"status": "success", "data": { "data": _data, "message": "Login successful", "token": str(_token) } })
def post(self): json_input = request.get_json() keys = [ 'user_type', 'firstname', 'lastname', 'email', 'image_url', 'mobile_number', 'password', 'authentication_type', 'school' ] _user = {} if validate_input_data(json_input, keys, _user): return validate_input_data(json_input, keys, _user) data, errors = user_schema.load(json_input) if errors: return moov_errors(errors, 422) if validate_empty_string(json_input['password']): return moov_errors('Password cannot be empty', 400) # verify email if User.is_user_data_taken(json_input['email']): return moov_errors('User already exists', 400) # verify empty request fields if is_empty_request_fields(json_input): return moov_errors("Empty strings are not allowed, exception for image urls", 400) # verify school school = get_school(str(json_input['school']).lower()) if not school: return moov_errors('{0} (school) does not exist'.format(str(json_input['school'])), 400) user_type = UserType.query.filter(UserType.title==data['user_type'].lower()).first() user_type_id = user_type.id if user_type else None unauthorized_list = ["super_admin", "admin", "school", "car_owner", "moov"] if is_user_type_authorized(unauthorized_list, data['user_type'].lower()): return moov_errors("Unauthorized, you cannot create a/an {0}".format(data['user_type']), 401) if not user_type_id: return moov_errors("User type can only be student or driver", 400) moov_email = os.environ.get("MOOV_EMAIL") moov_user = User.query.filter(User.email==moov_email).first() if not moov_user: return not_found_errors(moov_email) _transaction_icon = "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973461_1280.png" transaction_icon = Icon.query.filter(Icon.operation_type=="moov_operation").first() if transaction_icon: _transaction_icon_id = transaction_icon.id authentication_type = "email" if "authentication_type" not in json_input else json_input['authentication_type'] authentication_type = get_authentication_type(authentication_type) new_user = User( password=data['password'], school_id=school.id, user_type_id=user_type_id, authentication_type=authentication_type, firstname=data['firstname'], lastname=data['lastname'], email=data['email'], image_url=data['image_url'] if json_input.get('image_url') else \ "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973461_1280.png", mobile_number=data['mobile_number'] if json_input.get('mobile_number') else "" ) new_user.save() user_wallet = Wallet( wallet_amount= 0.00, user_id = new_user.id, description = "{0} {1}'s Wallet".format((new_user.lastname).title(), (new_user.firstname).title()) ) user_wallet.save() user_notification = Notification( message="Welcome to MOOV app.", recipient_id=new_user.id, sender_id=moov_user.id, transaction_icon_id=_transaction_icon_id ) user_notification.save() token_date = datetime.datetime.utcnow() payload = { "id": new_user.id, "stamp": str(token_date) } _token = jwt.encode(payload, os.getenv("TOKEN_KEY"), algorithm='HS256') message = "The profile with email {0} has been created succesfully".format(new_user.email) _data, _ = user_schema.dump(new_user) _data["wallet_amount"] = user_wallet.wallet_amount _data["school"] = str(new_user.school_information.name) _data["user_type"] = new_user.user_type.title _data.pop('password', None) _data.pop('user_id', None) if user_type.title.lower() == "driver": new_driver_info = DriverInfo( driver_id=new_user.id ) new_driver_info.save() user_notification = Notification( message="Thank you for registering to be a MOOV driver. \ Your request is waiting approval, we will get back to you soon", recipient_id=new_user.id, sender_id=moov_user.id, transaction_icon_id=_transaction_icon_id ) user_notification.save() return { 'status': 'success', 'data': { 'user': _data, 'message': message, 'token': _token } }, 201
def post(self): json_input = request.get_json() keys = ['email'] if validate_input_data(json_input, keys): return validate_input_data(json_input, keys) _user = User.query.filter(User.email == json_input['email']).first() if not _user: return moov_errors('User does not exist', 404) if _user.authentication_type.value != None and \ _user.authentication_type.value != "email_type": return moov_errors( 'You cannot reset password for authentications other than email', 401) generated_password = generate_password() new_password = ForgotPassword(user_id=_user.id, temp_password=generated_password, used=False) new_password.save() _user.reset_password = True _user.save() moov_email = os.environ.get("MOOV_EMAIL") moov_user = User.query.filter(User.email == moov_email).first() if not moov_user: return not_found_errors(moov_email) _transaction_icon_id = "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973461_1280.png" transaction_icon = Icon.query.filter( Icon.operation_type == "moov_operation").first() if transaction_icon: _transaction_icon_id = transaction_icon.id message = "You reset your password" save_notification(recipient_id=_user.id, sender_id=moov_user.id, message=message, transaction_icon_id=_transaction_icon_id) send_mail = send_forgot_password_mail( email=_user.email, firstname=_user.firstname.title(), password=generated_password) if send_mail["status"]: return { 'status': 'success', 'data': { 'message': "Password reset successful, check email for temporary password which is valid for 24 hours" } }, 200 return { 'status': 'fail', 'data': { 'message': "Email was not sent successfully" } }, 503
def post(self): json_input = request.get_json() keys = [ 'type_of_operation', 'cost_of_transaction', 'receiver_email', 'school_name', 'verification_code', 'car_owner_email', 'free_token' ] _transaction = {} if validate_input_data(json_input, keys, _transaction): return validate_input_data(json_input, keys, _transaction) data, errors = transaction_schema.load(json_input) if errors: return moov_errors(errors, 422) # establishing the _current_user is valid and not an admin _current_user_id = g.current_user.id _current_user = User.query.get(_current_user_id) if not _current_user: return moov_errors('User does not exist', 404) _current_user_type = (_current_user.user_type.title).lower() if _current_user_type == "admin": return moov_errors('Unauthorized access', 401) _transaction_icon = "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973461_1280.png" moov_email = os.environ.get("MOOV_EMAIL") moov_user = User.query.filter(User.email == moov_email).first() if not moov_user: return not_found_errors(moov_email) # case load_wallet if str(json_input['type_of_operation']).lower() == 'load_wallet': if 'verification_code' not in json_input: return moov_errors( 'Transaction denied. Verification is compulsory to load wallet', 400) # third-party api to verify paystack payment paystack_verified = verify_paystack_payment( user=_current_user, verification_code=str(json_input['verification_code'])) if not paystack_verified: return moov_errors( "Unauthorized transaction. Paystack payment was not verified", 401) cost_of_transaction = json_input["cost_of_transaction"] message = "Cost of transaction cannot be a negative value" if check_transaction_validity(cost_of_transaction, message): return check_transaction_validity(cost_of_transaction, message) _data, _ = load_wallet_operation(cost_of_transaction, _current_user, _current_user_id, moov_user) _data["free_ride_token"] = "" return { 'status': 'success', 'data': { 'transaction': _data, 'message': "Transaction succesful" } }, 201 # case ride_fare and transfer if ('receiver_email') in json_input: cost_of_transaction = json_input["cost_of_transaction"] _receiver_email = json_input['receiver_email'] _sender_id = _current_user_id _sender = _current_user _receiver = User.query.filter( User.email == _receiver_email).first() if not _receiver: return moov_errors("User does not exist", 404) if str(_receiver.user_type.title) == "admin": return moov_errors("Unauthorized access", 401) _receiver_wallet = Wallet.query.filter( Wallet.user_id == _receiver.id).first() _sender_wallet = Wallet.query.filter( Wallet.user_id == _sender_id).first() message = "Cost of transaction cannot be a negative value" if check_transaction_validity(cost_of_transaction, message): return check_transaction_validity(cost_of_transaction, message) receiver_amount_before_transaction = _receiver_wallet.wallet_amount sender_amount_before_transaction = _sender_wallet.wallet_amount sender_amount_after_transaction = _sender_wallet.wallet_amount - cost_of_transaction message = "Sorry, you cannot transfer more than your wallet amount" if check_transaction_validity(sender_amount_after_transaction, message): return check_transaction_validity( sender_amount_after_transaction, message) # case transfer if str(json_input['type_of_operation']).lower() == 'transfer': if str(_receiver.id) == str(_sender_id): return moov_errors( "Unauthorized. A user cannot transfer to him/herself", 401) transfer_percentage_price = (get_percentage_price( title="default_transfer")).price transfer_charge = transfer_percentage_price * cost_of_transaction sender_amount_after_transaction = _sender_wallet.wallet_amount - cost_of_transaction - transfer_charge if check_transaction_validity(sender_amount_after_transaction, message): return check_transaction_validity( sender_amount_after_transaction, message) moov_wallet = get_wallet(email=moov_email) if not moov_wallet: return not_found_errors(moov_email) _data, _ = transfer_operation( _sender, _receiver, _sender_wallet, _receiver_wallet, moov_wallet, cost_of_transaction, transfer_charge, sender_amount_before_transaction, receiver_amount_before_transaction, sender_amount_after_transaction, moov_user) _data["free_ride_token"] = "" return { 'status': 'success', 'data': { 'transaction': _data, 'message': "Transaction succesful" } }, 201 # case ride_fare if str(json_input['type_of_operation']).lower() == 'ride_fare': _data = {} free_ride_icon = Icon.query.filter( Icon.operation_type == "free_ride_operation").first() if free_ride_icon: free_ride_icon_id = free_ride_icon.id if ("free_token" in json_input) and (json_input["free_token"] is not None): token_valid = FreeRide.query.filter( FreeRide.token == json_input["free_token"]).first() # error handlers if not token_valid: return moov_errors( "{0} is not a valid token".format( json_input["free_token"]), 404) if not token_valid.token_status: return moov_errors( "{0} has been used".format( json_input["free_token"]), 400) # set the token to false i.e. make it inactive token_valid.token_status = False token_valid.save() # save notification transaction_icon = Icon.query.filter( Icon.operation_type == "ride_operation").first() if transaction_icon: _transaction_icon_id = transaction_icon.id notification_user_sender_message = "Your transaction costs N0, your free token {0} was used".format( json_input["free_token"]) notification_user_receiver_message = "Your transaction with {0} was a free ride".format( str(_sender.firstname).title()) save_notification(recipient_id=_sender.id, sender_id=moov_user.id, message=notification_user_sender_message, transaction_icon_id=_transaction_icon_id) save_notification( recipient_id=_receiver.id, sender_id=moov_user.id, message=notification_user_receiver_message, transaction_icon_id=_transaction_icon_id) # save transaction transaction_detail = "Free ride token {0} was used for this ride transaction".format( json_input["free_token"]) _data, _ = save_transaction( transaction_detail=transaction_detail, type_of_operation=OperationType.ride_type, type_of_transaction=TransactionType.both_types, cost_of_transaction=0, _receiver=_receiver, _sender=_sender, _receiver_wallet=_receiver_wallet, _sender_wallet=_sender_wallet, receiver_amount_before_transaction= receiver_amount_before_transaction, sender_amount_before_transaction= sender_amount_before_transaction, receiver_amount_after_transaction=( receiver_amount_before_transaction + 0), sender_amount_after_transaction=( sender_amount_before_transaction + 0)) _data["free_ride_token"] = "" else: # increments the number of rides taken by a user _sender.number_of_rides += 1 if "school_name" not in json_input: return moov_errors( "school_name field is compulsory for ride fare", 400) school = get_school( (str(json_input["school_name"])).lower()) if not school: return not_found_errors(json_input["school_name"]) school_email = school.email car_owner_email = os.environ.get("CAR_OWNER_EMAIL") if ( "car_owner" not in json_input) else json_input["car_owner"] car_owner = get_user(car_owner_email) if not car_owner: return not_found_errors(car_owner_email) moov_wallet = get_wallet(email=moov_email) school_wallet = get_wallet(email=school_email) car_owner_wallet = get_wallet(email=car_owner_email) if not moov_wallet: return not_found_errors(moov_email) if not school_wallet: return not_found_errors(school_email) if not car_owner_wallet: return not_found_errors(car_owner_email) # change here in case percentage cut is dynamic for drivers of different schools driver_percentage_price_info = get_percentage_price( title="default_driver") if not driver_percentage_price_info: # ignore repitition from above for now driver_percentage_price_info = get_percentage_price( title="default_driver") school_percentage_price_info = get_percentage_price( title=school.email) if not school_percentage_price_info: school_percentage_price_info = get_percentage_price( title="default_school") car_owner_percentage_price_info = get_percentage_price( title=car_owner.email) if not car_owner_percentage_price_info: car_owner_percentage_price_info = get_percentage_price( title="default_car_owner") if not car_owner_percentage_price_info or not school_percentage_price_info: return moov_errors( "Percentage price was not set for the school or car_owner ({0}, {1})" .format(school.name, car_owner_email), 400) # free ride generation free_ride_token = get_free_ride_token(_sender) if free_ride_token: free_ride_description = "Token generated for {0} on the {1} for ride number {2}".format( _sender.email, str(datetime.now()), _sender.number_of_rides) save_free_ride_token( free_ride_type=FreeRideType.ride_type, token=free_ride_token, description=free_ride_description, user_id=_sender_id) free_ride_notification_message = "You have earned a free ride token '{0}'".format( free_ride_token) save_notification( recipient_id=_sender_id, sender_id=moov_user.id, message=free_ride_notification_message, transaction_icon_id=free_ride_icon_id) _data, _ = ride_fare_operation( _sender, _receiver, driver_percentage_price_info, school_percentage_price_info, car_owner_percentage_price_info, cost_of_transaction, receiver_amount_before_transaction, sender_amount_before_transaction, sender_amount_after_transaction, moov_wallet, school_wallet, car_owner_wallet, _sender_wallet, _receiver_wallet, moov_user) _data["free_ride_token"] = free_ride_token return { 'status': 'success', 'data': { 'transaction': _data, 'message': "Transaction succesful" } }, 201 # cases that don't meet the required condition return moov_errors("Transaction denied", 400)
def check_transaction_validity(amount, message): if amount < 0: return moov_errors(message, 400)