Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bc_obps/bc_obps/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
os.environ.get("GOOGLE_APPLICATION_CREDENTIALS")
)
GS_FILE_OVERWRITE = False
GS_BLOB_CHUNK_SIZE = int(2.5 * 1024 * 1024) # 2.5MB

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ.get("DJANGO_SECRET_KEY")
Expand Down
6 changes: 3 additions & 3 deletions bc_obps/common/tests/endpoints/auth/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@
"kwargs": {"report_version_id": MOCK_INT},
},
{
"method": "put",
"method": "post",
"endpoint_name": "register_edit_operation_information",
"kwargs": {"operation_id": MOCK_UUID},
},
Expand All @@ -234,7 +234,7 @@
"kwargs": {"version_id": MOCK_INT},
},
{
"method": "put",
"method": "post",
"endpoint_name": "update_operation",
"kwargs": {"operation_id": MOCK_UUID},
},
Expand All @@ -258,7 +258,7 @@
"kwargs": {"operation_id": MOCK_UUID},
},
{
"method": "put",
"method": "post",
"endpoint_name": "create_or_replace_new_entrant_application",
"kwargs": {"operation_id": MOCK_UUID},
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
from typing import Literal, Tuple
from uuid import UUID
from django.http import HttpRequest
from ninja import File, Form, UploadedFile
from registration.constants import OPERATION_TAGS
from registration.schema.generic import Message
from service.error_service.custom_codes_4xx import custom_codes_4xx
from registration.schema import (
from registration.schema.operation import (
OperationNewEntrantApplicationInWithDocuments,
OperationUpdateOut,
OperationNewEntrantApplicationIn,
OperationNewEntrantApplicationOut,
Message,
)
from service.operation_service import OperationService
from common.permissions import authorize
Expand All @@ -32,16 +34,23 @@ def get_operation_new_entrant_application(request: HttpRequest, operation_id: UU
return 200, OperationService.get_if_authorized(get_current_user_guid(request), operation_id, ['id', 'operator_id'])


@router.put(
@router.post(
"/operations/{uuid:operation_id}/registration/new-entrant-application",
response={200: OperationUpdateOut, custom_codes_4xx: Message},
tags=OPERATION_TAGS,
description="Creates or replaces a new entrant application document for an Operation",
auth=authorize("approved_industry_user"),
)
def create_or_replace_new_entrant_application(
request: HttpRequest, operation_id: UUID, payload: OperationNewEntrantApplicationIn
request: HttpRequest,
operation_id: UUID,
details: Form[OperationNewEntrantApplicationIn],
new_entrant_application: UploadedFile = File(None),
) -> Tuple[Literal[200], Operation]:
payload = OperationNewEntrantApplicationInWithDocuments(
date_of_first_shipment=details.date_of_first_shipment,
**({'new_entrant_application': new_entrant_application} if new_entrant_application else {})
)
return 200, OperationService.create_or_replace_new_entrant_application(
get_current_user_guid(request), operation_id, payload
)
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
from typing import Literal, Tuple
from uuid import UUID
from django.http import HttpRequest
from registration.schema import OperationInformationIn, OperationUpdateOut, OperationRegistrationOut, Message
from registration.schema.generic import Message
from service.operation_service import OperationService
from registration.constants import OPERATION_TAGS
from ninja import File, Form, UploadedFile
from registration.schema.operation import (
OperationRegistrationIn,
OperationRegistrationInWithDocuments,
OperationUpdateOut,
OperationRegistrationOut,
)
from common.permissions import authorize
from common.api.utils import get_current_user_guid
from service.error_service.custom_codes_4xx import custom_codes_4xx
Expand All @@ -26,9 +33,8 @@ def register_get_operation_information(request: HttpRequest, operation_id: UUID)


##### PUT #####


@router.put(
# https://stackoverflow.com/questions/77083771/django-ninja-update-a-filefield
@router.post(
"/operations/{uuid:operation_id}/registration/operation",
response={200: OperationUpdateOut, custom_codes_4xx: Message},
tags=OPERATION_TAGS,
Expand All @@ -37,6 +43,16 @@ def register_get_operation_information(request: HttpRequest, operation_id: UUID)
auth=authorize('approved_industry_user'),
)
def register_edit_operation_information(
request: HttpRequest, operation_id: UUID, payload: OperationInformationIn
request: HttpRequest,
operation_id: UUID,
details: Form[OperationRegistrationIn],
# documents are optional because if the user hasn't given us an updated document, we don't have to do anything
boundary_map: UploadedFile = File(None),
process_flow_diagram: UploadedFile = File(None),
) -> Tuple[Literal[200], Operation]:
payload = OperationRegistrationInWithDocuments(
**details.dict(by_alias=True),
**({'boundary_map': boundary_map} if boundary_map else {}),
**({'process_flow_diagram': process_flow_diagram} if process_flow_diagram else {})
)
return 200, OperationService.register_operation_information(get_current_user_guid(request), operation_id, payload)
31 changes: 25 additions & 6 deletions bc_obps/registration/api/_operations/operation_id.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
from typing import Literal, Tuple
from uuid import UUID
from registration.schema import OperationInformationInUpdate, OperationOutV2, OperationOutWithDocuments, Message
from registration.schema.operation import (
OperationAdministrationIn,
OperationAdministrationInWithDocuments,
OperationAdministrationOut,
)
from common.permissions import authorize
from django.http import HttpRequest
from registration.constants import OPERATION_TAGS
Expand All @@ -9,14 +13,16 @@
from common.api.utils import get_current_user_guid
from registration.api.router import router
from registration.models import Operation
from registration.schema.generic import Message
from ninja import File, Form, UploadedFile


##### GET #####


@router.get(
"/operations/{uuid:operation_id}",
response={200: OperationOutV2, custom_codes_4xx: Message},
response={200: OperationAdministrationOut, custom_codes_4xx: Message},
tags=OPERATION_TAGS,
description="""Retrieves the details of a specific operation by its ID. Unlike the v1 endpoint, this endpoint does not
return the new entrant application field as it can be quite large and cause slow requests. If you need the new entrant application field,
Expand All @@ -30,7 +36,7 @@ def get_operation(request: HttpRequest, operation_id: UUID) -> Tuple[Literal[200

@router.get(
"/operations/{uuid:operation_id}/with-documents",
response={200: OperationOutWithDocuments, custom_codes_4xx: Message},
response={200: OperationAdministrationOut, custom_codes_4xx: Message},
tags=OPERATION_TAGS,
description="""Retrieves the details of a specific operation by its ID along with it's documents""",
exclude_none=True,
Expand All @@ -43,14 +49,27 @@ def get_operation_with_documents(request: HttpRequest, operation_id: UUID) -> Tu
##### PUT ######


@router.put(
@router.post(
"/operations/{uuid:operation_id}",
response={200: OperationOutV2, custom_codes_4xx: Message},
response={200: OperationAdministrationOut, custom_codes_4xx: Message},
tags=OPERATION_TAGS,
description="Updates the details of a specific operation by its ID.",
auth=authorize("approved_industry_user"),
)
def update_operation(
request: HttpRequest, operation_id: UUID, payload: OperationInformationInUpdate
request: HttpRequest,
operation_id: UUID,
details: Form[OperationAdministrationIn],
# documents are optional because if the user hasn't given us an updated document, we don't do anything
boundary_map: UploadedFile = File(None),
process_flow_diagram: UploadedFile = File(None),
new_entrant_application: UploadedFile = File(None),
) -> Tuple[Literal[200], Operation]:

payload = OperationAdministrationInWithDocuments(
**details.dict(by_alias=True),
**({'boundary_map': boundary_map} if boundary_map else {}),
**({'process_flow_diagram': process_flow_diagram} if process_flow_diagram else {}),
**({'new_entrant_application': new_entrant_application} if new_entrant_application else {})
)
return 200, OperationService.update_operation(get_current_user_guid(request), payload, operation_id)
20 changes: 16 additions & 4 deletions bc_obps/registration/api/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@
from typing import Tuple
from registration.schema import (
OperationCreateOut,
OperationInformationIn,
Message,
OperationTimelineFilterSchema,
OperationTimelineListOut,
)
from registration.schema.operation import OperationRegistrationInWithDocuments
from registration.schema.operation import OperationRegistrationIn
from service.operation_service import OperationService
from common.permissions import authorize
from django.http import HttpRequest
from common.api.utils import get_current_user_guid
from registration.api.router import router
from service.error_service.custom_codes_4xx import custom_codes_4xx
from ninja import Query
from ninja import Query, File, Form, UploadedFile
from django.db.models import QuerySet
from ninja.pagination import paginate
from registration.utils import CustomPagination
Expand Down Expand Up @@ -75,6 +76,17 @@ def get_registration_purposes(request: HttpRequest) -> Tuple[Literal[200], List[
auth=authorize("approved_industry_user"),
)
def register_create_operation_information(
request: HttpRequest, payload: OperationInformationIn
request: HttpRequest,
details: Form[OperationRegistrationIn],
boundary_map: UploadedFile = File(...), # File fields as separate params
process_flow_diagram: UploadedFile = File(...),
) -> Tuple[Literal[201], Operation]:
return 201, OperationService.register_operation_information(get_current_user_guid(request), None, payload)
payload = OperationRegistrationInWithDocuments(
**details.dict(by_alias=True), boundary_map=boundary_map, process_flow_diagram=process_flow_diagram
)

return 201, OperationService.register_operation_information(
get_current_user_guid(request),
None,
payload,
)
7 changes: 7 additions & 0 deletions bc_obps/registration/schema/document.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from registration.models.document import Document


def resolve_document(document: Document | None) -> str | None:
if document is not None:
return str(document.file.url)
return None
9 changes: 6 additions & 3 deletions bc_obps/registration/schema/multiple_operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@
from ninja import Field, ModelSchema
from registration.constants import BC_CORPORATE_REGISTRY_REGEX
from registration.models import MultipleOperator
from pydantic import field_validator
from pydantic import ConfigDict, field_validator


class MultipleOperatorIn(ModelSchema):
"""
Schema for the Multiple Operator part of the operation form
"""

model_config = ConfigDict(arbitrary_types_allowed=True)
id: Optional[int] = None
legal_name: str = Field(..., alias="mo_legal_name")
trade_name: str = Field(..., alias="mo_trade_name")
business_structure: str = Field(..., alias="mo_business_structure")
business_structure: str | BusinessStructure = Field(..., alias="mo_business_structure")
cra_business_number: int = Field(..., alias="mo_cra_business_number")
bc_corporate_registry_number: Optional[str] = Field(
None, alias="mo_bc_corporate_registry_number", pattern=BC_CORPORATE_REGISTRY_REGEX
Expand All @@ -33,7 +34,9 @@ def validate_cra_business_number(cls, value: int) -> Optional[int]:
@field_validator("business_structure")
@classmethod
def validate_business_structure(cls, value: str) -> BusinessStructure:
return validate_business_structure(value)
if isinstance(value, str):
return validate_business_structure(value)
return value

class Meta:
model = MultipleOperator
Expand Down
Loading
Loading