예제 #1
0
def upload_payment(user):
    """
    upload  a payment for a given project
    only the creator can upload a payment
    """
    if user["role"] != "Creator":
        abort(
            custom_make_response(
                "error", "You are not authorized to carry out this action.",
                403))
    try:
        receivedFile = request.files["paymentExcelFile"]
        if allowed_extension(receivedFile.filename) and receivedFile:
            return file_operation(
                receivedFile,
                PAYMENTS_UPLOAD_FOLDER,
                "Payment",
                user["companyId"],
                user["id"],
            )
        return custom_make_response(
            "error",
            "Only excel files are allowed, please select\
                 a payment excel file & try again.",
            400,
        )
    except Exception as e:
        error_messages(e, "payment")
예제 #2
0
파일: project.py 프로젝트: KabakiAntony/rms
def get_projects(user, companyId):
    """get projects for the given user company"""
    if user["companyId"] == companyId:
        company_projects = Project.query.filter_by(companyId=companyId).all()
        _projects = projects_schema.dump(company_projects)
        if not _projects:
            return abort(
                custom_make_response(
                    "error",
                    "No projects exist for your company, Once you\
                        create some they will appear here.",
                    404,
                )
            )
        elif _projects:
            return custom_make_response(
                "data", _projects, 200
            )
    else:
        return abort(
            custom_make_response(
                "error",
                "There appears to be a mismatch in the authorization\
                     data,Please logout, login & try again, if the problem\
                          persists,contact the site administrator.",
                400,
            )
        )
예제 #3
0
파일: user.py 프로젝트: KabakiAntony/rms
def set_new_password(user):
    """updates a user password from the reset page"""
    try:
        data = request.get_json()
        email = user["email"]
        new_password = data["password"]

        check_for_whitespace(data, ["email", "password"])
        isValidEmail(email)
        isValidPassword(new_password)
        User.query.filter_by(email=user["email"]).update(
            dict(password=f"{generate_password_hash(str(new_password))}"))
        db.session.commit()
        subject = """Password updated successfully."""
        content = f"""
        {password_reset_success_content()}
        <a href="/forgot"
        style="{button_style()}"
        >Forgot Password</a>
        {email_signature()}
        """
        send_mail(email, subject, content)
        return custom_make_response(
            "data", "Your password has been updated successfully", 200)
    except Exception as e:
        abort(
            custom_make_response("error", f"The following error ocurred: {e}",
                                 400))
예제 #4
0
파일: project.py 프로젝트: KabakiAntony/rms
def close_or_suspend_project(user, id):
    """
    close or suspend the project.
    """
    if user['role'] != "Creator":
        abort(
            custom_make_response(
                "error",
                "You are not authorized to carryout this function",
                403
            )
        )
    try:
        data = request.get_json()
        project_status = data['new_status']

        check_for_whitespace(data, ["new_status"])
        update_project_params = {
            "project_status": project_status
        }
        Project.query.filter_by(id=id).update(update_project_params)
        db.session.commit()
        return custom_make_response(
            "data", f"Project {project_status} successfully.", 200)

    except Exception as e:
        abort(
            custom_make_response(
                "error", f"The following error occured :: {e}", 400
            )
        )
예제 #5
0
def get_project_payments(user, project_no):
    """
    given a user and project id go fetch the
    given project payments over time.
    """
    file_data = (db.session.query(Project, Payments).filter(
        Project.projectNumber == Payments.project_number).filter_by(
            projectNumber=project_no).all())

    if not file_data:
        abort(
            custom_make_response(
                "error",
                "No file(s) have been found for your company,\
                     ask the creator to upload & try again.",
                404,
            ))
    files_list = []
    for result in file_data:
        result_format = {
            "project_name": result[0].project_name,
            "project_number": result[0].projectNumber,
            "employee_id": result[1].employee_id,
            "employee_name": result[1].employee_name,
            "expense_head": result[1].expense_head,
            "rate": result[1].rate,
            "days": result[1].days,
            "file_id": result[1].file_id,
            "float_amount": result[1].total_amount,
            "advance_amount": result[1].advance_amount
        }
        files_list.append(result_format)
    return custom_make_response("data", files_list, 200)
