예제 #1
0
def contract(contract_id):
    '''Contract profile page
    '''

    contract = ContractBase.query.get(contract_id)

    if contract:
        note_form = NoteForm()

        if note_form.validate_on_submit():
            new_note = ContractNote(
                note=note_form.data['note'],
                contract_id=contract_id, taken_by_id=current_user.id
            )
            db.session.add(new_note)
            db.session.commit()
            return redirect(url_for('wexplorer.contract', contract_id=contract_id))

        notes = ContractNote.query.filter(
            ContractNote.contract_id == contract_id,
            ContractNote.taken_by_id == current_user.id
        ).all()

        departments = set([i.department for i in contract.followers])

        current_app.logger.info('WEXCONTRACT - Viewed contract page {}'.format(contract.description))

        return dict(
            contract=contract, departments=departments,
            choices=Department.choices(),
            path='{path}?{query}'.format(
                path=request.path, query=request.query_string
            ), notes=notes, note_form=note_form
        )
    abort(404)
예제 #2
0
def filter(department_id):
    '''Filter contracts by which ones have departmental subscribers

    :param department_id: Department's unique ID
    :status 200: Renders template with all contracts followed by that department
    :status 404: When department is not found with the specified ID
    '''
    department = Department.query.get(int(department_id))

    if department:
        pagination_per_page = current_app.config.get('PER_PAGE', 50)
        page = int(request.args.get('page', 1))
        lower_bound_result = (page - 1) * pagination_per_page
        upper_bound_result = lower_bound_result + pagination_per_page

        contracts = db.session.execute(
            '''
            SELECT
                contract.id, description,
                count(contract_user_association.user_id) AS follows
            FROM contract
            LEFT OUTER JOIN contract_user_association
                ON contract.id = contract_user_association.contract_id
            FULL OUTER JOIN users
                ON contract_user_association.user_id = users.id
            JOIN department
                ON users.department_id = department.id
            WHERE department.id = :department
            GROUP BY 1,2
            HAVING count(contract_user_association.user_id) > 0
            ORDER BY 3 DESC, 1 ASC
            ''', {'department': int(department_id)}
        ).fetchall()

        if len(contracts) > 0:
            pagination = SimplePagination(page, pagination_per_page, len(contracts))
            results = contracts[lower_bound_result:upper_bound_result]
        else:
            pagination = None
            results = []

        current_app.logger.info('WEXFILTER - {department}: Filter by {department}'.format(
            department=department.name
        ))

        return render_template(
            'scout/filter.html',
            search_form=SearchForm(),
            results=results,
            pagination=pagination,
            department=department,
            choices=Department.choices(),
            path='{path}?{query}'.format(
                path=request.path, query=request.query_string
            )
        )
    abort(404)
def filter(department_id):
    '''Filter contracts by which ones have departmental subscribers

    :param department_id: Department's unique ID
    :status 200: Renders template with all contracts followed by that department
    :status 404: When department is not found with the specified ID
    '''
    department = Department.query.get(int(department_id))

    if department:
        pagination_per_page = current_app.config.get('PER_PAGE', 50)
        page = int(request.args.get('page', 1))
        lower_bound_result = (page - 1) * pagination_per_page
        upper_bound_result = lower_bound_result + pagination_per_page

        contracts = db.session.execute(
            '''
            SELECT
                contract.id, description,
                count(contract_user_association.user_id) AS follows
            FROM contract
            LEFT OUTER JOIN contract_user_association
                ON contract.id = contract_user_association.contract_id
            FULL OUTER JOIN users
                ON contract_user_association.user_id = users.id
            JOIN department
                ON users.department_id = department.id
            WHERE department.id = :department
            GROUP BY 1,2
            HAVING count(contract_user_association.user_id) > 0
            ORDER BY 3 DESC, 1 ASC
            ''', {'department': int(department_id)}
        ).fetchall()

        if len(contracts) > 0:
            pagination = SimplePagination(page, pagination_per_page, len(contracts))
            results = contracts[lower_bound_result:upper_bound_result]
        else:
            pagination = None
            results = []

        current_app.logger.info('WEXFILTER - {department}: Filter by {department}'.format(
            department=department.name
        ))

        return render_template(
            'scout/filter.html',
            search_form=SearchForm(),
            results=results,
            pagination=pagination,
            department=department,
            choices=Department.choices(),
            path='{path}?{query}'.format(
                path=request.path, query=request.query_string
            )
        )
    abort(404)
