Esempio n. 1
0
class DiscardCommodities(APIView):
    @swagger_auto_schema(tags=['Customs'],
                         operation_id=f"{ENDPOINT_ID}discard_commodity",
                         operation_summary="Discard a commodity",
                         responses={
                             200: Operation(),
                             400: ErrorResponse()
                         },
                         code_examples=[{
                             'lang':
                             'bash',
                             'source':
                             '''
                curl --request DELETE \\
                  --url /v1/customs_info/<CUSTOMS_INFO_ID>/commodities/<COMMODITY_ID> \\
                  --header 'Authorization: Token <API_KEY>'
                '''
                         }])
    def delete(self, request: Request, pk: str, ck: str):
        """
        Discard a customs commodity.
        """
        customs = models.Customs.access_by(request).get(pk=pk)
        shipment = customs.shipment_set.first()
        if shipment is not None and shipment.status == ShipmentStatus.purchased.value:
            raise PurplShipApiException(
                "The shipment related to this customs info has been 'purchased' and cannot be modified",
                status_code=status.HTTP_409_CONFLICT,
                code='state_error')

        commodity = customs.commodities.get(pk=ck)
        commodity.delete(keep_parents=True)
        serializer = Operation(
            dict(operation="Discard customs commodity", success=True))
        return Response(serializer.data)
Esempio n. 2
0
    def delete(self, request: Request, pk: str):
        """
        Remove a webhook.
        """
        webhook = models.Webhook.access_by(request).get(pk=pk)

        webhook.delete(keep_parents=True)
        serializer = Operation(dict(operation="Remove webhook", success=True))
        return Response(serializer.data)
Esempio n. 3
0
    def post(self, request: Request, pk: str):
        """
        test a webhook.
        """
        webhook = models.Webhook.access_by(request).get(pk=pk)

        notification, *_ = notify_subscribers([webhook], request.data)
        _, response = notification
        serializer = Operation(
            dict(operation="Test Webhook", success=response.ok))
        return Response(serializer.data)
Esempio n. 4
0
    def delete(self, request: Request, id_or_tracking_number: str):
        """
        Discard a shipment tracker.
        """
        tracker = models.Tracking.access_by(request).get(
            Q(pk=id_or_tracking_number)
            | Q(tracking_number=id_or_tracking_number))

        tracker.delete(keep_parents=True)
        serializer = Operation(
            dict(operation="Discard a tracker", success=True))
        return Response(serializer.data)
Esempio n. 5
0
class WebhookDetail(APIView):
    @swagger_auto_schema(tags=['Webhooks'],
                         operation_id=f"{ENDPOINT_ID}retrieve",
                         operation_summary="Retrieve a webhook",
                         responses={
                             200: Webhook(),
                             400: ErrorResponse()
                         })
    def get(self, request: Request, pk: str):
        """
        Retrieve a webhook.
        """
        webhook = models.Webhook.access_by(request).get(pk=pk)
        return Response(Webhook(webhook).data)

    @swagger_auto_schema(tags=['Webhooks'],
                         operation_id=f"{ENDPOINT_ID}update",
                         operation_summary="Update a webhook",
                         request_body=WebhookData(),
                         responses={
                             200: Webhook(),
                             400: ErrorResponse()
                         })
    def patch(self, request: Request, pk: str):
        """
        update a webhook.
        """
        webhook = models.Webhook.access_by(request).get(pk=pk)

        SerializerDecorator[WebhookSerializer](webhook,
                                               data=request.data).save()
        return Response(Webhook(webhook).data)

    @swagger_auto_schema(tags=['Webhooks'],
                         operation_id=f"{ENDPOINT_ID}remove",
                         operation_summary="Remove a webhook",
                         responses={
                             200: Operation(),
                             400: ErrorResponse()
                         })
    def delete(self, request: Request, pk: str):
        """
        Remove a webhook.
        """
        webhook = models.Webhook.access_by(request).get(pk=pk)

        webhook.delete(keep_parents=True)
        serializer = Operation(dict(operation="Remove webhook", success=True))
        return Response(serializer.data)
Esempio n. 6
0
    def delete(self, request: Request, pk: str):
        """
        Discard an address.
        """
        address = models.Address.access_by(request).get(pk=pk)
        shipment = address.shipper.first() or address.recipient.first()
        if shipment is not None:
            raise PurplShipApiException(
                "This address is linked to a shipment and cannot be removed",
                status_code=status.HTTP_409_CONFLICT,
                code='state_error')

        address.delete(keep_parents=True)
        serializer = Operation(dict(operation="Discard address", success=True))
        return Response(serializer.data)