예제 #6
0
def get_authorizer_files(user):
    """return the files for a given company for the authorizer"""
    file_data = (db.session.query(
        Files, Project,
        Employees).filter(Files.projectId == Project.id).filter(
            Files.createdBy == Employees.id).filter_by(
                companyId=user["companyId"]).all())

    if not file_data:
        abort(
            custom_make_response(
                "error",
                "No file(s) have been found for your company,\
                     ask the creator to upload & try again.",
                404,
            ))

    fileList = []
    for result in file_data:
        result_format = {
            "Id": result[0].id,
            "fileType": result[0].fileType,
            "project_name": result[1].project_name,
            "projectNumber": result[1].projectNumber,
            "fullname": result[2].fullname,
            "createdBy": result[0].createdBy,
            "fileStatus": result[0].fileStatus,
            "fileAmount": result[0].fileAmount,
            "dateCreated": result[0].dateCreated.strftime("%Y-%m-%d"),
            "fileName": result[0].fileName,
        }
        fileList.append(result_format)
    return custom_make_response("data", fileList, 200)
예제 #7
0
def upload_employee_master(user):
    """
    upload the employee master file for a
    given company only the admin can do this
    """
    try:
        receivedFile = request.files["employeeExcelFile"]
        if allowed_extension(receivedFile.filename) and receivedFile:
            secureFilename = secure_filename(receivedFile.filename)
            filePath = os.path.join(
                current_app.root_path, EMPLOYEE_UPLOAD_FOLDER, secureFilename)
            receivedFile.save(filePath)
            new_file_path = rename_file(
                filePath,
                user["companyId"], EMPLOYEE_UPLOAD_FOLDER, "_employees_"
            )
            add_id_and_company_id(new_file_path, user["companyId"])
            updated_file_path = add_id_and_company_id(
                new_file_path, user["companyId"])
            csvFile = convert_to_csv(updated_file_path, EMPLOYEE_UPLOAD_FOLDER)
            insert_csv(csvFile, 'public."Employees"')
            return custom_make_response(
                "data", "Employees data saved successfully.", 200
            )
        else:
            return custom_make_response(
                "error", "Only excel files are allowed.", 400)
    except psycopg2.Error as e:
        # exceptions go to site administrator and email
        # the user gets a friendly error notification
        if e.pgcode == ("23505"):
            remove_unused_duplicates(updated_file_path)
            remove_unused_duplicates(csvFile)
            abort(
                custom_make_response(
                    "error",
                    "The record(s) you are trying to upload\
                        already exist in the database.",
                    409,
                )
            )
        elif e.pgcode == ("22P04"):
            remove_unused_duplicates(updated_file_path)
            remove_unused_duplicates(csvFile)
            abort(
                custom_make_response(
                    "error",
                    "The file you are uploading is not in the\
                        allowed format for employees file.",
                    400,
                )
            )
        else:
            abort(
                custom_make_response(
                    "error", f"The following error occured {e}", 400)
            )
예제 #8
0
def get_project_region(user, projectId):
    """
    get project regions
    """
    project_regions = ProjectRegions.query.filter_by(projectId=projectId).all()
    regions = project_regions_schema.dump(project_regions)
    if not regions:
        abort(
            custom_make_response(
                "error", "No regions have been found for that project\
                    please create some and try again.", 404))
    else:
        return custom_make_response("data", regions, 200)
예제 #9
0
def authorize_or_reject_withdraw(user, id):
    """authorize or reject file"""
    try:
        data = request.get_json()
        new_status = data["new_status"]
        advance_amount = data["advance_amount"]
        fileId = id
        date_actioned = datetime.datetime.utcnow()
        todays_date = date_actioned.strftime("%Y-%m-%d")
        file_status = new_status

        check_for_whitespace(data, ["new_status", "file_id"])
        new_file_params = {
            "fileStatus": file_status,
            "dateAuthorizedOrRejected": todays_date,
            "authorizedOrRejectedBy": user["id"],
        }
        Files.query.filter_by(id=fileId).update(new_file_params)

        if data["new_status"] == "Authorized":
            returned_file, project_id, file_type = get_authorized_files(id)
            returned_file["advance_amount"] = float(advance_amount)
            authorized_file = Payments(**returned_file)
            db.session.add(authorized_file)
            db.session.commit()
            if file_type == "Payment":
                _budget_file = Files.query.\
                    filter_by(projectId=project_id).\
                    filter_by(fileType="Budget").all()
                budget_file = files_schema.dump(_budget_file)
                budget_amount = budget_file[0]["fileAmount"]
                new_budget_amount = budget_amount - float(advance_amount)
                new_amount = {"fileAmount": new_budget_amount}
                Files.query.filter_by(projectId=project_id).\
                    filter_by(fileType="Budget").update(new_amount)
                payment_file = get_individual_payment_amount(id)
                for file in payment_file:
                    auth_advance_amount = {
                        "advance_amount": file['total_amount']
                    }
                    Payments.query.filter(Payments.file_id == id).\
                        filter(Payments.id == file['id']).\
                        update(auth_advance_amount)
                    db.session.commit()
        return custom_make_response("data",
                                    f"File {file_status} successfully.", 200)

    except Exception as e:
        abort(
            custom_make_response("error",
                                 f"The following error occured :: {e}", 400))
