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)
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]