예제 #4
0
def feedback_handler(contract_id=None, search_for=None):
    '''
    Allow user to send feedback on the data present in a specific contract
    '''
    if contract_id:
        contract = ContractBase.query.get(contract_id)
    else:
        contract = ContractBase(
            description='Search term: ' + search_for
        )

    search_form = SearchForm()
    if contract:
        form = FeedbackForm()

        if not current_user.is_anonymous():
            form.sender.data = current_user.email

        if form.validate_on_submit():

            current_app.logger.info('WEXFEEDBACK - Feedback from {email} about {contract}'.format(
                email=form.sender.data,
                contract=contract.description
            ))

            feedback_sent = Notification(
                to_email=db.session.query(User.email).join(Role, User.role_id == Role.id).filter(
                    Role.name.in_(['admin', 'superadmin'])
                ).all(),
                subject='Scout contract feedback - ID: {id}, Description: {description}'.format(
                    id=contract.id if contract.id else 'N/A',
                    description=contract.description
                ), html_template='wexplorer/feedback_email.html',
                contract=contract, sender=form.data.get('sender'),
                body=form.data.get('body')
            ).send()

            if feedback_sent:
                flash('Thank you for your feedback!', 'alert-success')
            else:
                flash('Oh no! Something went wrong. We are looking into it.', 'alert-danger')

            if contract.id:
                return redirect(url_for('wexplorer.contract', contract_id=contract.id))
            return redirect(url_for('wexplorer.explore'))

        return render_template(
            'wexplorer/feedback.html',
            search_form=search_form,
            contract=contract,
            choices=Department.choices(),
            feedback_form=form,
            search_for=search_for
        )
    abort(404)
예제 #5
0
def feedback_handler(contract, search_for=None):
    """Allow user to send feedback on the data present in a specific contract

    Arguments:
        contract: :py:class:`~purchasing.data.contracts.ContractBase` object
        search_for: search term or None.

    Returns:
        Redirects to or renders the appropriate feedback handling template
    """
    form = FeedbackForm()
    search_form = SearchForm()

    if not current_user.is_anonymous():
        form.sender.data = current_user.email

    if form.validate_on_submit():

        current_app.logger.info(
            "WEXFEEDBACK - Feedback from {email} about {contract}".format(
                email=form.sender.data, contract=contract.description
            )
        )

        feedback_sent = Notification(
            to_email=db.session.query(User.email)
            .join(Role, User.role_id == Role.id)
            .filter(Role.name.in_(["admin", "superadmin"]))
            .all(),
            subject="Scout contract feedback - ID: {id}, Description: {description}".format(
                id=contract.id if contract.id else "N/A", description=contract.description
            ),
            html_template="scout/feedback_email.html",
            contract=contract,
            sender=form.data.get("sender"),
            body=form.data.get("body"),
        ).send()

        if feedback_sent:
            flash("Thank you for your feedback!", "alert-success")
        else:
            flash("Oh no! Something went wrong. We are looking into it.", "alert-danger")

        if contract.id:
            return redirect(url_for("scout.contract", contract_id=contract.id))
        return redirect(url_for("scout.explore"))

    return render_template(
        "scout/feedback.html",
        search_form=search_form,
        contract=contract,
        choices=Department.choices(),
        feedback_form=form,
        search_for=search_for,
    )
예제 #6
0
def filter_no_department():
    '''The landing page for filtering by departments

    :status 200: Renders the appropriate landing page.
    '''
    return render_template('scout/filter.html',
                           search_form=SearchForm(),
                           results=[],
                           choices=Department.choices(),
                           path='{path}?{query}'.format(
                               path=request.path, query=request.query_string))
예제 #7
0
def filter_no_department():
    '''The landing page for filtering by departments
    '''
    return render_template(
        'wexplorer/filter.html',
        search_form=SearchForm(),
        results=[],
        choices=Department.choices(),
        path='{path}?{query}'.format(
            path=request.path, query=request.query_string
        )
    )