예제 #10
0
파일: user.py 프로젝트: KabakiAntony/rms
def reactivate_system_user(user):
    """
    reactivate a suspended user account
    check if account is suspended if not
    then notify the user no need proceeding
    if account if already active.
    """
    try:
        data = request.get_json()
        email = data["email"]

        check_for_whitespace(data, ["email"])
        isValidEmail(email)
        employee = employee_schema.dump(
            Employees.query.filter_by(companyId=user['companyId']).filter_by(
                email=email).first())

        if not employee:
            abort(403)

        user = user_schema.dump(
            User.query.filter_by(email=email).filter_by(
                companyId=user['companyId']).first())

        if employee and not user:
            abort(404)

        if user['isActive'] == 'true':
            abort(400)

        User.query.filter_by(email=email).update(dict(isActive="true"))
        db.session.commit()

        return custom_make_response("data",
                                    "User account activated successfully", 200)

    except Exception as e:
        if (e.code == 400):
            return custom_make_response("error",
                                        "The user account is already active.",
                                        400)
        elif (e.code == 403):
            return custom_make_response(
                "error", "The user whose account you are trying to activate \
                        is not a member of your company", 403)

        elif (e.code == 404):
            return custom_make_response(
                "error", "You are trying to activate an account\
                        that does not exist, Please create one.", 404)
예제 #11
0
def get_project_number(user):
    """
    get the next project/job number for a given
    company
    """
    project_data = ProjectNumber.query.\
        filter_by(companyId=user['companyId']).first()
    the_number = project_number_schema.dump(project_data)
    if not the_number:
        abort(
            custom_make_response(
                "error", "No project/job number has been set for your company",
                404))
    else:
        return custom_make_response("data", the_number['projectNumber'], 200)
예제 #12
0
파일: user.py 프로젝트: KabakiAntony/rms
def suspend_system_user(user):
    """
    suspend a system user
    """
    try:
        data = request.get_json()
        email = data["email"]

        check_for_whitespace(data, ["email"])
        isValidEmail(email)
        employee = employee_schema.dump(
            Employees.query.filter_by(companyId=user['companyId']).filter_by(
                email=email).first())

        if not employee:
            abort(400)

        user = user_schema.dump(
            User.query.filter_by(email=email).filter_by(
                companyId=user['companyId']).first())
        if employee and not user:
            abort(404)

        if user['isActive'] == 'false':
            abort(403)

        User.query.filter_by(email=email).update(dict(isActive="false"))
        db.session.commit()
        return custom_make_response("data",
                                    "User account suspended successfully", 200)

    except Exception as e:
        if (e.code == 400):
            return custom_make_response(
                "error", "The user you are trying to suspend \
                    is not a member of your company", 400)
        elif (e.code == 404):
            return custom_make_response(
                "error", "The employee you are trying to\
                 suspend is not a system user.", 404)
        elif (e.code == 403):
            return custom_make_response(
                "error", "The user account is already suspended.", 403)
        else:
            return custom_make_response(
                "error", "An internal server error occured,\
                    the site admin has been notified, \
                        please give it a moment and try again.", 500)
예제 #13
0
def get_authorized_files(file_id):
    """return all info for a given file"""
    file_data = (db.session.query(
        Files, Project,
        Employees).filter(Files.projectId == Project.id).filter(
            Files.createdBy == Employees.id).filter(Files.id == file_id).all())

    if not file_data:
        abort(
            custom_make_response(
                "error",
                "No file(s) have been found for your company,\
                     ask the creator to upload & try again.",
                404,
            ))
    for result in file_data:
        result_format = {
            "id": generate_db_ids(),
            "employee_id": result[0].createdBy,
            "project_number": result[1].projectNumber,
            "project_name": result[1].project_name,
            "employee_name": result[2].fullname,
            "expense_head": result[0].fileType,
            "rate": 0,
            "days": 0,
            "total_amount": 0,
            "file_id": result[0].id,
        }
    return result_format, result[1].id, result[0].fileType
