-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* 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
1 parent
105c2d1
commit 8a8a798
Showing
31 changed files
with
1,901 additions
and
1,283 deletions.
There are no files selected for viewing
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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", | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
Oops, something went wrong.