Esempio n. 7
0
class TrackersDetails(APIView):
    permission_classes = [IsAuthenticatedOrReadOnly]

    @swagger_auto_schema(
        tags=["Trackers"],
        operation_id=f"{ENDPOINT_ID}retrieves",
        operation_summary="Retrieves a shipment tracker",
        responses={
            200: TrackingStatus(),
            404: ErrorResponse()
        },
    )
    def get(self, request: Request, id_or_tracking_number: str):
        """
        Retrieve a shipment tracker
        """
        __filter = Q(pk=id_or_tracking_number) | Q(
            tracking_number=id_or_tracking_number)
        trackers = models.Tracking.objects.filter(__filter)

        if len(trackers) == 0:
            models.Tracking.objects.get(__filter)

        return Response(TrackingStatus(trackers.first()).data)

    @swagger_auto_schema(
        tags=["Trackers"],
        operation_id=f"{ENDPOINT_ID}remove",
        operation_summary="Discard a shipment tracker",
        responses={
            200: Operation(),
            400: ErrorResponse()
        },
    )
    def delete(self, request: Request, id_or_tracking_number: str):
        """
        Discard a shipment tracker.
        """
        tracker = models.Tracking.access_by(request).get(
            Q(pk=id_or_tracking_number)
            | Q(tracking_number=id_or_tracking_number))

        tracker.delete(keep_parents=True)
        serializer = Operation(
            dict(operation="Discard a tracker", success=True))
        return Response(serializer.data)
Esempio n. 8
0
    def delete(self, request: Request, pk: str, ck: str):
        """
        Discard a customs commodity.
        """
        customs = models.Customs.access_by(request).get(pk=pk)
        shipment = customs.shipment_set.first()
        if shipment is not None and shipment.status == ShipmentStatus.purchased.value:
            raise PurplShipApiException(
                "The shipment related to this customs info has been 'purchased' and cannot be modified",
                status_code=status.HTTP_409_CONFLICT,
                code='state_error')

        commodity = customs.commodities.get(pk=ck)
        commodity.delete(keep_parents=True)
        serializer = Operation(
            dict(operation="Discard customs commodity", success=True))
        return Response(serializer.data)
Esempio n. 9
0
class WebhookTest(APIView):
    @swagger_auto_schema(tags=['Webhooks'],
                         operation_id=f"{ENDPOINT_ID}test",
                         operation_summary="Test a webhook",
                         request_body=WebhookTestRequest(),
                         responses={
                             200: Operation(),
                             400: ErrorResponse()
                         })
    def post(self, request: Request, pk: str):
        """
        test a webhook.
        """
        webhook = models.Webhook.access_by(request).get(pk=pk)

        notification, *_ = notify_subscribers([webhook], request.data)
        _, response = notification
        serializer = Operation(
            dict(operation="Test Webhook", success=response.ok))
        return Response(serializer.data)
Esempio n. 10
0
    def delete(self, request: Request, pk: str):
        """
        Remove a parcel.
        """
        parcel = models.Parcel.access_by(request).get(pk=pk)
        shipment = parcel.shipment_parcels.first()

        if shipment is not None and (
                shipment.status == ShipmentStatus.purchased.value
                or len(shipment.shipment_parcels.all()) == 1):
            raise PurplShipApiException(
                "A shipment attached to this parcel is purchased or has only one parcel. The parcel cannot be removed!",
                status_code=status.HTTP_409_CONFLICT,
                code='state_error')

        parcel.delete(keep_parents=True)
        shipment.shipment_parcels.set(
            shipment.shipment_parcels.exclude(id=parcel.id))
        serializer = Operation(dict(operation="Remove parcel", success=True))
        reset_related_shipment_rates(shipment)
        return Response(serializer.data)