예제 #14
0
def send_mail(user_email, the_subject, the_content):
    """send email on relevant user action"""
    message = Mail(
        from_email=("*****@*****.**", "BT Technologies Team"),
        to_emails=user_email,
        subject=the_subject,
        html_content=the_content,
    )
    try:
        sg = SendGridAPIClient(os.environ.get("SENDGRID_KEY"))
        sg.send(message)
    except Exception as e:
        custom_make_response(
            "error",
            f"an error occured sending email contact administrator\
                     {e}",
            500,
        )
예제 #15
0
파일: company.py 프로젝트: KabakiAntony/rms
def get_companies(user):
    """
    get all companies that are registered
    at any onetime
    """
    # please note only the site admin
    # should have access to this data
    all_companies = Company.query.all()
    return custom_make_response("data", companies_schema.dump(all_companies),
                                200)
예제 #16
0
def update_project_number(user):
    """
    update project/job number for a given company
    """
    try:
        data = request.json()
        companyId = user['companyId']
        projectNumber = data['projectNumber']
        check_for_whitespace(data, ["projectNumber"])
        update_project_number = {"projectNumber": projectNumber + 1}
        ProjectNumber.query.\
            filter_by(companyId=companyId).update(update_project_number)
        db.session.commit()
        return custom_make_response("data",
                                    "Project number updated successfully.",
                                    200)

    except Exception as e:
        abort(
            custom_make_response("error",
                                 f"The following error occured :: {e}", 400))
예제 #17
0
def get_employees(user, companyId):
    """
    return the employees of a given company
    """
    if user["companyId"] == companyId:
        company_employees = Employees.query.filter_by(
            companyId=companyId).all()
        if not company_employees:
            return abort(
                custom_make_response(
                    "error",
                    "No employees have been found for your company,\
                        please upload & try again.",
                    404,
                )
            )
        elif company_employees:
            return custom_make_response(
                "data", employees_schema.dump(company_employees), 200
            )
        else:
            return abort(
                custom_make_response(
                    "error",
                    "Bummer an error occured fetching the records,\
                        please refresh and try again.",
                    500,
                )
            )

    else:
        return abort(
            custom_make_response(
                "error",
                "There appears to be a mismatch in the authorization\
                     data,Please logout, login and try again, if problem\
                          persists,contact the site administrator.",
                401,
            )
        )
예제 #18
0
def specify_job_number(user):
    """
    specify a job/project number for the
    projects of a given company
    """
    try:
        data = request.get_json()
        project_number = data['projectNumber']
        # current_user = User.query.filter_by(id=user["id"]).first()
        # _data = user_schema.dump(current_user)
        companyId = user["companyId"]
        id = generate_db_ids()

        check_for_whitespace(data, ["projectNumber", "companyId"])

        if ProjectNumber.query.filter_by(companyId=companyId).first():
            abort(409)

        new_project_number = ProjectNumber(id=id,
                                           projectNumber=project_number,
                                           companyId=companyId)

        db.session.add(new_project_number)
        db.session.commit()
        return custom_make_response(
            "data", f"Project number {project_number} set successfully.", 201)
    except Exception as e:
        if (e.code == 409):
            return custom_make_response(
                "error",
                """
                    You already have a project/job number set for your company.
                    It can only be set once.
                    """,
                409,
            )
        else:
            return custom_make_response(
                "error",
                f"{e} One or more mandatory fields has not been filled!", 400)
예제 #19
0
def get_pending_company_files(user, companyId):
    """ return all the pending files for a given company """
    if companyId == user['companyId']:
        files_data = db.session.query(Files, DetailedFile).\
            filter(Files.id == DetailedFile.id).\
            filter_by(companyId=user['companyId']).\
            filter_by(fileStatus="Pending").all()

    if not files_data:
        return abort(
            custom_make_response(
                "error", "No pending  file(s) have been \
                    found for your company,upload some & try again.", 404))

    fileList = []
    for result in files_data:
        result_format = {
            "Id": result[0].id,
            "fileStatus": result[0].fileStatus,
            "fileName": result[0].fileName,
            "wages": result[1].wages,
            "perDiem": result[1].perDiem,
            "telephoneCosts": result[1].telephoneCosts,
            "fieldTravelExpenses": result[1].fieldTravelExpenses,
            "administrativeSupport": result[1].administrativeSupport,
            "accomodationAllowance": result[1].accomodationAllowance,
            "consultants": result[1].consultants,
            "professionalCosts": result[1].professionalCosts,
            "printingAndStationery": result[1].printingAndStationery,
            "covid19PPEs": result[1].covid19PPEs,
            "venueHire": result[1].venueHire,
            "refreshments": result[1].refreshments,
            "transcription": result[1].transcription,
            "incentives": result[1].incentives,
            "zAmount": result[1].totalAmount
        }
        fileList.append(result_format)
    return custom_make_response("data", fileList, 200)