def filter_no_department():
    """The landing page for filtering by departments

    :status 200: Renders the appropriate landing page.
    """
    return render_template(
        "scout/filter.html",
        search_form=SearchForm(),
        results=[],
        choices=Department.choices(),
        path="{path}?{query}".format(path=request.path, query=request.query_string),
    )
def feedback_handler(contract, search_for=None):
    '''Allow user to send feedback on the data present in a specific contract

    Arguments:
        contract: :py:class:`~purchasing.data.contracts.ContractBase` object
        search_for: search term or None.

    Returns:
        Redirects to or renders the appropriate feedback handling template
    '''
    form = FeedbackForm()
    search_form = SearchForm()

    if not current_user.is_anonymous:
        form.sender.data = current_user.email

    if form.validate_on_submit():

        current_app.logger.info('WEXFEEDBACK - Feedback from {email} about {contract}'.format(
            email=form.sender.data,
            contract=contract.description
        ))

        feedback_sent = Notification(
            to_email=db.session.query(User.email).filter(
                User.roles.any(Role.name.in_(['admin', 'superadmin']))
            ).all(),
            subject='Scout contract feedback - ID: {id}, Description: {description}'.format(
                id=contract.id if contract.id else 'N/A',
                description=contract.description
            ), html_template='scout/feedback_email.html',
            contract=contract, sender=form.data.get('sender'),
            body=form.data.get('body')
        ).send()

        if feedback_sent:
            flash('Thank you for your feedback!', 'alert-success')
        else:
            flash('Oh no! Something went wrong. We are looking into it.', 'alert-danger')

        if contract.id:
            return redirect(url_for('scout.contract', contract_id=contract.id))
        return redirect(url_for('scout.explore'))

    return render_template(
        'scout/feedback.html',
        search_form=search_form,
        contract=contract,
        choices=Department.choices(),
        feedback_form=form,
        search_for=search_for
    )
예제 #10
0
def company(company_id):
    company = Company.query.get(company_id)

    if company:
        current_app.logger.info('WEXCOMPANY - Viewed company page {}'.format(company.company_name))
        return dict(
            company=company,
            choices=Department.choices(),
            path='{path}?{query}'.format(
                path=request.path, query=request.query_string
            )
        )
    abort(404)
def feedback_handler(contract, search_for=None):
    '''Allow user to send feedback on the data present in a specific contract

    Arguments:
        contract: :py:class:`~purchasing.data.contracts.ContractBase` object
        search_for: search term or None.

    Returns:
        Redirects to or renders the appropriate feedback handling template
    '''
    form = FeedbackForm()
    search_form = SearchForm()

    if not current_user.is_anonymous():
        form.sender.data = current_user.email

    if form.validate_on_submit():

        current_app.logger.info(
            'WEXFEEDBACK - Feedback from {email} about {contract}'.format(
                email=form.sender.data, contract=contract.description))

        feedback_sent = Notification(
            to_email=db.session.query(User.email).join(
                Role, User.role_id == Role.id).filter(
                    Role.name.in_(['admin', 'superadmin'])).all(),
            subject=
            'Scout contract feedback - ID: {id}, Description: {description}'.
            format(id=contract.id if contract.id else 'N/A',
                   description=contract.description),
            html_template='scout/feedback_email.html',
            contract=contract,
            sender=form.data.get('sender'),
            body=form.data.get('body')).send()

        if feedback_sent:
            flash('Thank you for your feedback!', 'alert-success')
        else:
            flash('Oh no! Something went wrong. We are looking into it.',
                  'alert-danger')

        if contract.id:
            return redirect(url_for('scout.contract', contract_id=contract.id))
        return redirect(url_for('scout.explore'))

    return render_template('scout/feedback.html',
                           search_form=search_form,
                           contract=contract,
                           choices=Department.choices(),
                           feedback_form=form,
                           search_for=search_for)
