def mutate_and_get_payload(cls, root, info, **input):
        boat = get_node_from_global_id(info,
                                       input.pop("id"),
                                       only_type=BoatNode,
                                       nullable=False)

        add_certificates = input.pop("add_boat_certificates", [])
        update_certificates = input.pop("update_boat_certificates", [])
        remove_certificates = input.pop("remove_boat_certificates", [])

        try:
            update_object(boat, input)
            remove_boat_certificates(remove_certificates, boat)
            update_boat_certificates(update_certificates, info)
            add_boat_certificates(add_certificates, boat)
        except ValidationError as e:
            raise VenepaikkaGraphQLError(e)

        return UpdateBoatMutation(boat=boat)
    def lookup_application_and_customer(cls, info, input):
        from customers.schema import ProfileNode  # import here avoid circular import

        if application_id := input.pop("application_id", None):
            if "customer_id" in input:
                raise VenepaikkaGraphQLError(
                    _(
                        "Can not specify both application and customer when creating a new berth lease"
                    )
                )
            application: BerthApplication = get_node_from_global_id(
                info, application_id, only_type=BerthApplicationNode, nullable=False,
            )
            if not application.customer:
                raise VenepaikkaGraphQLError(
                    _("Application must be connected to an existing customer first")
                )
            input["application"] = application
            input["customer"] = application.customer
    def mutate_and_get_payload(cls, root, info, **input):
        width = input.pop("width", None)
        length = input.pop("length", None)

        place_type, created = WinterStoragePlaceType.objects.get_or_create(
            width=width, length=length
        )
        input["place_type"] = place_type

        input["winter_storage_section"] = get_node_from_global_id(
            info,
            input.pop("winter_storage_section_id"),
            only_type=WinterStorageSectionNode,
            nullable=False,
        )
        winter_storage_place = WinterStoragePlace.objects.create(**input)
        return CreateWinterStoragePlaceMutation(
            winter_storage_place=winter_storage_place
        )
    def mutate_and_get_payload(cls, root, info, **input):

        if input.get("area_id"):
            area = get_node_from_global_id(
                info,
                input.pop("area_id"),
                only_type=WinterStorageAreaNode,
                nullable=False,
            )
            input["area"] = area

        try:
            # identifier is unique within sections of WinterStorageArea
            winter_storage_section = WinterStorageSection.objects.create(**input)
        except IntegrityError as e:
            raise VenepaikkaGraphQLError(e)

        return CreateWinterStorageSectionMutation(
            winter_storage_section=winter_storage_section
        )
class CreateWinterStorageLeaseMutation(graphene.ClientIDMutation):
    class Input(AbstractLeaseInput):
        application_id = graphene.ID(required=True)
        place_id = graphene.ID()
        section_id = graphene.ID()

    winter_storage_lease = graphene.Field(WinterStorageLeaseNode)

    @classmethod
    @view_permission_required(WinterStorageApplication, CustomerProfile)
    @add_permission_required(WinterStorageLease)
    @transaction.atomic
    def mutate_and_get_payload(cls, root, info, **input):  # noqa: C901
        if "place_id" in input and "section_id" in input:
            raise VenepaikkaGraphQLError(
                _("Cannot receive both Winter Storage Place and Section")
            )

        application = get_node_from_global_id(
            info,
            input.pop("application_id"),
            only_type=WinterStorageApplicationNode,
            nullable=False,
        )

        if not application.customer:
            raise VenepaikkaGraphQLError(
                _("Application must be connected to an existing customer first")
            )

        if place_id := input.pop("place_id", None):
            place = get_node_from_global_id(
                info, place_id, only_type=WinterStoragePlaceNode, nullable=False,
            )
            input["place"] = place
        elif section_id := input.pop("section_id", None):
            section = get_node_from_global_id(
                info, section_id, only_type=WinterStorageSectionNode, nullable=False,
            )
            input["section"] = section
    def mutate_and_get_payload(cls, root, info, id, **input):
        try:
            lease: WinterStorageLease = get_node_from_global_id(
                info, id, only_type=WinterStorageLeaseNode, nullable=False,
            )

            lease = terminate_lease(
                lease,
                end_date=input.get("end_date"),
                profile_token=input.get("profile_token"),
                send_notice=True,
            )
        except (
            WinterStorageLease.DoesNotExist,
            AnymailError,
            OSError,
            ValidationError,
            VenepaikkaGraphQLError,
        ) as e:
            raise VenepaikkaGraphQLError(str(e)) from e

        return TerminateWinterStorageLeaseMutation(winter_storage_lease=lease)
    def mutate_and_get_payload(cls, root, info, **input):
        owner = get_node_from_global_id(info,
                                        input.pop("owner_id"),
                                        only_type=ProfileNode,
                                        nullable=False)
        input["owner"] = owner
        try:
            input["boat_type"] = BoatType.objects.get(
                id=input.pop("boat_type_id"))
        except BoatType.DoesNotExist as e:
            raise VenepaikkaGraphQLError(e)

        add_certificates = input.pop("add_boat_certificates", [])

        try:
            boat = Boat.objects.create(**input)
            add_boat_certificates(add_certificates, boat)
        except ValidationError as e:
            # Flatten all the error messages on a single list
            errors = sum(e.message_dict.values(), [])
            raise VenepaikkaGraphQLError(errors)

        return CreateBoatMutation(boat=boat)
    def mutate_and_get_payload(cls, root, info, **kwargs):
        from resources.models import BoatType
        from resources.schema import WinterStorageAreaNode

        application_data = kwargs.pop("winter_storage_application")

        boat_type_id = application_data.pop("boat_type", None)
        if boat_type_id:
            application_data["boat_type"] = BoatType.objects.get(
                id=int(boat_type_id))

        chosen_areas = application_data.pop("chosen_areas", [])

        application = WinterStorageApplication.objects.create(
            **application_data)

        for choice in chosen_areas:
            winter_storage_area = get_node_from_global_id(
                info,
                choice.get("winter_area_id"),
                only_type=WinterStorageAreaNode)
            WinterStorageAreaChoice.objects.get_or_create(
                winter_storage_area=winter_storage_area,
                priority=choice.get("priority"),
                application=application,
            )

        application.area_type = application.resolve_area_type()
        application.save()

        # Send notifications when all m2m relations are saved
        sender = (UNMARKED_WS_SENDER if application.area_type
                  == ApplicationAreaType.UNMARKED else MARKED_WS_SENDER)
        application_saved.send(sender=sender, application=application)

        return CreateWinterStorageApplicationMutation(
            winter_storage_application=application)
    def mutate_and_get_payload(cls, root, info, **input):
        suitable_boat_types = input.pop("suitable_boat_types", [])

        if input.get("harbor_id"):
            harbor = get_node_from_global_id(
                info, input.pop("harbor_id"), only_type=HarborNode, nullable=False,
            )
            input["harbor"] = harbor

        boat_types = set()
        for boat_type_id in suitable_boat_types:
            try:
                boat_type = BoatType.objects.get(pk=boat_type_id)
            except BoatType.DoesNotExist as e:
                raise VenepaikkaGraphQLError(e)
            boat_types.add(boat_type)

        try:
            pier = Pier.objects.create(**input)
            pier.suitable_boat_types.set(boat_types)
        except IntegrityError as e:
            raise VenepaikkaGraphQLError(e)

        return CreatePierMutation(pier=pier)