예제 #20
0
def create_project_region(user, projectId):
    """
    create project regions
    """
    try:
        data = request.get_json()
        region = data['region']
        projectId = data['projectId']
        id = generate_db_ids()

        check_for_whitespace(data, ["region", "projectId", "id"])
        if ProjectRegions.query.filter_by(region=data['region']).\
                filter_by(projectId=data['projectId']).first():
            abort(409)

        new_region = ProjectRegions(id=id, projectId=projectId, region=region)

        db.session.add(new_region)
        db.session.commit()
        return custom_make_response("data",
                                    f" {region} region created successfully.",
                                    201)
    except Exception as e:
        if (e.code == 409):
            return custom_make_response(
                "error",
                """
                    You already have a region with that name for the selected project,
                    Please change and try again !
                    """,
                409,
            )
        else:
            return custom_make_response(
                "error",
                f"{e} One or more mandatory fields has not been filled!", 400)
예제 #21
0
파일: company.py 프로젝트: KabakiAntony/rms
def company_signup_intent():
    """
    send a sign up link on the email to
    would be customers
    """
    try:
        data = request.get_json()
        email = data["email"]
        company = data["company"]
        id = generate_db_ids()

        check_for_whitespace(data, ["email", "company"])

        if not (email and company):
            abort(400)

        isValidEmail(email)

        if Company.query.filter_by(company=data["company"]).first():
            abort(409)

        token = jwt.encode(
            {
                "email": email,
                "company": company,
                "exp":
                datetime.datetime.utcnow() + datetime.timedelta(minutes=30),
            },
            KEY,
            algorithm="HS256",
        )
        # send signup intent email
        subject = f"""Thank you for requesting to register {company}."""
        content = f"""
        Welcome ,
        <br/>
        <br/>
        We are grateful to have you.<br/>
        Please click on register below to register your personal
        information to start using the system.<br/>Kindly note this
        link will only be active for thirty minutes.
        <br/>
        <br/>
        <a href="{signup_url}?in={token.decode('utf-8')}"
        style="{button_style()}">Register</a>
        <br/>
        <br/>
        Regards Antony,<br/>
        RMS Admin.
        """
        new_company = Company(id=id,
                              company=company,
                              joined_at=datetime.datetime.utcnow())
        db.session.add(new_company)
        db.session.commit()
        send_mail(email, subject, content)
        resp = custom_make_response(
            "data", {
                "message": f"Link to register {company} sent \
                    successfully,head over to {email} inbox for instructions",
                "admin_token": token.decode('utf-8'),
                "company": {
                    "company": company,
                    "email": email
                }
            }, 201)
        return resp

    except Exception as e:
        error = ""
        if (e.code == 409):
            error = custom_make_response(
                "error",
                "Your company is already registered, please\
                        contact the company admin.",
                409,
            )
        elif (e.code == 404):
            error = custom_make_response(
                "error", "Please enter a valid email address.", 404)
        elif (e.code == 400):
            error = custom_make_response(
                "error", "One or more mandatory fields has not been filled.",
                400)
    return error
