karrio-server-manager 2025.5rc1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- karrio/server/manager/__init__.py +1 -0
- karrio/server/manager/admin.py +1 -0
- karrio/server/manager/apps.py +13 -0
- karrio/server/manager/migrations/0001_initial.py +1358 -0
- karrio/server/manager/migrations/0002_auto_20201127_0721.py +61 -0
- karrio/server/manager/migrations/0003_auto_20201230_0820.py +34 -0
- karrio/server/manager/migrations/0004_auto_20210125_2125.py +18 -0
- karrio/server/manager/migrations/0005_auto_20210216_0758.py +27 -0
- karrio/server/manager/migrations/0006_auto_20210307_0438.py +24 -0
- karrio/server/manager/migrations/0006_auto_20210308_0302.py +53 -0
- karrio/server/manager/migrations/0007_merge_20210311_1428.py +14 -0
- karrio/server/manager/migrations/0008_remove_shipment_doc_images.py +17 -0
- karrio/server/manager/migrations/0009_auto_20210326_1425.py +28 -0
- karrio/server/manager/migrations/0010_auto_20210403_1404.py +28 -0
- karrio/server/manager/migrations/0011_auto_20210426_1924.py +48 -0
- karrio/server/manager/migrations/0012_auto_20210427_1319.py +24 -0
- karrio/server/manager/migrations/0013_customs_invoice_date.py +18 -0
- karrio/server/manager/migrations/0014_auto_20210515_0928.py +24 -0
- karrio/server/manager/migrations/0015_auto_20210601_0340.py +182 -0
- karrio/server/manager/migrations/0016_shipment_archived.py +18 -0
- karrio/server/manager/migrations/0017_auto_20210629_1650.py +22 -0
- karrio/server/manager/migrations/0018_auto_20210705_1049.py +23 -0
- karrio/server/manager/migrations/0019_auto_20210722_1131.py +43 -0
- karrio/server/manager/migrations/0020_tracking_messages.py +20 -0
- karrio/server/manager/migrations/0021_tracking_estimated_delivery.py +18 -0
- karrio/server/manager/migrations/0022_auto_20211122_2100.py +53 -0
- karrio/server/manager/migrations/0023_auto_20211227_2141.py +118 -0
- karrio/server/manager/migrations/0024_alter_parcel_items.py +18 -0
- karrio/server/manager/migrations/0025_auto_20220113_1158.py +25 -0
- karrio/server/manager/migrations/0026_parcel_reference_number.py +18 -0
- karrio/server/manager/migrations/0027_custom_migration_2021_1.py +47 -0
- karrio/server/manager/migrations/0028_auto_20220303_1153.py +39 -0
- karrio/server/manager/migrations/0029_auto_20220303_1249.py +55 -0
- karrio/server/manager/migrations/0030_alter_shipment_status.py +44 -0
- karrio/server/manager/migrations/0031_shipment_invoice.py +34 -0
- karrio/server/manager/migrations/0032_custom_migration_2022_3.py +26 -0
- karrio/server/manager/migrations/0033_auto_20220504_1335.py +57 -0
- karrio/server/manager/migrations/0034_commodity_hs_code.py +18 -0
- karrio/server/manager/migrations/0035_parcel_options.py +26 -0
- karrio/server/manager/migrations/0036_alter_tracking_shipment.py +24 -0
- karrio/server/manager/migrations/0037_auto_20220710_1350.py +28 -0
- karrio/server/manager/migrations/0038_alter_tracking_status.py +18 -0
- karrio/server/manager/migrations/0039_documentuploadrecord.py +43 -0
- karrio/server/manager/migrations/0040_parcel_freight_class.py +18 -0
- karrio/server/manager/migrations/0041_alter_commodity_options_alter_parcel_options.py +29 -0
- karrio/server/manager/migrations/0042_remove_shipment_shipment_tracking_number_idx_and_more.py +658 -0
- karrio/server/manager/migrations/0043_customs_duty_billing_address_and_more.py +62 -0
- karrio/server/manager/migrations/0044_address_address_line1_temp_and_more.py +326 -0
- karrio/server/manager/migrations/0045_alter_customs_duty_billing_address_and_more.py +45 -0
- karrio/server/manager/migrations/0046_auto_20230114_0930.py +78 -0
- karrio/server/manager/migrations/0047_remove_shipment_shipment_tracking_number_idx_and_more.py +595 -0
- karrio/server/manager/migrations/0048_commodity_title_alter_commodity_description_and_more.py +53 -0
- karrio/server/manager/migrations/0049_auto_20230318_0708.py +39 -0
- karrio/server/manager/migrations/0050_address_street_number_tracking_account_number_and_more.py +60 -0
- karrio/server/manager/migrations/0051_auto_20230330_0556.py +56 -0
- karrio/server/manager/migrations/0052_auto_20230520_0811.py +35 -0
- karrio/server/manager/migrations/0053_alter_commodity_weight_unit_alter_parcel_weight_unit.py +32 -0
- karrio/server/manager/migrations/0054_alter_address_company_name_alter_address_person_name.py +22 -0
- karrio/server/manager/migrations/0055_alter_tracking_status.py +32 -0
- karrio/server/manager/migrations/0056_tracking_delivery_image_tracking_signature_image.py +22 -0
- karrio/server/manager/migrations/0057_alter_customs_invoice_date.py +18 -0
- karrio/server/manager/migrations/0058_manifest_shipment_manifest.py +124 -0
- karrio/server/manager/migrations/0059_shipment_return_address.py +24 -0
- karrio/server/manager/migrations/0060_pickup_meta_alter_address_country_code_and_more.py +527 -0
- karrio/server/manager/migrations/0061_alter_customs_incoterm.py +37 -0
- karrio/server/manager/migrations/0062_alter_tracking_status.py +35 -0
- karrio/server/manager/migrations/__init__.py +0 -0
- karrio/server/manager/models.py +984 -0
- karrio/server/manager/router.py +3 -0
- karrio/server/manager/serializers/__init__.py +50 -0
- karrio/server/manager/serializers/address.py +82 -0
- karrio/server/manager/serializers/commodity.py +51 -0
- karrio/server/manager/serializers/customs.py +84 -0
- karrio/server/manager/serializers/document.py +113 -0
- karrio/server/manager/serializers/manifest.py +85 -0
- karrio/server/manager/serializers/parcel.py +84 -0
- karrio/server/manager/serializers/pickup.py +285 -0
- karrio/server/manager/serializers/rate.py +19 -0
- karrio/server/manager/serializers/shipment.py +869 -0
- karrio/server/manager/serializers/tracking.py +250 -0
- karrio/server/manager/signals.py +70 -0
- karrio/server/manager/tests/__init__.py +10 -0
- karrio/server/manager/tests/test_addresses.py +110 -0
- karrio/server/manager/tests/test_custom_infos.py +97 -0
- karrio/server/manager/tests/test_parcels.py +104 -0
- karrio/server/manager/tests/test_pickups.py +345 -0
- karrio/server/manager/tests/test_shipments.py +833 -0
- karrio/server/manager/tests/test_trackers.py +215 -0
- karrio/server/manager/urls.py +10 -0
- karrio/server/manager/views/__init__.py +9 -0
- karrio/server/manager/views/addresses.py +154 -0
- karrio/server/manager/views/customs.py +159 -0
- karrio/server/manager/views/documents.py +131 -0
- karrio/server/manager/views/manifests.py +160 -0
- karrio/server/manager/views/parcels.py +155 -0
- karrio/server/manager/views/pickups.py +182 -0
- karrio/server/manager/views/shipments.py +335 -0
- karrio/server/manager/views/trackers.py +364 -0
- karrio_server_manager-2025.5rc1.dist-info/METADATA +28 -0
- karrio_server_manager-2025.5rc1.dist-info/RECORD +102 -0
- karrio_server_manager-2025.5rc1.dist-info/WHEEL +5 -0
- karrio_server_manager-2025.5rc1.dist-info/top_level.txt +2 -0
@@ -0,0 +1,160 @@
|
|
1
|
+
import io
|
2
|
+
import base64
|
3
|
+
import logging
|
4
|
+
import django_downloadview
|
5
|
+
import django.urls as urls
|
6
|
+
import django.core.files.base as base
|
7
|
+
import rest_framework.status as status
|
8
|
+
import rest_framework.request as request
|
9
|
+
import rest_framework.response as response
|
10
|
+
import rest_framework.pagination as pagination
|
11
|
+
import rest_framework.throttling as throttling
|
12
|
+
import django_filters.rest_framework as django_filters
|
13
|
+
|
14
|
+
import karrio.server.openapi as openapi
|
15
|
+
import karrio.server.core.views.api as api
|
16
|
+
import karrio.server.core.filters as filters
|
17
|
+
import karrio.server.manager.models as models
|
18
|
+
import karrio.server.manager.router as router
|
19
|
+
import karrio.server.manager.serializers as serializers
|
20
|
+
|
21
|
+
ENDPOINT_ID = "$$$$&&" # This endpoint id is used to make operation ids unique make sure not to duplicate
|
22
|
+
logger = logging.getLogger(__name__)
|
23
|
+
Manifests = serializers.PaginatedResult("ManifestList", serializers.Manifest)
|
24
|
+
|
25
|
+
|
26
|
+
class ManifestList(api.GenericAPIView):
|
27
|
+
throttle_scope = "carrier_request"
|
28
|
+
pagination_class = type(
|
29
|
+
"CustomPagination", (pagination.LimitOffsetPagination,), dict(default_limit=20)
|
30
|
+
)
|
31
|
+
filter_backends = (django_filters.DjangoFilterBackend,)
|
32
|
+
filterset_class = filters.ManifestFilters
|
33
|
+
serializer_class = Manifests
|
34
|
+
model = models.Manifest
|
35
|
+
|
36
|
+
def get_throttles(self):
|
37
|
+
if self.request.method == "POST":
|
38
|
+
return [throttling.ScopedRateThrottle()]
|
39
|
+
return super().get_throttles()
|
40
|
+
|
41
|
+
@openapi.extend_schema(
|
42
|
+
tags=["Manifests"],
|
43
|
+
operation_id=f"{ENDPOINT_ID}list",
|
44
|
+
extensions={"x-operationId": "listManifests"},
|
45
|
+
summary="List manifests",
|
46
|
+
responses={
|
47
|
+
200: Manifests(),
|
48
|
+
404: serializers.ErrorResponse(),
|
49
|
+
500: serializers.ErrorResponse(),
|
50
|
+
},
|
51
|
+
parameters=filters.ManifestFilters.parameters,
|
52
|
+
)
|
53
|
+
def get(self, request: request.Request):
|
54
|
+
"""
|
55
|
+
Retrieve all manifests.
|
56
|
+
"""
|
57
|
+
manifests = self.filter_queryset(self.get_queryset())
|
58
|
+
response = self.paginate_queryset(
|
59
|
+
serializers.Manifest(manifests, many=True).data
|
60
|
+
)
|
61
|
+
return self.get_paginated_response(response)
|
62
|
+
|
63
|
+
@openapi.extend_schema(
|
64
|
+
tags=["Manifests"],
|
65
|
+
operation_id=f"{ENDPOINT_ID}create",
|
66
|
+
extensions={"x-operationId": "createManifest"},
|
67
|
+
summary="Create a manifest",
|
68
|
+
responses={
|
69
|
+
201: serializers.Manifest(),
|
70
|
+
400: serializers.ErrorResponse(),
|
71
|
+
424: serializers.ErrorMessages(),
|
72
|
+
500: serializers.ErrorResponse(),
|
73
|
+
},
|
74
|
+
request=serializers.ManifestData(),
|
75
|
+
)
|
76
|
+
def post(self, request: request.HttpRequest):
|
77
|
+
"""Create a manifest for one or many shipments with labels already purchased."""
|
78
|
+
|
79
|
+
manifest = (
|
80
|
+
serializers.ManifestSerializer.map(data=request.data, context=request)
|
81
|
+
.save()
|
82
|
+
.instance
|
83
|
+
)
|
84
|
+
|
85
|
+
return response.Response(
|
86
|
+
serializers.Manifest(manifest).data, status=status.HTTP_201_CREATED
|
87
|
+
)
|
88
|
+
|
89
|
+
|
90
|
+
class ManifestDetails(api.APIView):
|
91
|
+
|
92
|
+
@openapi.extend_schema(
|
93
|
+
tags=["Manifests"],
|
94
|
+
operation_id=f"{ENDPOINT_ID}retrieve",
|
95
|
+
extensions={"x-operationId": "retrieveManifest"},
|
96
|
+
summary="Retrieve a manifest",
|
97
|
+
responses={
|
98
|
+
200: serializers.Manifest(),
|
99
|
+
404: serializers.ErrorResponse(),
|
100
|
+
500: serializers.ErrorResponse(),
|
101
|
+
},
|
102
|
+
)
|
103
|
+
def get(self, request: request.Request, pk: str):
|
104
|
+
"""Retrieve a shipping manifest."""
|
105
|
+
manifest = models.Manifest.access_by(request).get(pk=pk)
|
106
|
+
return response.Response(serializers.Manifest(manifest).data)
|
107
|
+
|
108
|
+
|
109
|
+
class ManifestDoc(django_downloadview.VirtualDownloadView):
|
110
|
+
@openapi.extend_schema(exclude=True)
|
111
|
+
def get(
|
112
|
+
self,
|
113
|
+
request: request.Request,
|
114
|
+
pk: str,
|
115
|
+
doc: str = "manifest",
|
116
|
+
format: str = "pdf",
|
117
|
+
**kwargs,
|
118
|
+
):
|
119
|
+
"""Retrieve a manifest file."""
|
120
|
+
self.manifest = models.Manifest.objects.get(pk=pk, manifest__isnull=False)
|
121
|
+
self.document = getattr(self.manifest, doc, None)
|
122
|
+
self.name = f"{doc}_{self.manifest.id}.{format}"
|
123
|
+
|
124
|
+
query_params = request.GET.dict()
|
125
|
+
self.preview = "preview" in query_params
|
126
|
+
self.attachment = "download" in query_params
|
127
|
+
|
128
|
+
response = super(ManifestDoc, self).get(request, pk, doc, format, **kwargs)
|
129
|
+
response["X-Frame-Options"] = "ALLOWALL"
|
130
|
+
return response
|
131
|
+
|
132
|
+
def get_file(self):
|
133
|
+
content = base64.b64decode(self.document or "")
|
134
|
+
buffer = io.BytesIO()
|
135
|
+
buffer.write(content)
|
136
|
+
|
137
|
+
return base.ContentFile(buffer.getvalue(), name=self.name)
|
138
|
+
|
139
|
+
|
140
|
+
router.router.urls.append(
|
141
|
+
urls.path(
|
142
|
+
"manifests",
|
143
|
+
ManifestList.as_view(),
|
144
|
+
name="manifest-list",
|
145
|
+
)
|
146
|
+
)
|
147
|
+
router.router.urls.append(
|
148
|
+
urls.path(
|
149
|
+
"manifests/<str:pk>",
|
150
|
+
ManifestDetails.as_view(),
|
151
|
+
name="manifest-details",
|
152
|
+
)
|
153
|
+
)
|
154
|
+
router.router.urls.append(
|
155
|
+
urls.re_path(
|
156
|
+
r"^manifests/(?P<pk>\w+)/(?P<doc>[a-z0-9]+).(?P<format>[a-z0-9]+)",
|
157
|
+
ManifestDoc.as_view(),
|
158
|
+
name="manifest-docs",
|
159
|
+
)
|
160
|
+
)
|
@@ -0,0 +1,155 @@
|
|
1
|
+
import logging
|
2
|
+
|
3
|
+
from django.urls import path
|
4
|
+
from rest_framework import status
|
5
|
+
from rest_framework.request import Request
|
6
|
+
from rest_framework.response import Response
|
7
|
+
from rest_framework.pagination import LimitOffsetPagination
|
8
|
+
|
9
|
+
from karrio.server.manager.router import router
|
10
|
+
from karrio.server.core.views.api import GenericAPIView, APIView
|
11
|
+
from karrio.server.manager.serializers import (
|
12
|
+
PaginatedResult,
|
13
|
+
ErrorResponse,
|
14
|
+
ParcelData,
|
15
|
+
Parcel,
|
16
|
+
ParcelSerializer,
|
17
|
+
can_mutate_parcel,
|
18
|
+
)
|
19
|
+
import karrio.server.manager.models as models
|
20
|
+
import karrio.server.openapi as openapi
|
21
|
+
|
22
|
+
logger = logging.getLogger(__name__)
|
23
|
+
ENDPOINT_ID = "$$$" # This endpoint id is used to make operation ids unique make sure not to duplicate
|
24
|
+
Parcels = PaginatedResult("ParcelList", Parcel)
|
25
|
+
|
26
|
+
|
27
|
+
class ParcelList(GenericAPIView):
|
28
|
+
queryset = models.Parcel.objects
|
29
|
+
pagination_class = type(
|
30
|
+
"CustomPagination", (LimitOffsetPagination,), dict(default_limit=20)
|
31
|
+
)
|
32
|
+
serializer_class = Parcels
|
33
|
+
|
34
|
+
@openapi.extend_schema(
|
35
|
+
tags=["Parcels"],
|
36
|
+
operation_id=f"{ENDPOINT_ID}list",
|
37
|
+
extensions={"x-operationId": "listParcels"},
|
38
|
+
summary="List all parcels",
|
39
|
+
responses={
|
40
|
+
200: Parcels(),
|
41
|
+
404: ErrorResponse(),
|
42
|
+
500: ErrorResponse(),
|
43
|
+
},
|
44
|
+
)
|
45
|
+
def get(self, request: Request):
|
46
|
+
"""
|
47
|
+
Retrieve all stored parcels.
|
48
|
+
"""
|
49
|
+
parcels = models.Parcel.access_by(request).filter(
|
50
|
+
**{
|
51
|
+
f"{prop}__isnull": True
|
52
|
+
for prop in models.Parcel.HIDDEN_PROPS
|
53
|
+
if prop != "org"
|
54
|
+
}
|
55
|
+
)
|
56
|
+
serializer = Parcel(parcels, many=True)
|
57
|
+
response = self.paginate_queryset(serializer.data)
|
58
|
+
|
59
|
+
return self.get_paginated_response(response)
|
60
|
+
|
61
|
+
@openapi.extend_schema(
|
62
|
+
tags=["Parcels"],
|
63
|
+
operation_id=f"{ENDPOINT_ID}create",
|
64
|
+
extensions={"x-operationId": "createParcel"},
|
65
|
+
summary="Create a parcel",
|
66
|
+
request=ParcelData(),
|
67
|
+
responses={
|
68
|
+
201: Parcel(),
|
69
|
+
400: ErrorResponse(),
|
70
|
+
500: ErrorResponse(),
|
71
|
+
},
|
72
|
+
)
|
73
|
+
def post(self, request: Request):
|
74
|
+
"""
|
75
|
+
Create a new parcel.
|
76
|
+
"""
|
77
|
+
parcel = (
|
78
|
+
ParcelSerializer.map(data=request.data, context=request).save().instance
|
79
|
+
)
|
80
|
+
return Response(Parcel(parcel).data, status=status.HTTP_201_CREATED)
|
81
|
+
|
82
|
+
|
83
|
+
class ParcelDetail(APIView):
|
84
|
+
|
85
|
+
@openapi.extend_schema(
|
86
|
+
tags=["Parcels"],
|
87
|
+
operation_id=f"{ENDPOINT_ID}retrieve",
|
88
|
+
extensions={"x-operationId": "retrieveParcel"},
|
89
|
+
summary="Retrieve a parcel",
|
90
|
+
responses={
|
91
|
+
200: Parcel(),
|
92
|
+
404: ErrorResponse(),
|
93
|
+
500: ErrorResponse(),
|
94
|
+
},
|
95
|
+
)
|
96
|
+
def get(self, request: Request, pk: str):
|
97
|
+
"""
|
98
|
+
Retrieve a parcel.
|
99
|
+
"""
|
100
|
+
address = models.Parcel.access_by(request).get(pk=pk)
|
101
|
+
return Response(Parcel(address).data)
|
102
|
+
|
103
|
+
@openapi.extend_schema(
|
104
|
+
tags=["Parcels"],
|
105
|
+
operation_id=f"{ENDPOINT_ID}update",
|
106
|
+
extensions={"x-operationId": "updateParcel"},
|
107
|
+
summary="Update a parcel",
|
108
|
+
request=ParcelData(),
|
109
|
+
responses={
|
110
|
+
200: Parcel(),
|
111
|
+
400: ErrorResponse(),
|
112
|
+
404: ErrorResponse(),
|
113
|
+
409: ErrorResponse(),
|
114
|
+
500: ErrorResponse(),
|
115
|
+
},
|
116
|
+
)
|
117
|
+
def patch(self, request: Request, pk: str):
|
118
|
+
"""
|
119
|
+
modify an existing parcel's details.
|
120
|
+
"""
|
121
|
+
parcel = models.Parcel.access_by(request).get(pk=pk)
|
122
|
+
can_mutate_parcel(parcel, update=True)
|
123
|
+
|
124
|
+
ParcelSerializer.map(parcel, data=request.data).save()
|
125
|
+
|
126
|
+
return Response(Parcel(parcel).data)
|
127
|
+
|
128
|
+
@openapi.extend_schema(
|
129
|
+
tags=["Parcels"],
|
130
|
+
operation_id=f"{ENDPOINT_ID}discard",
|
131
|
+
extensions={"x-operationId": "discardParcel"},
|
132
|
+
summary="Remove a parcel",
|
133
|
+
responses={
|
134
|
+
200: Parcel(),
|
135
|
+
404: ErrorResponse(),
|
136
|
+
409: ErrorResponse(),
|
137
|
+
500: ErrorResponse(),
|
138
|
+
},
|
139
|
+
)
|
140
|
+
def delete(self, request: Request, pk: str):
|
141
|
+
"""
|
142
|
+
Remove a parcel.
|
143
|
+
"""
|
144
|
+
parcel = models.Parcel.access_by(request).get(pk=pk)
|
145
|
+
can_mutate_parcel(parcel, update=True, delete=True)
|
146
|
+
|
147
|
+
parcel.delete(keep_parents=True)
|
148
|
+
|
149
|
+
return Response(Parcel(parcel).data)
|
150
|
+
|
151
|
+
|
152
|
+
router.urls.append(path("parcels", ParcelList.as_view(), name="parcel-list"))
|
153
|
+
router.urls.append(
|
154
|
+
path("parcels/<str:pk>", ParcelDetail.as_view(), name="parcel-details")
|
155
|
+
)
|
@@ -0,0 +1,182 @@
|
|
1
|
+
import logging
|
2
|
+
|
3
|
+
from django.urls import path
|
4
|
+
from rest_framework import status
|
5
|
+
from rest_framework.pagination import LimitOffsetPagination
|
6
|
+
from rest_framework.response import Response
|
7
|
+
from rest_framework.request import Request
|
8
|
+
from django_filters.rest_framework import DjangoFilterBackend
|
9
|
+
|
10
|
+
from karrio.server.core.views.api import GenericAPIView, APIView
|
11
|
+
from karrio.server.core.filters import PickupFilters
|
12
|
+
from karrio.server.manager.router import router
|
13
|
+
from karrio.server.manager.serializers import (
|
14
|
+
PaginatedResult,
|
15
|
+
Pickup,
|
16
|
+
ErrorResponse,
|
17
|
+
ErrorMessages,
|
18
|
+
PickupData,
|
19
|
+
PickupUpdateData,
|
20
|
+
PickupCancelData,
|
21
|
+
)
|
22
|
+
import karrio.server.manager.models as models
|
23
|
+
import karrio.server.openapi as openapi
|
24
|
+
|
25
|
+
ENDPOINT_ID = "$$$$" # This endpoint id is used to make operation ids unique make sure not to duplicate
|
26
|
+
logger = logging.getLogger(__name__)
|
27
|
+
Pickups = PaginatedResult("PickupList", Pickup)
|
28
|
+
|
29
|
+
|
30
|
+
class PickupList(GenericAPIView):
|
31
|
+
pagination_class = type(
|
32
|
+
"CustomPagination", (LimitOffsetPagination,), dict(default_limit=20)
|
33
|
+
)
|
34
|
+
filter_backends = (DjangoFilterBackend,)
|
35
|
+
filterset_class = PickupFilters
|
36
|
+
serializer_class = Pickups
|
37
|
+
model = models.Pickup
|
38
|
+
|
39
|
+
@openapi.extend_schema(
|
40
|
+
tags=["Pickups"],
|
41
|
+
operation_id=f"{ENDPOINT_ID}list",
|
42
|
+
extensions={"x-operationId": "listPickups"},
|
43
|
+
summary="List shipment pickups",
|
44
|
+
responses={
|
45
|
+
200: Pickups(),
|
46
|
+
404: ErrorResponse(),
|
47
|
+
500: ErrorResponse(),
|
48
|
+
},
|
49
|
+
parameters=PickupFilters.parameters,
|
50
|
+
)
|
51
|
+
def get(self, request: Request):
|
52
|
+
"""
|
53
|
+
Retrieve all scheduled pickups.
|
54
|
+
"""
|
55
|
+
pickups = self.filter_queryset(self.get_queryset())
|
56
|
+
response = self.paginate_queryset(Pickup(pickups, many=True).data)
|
57
|
+
return self.get_paginated_response(response)
|
58
|
+
|
59
|
+
|
60
|
+
class PickupRequest(APIView):
|
61
|
+
throttle_scope = "carrier_request"
|
62
|
+
|
63
|
+
@openapi.extend_schema(
|
64
|
+
tags=["Pickups"],
|
65
|
+
operation_id=f"{ENDPOINT_ID}schedule",
|
66
|
+
extensions={"x-operationId": "schedulePickup"},
|
67
|
+
summary="Schedule a pickup",
|
68
|
+
responses={
|
69
|
+
201: Pickup(),
|
70
|
+
400: ErrorResponse(),
|
71
|
+
424: ErrorMessages(),
|
72
|
+
500: ErrorResponse(),
|
73
|
+
},
|
74
|
+
request=PickupData(),
|
75
|
+
)
|
76
|
+
def post(self, request: Request, carrier_name: str):
|
77
|
+
"""
|
78
|
+
Schedule a pickup for one or many shipments with labels already purchased.
|
79
|
+
"""
|
80
|
+
carrier_filter = {
|
81
|
+
"carrier_name": carrier_name,
|
82
|
+
}
|
83
|
+
|
84
|
+
pickup = (
|
85
|
+
PickupData.map(data=request.data, context=request)
|
86
|
+
.save(carrier_filter=carrier_filter)
|
87
|
+
.instance
|
88
|
+
)
|
89
|
+
|
90
|
+
return Response(Pickup(pickup).data, status=status.HTTP_201_CREATED)
|
91
|
+
|
92
|
+
|
93
|
+
class PickupDetails(APIView):
|
94
|
+
throttle_scope = "carrier_request"
|
95
|
+
|
96
|
+
@openapi.extend_schema(
|
97
|
+
tags=["Pickups"],
|
98
|
+
operation_id=f"{ENDPOINT_ID}retrieve",
|
99
|
+
extensions={"x-operationId": "retrievePickup"},
|
100
|
+
summary="Retrieve a pickup",
|
101
|
+
responses={
|
102
|
+
200: Pickup(),
|
103
|
+
404: ErrorResponse(),
|
104
|
+
500: ErrorResponse(),
|
105
|
+
},
|
106
|
+
)
|
107
|
+
def get(self, request: Request, pk: str):
|
108
|
+
"""Retrieve a scheduled pickup."""
|
109
|
+
pickup = models.Pickup.access_by(request).get(pk=pk)
|
110
|
+
return Response(Pickup(pickup).data)
|
111
|
+
|
112
|
+
@openapi.extend_schema(
|
113
|
+
tags=["Pickups"],
|
114
|
+
operation_id=f"{ENDPOINT_ID}update",
|
115
|
+
extensions={"x-operationId": "updatePickup"},
|
116
|
+
summary="Update a pickup",
|
117
|
+
responses={
|
118
|
+
200: Pickup(),
|
119
|
+
404: ErrorResponse(),
|
120
|
+
400: ErrorResponse(),
|
121
|
+
424: ErrorMessages(),
|
122
|
+
500: ErrorResponse(),
|
123
|
+
},
|
124
|
+
request=PickupUpdateData(),
|
125
|
+
)
|
126
|
+
def post(self, request: Request, pk: str):
|
127
|
+
"""
|
128
|
+
Modify a pickup for one or many shipments with labels already purchased.
|
129
|
+
"""
|
130
|
+
pickup = models.Pickup.access_by(request).get(pk=pk)
|
131
|
+
instance = (
|
132
|
+
PickupUpdateData.map(pickup, data=request.data, context=request)
|
133
|
+
.save()
|
134
|
+
.instance
|
135
|
+
)
|
136
|
+
|
137
|
+
return Response(Pickup(instance).data, status=status.HTTP_200_OK)
|
138
|
+
|
139
|
+
|
140
|
+
class PickupCancel(APIView):
|
141
|
+
|
142
|
+
@openapi.extend_schema(
|
143
|
+
tags=["Pickups"],
|
144
|
+
operation_id=f"{ENDPOINT_ID}cancel",
|
145
|
+
extensions={"x-operationId": "cancelPickup"},
|
146
|
+
summary="Cancel a pickup",
|
147
|
+
responses={
|
148
|
+
200: Pickup(),
|
149
|
+
404: ErrorResponse(),
|
150
|
+
409: ErrorResponse(),
|
151
|
+
424: ErrorMessages(),
|
152
|
+
500: ErrorResponse(),
|
153
|
+
},
|
154
|
+
request=PickupCancelData(),
|
155
|
+
)
|
156
|
+
def post(self, request: Request, pk: str):
|
157
|
+
"""
|
158
|
+
Cancel a pickup of one or more shipments.
|
159
|
+
"""
|
160
|
+
pickup = models.Pickup.access_by(request).get(pk=pk)
|
161
|
+
|
162
|
+
update = PickupCancelData.map(pickup, data=request.data).save().instance
|
163
|
+
|
164
|
+
return Response(Pickup(update).data)
|
165
|
+
|
166
|
+
|
167
|
+
router.urls.append(path("pickups", PickupList.as_view(), name="shipment-pickup-list"))
|
168
|
+
router.urls.append(
|
169
|
+
path("pickups/<str:pk>", PickupDetails.as_view(), name="shipment-pickup-details")
|
170
|
+
)
|
171
|
+
router.urls.append(
|
172
|
+
path(
|
173
|
+
"pickups/<str:pk>/cancel", PickupCancel.as_view(), name="shipment-pickup-cancel"
|
174
|
+
)
|
175
|
+
)
|
176
|
+
router.urls.append(
|
177
|
+
path(
|
178
|
+
"pickups/<str:carrier_name>/schedule",
|
179
|
+
PickupRequest.as_view(),
|
180
|
+
name="shipment-pickup-request",
|
181
|
+
)
|
182
|
+
)
|