import logging from django.contrib import messages from django.contrib.auth.decorators import login_required from django.http import HttpResponse from django.shortcuts import get_object_or_404, redirect, render from django.views.decorators.http import require_http_methods, require_POST from shipping.models import Shipment from shipping.services import ( ShippingError, buy_label, create_shipment_for_order, pirate_ship_csv, quote_rates, ) from shop.models import Order logger = logging.getLogger(__name__) @login_required def shipment_list(request): shipments = Shipment.objects.select_related("order")[:200] labeled = Shipment.objects.filter(status=Shipment.Status.LABELED).values_list( "order_id", flat=True ) unshipped = Order.objects.filter(status=Order.Status.PAID).exclude(pk__in=labeled) return render( request, "shipping/list.html", {"shipments": shipments, "unshipped": unshipped}, ) @login_required @require_POST def shipment_create(request): order = get_object_or_404(Order, pk=request.POST.get("order")) try: weight = int(request.POST.get("weight_oz") or "16") except ValueError: weight = 16 try: shipment = create_shipment_for_order(order, weight_oz=weight) quote_rates(shipment) except ShippingError as exc: messages.error(request, str(exc)) return redirect("shipping:shipment_list") except Exception as exc: # noqa: BLE001 logger.exception("rate quote failed") messages.error(request, f"Could not quote rates: {exc}") return redirect("shipping:shipment_list") return redirect("shipping:shipment_detail", pk=shipment.pk) @login_required def shipment_detail(request, pk): shipment = get_object_or_404(Shipment.objects.select_related("order"), pk=pk) return render(request, "shipping/detail.html", {"shipment": shipment}) @login_required @require_POST def shipment_buy(request, pk): shipment = get_object_or_404(Shipment, pk=pk) rate_id = (request.POST.get("rate_id") or "").strip() try: buy_label(shipment, rate_id=rate_id) except ShippingError as exc: messages.error(request, str(exc)) except Exception as exc: # noqa: BLE001 logger.exception("buy label failed") messages.error(request, f"Could not buy label: {exc}") else: messages.success(request, f"Label created for {shipment.order.number}.") return redirect("shipping:shipment_detail", pk=shipment.pk) @login_required @require_http_methods(["GET"]) def pirate_ship_export(request): body = pirate_ship_csv() response = HttpResponse(body, content_type="text/csv") response["Content-Disposition"] = 'attachment; filename="pirate-ship-orders.csv"' return response