Skip to content

Commit

Permalink
Merge branch 'master' into TP2000-885--quota-geo-data-measure-creation
Browse files Browse the repository at this point in the history
  • Loading branch information
dalecannon authored Sep 19, 2023
2 parents 4996b6e + 2760a42 commit 73804d8
Show file tree
Hide file tree
Showing 11 changed files with 194 additions and 21 deletions.
19 changes: 19 additions & 0 deletions common/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,25 @@ def test_as_at_today(model1_with_history):
}


def test_as_at_today_and_beyond(date_ranges, validity_factory):
"""Ensure only records active at the current date and future records are
fetched."""
outdated_record = {validity_factory.create(valid_between=date_ranges.earlier).pk}

active_and_future_records = {
validity_factory.create(valid_between=date_ranges.normal).pk,
validity_factory.create(valid_between=date_ranges.later).pk,
}

test_model = validity_factory._meta.get_model_class()
queryset = set(
test_model.objects.as_at_today_and_beyond().values_list("pk", flat=True),
)

assert queryset != outdated_record
assert queryset == active_and_future_records


def test_get_version_raises_error():
"""Ensure that trying to get a specific version raises an error if no
identifiers given."""
Expand Down
18 changes: 9 additions & 9 deletions geo_areas/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def __init__(self, *args, **kwargs):
GeographicalArea.objects.filter(area_code=AreaCode.COUNTRY)
.current()
.with_latest_description()
.as_at_today()
.as_at_today_and_beyond()
.order_by("description")
)
self.fields[
Expand All @@ -107,7 +107,7 @@ def __init__(self, *args, **kwargs):
GeographicalArea.objects.filter(area_code=AreaCode.REGION)
.current()
.with_latest_description()
.as_at_today()
.as_at_today_and_beyond()
.order_by("description")
)
self.fields[
Expand Down Expand Up @@ -196,7 +196,7 @@ def __init__(self, *args, **kwargs):
GeographicalArea.objects.filter(area_code=AreaCode.GROUP)
.current()
.with_latest_description()
.as_at_today()
.as_at_today_and_beyond()
.order_by("description")
)
self.fields[
Expand Down Expand Up @@ -542,7 +542,7 @@ def __init__(self, *args, **kwargs):
.exclude(pk__in=current_memberships)
.current()
.with_latest_description()
.as_at_today()
.as_at_today_and_beyond()
.order_by("description")
)
self.fields[
Expand Down Expand Up @@ -631,7 +631,7 @@ def __init__(self, *args, **kwargs):
)
.current()
.with_latest_description()
.as_at_today()
.as_at_today_and_beyond()
.order_by("description")
)
self.fields[
Expand Down Expand Up @@ -768,7 +768,7 @@ def __init__(self, *args, **kwargs):
self.fields["erga_omnes_exclusion"].queryset = (
GeographicalArea.objects.current()
.with_latest_description()
.as_at_today()
.as_at_today_and_beyond()
.order_by("description")
)
self.fields[
Expand Down Expand Up @@ -803,7 +803,7 @@ def __init__(self, *args, **kwargs):
GeographicalArea.objects.current()
.with_latest_description()
.filter(area_code=AreaCode.GROUP)
.as_at_today()
.as_at_today_and_beyond()
.order_by("description")
)
# descriptions__description" should make this implicitly distinct()
Expand All @@ -830,7 +830,7 @@ def __init__(self, *args, **kwargs):
self.fields["geo_group_exclusion"].queryset = (
GeographicalArea.objects.current()
.with_latest_description()
.as_at_today()
.as_at_today_and_beyond()
.order_by("description")
)
self.fields[
Expand Down Expand Up @@ -879,7 +879,7 @@ def __init__(self, *args, **kwargs):
GeographicalArea.objects.current()
.with_latest_description()
.exclude(area_code=AreaCode.GROUP)
.as_at_today()
.as_at_today_and_beyond()
.order_by("description")
)

Expand Down
79 changes: 74 additions & 5 deletions quotas/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def __init__(self, *args, **kwargs):
self.fields["exclusion"].queryset = (
GeographicalArea.objects.current()
.with_latest_description()
.as_at_today()
.as_at_today_and_beyond()
.order_by("description")
)
self.fields[
Expand Down Expand Up @@ -258,7 +258,7 @@ def init_fields(self):
self.fields["geographical_area"].queryset = (
GeographicalArea.objects.current()
.with_latest_description()
.as_at_today()
.as_at_today_and_beyond()
.order_by("description")
)
self.fields[
Expand All @@ -274,21 +274,90 @@ class Meta:
model = models.QuotaDefinition
fields = [
"valid_between",
"description",
"volume",
"initial_volume",
"measurement_unit",
"measurement_unit_qualifier",
"quota_critical_threshold",
"quota_critical",
]

description = forms.CharField(label="", widget=forms.Textarea(), required=False)
volume = forms.DecimalField(
label="Current volume",
widget=forms.TextInput(),
error_messages={"invalid": "Volume must be a number"},
)
initial_volume = forms.DecimalField(
widget=forms.TextInput(),
error_messages={"invalid": "Initial volume must be a number"},
)
quota_critical_threshold = forms.DecimalField(
label="Threshold",
help_text="The point at which this quota definition period becomes critical, as a percentage of the total volume.",
widget=forms.TextInput(),
error_messages={"invalid": "Critical threshold must be a number"},
)
quota_critical = forms.TypedChoiceField(
label="Is the quota definition period in a critical state?",
help_text="This determines if a trader needs to pay securities when utilising the quota.",
coerce=lambda value: value == "True",
choices=((True, "Yes"), (False, "No")),
widget=forms.RadioSelect(),
)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.init_layout()
self.init_fields()

def init_fields(self):
self.fields["measurement_unit"].queryset = self.fields[
"measurement_unit"
].queryset.order_by("code")
self.fields[
"measurement_unit"
].label_from_instance = lambda obj: f"{obj.code} - {obj.description}"

self.fields["measurement_unit_qualifier"].queryset = self.fields[
"measurement_unit_qualifier"
].queryset.order_by("code")
self.fields[
"measurement_unit_qualifier"
].label_from_instance = lambda obj: f"{obj.code} - {obj.description}"

def init_layout(self):
self.helper = FormHelper(self)
self.helper.label_size = Size.SMALL
self.helper.legend_size = Size.SMALL

self.helper.layout = Layout(
Div(
"start_date",
"end_date",
Accordion(
AccordionSection(
"Description",
"description",
),
AccordionSection(
"Validity period",
"start_date",
"end_date",
),
AccordionSection(
"Measurements",
Field("measurement_unit", css_class="govuk-!-width-full"),
Field("measurement_unit_qualifier", css_class="govuk-!-width-full"),
),
AccordionSection(
"Volume",
"initial_volume",
"volume",
),
AccordionSection(
"Criticality",
"quota_critical_threshold",
"quota_critical",
),
css_class="govuk-!-width-two-thirds",
),
Submit(
Expand Down
8 changes: 4 additions & 4 deletions quotas/jinja2/quotas/tables/definitions.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"rows": [
{
"key": { "text": "Description" },
"value": { "text": object.description if object.description else "-" },
"value": { "text": object.description if object.description else "" },
"actions": {"items": []}
},
{
Expand Down Expand Up @@ -53,12 +53,12 @@

{{ table_rows.append([
{"text": object_details },
{"text": quota_data[object.sid].status if quota_data[object.sid] else "-" },
{"text": quota_data[object.sid].status if quota_data[object.sid] else "" },
{"text": "{:%d %b %Y}".format(object.valid_between.lower) },
{"text": "{:%d %b %Y}".format(object.valid_between.upper) if object.valid_between.upper else "-"},
{"text": "{:%d %b %Y}".format(object.valid_between.upper) if object.valid_between.upper else ""},
{"text": intcomma(object.initial_volume) },
{"text": intcomma(object.volume) },
{"text": intcomma(quota_data[object.sid].balance) if quota_data[object.sid] else "-" },
{"text": intcomma(quota_data[object.sid].balance) if quota_data[object.sid] else "" },
{"text": object.measurement_unit.abbreviation|title},
{"text": actions_html },
]) or "" }}
Expand Down
14 changes: 14 additions & 0 deletions quotas/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,7 @@ def test_update_quota_definition(valid_user_client, date_ranges):
valid_between=date_ranges.big_no_end,
)
url = reverse("quota_definition-ui-edit", kwargs={"sid": quota_definition.sid})
measurement_unit = factories.MeasurementUnitFactory()

data = {
"start_date_0": date_ranges.normal.lower.day,
Expand All @@ -874,6 +875,13 @@ def test_update_quota_definition(valid_user_client, date_ranges):
"end_date_0": date_ranges.normal.upper.day,
"end_date_1": date_ranges.normal.upper.month,
"end_date_2": date_ranges.normal.upper.year,
"description": "Lorem ipsum.",
"volume": "80601000.000",
"initial_volume": "80601000.000",
"measurement_unit": measurement_unit.pk,
"measurement_unit_qualifier": "",
"quota_critical_threshold": "90",
"quota_critical": "False",
}

response = valid_user_client.post(url, data)
Expand All @@ -892,6 +900,12 @@ def test_update_quota_definition(valid_user_client, date_ranges):
)

assert updated_definition.valid_between == date_ranges.normal
assert updated_definition.description == "Lorem ipsum."
assert updated_definition.volume == 80601000.000
assert updated_definition.initial_volume == 80601000.000
assert updated_definition.measurement_unit == measurement_unit
assert updated_definition.quota_critical_threshold == 90
assert updated_definition.quota_critical == False


def test_delete_quota_definition_page_200(valid_user_client):
Expand Down
5 changes: 5 additions & 0 deletions quotas/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@
views.QuotaDefinitionUpdate.as_view(),
name="quota_definition-ui-edit",
),
path(
f"quota_definitions/<sid>/edit-update/",
views.QuotaDefinitionUpdate.as_view(),
name="quota_definition-ui-edit-update",
),
path(
f"quota_definitions/<sid>/delete/",
views.QuotaDefinitionDelete.as_view(),
Expand Down
29 changes: 29 additions & 0 deletions reports/migrations/0001_report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 3.2.20 on 2023-09-11 14:27

from django.db import migrations, models


class Migration(migrations.Migration):
initial = True

dependencies = []

operations = [
migrations.CreateModel(
name="Report",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
],
options={
"db_table": "report",
},
),
]
30 changes: 30 additions & 0 deletions reports/migrations/0002_create_custom_permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from django.contrib.auth.models import Permission, Group
from django.contrib.contenttypes.models import ContentType
from reports.models import Report
from django.db import migrations


def create_custom_permissions(apps, schema_editor):
content_type = ContentType.objects.get_for_model(Report)

view_permission, _ = Permission.objects.get_or_create(
codename="view_report_index",
name="Can view report index",
content_type=content_type,
)

edit_permission, _ = Permission.objects.get_or_create(
codename="view_report",
name="Can view reports",
content_type=content_type,
)


class Migration(migrations.Migration):
dependencies = [
("reports", "0001_report"),
]

operations = [
migrations.RunPython(create_custom_permissions),
]
8 changes: 7 additions & 1 deletion reports/models.py
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
# Create your models here.
from django.db import models


class Report(models.Model):
class Meta:
# Define the name for the database table (optional)
db_table = "report"
4 changes: 2 additions & 2 deletions reports/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import reports.utils as utils


@permission_required("app.view_report_index")
@permission_required("reports.view_report_index")
def index(request):
context = {
"report": index_model.IndexTable(),
Expand All @@ -16,7 +16,7 @@ def index(request):
return render(request, "reports/index.jinja", context)


@permission_required("app.view_report")
@permission_required("reports.view_report")
def report(request):
# find the report based on the request
report_class = utils.get_report_by_slug(request.resolver_match.url_name)
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
aiohttp==3.8.5
apsw==3.43.0.0
aioresponses==0.7.4
allure-pytest-bdd==2.8.40
api-client==1.3.0
Expand Down

0 comments on commit 73804d8

Please sign in to comment.