Esempio n. 11
0
class AddressDetail(APIView):
    @swagger_auto_schema(tags=['Addresses'],
                         operation_id=f"{ENDPOINT_ID}retrieve",
                         operation_summary="Retrieve an address",
                         responses={
                             200: Address(),
                             400: ErrorResponse()
                         },
                         code_examples=[{
                             'lang':
                             'bash',
                             'source':
                             '''
                curl --request GET \\
                  --url /v1/addresses/<ADDRESS_ID> \\
                  --header 'Authorization: Token <API_KEY>'
                '''
                         }])
    def get(self, request: Request, pk: str):
        """
        Retrieve an address.
        """
        address = models.Address.access_by(request).get(pk=pk)
        return Response(Address(address).data)

    @swagger_auto_schema(tags=['Addresses'],
                         operation_id=f"{ENDPOINT_ID}update",
                         operation_summary="Update an address",
                         request_body=AddressData(),
                         responses={
                             200: Address(),
                             400: ErrorResponse()
                         },
                         code_examples=[{
                             'lang':
                             'bash',
                             'source':
                             '''
                curl --request PATCH \\
                  --url /v1/addresses/<ADDRESS_ID> \\
                  --header 'Authorization: Token <API_KEY>' \\
                  --header 'Content-Type: application/json' \\
                  --data '{
                    "city": "Pierrefonds"
                }'
                '''
                         }])
    def patch(self, request: Request, pk: str):
        """
        update an address.
        """
        address = models.Address.access_by(request).get(pk=pk)
        shipment = address.shipper.first() or address.recipient.first()
        if shipment is not None and shipment.status == ShipmentStatus.purchased.value:
            raise PurplShipApiException(
                "The shipment related to this address has been 'purchased' and can no longer be modified",
                status_code=status.HTTP_409_CONFLICT,
                code='state_error')

        SerializerDecorator[AddressSerializer](address,
                                               data=request.data).save()
        reset_related_shipment_rates(shipment)
        return Response(Address(address).data)

    @swagger_auto_schema(tags=['Addresses'],
                         operation_id=f"{ENDPOINT_ID}discard",
                         operation_summary="Discard an address",
                         responses={
                             200: Operation(),
                             400: ErrorResponse()
                         },
                         code_examples=[{
                             'lang':
                             'bash',
                             'source':
                             '''
                curl --request DELETE \\
                  --url /v1/addresses/<ADDRESS_ID> \\
                  --header 'Authorization: Token <API_KEY>'
                '''
                         }])
    def delete(self, request: Request, pk: str):
        """
        Discard an address.
        """
        address = models.Address.access_by(request).get(pk=pk)
        shipment = address.shipper.first() or address.recipient.first()
        if shipment is not None:
            raise PurplShipApiException(
                "This address is linked to a shipment and cannot be removed",
                status_code=status.HTTP_409_CONFLICT,
                code='state_error')

        address.delete(keep_parents=True)
        serializer = Operation(dict(operation="Discard address", success=True))
        return Response(serializer.data)
Esempio n. 12
0
class ParcelDetail(APIView):
    @swagger_auto_schema(tags=['Parcels'],
                         operation_id=f"{ENDPOINT_ID}retrieve",
                         operation_summary="Retrieve a parcel",
                         responses={
                             200: Parcel(),
                             400: ErrorResponse()
                         },
                         code_examples=[{
                             'lang':
                             'bash',
                             'source':
                             '''
                curl --request GET \\
                  --url /v1/parcels/<PARCEL_ID> \\
                  --header 'Authorization: Token <API_KEY>'
                '''
                         }])
    def get(self, request: Request, pk: str):
        """
        Retrieve a parcel.
        """
        address = models.Parcel.access_by(request).get(pk=pk)
        return Response(Parcel(address).data)

    @swagger_auto_schema(tags=['Parcels'],
                         operation_id=f"{ENDPOINT_ID}update",
                         operation_summary="Update a parcel",
                         request_body=ParcelData(),
                         responses={
                             200: Parcel(),
                             400: ErrorResponse()
                         },
                         code_examples=[{
                             'lang':
                             'bash',
                             'source':
                             '''
                curl --request PATCH \\
                    --url /v1/parcels/<PARCEL_ID> \\
                    --header 'Authorization: Token <API_KEY>' \\
                    --header 'Content-Type: application/json' \\
                    --data '{
                      "weight": 1.2,
                    }'
                '''
                         }])
    def patch(self, request: Request, pk: str):
        """
        modify an existing parcel's details.
        """
        parcel = models.Parcel.access_by(request).get(pk=pk)
        shipment = parcel.shipment_parcels.first()
        if shipment is not None and shipment.status == ShipmentStatus.purchased.value:
            raise PurplShipApiException(
                "The shipment related to this parcel has been 'purchased' and can no longer be modified",
                status_code=status.HTTP_409_CONFLICT,
                code='state_error')

        SerializerDecorator[ParcelSerializer](parcel, data=request.data).save()
        reset_related_shipment_rates(shipment)
        return Response(Parcel(parcel).data)

    @swagger_auto_schema(tags=['Parcels'],
                         operation_id=f"{ENDPOINT_ID}discard",
                         operation_summary="Remove a parcel",
                         responses={
                             200: Operation(),
                             400: ErrorResponse()
                         },
                         code_examples=[{
                             'lang':
                             'bash',
                             'source':
                             '''
                curl --request DELETE \\
                    --url /v1/parcels/<PARCEL_ID> \\
                    --header 'Authorization: Token <API_KEY>'
                '''
                         }])
    def delete(self, request: Request, pk: str):
        """
        Remove a parcel.
        """
        parcel = models.Parcel.access_by(request).get(pk=pk)
        shipment = parcel.shipment_parcels.first()

        if shipment is not None and (
                shipment.status == ShipmentStatus.purchased.value
                or len(shipment.shipment_parcels.all()) == 1):
            raise PurplShipApiException(
                "A shipment attached to this parcel is purchased or has only one parcel. The parcel cannot be removed!",
                status_code=status.HTTP_409_CONFLICT,
                code='state_error')

        parcel.delete(keep_parents=True)
        shipment.shipment_parcels.set(
            shipment.shipment_parcels.exclude(id=parcel.id))
        serializer = Operation(dict(operation="Remove parcel", success=True))
        reset_related_shipment_rates(shipment)
        return Response(serializer.data)