예제 #12
0
def company(company_id):
    '''Company profile page

    :param contract_id: Unique ID for a :py:class:`~purchasing.data.companies.Company` object
    :status 200: Renders the company profile template
    :status 404: Unique company ID not found
    '''
    company = Company.query.get(company_id)

    if company:
        current_app.logger.info('WEXCOMPANY - Viewed company page {}'.format(
            company.company_name))
        return dict(company=company,
                    choices=Department.choices(),
                    path='{path}?{query}'.format(path=request.path,
                                                 query=request.query_string))
    abort(404)
def company(company_id):
    """Company profile page

    :param contract_id: Unique ID for a :py:class:`~purchasing.data.companies.Company` object
    :status 200: Renders the company profile template
    :status 404: Unique company ID not found
    """
    company = Company.query.get(company_id)

    if company:
        current_app.logger.info("WEXCOMPANY - Viewed company page {}".format(company.company_name))
        return dict(
            company=company,
            choices=Department.choices(),
            path="{path}?{query}".format(path=request.path, query=request.query_string),
        )
    abort(404)
def contract(contract_id):
    '''Contract profile page

    For GET requests, render the profile page. For POSTs,
    try to submit a new note.

    :param contract_id: Unique ID for a :py:class:`~purchasing.data.contracts.ContractBase` object
    :status 200: Renders the contract profile template
    :status 302: Try to post note, then redirect to the same page's contract view
    :status 404: Unique contract ID not found
    '''

    contract = ContractBase.query.get(contract_id)

    if contract:
        note_form = NoteForm()

        if note_form.validate_on_submit():
            new_note = ContractNote(
                note=note_form.data['note'],
                contract_id=contract_id, taken_by_id=current_user.id
            )
            db.session.add(new_note)
            db.session.commit()
            return redirect(url_for('scout.contract', contract_id=contract_id))

        notes = ContractNote.query.filter(
            ContractNote.contract_id == contract_id,
            ContractNote.taken_by_id == current_user.id
        ).all()

        departments = set([i.department for i in contract.followers])

        current_app.logger.info('WEXCONTRACT - Viewed contract page {}'.format(contract.description))

        return dict(
            contract=contract, departments=departments,
            choices=Department.choices(),
            path='{path}?{query}'.format(
                path=request.path, query=request.query_string
            ), notes=notes, note_form=note_form
        )
    abort(404)
예제 #15
0
def contract(contract_id):
    '''Contract profile page

    For GET requests, render the profile page. For POSTs,
    try to submit a new note.

    :param contract_id: Unique ID for a :py:class:`~purchasing.data.contracts.ContractBase` object
    :status 200: Renders the contract profile template
    :status 302: Try to post note, then redirect to the same page's contract view
    :status 404: Unique contract ID not found
    '''

    contract = ContractBase.query.get(contract_id)

    if contract:
        note_form = NoteForm()

        if note_form.validate_on_submit():
            new_note = ContractNote(
                note=note_form.data['note'],
                contract_id=contract_id, taken_by_id=current_user.id
            )
            db.session.add(new_note)
            db.session.commit()
            return redirect(url_for('scout.contract', contract_id=contract_id))

        notes = ContractNote.query.filter(
            ContractNote.contract_id == contract_id,
            ContractNote.taken_by_id == current_user.id
        ).all()

        departments = set([i.department for i in contract.followers])

        current_app.logger.info('WEXCONTRACT - Viewed contract page {}'.format(contract.description))

        return dict(
            contract=contract, departments=departments,
            choices=Department.choices(),
            path='{path}?{query}'.format(
                path=request.path, query=request.query_string
            ), notes=notes, note_form=note_form
        )
    abort(404)