예제 #22
0
def file_operation(received_file, upload_folder, file_src, company_id,
                   user_id):
    """
    takes a file from payments/budget uploads ,
    convert the file to a csv , extract an amount
    current_app.root_path
    """

    secureFilename = secure_filename(received_file.filename)
    filePath = os.path.join(current_app.root_path, upload_folder,
                            secureFilename)
    received_file.save(filePath)
    renamed_file_path = rename_file(
        filePath,
        company_id,
        upload_folder,
        "_" + request.form["projectName"] + "_" + file_src + "_",
    )
    csvFile = convert_to_csv(renamed_file_path, upload_folder)

    if file_src == "Budget":
        _amount = get_budget_amount(csvFile, renamed_file_path)
        if check_pending_files(company_id, file_src, _amount):
            remove_unused_duplicates(csvFile)
            remove_unused_duplicates(renamed_file_path)
            abort(409, "File Pending")
    else:
        _amount = get_payment_amount(csvFile, renamed_file_path)
        if check_pending_files(company_id, file_src, _amount):
            remove_unused_duplicates(csvFile)
            remove_unused_duplicates(renamed_file_path)
            abort(409, "File Pending")

        budget_file = get_project_file(company_id, "Budget")
        if not budget_file:
            remove_unused_duplicates(csvFile)
            remove_unused_duplicates(renamed_file_path)
            abort(404, "No Budget For Project")

        budget_amount = budget_file["fileAmount"]
        if budget_amount < float(_amount):
            remove_unused_duplicates(csvFile)
            remove_unused_duplicates(renamed_file_path)
            abort(400, "Project Amount Greater Than")

        status = budget_file["fileStatus"]
        if not (status == "Authorized"):
            remove_unused_duplicates(csvFile)
            remove_unused_duplicates(renamed_file_path)
            abort(400, "Budget  Unauthorized")

    id = generate_db_ids()
    the_file_name = get_file_name(renamed_file_path)
    insert_file_data(id, company_id, _amount, file_src, the_file_name, user_id)
    if file_src == "Budget":
        altered_csv_file = add_file_id(csvFile, id)
        insert_csv(altered_csv_file, 'public."DetailedFile"')
    else:
        data_file = pandas.read_csv(csvFile)
        rows = data_file.count()[0]
        data_file.insert(0, "id", "")
        for row in range(rows):
            new_id = generate_db_ids()
            data_file.loc[row, "id"] = new_id
            data_file.loc[row, "advance_amount"] = 0.0
            row + 1

        data_file.loc[:, "file_id"] = id
        data_file.to_csv(csvFile, index=False)
        data_file = pandas.read_csv(csvFile)
        insert_csv(csvFile, 'public."Payments"')
    return custom_make_response(
        "data", f"{file_src} file successfully sent for authorization.", 200)
예제 #23
0
파일: user.py 프로젝트: KabakiAntony/rms
def signin_all_users():
    """
    this signs in all users
    """
    try:
        user_data = request.get_json()
        email = user_data["email"]
        password = user_data["password"]

        # check data for sanity incase it bypass js on the frontend
        check_for_whitespace(user_data, ["email", "password"])
        isValidEmail(email)

        user = User.query.filter_by(email=user_data["email"]).first()

        if not user:
            abort(401)

        _user = user_schema.dump(user)
        _password_hash = _user["password"]

        if not User.compare_password(_password_hash, password):
            abort(401)

        _curr_user = user_schema.dump(user)
        if _curr_user["isActive"] != "true":
            abort(403)

        token = jwt.encode(
            {
                "id":
                _curr_user["id"],
                "role":
                _curr_user["role"],
                "exp":
                datetime.datetime.utcnow() + datetime.timedelta(minutes=480),
            },
            KEY,
            algorithm="HS256",
        )
        resp = custom_make_response(
            "data", {
                "message": "Signed in successfully, \
                    preparing your dashboard...",
                "auth_token": token.decode('utf-8'),
                "username": _curr_user["username"],
                "role": _curr_user["role"],
                "companyId": _curr_user["companyId"]
            }, 200)
        return resp

    except Exception as e:
        if (e.code == 401):
            return custom_make_response(
                "error",
                "Incorrect email and or password, check & try again !", 401)
        elif (e.code == 403):
            return custom_make_response(
                "error",
                "Your account is not in active\
                         status, contact company admin.",
                403,
            )
        elif (e.code == 400):
            return custom_make_response(
                "error", "One or more mandatory fields has not been filled.",
                400)
        else:
            return custom_make_response(
                "error", "Bummer an internal server error has occured,\
                    the site admin has been notified, Please give it a \
                        moment and try again.", 500)
예제 #24
0
파일: user.py 프로젝트: KabakiAntony/rms
def forgot_password():
    """send reset password email"""
    try:
        user_data = request.get_json()
        email = user_data["email"]

        check_for_whitespace(user_data, ["email"])
        isValidEmail(email)
        user = User.query.filter_by(email=user_data["email"]).first()
        if not user:
            # well this is interesting we are aborting with a code
            # 200 normally this is not the case but for this one we
            # have to make an exception reason being we don't
            # want to allow enumeration attacks on our system so we
            # we want to make it like we sending the email even though
            # that will not always be the case.
            abort(200)

        this_user = user_schema.dump(user)
        token = jwt.encode(
            {
                "id": this_user["id"],
                "email": this_user["email"],
                "exp":
                datetime.datetime.utcnow() + datetime.timedelta(minutes=30),
            },
            KEY,
            algorithm="HS256",
        )
        subject = """Password reset request"""
        content = f"""
        Hey {this_user['username'].split('.', 1)[0]},
        {password_reset_request_content()}
        <a href="{password_reset_url}?u={token.decode('utf-8')}"
        style="{button_style()}"
        >Reset Password</a>
        {email_signature()}
        """
        send_mail(email, subject, content)
        resp = custom_make_response(
            "data", {
                "message":
                "An email has been sent to the address on record,\
                If you don't receive one shortly, please contact\
                    the site admin.",
            }, 202)
        return resp

    except Exception as e:
        # exceptions go to site administrator and email
        # the user gets a friendly error notification
        if (e.code == 200):
            return custom_make_response(
                "data", {
                    "message":
                    "An email has been sent to the address on record,\
                        If you don't receive one shortly, please contact\
                            the site admin.",
                }, 200)
        elif (e.code == 400):
            return custom_make_response(
                "error", "Please enter an email and try again.", 400)
        else:
            return custom_make_response(
                "error", "Bummer an internal server error has occured\
                    the site admin has been notified, Please\
                        give it some moment and try again.", 500)
