from django.db.models import F, Sum
from .models import PartsIssue, PartsDisposition
from .request_queries import parts_requests
from .queries import authorized_locations
from apps.parts.locking import persisted_pk


def parts_issues(*, actor, unresolved_only=False):
    rows = PartsIssue.objects.filter(reservation__line__request_id__in=parts_requests(actor=actor).values("pk"),
        custody_location_id__in=authorized_locations(actor=actor).values("pk")).select_related(
        "service_case", "reservation__spare_part", "reservation__location", "custody_location", "issuer", "recipient").annotate(
        resolved_quantity=Sum("dispositions__quantity", default=0)).order_by("issued_at", "pk")
    return rows.filter(resolved_quantity__lt=F("reservation__quantity")) if unresolved_only else rows


def parts_usage(*, actor):
    return PartsDisposition.objects.filter(issue_id__in=parts_issues(actor=actor).values("pk")).select_related(
        "issue__service_case", "issue__reservation__spare_part", "movement__source", "movement__destination", "repair_action__repair_execution", "actor").order_by("recorded_at", "pk")


def issue_detail(*, actor, issue):
    return parts_issues(actor=actor).prefetch_related("dispositions__movement__unit_links__unit__spare_part").get(pk=persisted_pk(issue, PartsIssue))


def defective_recoveries(*, actor):
    from apps.access.authorization import authorized_queryset
    from apps.organization.models import ServiceCenter
    from .models import DefectiveRecovery
    centers = authorized_queryset(user=actor, permission="inventory.view_stock", queryset=ServiceCenter.objects.all())
    return DefectiveRecovery.objects.filter(service_case__service_center_id__in=centers.values("pk"),
        location_id__in=authorized_locations(actor=actor).values("pk")).select_related(
        "service_case", "device", "repair_action__repair_execution", "replacement", "location", "actor").order_by("recovered_at", "pk")