Esempio n. 13
0
class CustomsDetail(APIView):
    @swagger_auto_schema(tags=['Customs'],
                         operation_id=f"{ENDPOINT_ID}retrieve",
                         operation_summary="Retrieve a customs info",
                         responses={
                             200: Customs(),
                             400: ErrorResponse()
                         },
                         code_examples=[{
                             'lang':
                             'bash',
                             'source':
                             '''
                curl --request GET \\
                  --url /v1/customs_info/<CUSTOMS_INFO_ID> \\
                  --header 'Authorization: Token <API_KEY>'
                '''
                         }])
    def get(self, request: Request, pk: str):
        """
        Retrieve customs declaration.
        """
        address = models.Customs.access_by(request).get(pk=pk)
        return Response(Customs(address).data)

    @swagger_auto_schema(tags=['Customs'],
                         operation_id=f"{ENDPOINT_ID}update",
                         operation_summary="Update a customs info",
                         request_body=CustomsData(),
                         responses={
                             200: Customs(),
                             400: ErrorResponse()
                         },
                         code_examples=[{
                             'lang':
                             'bash',
                             'source':
                             '''
                curl --request PATCH \\
                  --url /v1/customs_info/<CUSTOMS_INFO_ID> \\
                  --header 'Authorization: Token <API_KEY>' \\
                  --header 'Content-Type: application/json' \\
                  --data '{
                    "content_type": "merchandise",
                    "duty": {
                      "paid_by": "recipient",
                      "currency": "CAD",
                      "declared_value": 100,
                    }
                  }'
                '''
                         }])
    def patch(self, request: Request, pk: str):
        """
        modify an existing customs declaration.
        """
        customs = models.Customs.access_by(request).get(pk=pk)
        shipment = customs.shipment_set.first()
        if shipment is not None and shipment.status == ShipmentStatus.purchased.value:
            raise PurplShipApiException(
                "The shipment related to this customs info has been 'purchased' and can no longer be modified",
                status_code=status.HTTP_409_CONFLICT,
                code='state_error')

        SerializerDecorator[CustomsSerializer](customs,
                                               data=request.data,
                                               context=request).save()
        reset_related_shipment_rates(shipment)
        return Response(Customs(customs).data)

    @swagger_auto_schema(tags=['Customs'],
                         operation_id=f"{ENDPOINT_ID}discard",
                         operation_summary="Discard a customs info",
                         responses={
                             200: Operation(),
                             400: ErrorResponse()
                         },
                         code_examples=[{
                             'lang':
                             'bash',
                             'source':
                             '''
                curl --request DELETE \\
                  --url /v1/customs_info/<CUSTOMS_INFO_ID> \\
                  --header 'Authorization: Token <API_KEY>'
                '''
                         }])
    def delete(self, request: Request, pk: str):
        """
        Discard a customs declaration.
        """
        customs = models.Customs.access_by(request).get(pk=pk)
        shipment = customs.shipment_set.first()
        if shipment is not None and shipment.status == ShipmentStatus.purchased.value:
            raise PurplShipApiException(
                "The shipment related to this customs info has been 'purchased' and cannot be discarded",
                status_code=status.HTTP_409_CONFLICT,
                code='state_error')

        customs.delete(keep_parents=True)
        shipment.customs = None
        serializer = Operation(
            dict(operation="Discard customs info", success=True))
        reset_related_shipment_rates(shipment)
        return Response(serializer.data)