def search():
    '''The search results page for scout

    In order to create permalinks to each search/filter result combination,
    POST methods have their form arguments popped off and then are immediately
    redirected to GET methods.

    .. seealso ::
        * :py:mod:`purchasing.data.searches` for more on the search query
        * :py:class:`~purchasing.scout.forms.SearchForm` for the search form construction
        * :py:func:`~purchasing.scout.util.build_filter` for how filters are built
        * :py:func:`~purchasing.scout.util.build_cases` for how case statements are built

    :status 200: Render the search template with the given results
    :status 302: Pop the passed form arguments to the request URL
        and redirect to the search view
    '''
    if request.method == 'POST':
        args = request.form.to_dict()
        if args.get('contract_type') == '__None':
            del args['contract_type']

        return redirect(url_for('scout.search', **args))

    department = request.args.get('department')
    if department and department not in ['', 'None']:
        return redirect(url_for('scout.filter', department=department))

    search_form = SearchForm()
    search_for = request.args.get('q') or ''
    search_form.q.data = search_for

    # strip out "crazy" characters
    search_for = re.sub(CRAZY_CHARS, '', search_for)
    search_for = ' | '.join(search_for.split())

    pagination_per_page = current_app.config.get('PER_PAGE', 50)
    page = int(request.args.get('page', 1))
    lower_bound_result = (page - 1) * pagination_per_page
    upper_bound_result = lower_bound_result + pagination_per_page

    filter_or = build_filter(
        request.args, FILTER_FIELDS, search_for, search_form,
        not any([request.args.get(name) for name, _, _ in FILTER_FIELDS])
    )

    filter_and = []
    if request.args.get('contract_type') is not None:
        filter_and = [
            ContractBase.contract_type_id == int(request.args.get('contract_type'))
        ]
        search_form.contract_type.data = ContractType.query.get(int(request.args.get('contract_type')))

    found_in_case = build_cases(
        request.args, FILTER_FIELDS, search_for,
        not any([request.args.get(name) for name, _, _ in FILTER_FIELDS])
    )

    # determine if we are getting archived contracts
    if request.args.get('archived') == 'y':
        search_form['archived'].checked = True
        archived = True
    else:
        archived = False

    if search_for != '':
        contracts = find_contract_metadata(
            search_for, found_in_case, filter_or, filter_and,
            archived
        )
    else:
        contracts = return_all_contracts(
            filter_and, archived
        )

    pagination = SimplePagination(page, pagination_per_page, len(contracts))

    current_app.logger.info('WEXSEARCH - {search_for}: {user} searched for "{search_for}"'.format(
        search_for=search_for,
        user=current_user.email if not current_user.is_anonymous else 'anonymous'
    ))

    user_follows = [] if current_user.is_anonymous else current_user.get_following()

    return render_template(
        'scout/search.html',
        current_user=current_user,
        user_follows=user_follows,
        search_for=search_for,
        results=contracts[lower_bound_result:upper_bound_result],
        pagination=pagination,
        search_form=search_form,
        choices=Department.choices(),
        path='{path}?{query}'.format(
            path=request.path, query=request.query_string
        )
    )
예제 #17
0
def search():
    '''
    The search results page for scout
    '''
    if request.method == 'POST':
        args = request.form.to_dict()
        if args.get('contract_type') == '__None':
            del args['contract_type']

        return redirect(url_for('wexplorer.search', **args))

    department = request.args.get('department')
    if department and department not in ['', 'None']:
        return redirect(url_for('wexplorer.filter', department=department))

    search_form = SearchForm()
    search_for = request.args.get('q') or ''
    search_form.q.data = search_for

    # strip out "crazy" characters
    search_for = re.sub(CRAZY_CHARS, '', search_for)
    search_for = ' | '.join(search_for.split())

    pagination_per_page = current_app.config.get('PER_PAGE', 50)
    page = int(request.args.get('page', 1))
    lower_bound_result = (page - 1) * pagination_per_page
    upper_bound_result = lower_bound_result + pagination_per_page

    # build filter and filter form
    fields = [
        ('company_name', 'Company Name', SearchView.tsv_company_name),
        ('line_item', 'Line Item', SearchView.tsv_line_item_description),
        ('contract_description', 'Contract Description', SearchView.tsv_contract_description),
        ('contract_detail', 'Contract Detail', SearchView.tsv_detail_value),
        ('financial_id', 'Controller Number', SearchView.financial_id),
    ]

    filter_or = build_filter(
        request.args, fields, search_for, search_form,
        not any([request.args.get(name) for name, _, _ in fields])
    )

    filter_and = []
    if request.args.get('contract_type') is not None:
        filter_and = [
            ContractBase.contract_type_id == int(request.args.get('contract_type'))
        ]
        search_form.contract_type.data = ContractType.query.get(int(request.args.get('contract_type')))

    found_in_case = build_cases(
        request.args, fields, search_for,
        not any([request.args.get(name) for name, _, _ in fields])
    )

    # determine if we are getting archived contracts
    if request.args.get('archived') == 'y':
        search_form['archived'].checked = True
        archived = True
    else:
        archived = False

    if search_for != '':
        contracts = find_contract_metadata(
            search_for, found_in_case, filter_or, filter_and,
            archived
        )
    else:
        contracts = return_all_contracts(
            filter_and, archived
        )

    pagination = SimplePagination(page, pagination_per_page, len(contracts))

    current_app.logger.info('WEXSEARCH - {search_for}: {user} searched for "{search_for}"'.format(
        search_for=search_for,
        user=current_user.email if not current_user.is_anonymous() else 'anonymous'
    ))

    user_follows = [] if current_user.is_anonymous() else current_user.get_following()

    return render_template(
        'wexplorer/search.html',
        current_user=current_user,
        user_follows=user_follows,
        search_for=search_for,
        results=contracts[lower_bound_result:upper_bound_result],
        pagination=pagination,
        search_form=search_form,
        choices=Department.choices(),
        path='{path}?{query}'.format(
            path=request.path, query=request.query_string
        )
    )