Example #10
0
def resolve_piers(info, **kwargs):
    min_width = kwargs.get("min_berth_width")
    min_length = kwargs.get("min_berth_length")
    application_global_id = kwargs.get("for_application")
    harbor_id = kwargs.get("harbor_id")

    # Filter out piers with no berths that fit the
    # passed dimensions only if the dimensions were given.
    # Otherwise, return the whole list of piers.
    has_dimensions_filter = min_width or min_length

    if has_dimensions_filter and application_global_id:
        raise VenepaikkaGraphQLError(
            _("You cannot filter by dimension (width, length) and application a the same time."
              ))

    if application_global_id:
        user = info.context.user
        if (user and user.is_authenticated
                and user_has_view_permission(BerthApplication)(user)):
            application = get_node_from_global_id(
                info, application_global_id, only_type=BerthApplicationNode)

            min_width = application.boat_width
            # NOTE: not setting min_length here on purpose.
            # See VEN-1251: berths that are too short need to be shown in the UI
        else:
            raise VenepaikkaGraphQLError(
                _("You do not have permission to perform this action"))

    if harbor_id:
        query = Pier.objects.filter(harbor_id=harbor_id)
    else:
        query = Pier.objects.all()

    suitable_berth_types = BerthType.objects.all()
    if min_width:
        suitable_berth_types = suitable_berth_types.filter(
            width__gte=min_width)
    if min_length:
        suitable_berth_types = suitable_berth_types.filter(
            length__gte=min_length)

    berth_queryset = Berth.objects.select_related("berth_type").filter(
        berth_type__in=suitable_berth_types)

    query = query.prefetch_related(
        Prefetch("berths", queryset=berth_queryset),
        "suitable_boat_types",
        "harbor__translations",
        "harbor__availability_level__translations",
        "harbor__municipality__translations",
    ).select_related("harbor", "harbor__availability_level",
                     "harbor__municipality")

    if has_dimensions_filter:
        dimensions_filter = Q()
        if min_width:
            dimensions_filter &= Q(berths__berth_type__width__gte=min_width)
        if min_length:
            dimensions_filter &= Q(berths__berth_type__length__gte=min_length)

        query = query.annotate(
            berth_count=Count("berths", filter=dimensions_filter)).filter(
                berth_count__gt=0)

    return query
                _(
                    "Must specify either application or customer when creating a new berth lease"
                )
            )

    @classmethod
    @view_permission_required(BerthApplication, CustomerProfile)
    @add_permission_required(BerthLease)
    @transaction.atomic
    def mutate_and_get_payload(cls, root, info, **input):
        cls.lookup_application_and_customer(info, input)
        if boat := lookup_or_create_boat(info, input):
            input["boat"] = boat

        berth = get_node_from_global_id(
            info, input.pop("berth_id"), only_type=BerthNode, nullable=False,
        )
        input["berth"] = berth

        try:
            lease = BerthLease.objects.create(**input)

            order = Order.objects.create(customer=input["customer"], lease=lease)
            # Do not create a contract for non-billable customers.
            if not input["customer"].is_non_billable_customer():
                get_contract_service().create_berth_contract(lease)
        except BerthProduct.DoesNotExist as e:
            raise VenepaikkaGraphQLError(e)
        except ValidationError as e:
            raise VenepaikkaGraphQLError(str(e))
 def get_nodes_to_check(info, **input):
     application = get_node_from_global_id(info,
                                           input.get("id"),
                                           only_type=BerthApplicationNode,
                                           nullable=True)
     return [application]