예제 #25
0
파일: user.py 프로젝트: KabakiAntony/rms
def signup_system_users():
    """
    signup system users
    """
    try:
        user_data = request.get_json()
        role = user_data["role"]
        if role == "Admin":
            this_company = Company.query.filter_by(
                company=user_data["company"]).first()
            _company = company_schema.dump(this_company)
            companyId = _company["id"]
            password = user_data["password"]
        else:
            companyId = user_data["companyId"]
            password = generate_random_password()
        email = user_data["email"]
        isActive = user_data["isActive"]

        this_employee = (Employees.query.filter_by(
            email=user_data["email"]).filter_by(
                companyId=user_data["companyId"]).first())
        employee = employee_schema.dump(this_employee)
        id = employee["id"]
        username = employee["fullname"].split(" ")[0] + "." + id

        # check data for sanity incase it bypass js on the frontend
        check_for_whitespace(
            user_data,
            ["companyId", "username", "email", "password", "role", "status"])
        isValidEmail(email)
        # check if user is already registered
        if User.query.filter_by(email=user_data["email"]).first():
            abort(409)

        isValidPassword(password)
        new_user = User(
            id=id,
            username=username,
            email=email,
            password=password,
            companyId=companyId,
            role=role,
            isActive=isActive,
        )

        db.session.add(new_user)
        db.session.commit()

        if role != "Admin":
            token = jwt.encode(
                {
                    "id":
                    id,
                    "email":
                    user_data["email"],
                    "exp":
                    datetime.datetime.utcnow() + datetime.timedelta(minutes=30)
                },
                KEY,
                algorithm="HS256",
            )
            subject = """Activate your account."""
            content = f"""
            Hey {username.split('.', 1)[0]},
            {non_admin_user_registration_content()}
            <a href="{password_reset_url}?u={token.decode('utf-8')}"
            style="{button_style()}">Activate account</a>
            {email_signature()}
            """
            send_mail(email, subject, content)

        return custom_make_response(
            "data",
            f"User registered successfully, email sent to {email}\
                for further instructions.",
            201,
        )

    except Exception as e:
        message = str(e)
        if "id" in message:
            return custom_make_response(
                "error",
                "The user you are creating an account for\
                is not on your company masterfile,\
                    Please add them and try again.",
                400,
            )
        elif (e.code == 409):
            return custom_make_response(
                "error",
                "A user account with that email already exists,\
                    please use another one and try again.",
                409,
            )
        else:
            return custom_make_response(
                "error", "Bummer an internal server error occured\
                    site admin has been notified, please give\
                        it a moment and try again.", 500)
예제 #26
0
파일: project.py 프로젝트: KabakiAntony/rms
def create_new_project(user):
    """
    create new project
    only the admin can create projects
    """
    try:
        data = request.get_json()
        current_user = User.query.filter_by(id=user["id"]).first()
        _data = user_schema.dump(current_user)
        companyId = _data["companyId"]
        projectName = data["project_name"] + "." + companyId
        dateFrom = data["date_from"]
        id = generate_db_ids()
        project_data = ProjectNumber.query.\
            filter_by(companyId=user['companyId']).first()
        the_number = project_number_schema.dump(project_data)
        project_number = the_number['projectNumber']

        check_for_whitespace(
            data, ["project_name", "companyId", "dateFrom"])
        if Project.query.filter_by(project_name=projectName).first():
            abort(409)

        new_project = Project(
            id=id,
            project_name=projectName,
            companyId=companyId,
            date_from=dateFrom,
            project_status="Active",
            projectNumber=project_number
        )

        db.session.add(new_project)

        update_project_number = {
            "projectNumber": project_number + 1
        }
        ProjectNumber.query.filter_by(companyId=companyId).\
            update(update_project_number)
        db.session.commit()

        return custom_make_response(
            "data",
            f"Project {projectName.split('.', 1)[0]} created successfully.",
            201
        )
    except Exception as e:
        # exceptions go to site administrator log and email
        # the user gets a friendly error notification
        if (e.code == 409):
            return custom_make_response(
                    "error",
                    """
                    You already have another project in that name,
                    Please change and try again !
                    """,
                    409,
                )
        else:
            return custom_make_response(
                "error",
                f"{e} One or more mandatory fields has not been filled!", 400
            )