예제 #18
0
def explore():
    '''The landing page for scout. Renders the "big search" template.

    :status 200: Renders the appropriate landing page.
    '''
    return dict(current_user=current_user, choices=Department.choices())
예제 #19
0
def search():
    '''The search results page for scout

    In order to create permalinks to each search/filter result combination,
    POST methods have their form arguments popped off and then are immediately
    redirected to GET methods.

    .. seealso ::
        * :py:mod:`purchasing.data.searches` for more on the search query
        * :py:class:`~purchasing.scout.forms.SearchForm` for the search form construction
        * :py:func:`~purchasing.scout.util.build_filter` for how filters are built
        * :py:func:`~purchasing.scout.util.build_cases` for how case statements are built

    :status 200: Render the search template with the given results
    :status 302: Pop the passed form arguments to the request URL
        and redirect to the search view
    '''
    if request.method == 'POST':
        args = request.form.to_dict()
        if args.get('contract_type') == '__None':
            del args['contract_type']

        return redirect(url_for('scout.search', **args))

    department = request.args.get('department')
    if department and department not in ['', 'None']:
        return redirect(url_for('scout.filter', department=department))

    search_form = SearchForm()
    search_for = request.args.get('q') or ''
    search_form.q.data = search_for

    # strip out "crazy" characters
    search_for = re.sub(CRAZY_CHARS, '', search_for)
    search_for = ' | '.join(search_for.split())

    pagination_per_page = current_app.config.get('PER_PAGE', 50)
    page = int(request.args.get('page', 1))
    lower_bound_result = (page - 1) * pagination_per_page
    upper_bound_result = lower_bound_result + pagination_per_page

    filter_or = build_filter(
        request.args, FILTER_FIELDS, search_for, search_form,
        not any([request.args.get(name) for name, _, _ in FILTER_FIELDS])
    )

    filter_and = []
    if request.args.get('contract_type') is not None:
        filter_and = [
            ContractBase.contract_type_id == int(request.args.get('contract_type'))
        ]
        search_form.contract_type.data = ContractType.query.get(int(request.args.get('contract_type')))

    found_in_case = build_cases(
        request.args, FILTER_FIELDS, search_for,
        not any([request.args.get(name) for name, _, _ in FILTER_FIELDS])
    )

    # determine if we are getting archived contracts
    if request.args.get('archived') == 'y':
        search_form['archived'].checked = True
        archived = True
    else:
        archived = False

    if search_for != '':
        contracts = find_contract_metadata(
            search_for, found_in_case, filter_or, filter_and,
            archived
        )
    else:
        contracts = return_all_contracts(
            filter_and, archived
        )

    pagination = SimplePagination(page, pagination_per_page, len(contracts))

    current_app.logger.info('WEXSEARCH - {search_for}: {user} searched for "{search_for}"'.format(
        search_for=search_for,
        user=current_user.email if not current_user.is_anonymous() else 'anonymous'
    ))

    user_follows = [] if current_user.is_anonymous() else current_user.get_following()

    return render_template(
        'scout/search.html',
        current_user=current_user,
        user_follows=user_follows,
        search_for=search_for,
        results=contracts[lower_bound_result:upper_bound_result],
        pagination=pagination,
        search_form=search_form,
        choices=Department.choices(),
        path='{path}?{query}'.format(
            path=request.path, query=request.query_string
        )
    )
