Esempio n. 1
0
    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
                        }
                    })
Esempio n. 2
0
    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
Esempio n. 3
0
    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)
Esempio n. 4
0
    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
Esempio n. 5
0
    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
Esempio n. 6
0
    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
Esempio n. 7
0
    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
Esempio n. 8
0
    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
                        }
                    })
Esempio n. 9
0
    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
Esempio n. 10
0
    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
Esempio n. 11
0
    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)
                        }
                    })
Esempio n. 12
0
    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
Esempio n. 13
0
    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
Esempio n. 14
0
    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)
Esempio n. 15
0
def check_transaction_validity(amount, message):
    if amount < 0:
        return moov_errors(message, 400)