diff --git a/ordr3/templates/orders/list_content.jinja2 b/ordr3/templates/orders/list_content.jinja2
index a2877c9..9161b6d 100644
--- a/ordr3/templates/orders/list_content.jinja2
+++ b/ordr3/templates/orders/list_content.jinja2
@@ -5,8 +5,8 @@
|
{% endif %}
- {{ order.model.created_on.strftime("%Y-%m-%d") }}
- {{ order.model.created_on.strftime("%H:%I:%S") }}
+ {{ order.model.created_on|as_date }}
+ {{ order.model.created_on|as_time }}
|
{{ order.model.cas_description }}
@@ -34,7 +34,7 @@
|
{% if request.has_permission("edit", order) %}
- {{ macros.icon("pencil")}}
+ {{ macros.icon("pencil")}}
{% elif request.has_permission("view", order) %}
{{ macros.icon("eye")}}
{% endif %}
diff --git a/ordr3/templates/orders/view.jinja2 b/ordr3/templates/orders/view.jinja2
new file mode 100644
index 0000000..e1f6886
--- /dev/null
+++ b/ordr3/templates/orders/view.jinja2
@@ -0,0 +1,55 @@
+{% extends "ordr3:templates/layout_full.jinja2" %}
+
+{% block subtitle %} View Order {{context.model.cas_description}} {% endblock subtitle %}
+
+{% block content %}
+
+
+ Details for Order {{ context.model.cas_description }}
+
+ - Cas / Description
+ - {{ context.model.cas_description }}
+ - Vendor
+ - {{ context.model.vendor }}
+ - Catalog Nr.
+ - {{ context.model.catalog_nr }}
+ - Package Size
+ - {{ context.model.package_size }}
+ - Amount, Price
+ - {{ context.model.amount }} * {{ "%.2f"|format(context.model.unit_price) }} {{ context.model.currency }}
+ - Price, total
+ - {{ "%.2f"|format(context.model.total_price) }} {{ context.model.currency }}
+ - Ordered By
+ - {{ context.model.created_by }}
+ - Ordered On
+ - {{ context.model.created_on.strftime("%Y-%m-%d %H:%I") }}
+ - Account
+ - {{ context.model.account|default("-", True) }}
+ - Comment
+ - {{ context.model.comment|default("-", True) }}
+
+ - Status
+ - {{ macros.status_label(context.model.status) }}
+
+
+ Deleting this order is permanent and cannot be undone!
+
+
+
+
+
+{% endblock content %}
+
+
diff --git a/ordr3/views/__init__.py b/ordr3/views/__init__.py
index 4f52126..7eabd22 100644
--- a/ordr3/views/__init__.py
+++ b/ordr3/views/__init__.py
@@ -3,7 +3,10 @@
some view helpers are defined here
"""
-from collections import UserDict
+import re
+from collections import UserDict, namedtuple
+
+RE_SIMPLE_URL = re.compile("((?:www|http)\\S+)")
def get_offset(request):
@@ -21,6 +24,39 @@ class DefaultQueryParams(UserDict):
return {k: v for k, v in copied.items() if v is not None}
+def jinja_date(some_date):
+ return some_date.strftime("%Y-%m-%d")
+
+
+def jinja_time(some_date):
+ return some_date.strftime("%H:%I")
+
+
+def jinja_datetime(some_date):
+ return some_date.strftime("%Y-%m-%d %H:%I")
+
+
+def _as_html_link(url, css_class):
+ return f'{url}'
+
+
+def jinja_extract_links(text, css_class=""):
+ links = RE_SIMPLE_URL.findall(text)
+ return [_as_html_link(url, css_class) for url in links]
+
+
+def jinja_view_comment(text, css_class):
+ links = RE_SIMPLE_URL.findall(text)
+ for url in links:
+ html = _as_html_link(url, css_class)
+ text = text.replace(url, html)
+ return text
+
+
+def jinja_nl2br(text, replacement=" "):
+ return replacement.join(text.splitlines())
+
+
def includeme(config):
""" adding request helpers
diff --git a/ordr3/views/orders.py b/ordr3/views/orders.py
index 061a808..ef2c94d 100644
--- a/ordr3/views/orders.py
+++ b/ordr3/views/orders.py
@@ -239,6 +239,17 @@ def batch_edit_confirm(context, request):
return HTTPFound(request.resource_path(context))
+@view_config(
+ context="ordr3:resources.Order",
+ permission="view",
+ name="view",
+ request_method="GET",
+ renderer="ordr3:templates/orders/view.jinja2",
+)
+def view_order(context, request):
+ return {"csrf_token": get_csrf_token(request)}
+
+
@view_config(
context="ordr3:resources.Order",
permission="delete",
diff --git a/ordr3/views/root.py b/ordr3/views/root.py
index e51e0da..47fa1de 100644
--- a/ordr3/views/root.py
+++ b/ordr3/views/root.py
@@ -1,10 +1,16 @@
""" static and login pages """
-from pyramid.view import view_config
+from pyramid.view import (
+ view_config,
+ notfound_view_config,
+ forbidden_view_config,
+)
from pyramid.httpexceptions import HTTPFound
+# @forbidden_view_config()
+# @notfound_view_config()
@view_config(
context="ordr3:resources.Root", permission="view",
)
diff --git a/tests/test_models.py b/tests/test_models.py
index 402298d..655a5fe 100644
--- a/tests/test_models.py
+++ b/tests/test_models.py
@@ -64,6 +64,25 @@ def test_orderitem_add_to_log_non_empty_log():
assert order.status == log_entry_2.status
+@pytest.mark.parametrize(
+ "status,expected",
+ [
+ ("OPEN", False),
+ ("APPROVAL", True),
+ ("ORDERED", True),
+ ("COMPLETED", True),
+ ("HOLD", False),
+ ],
+)
+def test_orderitem_in_process(status, expected):
+ from ordr3.models import OrderItem, OrderStatus
+
+ order = OrderItem(*list("ABCDEFGHIJK"))
+ order.status = OrderStatus[status]
+
+ assert order.in_process == expected
+
+
def test_LogEntry_init():
from ordr3.models import LogEntry
diff --git a/tests/test_repo.py b/tests/test_repo.py
index eb0e3dc..64bb1d6 100644
--- a/tests/test_repo.py
+++ b/tests/test_repo.py
@@ -79,6 +79,26 @@ def test_sql_repo_add_order(session, example_orders):
assert order == example_orders[0]
+def test_sql_repo_delete_order(session, example_orders):
+ from ordr3.repo import SqlAlchemyRepository
+ from ordr3.services import create_log_entry
+ from ordr3.models import LogEntry, OrderStatus, User
+
+ repo = SqlAlchemyRepository(session)
+ repo.add_order(example_orders[0])
+ repo.add_order(example_orders[1])
+ user = User(*list("ABCDEFG"))
+ create_log_entry(example_orders[0], OrderStatus.APPROVAL, user)
+ create_log_entry(example_orders[1], OrderStatus.APPROVAL, user)
+ session.flush()
+
+ repo.delete_order(example_orders[0])
+ session.flush()
+
+ assert repo.list_orders() == [example_orders[1]]
+ assert session.query(LogEntry).all() == example_orders[1].log
+
+
def test_sql_repo_get_order(session, example_orders):
from ordr3.repo import SqlAlchemyRepository
@@ -126,6 +146,19 @@ def test_sql_repo_add_user(session, example_users):
assert user == example_users[0]
+def test_sql_repo_delte_user(session, example_users):
+ from ordr3.repo import SqlAlchemyRepository
+
+ repo = SqlAlchemyRepository(session)
+ repo.add_user(example_users[0])
+ repo.add_user(example_users[1])
+ session.flush()
+
+ repo.delete_user(example_users[0])
+
+ assert repo.list_users() == [example_users[1]]
+
+
def test_sql_repo_get_user(session, example_users):
from ordr3.repo import SqlAlchemyRepository
@@ -204,6 +237,19 @@ def test_sql_repo_list_users(session, example_users):
assert repo.list_users() == [earlier, later]
+def test_sql_repo_count_new_users(session, example_users):
+ from ordr3.repo import SqlAlchemyRepository
+ from ordr3.models import UserRole
+
+ repo = SqlAlchemyRepository(session)
+ example_users[0].role = UserRole.NEW
+ repo.add_user(example_users[0])
+ repo.add_user(example_users[1])
+ session.flush()
+
+ assert repo.count_new_users() == 1
+
+
def test_sql_search_vendor(session, example_users):
from ordr3.repo import SqlAlchemyRepository
from ordr3.models import Vendor
diff --git a/tests/test_services.py b/tests/test_services.py
index e779558..cda6a46 100644
--- a/tests/test_services.py
+++ b/tests/test_services.py
@@ -149,24 +149,54 @@ def test_service_find_consumables(prefilled_repo):
assert [o.id for o in result] == [3, 0]
-def test_create_log_entry(prefilled_repo):
+def test_create_log_entry_noteworthy(prefilled_repo):
+ from ordr3.services import create_log_entry
+ from ordr3.models import OrderStatus, User
+
+ order = prefilled_repo.get_order(1)
+ user_1 = User(*list("ABCDEFG"))
+ user_2 = User(*list("AXCDEFG"))
+
+ # first log entry, order.created_by is automatically set
+ create_log_entry(order, OrderStatus.OPEN, user_1)
+ # second log entry
+ result = create_log_entry(order, OrderStatus.APPROVAL, user_2)
+
+ assert result is True
+ assert len(order.log) == 2
+ first_entry, second_entry = order.log
+ assert first_entry.order_id == order.id
+ assert first_entry.status == OrderStatus.OPEN
+ assert first_entry.by == "B"
+ assert isinstance(first_entry.date, datetime)
+ assert order.created_by == first_entry.by
+ assert order.created_on == first_entry.date
+ assert order.status == second_entry.status
+
+
+def test_create_log_entry_not_noteworthy_same_user(prefilled_repo):
+ from ordr3.services import create_log_entry
+ from ordr3.models import OrderStatus, User
+
+ order = prefilled_repo.get_order(1)
+ user = User(*list("ABCDEFG"))
+ order.created_by = user.username
+
+ result = create_log_entry(order, OrderStatus.APPROVAL, user)
+
+ assert result is False
+
+
+def test_create_log_entry_not_noteworthy_same_status(prefilled_repo):
from ordr3.services import create_log_entry
from ordr3.models import OrderStatus, User
order = prefilled_repo.get_order(1)
user = User(*list("ABCDEFG"))
- create_log_entry(order, OrderStatus.APPROVAL, user)
-
- assert len(order.log) == 1
- log_entry = order.log[0]
- assert log_entry.order_id == order.id
- assert log_entry.status == OrderStatus.APPROVAL
- assert log_entry.by == "B"
- assert isinstance(log_entry.date, datetime)
- assert order.status == log_entry.status
- assert order.created_by == log_entry.by
- assert order.created_on == log_entry.date
+ result = create_log_entry(order, OrderStatus.ORDERED, user)
+
+ assert result is False
@pytest.mark.parametrize(
|