
15 changed files with 411 additions and 46 deletions
@ -0,0 +1,87 @@ |
|||||||
|
{% extends "ordr3:templates/layout_full.jinja2" %} |
||||||
|
|
||||||
|
{% block subtitle %} Manage Users {% endblock subtitle %} |
||||||
|
|
||||||
|
|
||||||
|
{% block sidebar %} |
||||||
|
|
||||||
|
<nav class="nav nav-pills flex-column"> |
||||||
|
<div class="nav-link disabled text-small" tabindex="-1" aria-disabled="true">All Orders</div> |
||||||
|
<a class="nav-link {% if query_defaults['status'] == 'all' and not query_defaults['user'] %}active{% endif %}" href="{{ request.resource_url(context, query=query_defaults(status=None, user=None, search=None)) }}">All</a> |
||||||
|
{% for status in stati %} |
||||||
|
<a class="nav-link {% if query_defaults['status'] == status.name.lower() and not query_defaults['user'] %}active{% endif %}" href="{{ request.resource_url(context, query=query_defaults(status=status.name.lower(), user=None, search=None)) }}">{{status.name.lower()}}</a> |
||||||
|
{% endfor %} |
||||||
|
</nav> |
||||||
|
|
||||||
|
<nav class="nav nav-pills flex-column mt-3"> |
||||||
|
<div class="nav-link disabled text-small" tabindex="-1" aria-disabled="true">My Orders</div> |
||||||
|
<a class="nav-link {% if query_defaults['status'] == 'all' and query_defaults['user'] == request.user.username %}active{% endif %}" href="{{ request.resource_url(context, query=query_defaults(status=None, user=request.user.username, search=None)) }}">All</a> |
||||||
|
{% for status in stati %} |
||||||
|
<a class="nav-link {% if query_defaults['status'] == status.name.lower() and query_defaults['user'] == request.user.username %}active{% endif %}" href="{{ request.resource_url(context, query=query_defaults(status=status.name.lower(), user=request.user.username, search=None)) }}">{{status.name.lower()}}</a> |
||||||
|
{% endfor %} |
||||||
|
</nav> |
||||||
|
|
||||||
|
{% if request.has_permission("edit-multiple", context) %} |
||||||
|
<nav class="nav nav-pills flex-column mt-3"> |
||||||
|
<div class="nav-link disabled text-small" tabindex="-1" aria-disabled="true">Specials</div> |
||||||
|
<a class="nav-link {% if query_defaults['user'] == '-purchaser-' %}active{% endif %}" href="{{ request.resource_url(context, query=query_defaults(status=None, user='-purchaser-', search=None)) }}">Edited by me</a> |
||||||
|
</nav> |
||||||
|
|
||||||
|
{% endif %} |
||||||
|
|
||||||
|
{% endblock sidebar %} |
||||||
|
|
||||||
|
|
||||||
|
{% block content %} |
||||||
|
|
||||||
|
<div class="col-10"> |
||||||
|
<form id="o3-multiple-form" method="POST"> |
||||||
|
<table class="table table-hover o3-data-table o3-data-hide-details"> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
{% if request.has_permission("edit-multiple", context) %} |
||||||
|
<th scope="col"><input type="checkbox" id="o3-selectall"></th> |
||||||
|
{% endif %} |
||||||
|
<th scope="col"> |
||||||
|
Date |
||||||
|
<div class="text-secondary small">Time</div> |
||||||
|
</th> |
||||||
|
<th scope="col"> |
||||||
|
CAS / Description |
||||||
|
<div class="text-secondary small">Catalog Nr.</div> |
||||||
|
</th> |
||||||
|
<th scope="col"> |
||||||
|
Vendor |
||||||
|
<div class="text-secondary small">Account</div> |
||||||
|
</th> |
||||||
|
<th scope="col" class="o3-dont-wrap text-right"> |
||||||
|
Total Price |
||||||
|
<div class="text-secondary small">Unit Price</div> |
||||||
|
</th> |
||||||
|
<th scope="col"> |
||||||
|
Status |
||||||
|
<div class="text-secondary small"> </div> |
||||||
|
</th> |
||||||
|
<th scope="col"> |
||||||
|
Ordered by |
||||||
|
<div class="text-secondary small"> </div> |
||||||
|
</th> |
||||||
|
<th scope="col"> |
||||||
|
Actions |
||||||
|
<div class="text-secondary small"> </div> |
||||||
|
</th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody class="infinite-container"> |
||||||
|
{% include 'ordr3:templates/orders/list_content.jinja2' %} |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
</form> |
||||||
|
{% if not orders %} |
||||||
|
<p class="bg-light text-center pt-2 pb-2">No data available</p> |
||||||
|
{% endif %} |
||||||
|
</div> |
||||||
|
|
||||||
|
<input type="checkbox" class="form-control"> |
||||||
|
|
||||||
|
{% endblock content %} |
@ -0,0 +1,53 @@ |
|||||||
|
{% import 'ordr3:templates/macros.jinja2' as macros with context %} |
||||||
|
{% for order in orders %} |
||||||
|
<tr class="infinite-item"> |
||||||
|
{% if request.has_permission("edit-multiple", context) %} |
||||||
|
<td><input type="checkbox" name="selection" value="{{order.model.id}}" class="o3-multiple-selection"></td> |
||||||
|
{% endif %} |
||||||
|
<td class="o3-dont-wrap"> |
||||||
|
{{ order.model.created_on.strftime("%Y-%m-%d") }} |
||||||
|
<div class="text-secondary small">{{ order.model.created_on.strftime("%H:%I:%S") }}</div> |
||||||
|
</td> |
||||||
|
<td> |
||||||
|
<a class="o3-copy" title="copy to clipboard">{{ order.model.cas_description }}</a> |
||||||
|
<div class="text-secondary small"><a class="o3-copy" title="copy to clipboard">{{ order.model.catalog_nr }}</a></div> |
||||||
|
</td> |
||||||
|
<td> |
||||||
|
<a class="o3-copy" title="copy to clipboard">{{ order.model.vendor }}</a> |
||||||
|
<div class="text-secondary small"><a class="o3-copy" title="copy to clipboard">{{ order.model.account }}</a></div> |
||||||
|
</td> |
||||||
|
<td class="text-right"> |
||||||
|
<span class="o3-dont-wrap"><a class="o3-copy" title="copy to clipboard">{{ "%.2f"|format(order.model.total_price)|replace(".", ",") }}</a> {{ order.model.currency }}</span> |
||||||
|
<div class="text-secondary small o3-dont-wrap"><a class="o3-copy" title="copy to clipboard">{{ order.model.amount }}</a> * <a class="o3-copy" title="copy to clipboard">{{ "%.2f"|format(order.model.unit_price)|replace(".", ",") }}</a> {{ order.model.currency }}</div> |
||||||
|
</td> |
||||||
|
<td> |
||||||
|
{{ macros.status_label(order.model.status) }} |
||||||
|
<div class="text-secondary small"> </div> |
||||||
|
</td> |
||||||
|
<td> |
||||||
|
<a href="{{ request.resource_url(context, query={'user':order.model.created_by})}}" title="Show orders for this user">{{ order.model.created_by}}</a> |
||||||
|
<div class="text-secondary small"> </div> |
||||||
|
</td> |
||||||
|
<td class="o3-actions"> |
||||||
|
{% if request.has_permission("edit", order) %} |
||||||
|
<a href="{{ request.resource_url(order, 'edit') }}" title="Edit Order">{{ macros.icon("pencil")}}</a> |
||||||
|
{% elif request.has_permission("view", order) %} |
||||||
|
<a href="{{ request.resource_url(order) }}" title="View Order">{{ macros.icon("eye")}}</a> |
||||||
|
{% endif %} |
||||||
|
{% if request.has_permission("delete", order) %} |
||||||
|
<a href="{{ request.resource_url(order, 'delete') }}" title="Delete Order">{{ macros.icon("trash")}}</a> |
||||||
|
{% endif %} |
||||||
|
<div class="text-secondary small"> </div> |
||||||
|
</td> |
||||||
|
</tr> |
||||||
|
{% endfor %} |
||||||
|
{% if next_offset %} |
||||||
|
<tr class="infinite-more-link" href="{{ request.resource_url(context, query=query_defaults(o=next_offset)) }}"> |
||||||
|
<td colspan="6"> |
||||||
|
<button class="btn btn-outline-primary btn-small"> |
||||||
|
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> |
||||||
|
Loading... |
||||||
|
</button> |
||||||
|
</td> |
||||||
|
</tr> |
||||||
|
{% endif %} |
@ -0,0 +1,83 @@ |
|||||||
|
# import deform |
||||||
|
from sqlalchemy import or_ # , func |
||||||
|
|
||||||
|
# from pyramid.csrf import get_csrf_token |
||||||
|
from pyramid.view import view_config |
||||||
|
|
||||||
|
from . import DefaultQueryParams, get_offset |
||||||
|
from .. import models, resources # , events, services |
||||||
|
|
||||||
|
# from pyramid.httpexceptions import HTTPFound |
||||||
|
|
||||||
|
# from ..schemas import account |
||||||
|
|
||||||
|
|
||||||
|
def get_status(request): |
||||||
|
status_param = request.GET.get("status", "") |
||||||
|
try: |
||||||
|
return models.OrderStatus[status_param.upper()] |
||||||
|
except KeyError: |
||||||
|
return None |
||||||
|
|
||||||
|
|
||||||
|
@view_config( |
||||||
|
context="ordr3:resources.OrderList", |
||||||
|
permission="view", |
||||||
|
request_method="GET", |
||||||
|
renderer="ordr3:templates/orders/list.jinja2", |
||||||
|
) |
||||||
|
@view_config( |
||||||
|
context="ordr3:resources.OrderList", |
||||||
|
permission="view", |
||||||
|
request_method="GET", |
||||||
|
xhr=True, |
||||||
|
renderer="ordr3:templates/orders/list_content.jinja2", |
||||||
|
) |
||||||
|
def list(context, request): |
||||||
|
limit = 25 |
||||||
|
offset = get_offset(request) |
||||||
|
status = get_status(request) |
||||||
|
username = request.GET.get("user", None) |
||||||
|
search = request.GET.get("search", None) |
||||||
|
|
||||||
|
query = request.repo.session.query(models.OrderItem).order_by( |
||||||
|
models.OrderItem.created_on.desc() |
||||||
|
) |
||||||
|
if status: |
||||||
|
query = query.filter(models.OrderItem.status == status) |
||||||
|
if username == "-purchaser-": |
||||||
|
query = ( |
||||||
|
query.distinct() |
||||||
|
.join(models.OrderItem.log) |
||||||
|
.filter(models.LogEntry.by == request.user.username) |
||||||
|
) |
||||||
|
elif username: |
||||||
|
query = query.filter(models.OrderItem.created_by == username) |
||||||
|
if search: |
||||||
|
term = "%{}%".format(search) |
||||||
|
query = query.filter( |
||||||
|
or_( |
||||||
|
models.OrderItem.cas_description.ilike(term), |
||||||
|
models.OrderItem.vendor.ilike(term), |
||||||
|
models.OrderItem.catalog_nr.ilike(term), |
||||||
|
models.OrderItem.account.ilike(term), |
||||||
|
models.OrderItem.created_by.ilike(term), |
||||||
|
) |
||||||
|
) |
||||||
|
orders = query[offset : offset + limit] # noqa: E203 |
||||||
|
|
||||||
|
next_offset = None if limit != len(orders) else (offset + limit) |
||||||
|
order_resources = [resources.Order.from_model(u, context) for u in orders] |
||||||
|
|
||||||
|
filter_status = "all" if status is None else status.name.lower() |
||||||
|
query_defaults = DefaultQueryParams( |
||||||
|
status=filter_status, user=username, search=search |
||||||
|
) |
||||||
|
|
||||||
|
return { |
||||||
|
"is_order_list": True, |
||||||
|
"next_offset": next_offset, |
||||||
|
"orders": order_resources, |
||||||
|
"stati": models.OrderStatus, |
||||||
|
"query_defaults": query_defaults, |
||||||
|
} |
Binary file not shown.
Loading…
Reference in new issue