Skip to content

Commit

Permalink
rc/green-doors-1 (#721)
Browse files Browse the repository at this point in the history
* TSS-1482: Barrier Downloads (#714)

* init

* refactor

* Update

* Presigned URL view

* Updates + tests

* format

* format

* fixt dataset test

* remaining tests

* format

* Patch + additional tests

* format

* Rename barrier-reports -> barrier-downloads

* remaining report name changes

* format

* updates

* format

* returned a paginated list to match frontend signature for  a list result

* fix test

* format

* f

* delete download

* barrier fiters

* format

* format;

* f

* id return name

* adding count to database

* tests

* formatg

* Reinstate original qs

* f

* format

* fixing filters added to search when download is saved

* fixing broken test

---------

Co-authored-by: Asmund Bekker <[email protected]>
Co-authored-by: Uka Osim <[email protected]>

* Bump django from 4.2.7 to 4.2.10 (#718)

* Bump django from 4.2.7 to 4.2.10

Bumps [django](https://github.com/django/django) from 4.2.7 to 4.2.10.
- [Commits](django/django@4.2.7...4.2.10)

---
updated-dependencies:
- dependency-name: django
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Regenerating requirements.txt file

---------

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot[bot] <dependabot[bot]@users.noreply.github.com>

* Bump cryptography from 41.0.7 to 42.0.0 (#717)

* Bump cryptography from 41.0.7 to 42.0.0

Bumps [cryptography](https://github.com/pyca/cryptography) from 41.0.7 to 42.0.0.
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](pyca/cryptography@41.0.7...42.0.0)

---
updated-dependencies:
- dependency-name: cryptography
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Regenerating requirements.txt file

* removing data that should not be there

---------

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot[bot] <dependabot[bot]@users.noreply.github.com>
Co-authored-by: Uka Osim <[email protected]>

---------

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: abarolo <[email protected]>
Co-authored-by: Asmund Bekker <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot[bot] <dependabot[bot]@users.noreply.github.com>
  • Loading branch information
5 people authored Feb 27, 2024
1 parent 105c2d1 commit 8a8a798
Show file tree
Hide file tree
Showing 31 changed files with 1,901 additions and 1,283 deletions.
File renamed without changes.
5 changes: 5 additions & 0 deletions api/barrier_downloads/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.apps import AppConfig


class BarrierDownloadsConfig(AppConfig):
name = "api.barrier_downloads"
79 changes: 79 additions & 0 deletions api/barrier_downloads/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
BARRIER_FIELD_TO_COLUMN_TITLE = {
"id": "id",
"code": "code",
"title": "Title",
"status": "Status",
"priority": "Old Priority",
"priority_level": "Priority",
"overseas_region": "Overseas Region",
"location": "Location",
"admin_areas": "Admin areas",
"sectors": "Sectors",
"product": "Product",
"term": "Term",
"categories": "Barrier categories",
"source": "Source",
"team_count": "Team count",
"economic_assessment_rating": "Economic assessment rating",
"economic_assessment_explanation": "Economic assessment explanation",
"value_to_economy": "Value to economy",
"import_market_size": "Import market size",
"valuation_assessment_rating": "Valuation assessment rating",
"valuation_assessment_midpoint": "Midpoint value",
"valuation_assessment_explanation": "Valuation assessment explanation",
"commercial_value": "Commercial value estimate",
"reported_on": "Reported Date",
"status_date": "Status effective from date",
"resolved_date": "Resolved Date",
"status_summary": "Status summary",
"modified_on": "Last updated",
"tags": "Tags",
"trade_direction": "Trade direction",
"estimated_resolution_date": "Estimated resolution date",
"proposed_estimated_resolution_date": "Proposed estimated resolution date",
"previous_estimated_resolution_date": "The previous estimate for resolution date",
"estimated_resolution_updated_date": "The last date the resolution date was re-estimated",
"estimated_resolution_date_change_reason": "The reason for change to the estimated resolution date",
"summary": "Summary",
"link": "Link",
"wto_has_been_notified": "WTO Notified",
"wto_should_be_notified": "WTO Should Notify",
"wto_committee_notified": "WTO Committee Notified",
"wto_committee_notification_link": "WTO Committee Notified Link",
"wto_member_states": "WTO Raised Members",
"wto_committee_raised_in": "WTO Raised Committee",
"wto_raised_date": "WTO Raised Date",
"wto_case_number": "WTO Case Number",
"commodity_codes": "HS commodity codes",
"first_published_on": "First published date",
"last_published_on": "Last published date",
"public_view_status": "Public view status",
"public_eligibility_summary": "Public eligibility summary",
# TODO: last_public_view_status_update takes too long to calculate
# on production, and needs to be denormalised. Will be addressed in MAR-940
"last_public_view_status_update": "Last public view status update",
"changed_since_published": "Changed since published",
"public_id": "Public ID",
"public_title": "Public title",
"public_summary": "Public summary",
"public_is_resolved": "Published as resolved",
"latest_publish_note": "Latest publish note",
"resolvability_assessment_time": "Resolvability assessment time",
"resolvability_assessment_effort": "Resolvability assessment effort",
"strategic_assessment_scale": "Strategic assessment scale",
"is_top_priority": "Is Top Priority",
"top_priority_status": "Top Priority Status",
"top_priority_summary": "Reason for Top Priority Status",
"is_resolved_top_priority": "Is Resolved Top Priority",
"government_organisations": "Related Organisations",
"progress_update_status": "Progress update status",
"progress_update_message": "Progress update message",
"progress_update_date": "Progress update date",
"progress_update_author": "Progress update author",
"progress_update_next_steps": "Progress update next steps",
"next_steps_items": "Progress update list of next steps",
"programme_fund_progress_update_milestones": "Programme fund milestones",
"programme_fund_progress_update_expenditure": "Programme fund expenditure",
"programme_fund_progress_update_date": "Programme fund date",
"programme_fund_progress_update_author": "Programme fund author",
}
27 changes: 27 additions & 0 deletions api/barrier_downloads/csv.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from datetime import datetime
from decimal import Decimal


def _transform_csv_row(row):
return {key: _transform_csv_value(val) for key, val in row.items()}


def _transform_csv_value(value):
"""
Transforms values before they are written to a CSV file for better compatibility with Excel.
In particular, datetimes are formatted in a way that results in better compatibility with
Excel. Lists are converted to comma separated strings. Other values are passed through
unchanged (the csv module automatically formats None as an empty string).
These transformations are specific to CSV files and won't necessarily apply to other file
formats.
"""
if isinstance(value, datetime):
return value.strftime("%Y-%m-%d")
if isinstance(value, Decimal):
normalized_value = value.normalize()
return f"{normalized_value:f}"
if isinstance(value, list):
return "; ".join(str(x) for x in value)
return value
21 changes: 21 additions & 0 deletions api/barrier_downloads/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from rest_framework.exceptions import APIException


class BarrierDownloadStatusUpdateError(APIException):
status_code = 400
default_code = "error"


class BarrierDownloadDoesNotExist(APIException):
status_code = 404
default_code = "error"


class BarrierDownloadNotificationError(APIException):
status_code = 400
default_code = "error"


class BarrierDeleteError(APIException):
status_code = 400
default_code = "error"
105 changes: 105 additions & 0 deletions api/barrier_downloads/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Generated by Django 4.2.7 on 2024-02-13 14:39

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import uuid


class Migration(migrations.Migration):

initial = True

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.CreateModel(
name="BarrierDownload",
fields=[
(
"created_on",
models.DateTimeField(auto_now_add=True, db_index=True, null=True),
),
("modified_on", models.DateTimeField(auto_now=True, null=True)),
("archived", models.BooleanField(default=False)),
("archived_on", models.DateTimeField(blank=True, null=True)),
("archived_reason", models.TextField(blank=True)),
(
"id",
models.UUIDField(
default=uuid.uuid4, primary_key=True, serialize=False
),
),
(
"name",
models.CharField(
help_text="User defined barrier download name",
max_length=128,
null=True,
),
),
(
"status",
models.CharField(
choices=[
("PENDING", "Pending"),
("PROCESSING", "Processing"),
("COMPLETE", "Complete"),
("FAILED", "Failed"),
],
default="PENDING",
),
),
("filename", models.CharField(editable=False, max_length=255)),
(
"filters",
models.JSONField(
help_text="Filters used to generate Download Report"
),
),
(
"count",
models.IntegerField(
blank=True,
help_text="Number of barriers in the report",
null=True,
),
),
(
"archived_by",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="+",
to=settings.AUTH_USER_MODEL,
),
),
(
"created_by",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="+",
to=settings.AUTH_USER_MODEL,
),
),
(
"modified_by",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="+",
to=settings.AUTH_USER_MODEL,
),
),
],
options={
"abstract": False,
},
),
]
Empty file.
54 changes: 54 additions & 0 deletions api/barrier_downloads/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import uuid
from logging import getLogger

from django.conf import settings
from django.db import models

from api.barrier_downloads.exceptions import BarrierDownloadStatusUpdateError
from api.core.models import ArchivableMixin, BaseModel

logger = getLogger(__name__)


class BarrierDownloadStatus(models.TextChoices):
PENDING = "PENDING", "Pending"
PROCESSING = "PROCESSING", "Processing"
COMPLETE = "COMPLETE", "Complete"
FAILED = "FAILED", "Failed"


class BarrierDownload(ArchivableMixin, BaseModel):
id = models.UUIDField(primary_key=True, default=uuid.uuid4)
name = models.CharField(
max_length=128, help_text="User defined barrier download name", null=True
)
status = models.CharField(
choices=BarrierDownloadStatus.choices, default=BarrierDownloadStatus.PENDING
)
filename = models.CharField(
max_length=settings.CHAR_FIELD_MAX_LENGTH, editable=False
)
filters = models.JSONField(help_text="Filters used to generate Download Report")
count = models.IntegerField(
help_text="Number of barriers in the report", null=True, blank=True
)

def processing(self):
if self.status != BarrierDownloadStatus.PENDING:
raise BarrierDownloadStatusUpdateError(
"Can only process a pending Barrier Download"
)
self.status = BarrierDownloadStatus.PROCESSING
self.save()

def complete(self):
if self.status != BarrierDownloadStatus.PROCESSING:
raise BarrierDownloadStatusUpdateError(
"Can only complete a processing Barrier Download"
)
self.status = BarrierDownloadStatus.COMPLETE
self.save()

def fail(self):
self.status = BarrierDownloadStatus.FAILED
self.save()
Loading

0 comments on commit 8a8a798

Please sign in to comment.