예제 #27
0
def error_messages(msg, file_src):
    """cascade the error to the correct code"""
    db.session.rollback()
    message = str(msg)
    print(message)
    errorMessage = ""
    if ("InvalidTextRepresentation" in message
            or "list index out of range" in message or "totalAmount" in message
            or "Wrong file format" in message):
        errorMessage = custom_make_response(
            "error",
            f"The file you are uploading is not in \
                the allowed format for a {file_src} file,\
                please check & try again.",
            400,
        )
    elif "id" in message:
        errorMessage = custom_make_response(
            "error",
            f"Please select the project you are uploading\
                {file_src} file for.",
            400,
        )
    elif "File Pending" in message:
        errorMessage = custom_make_response(
            "error",
            f"A {file_src} file with similar info is available\
                         & marked as pending in the system,\
                              kindly ask your authorizer to act on it.",
            400,
        )
    elif "No Budget For Project" in message:
        errorMessage = custom_make_response(
            "error",
            "A budget was not found for this project please upload\
                        one for authorization before proceeding.",
            404,
        )
    elif "Budget  Unauthorized" in message:
        errorMessage = custom_make_response(
            "error",
            "The budget for this project has not been authorized,\
                Kindly ask the authorizer to act on it.",
            400,
        )
    elif "Project Amount Greater Than" in message:
        errorMessage = custom_make_response(
            "error",
            "The payment file amount exceeds the budget for this project,\
                please review your file & try again.",
            400,
        )
    elif "total_amount" in message:
        errorMessage = custom_make_response(
            "error",
            "The file is not in the correct format for a payment file,\
                please change & try again.",
            400,
        )
    else:
        errorMessage = custom_make_response(
            "error", f"The following error occured :: {message}", 400)

    abort(errorMessage)
예제 #28
0
def insert_admin_employee(company):
    """
    insert admin details to the employee
    table.
    """
    try:
        user_data = request.get_json()
        id = generate_db_ids()
        this_company = Company.query.filter_by(
            company=user_data["company"]).first()
        _company = company_schema.dump(this_company)
        companyId = _company["id"]
        fullname = user_data["fullname"]
        # mobile = user_data["mobile"]
        email = user_data["email"]
        password = user_data["password"]
        role = user_data["role"]
        isActive = user_data["isActive"]

        # check data for sanity incase it bypass js on the frontend
        check_for_whitespace(
            user_data,
            [
                "companyId",
                "fullname",
                "email",
                # "mobile",
                "password",
                "role",
                "isActive",
            ],
        )
        if (company['id'] != companyId):
            abort(
                custom_make_response(
                    "error",
                    "There is a mismatch in your token info,\
                        we could not complete the request,\
                            Please reopen this page and try again.",
                    401
                )
            )

        isValidEmail(email)

        new_employee = Employees(
            id=id,
            companyId=companyId,
            fullname=fullname,
            # mobile=mobile,
            email=email,
        )

        db.session.add(new_employee)
        db.session.commit()
        # once you have created an admin as an employee
        # let create them as user in the system.
        isValidPassword(password)

        new_user = User(
            id=id,
            username=user_data["fullname"].split(" ")[0] + "." + id,
            email=email,
            password=password,
            role=role,
            companyId=companyId,
            isActive=isActive,
        )

        db.session.add(new_user)
        db.session.commit()

        return custom_make_response(
            "data",
            "Registration completed Successfully,\
                you can now signin & start using the system.",
            201,
        )
    except Exception as e:
        message = str(e)
        if "UniqueViolation" and "Employees_mobile_key" in message:
            abort(
                custom_make_response(
                    "error",
                    "The mobile number you have entered seems\
                        to have been registered to another user,\
                            please change and try again. ",
                    409,
                )
            )
        elif "Employees_email_key" and "UniqueViolation" in message:
            abort(
                custom_make_response(
                    "error",
                    "The email address you have entered seems\
                        to have been registered to another user,\
                            please change and try again. ",
                    409,
                )
            )
        else:
            abort(
                custom_make_response(
                    "error", message,
                    500,
                )
            )