예제 #20
0
def explore():
    '''
    The landing page for wexplorer. Renders the "big search"
    template.
    '''
    return dict(current_user=current_user, choices=Department.choices())
def search():
    """The search results page for scout

    In order to create permalinks to each search/filter result combination,
    POST methods have their form arguments popped off and then are immediately
    redirected to GET methods.

    .. seealso ::
        * :py:mod:`purchasing.data.searches` for more on the search query
        * :py:class:`~purchasing.scout.forms.SearchForm` for the search form construction
        * :py:func:`~purchasing.scout.util.build_filter` for how filters are built
        * :py:func:`~purchasing.scout.util.build_cases` for how case statements are built
    """
    if request.method == "POST":
        args = request.form.to_dict()
        if args.get("contract_type") == "__None":
            del args["contract_type"]

        return redirect(url_for("scout.search", **args))

    department = request.args.get("department")
    if department and department not in ["", "None"]:
        return redirect(url_for("scout.filter", department=department))

    search_form = SearchForm()
    search_for = request.args.get("q") or ""
    search_form.q.data = search_for

    # strip out "crazy" characters
    search_for = re.sub(CRAZY_CHARS, "", search_for)
    search_for = " | ".join(search_for.split())

    pagination_per_page = current_app.config.get("PER_PAGE", 50)
    page = int(request.args.get("page", 1))
    lower_bound_result = (page - 1) * pagination_per_page
    upper_bound_result = lower_bound_result + pagination_per_page

    filter_or = build_filter(
        request.args,
        FILTER_FIELDS,
        search_for,
        search_form,
        not any([request.args.get(name) for name, _, _ in FILTER_FIELDS]),
    )

    filter_and = []
    if request.args.get("contract_type") is not None:
        filter_and = [ContractBase.contract_type_id == int(request.args.get("contract_type"))]
        search_form.contract_type.data = ContractType.query.get(int(request.args.get("contract_type")))

    found_in_case = build_cases(
        request.args, FILTER_FIELDS, search_for, not any([request.args.get(name) for name, _, _ in FILTER_FIELDS])
    )

    # determine if we are getting archived contracts
    if request.args.get("archived") == "y":
        search_form["archived"].checked = True
        archived = True
    else:
        archived = False

    if search_for != "":
        contracts = find_contract_metadata(search_for, found_in_case, filter_or, filter_and, archived)
    else:
        contracts = return_all_contracts(filter_and, archived)

    pagination = SimplePagination(page, pagination_per_page, len(contracts))

    current_app.logger.info(
        'WEXSEARCH - {search_for}: {user} searched for "{search_for}"'.format(
            search_for=search_for, user=current_user.email if not current_user.is_anonymous() else "anonymous"
        )
    )

    user_follows = [] if current_user.is_anonymous() else current_user.get_following()

    return render_template(
        "scout/search.html",
        current_user=current_user,
        user_follows=user_follows,
        search_for=search_for,
        results=contracts[lower_bound_result:upper_bound_result],
        pagination=pagination,
        search_form=search_form,
        choices=Department.choices(),
        path="{path}?{query}".format(path=request.path, query=request.query_string),
    )
def explore():
    '''The landing page for scout. Renders the "big search" template.

    :status 200: Renders the appropriate landing page.
    '''
    return dict(current_user=current_user, choices=Department.choices())
 def __init__(self, contract):
     self.title = better_title(contract.description)
     self.opportunity_type = ContractType.get_type(current_app.config.get('CONDUCTOR_TYPE', ''))
     self.department = Department.get_dept(current_app.config.get('CONDUCTOR_DEPARTMENT', ''))
 def __init__(self, contract):
     self.title = better_title(contract.description)
     self.opportunity_type = ContractType.get_type(
         current_app.config.get('CONDUCTOR_TYPE', ''))
     self.department = Department.get_dept(
         current_app.config.get('CONDUCTOR_DEPARTMENT', ''))