Esempio n. 1
0
    def resolve_berths(self,
                       info,
                       harbor: GlobalID = None,
                       pier: GlobalID = None,
                       min_width: Decimal = 0,
                       min_length: Decimal = 0,
                       **kwargs):
        if pier and harbor:
            raise VenepaikkaGraphQLError(
                _("Cannot pass both pier and harbor filters"))

        filters = Q()
        if harbor:
            filters &= Q(pier__harbor_id=from_global_id(harbor, HarborNode))
        if pier:
            filters &= Q(pier_id=from_global_id(pier, PierNode))
        if min_width:
            filters &= Q(berth_type__width__gte=min_width)
        if min_length:
            filters &= Q(berth_type__length__gte=min_length)
        if "is_available" in kwargs:
            filters &= Q(is_available=kwargs.get("is_available"))
        if "is_invoiceable" in kwargs:
            filters &= Q(is_invoiceable=kwargs.get("is_invoiceable"))

        return info.context.berth_loader.load_many(
            keys=Berth.objects.filter(filters).values_list("id", flat=True))
Esempio n. 2
0
    def parse_user(self, profile: Dict[str, dict]) -> HelsinkiProfileUser:
        user_id = from_global_id(profile.pop("id"))
        email = None
        phone = None
        if "primary_email" in profile:
            primary_email = profile.pop("primary_email")
            email = (primary_email is not None
                     and primary_email.get("email")) or None
        if "primary_phone" in profile:
            primary_phone = profile.pop("primary_phone")
            phone = (primary_phone is not None
                     and primary_phone.get("phone")) or None

        primary_address = profile.pop("primary_address", {}) or {}
        address = primary_address.get("address")
        postal_code = primary_address.get("postal_code")
        city = primary_address.get("city")

        return HelsinkiProfileUser(
            UUID(user_id),
            email=email,
            phone=phone,
            address=address,
            postal_code=postal_code,
            city=city,
            **profile,
        )
def remove_boat_certificates(certificates, boat):
    try:
        for cert_id in certificates:
            cert_id = from_global_id(cert_id)
            BoatCertificate.objects.get(pk=cert_id, boat=boat).delete()
    except BoatCertificate.DoesNotExist as e:
        raise VenepaikkaGraphQLError(e)
    def mutate_and_get_payload(cls, root, info, **input):
        from customers.schema import ProfileNode

        application = get_node_from_global_id(
            info, input.pop("id"), only_type=WinterStorageApplicationNode)

        cls.validate_application_status(application, info, input)

        # This allows for getting explicit None values
        if "customer_id" in input:
            customer_id = input.pop("customer_id", None)

            if is_customer(info.context.user):
                raise VenepaikkaGraphQLError(
                    _("A customer cannot modify the customer connected to the application"
                      ))

            input["customer"] = get_node_from_global_id(info,
                                                        customer_id,
                                                        only_type=ProfileNode,
                                                        nullable=True)

        if remove_choices := input.pop("remove_choices", []):
            for choice_id in remove_choices:
                try:
                    choice = WinterStorageAreaChoice.objects.get(
                        id=from_global_id(
                            choice_id, node_type=WinterStorageAreaChoiceType))
                    choice.delete()
                except WinterStorageAreaChoice.DoesNotExist:
                    pass
Esempio n. 5
0
    def create_profile(self,
                       first_name: str,
                       last_name: str,
                       email: str = None,
                       phone: str = None):
        from ..models import CustomerProfile

        variables = {
            "input": {
                "profile": {
                    "firstName": first_name,
                    "lastName": last_name
                }
            }
        }
        if email:
            variables["input"]["profile"]["addEmails"] = [{
                "primary": True,
                "email": email,
                "emailType": "NONE"
            }]
        if phone:
            variables["input"]["profile"]["addPhones"] = [{
                "primary": True,
                "phone": phone,
                "phoneType": "NONE"
            }]

        mutation = """
        mutation CreateProfile($input: CreateProfileMutationInput!) {
            createProfile(input: $input) {
                profile {
                    id
                }
            }
        }
        """
        response = self.query(query=mutation, variables=variables)
        global_id = response.get("createProfile", {}).get("profile",
                                                          {}).get("id")
        profile_id = UUID(from_global_id(global_id))
        profile = CustomerProfile.objects.create(id=profile_id)
        return profile
    def mutate_and_get_payload(cls, root, info, **input):
        input["id"] = from_global_id(global_id=input.pop("id"),
                                     node_type=ProfileNode)

        organization_input = None
        if "organization" in input:
            organization_input = input.pop("organization")

        try:
            profile = CustomerProfile.objects.create(**input)
            if organization_input:
                Organization.objects.create(customer=profile,
                                            **organization_input)
        except ValidationError as e:
            # Flatten all the error messages on a single list
            errors = sum(e.message_dict.values(), [])
            raise VenepaikkaGraphQLError(errors)

        return CreateBerthServicesProfileMutation(profile=profile)
def test_create_boat(api_client, customer_profile, boat_type):
    check_date = today().date()
    file_name = "certificate.pdf"
    owner_id = to_global_id(ProfileNode, customer_profile.id)
    boat_type_id = str(boat_type.id)

    variables = {
        "ownerId": owner_id,
        "boatTypeId": boat_type_id,
        "name": "Flying Dutchman",
        "length": random_decimal(as_string=True),
        "width": random_decimal(as_string=True),
        "addBoatCertificates": [
            {
                "file": SimpleUploadedFile(
                    name=file_name, content=None, content_type="application/pdf"
                ),
                "certificateType": random.choice(list(BoatCertificateType)).name,
                "validUntil": str(check_date),
                "checkedAt": str(check_date),
                "checkedBy": "John Wick",
            }
        ],
    }

    assert Boat.objects.count() == 0
    assert BoatCertificate.objects.count() == 0

    executed = api_client.execute(CREATE_BOAT_MUTATION, input=variables)

    certificates = executed["data"]["createBoat"]["boat"].pop("certificates")

    assert Boat.objects.count() == 1
    assert BoatCertificate.objects.count() == 1

    assert len(certificates) == 1

    # Test that all the expected files are in the instance certificates
    cert = certificates[0]
    cert_id = cert.pop("id")

    assert cert_id is not None
    cert_id = from_global_id(cert_id, BoatCertificateNode)

    assert get_boat_certificate_media_folder(
        BoatCertificate.objects.get(id=cert_id), "certificate.pdf"
    ) in cert.pop("file")
    assert cert == {
        "certificateType": variables["addBoatCertificates"][0]["certificateType"],
        "validUntil": str(check_date),
        "checkedAt": str(check_date),
        "checkedBy": "John Wick",
    }

    assert executed["data"]["createBoat"]["boat"] == {
        "owner": {"id": owner_id},
        "boatType": {"id": boat_type_id},
        "name": variables["name"],
        "length": variables["length"],
        "width": variables["width"],
    }
def test_update_boat(api_client, boat):
    boat_id = to_global_id(BoatNode, boat.id)
    owner_id = to_global_id(ProfileNode, boat.owner.id)
    boat_type_id = str(boat.boat_type.id)

    file_name_keep = "certificate-keep.pdf"
    file_name_delete = "certificate-delete.pdf"
    certificate_delete = BoatCertificateFactory(
        boat=boat, file=SimpleUploadedFile(name=file_name_delete, content=None)
    )

    variables = {
        "id": boat_id,
        "name": "Flying Dutchman",
        "length": random_decimal(as_string=True),
        "width": random_decimal(as_string=True),
        "addBoatCertificates": [
            {
                "file": SimpleUploadedFile(
                    name=file_name_keep, content=None, content_type="application/pdf"
                ),
                "certificateType": random.choice(list(BoatCertificateType)).name,
                "checkedBy": "John Wick",
            }
        ],
        "removeBoatCertificates": [
            to_global_id(BoatCertificateNode, certificate_delete.id)
        ],
    }

    assert Boat.objects.count() == 1
    assert BoatCertificate.objects.count() == 1

    executed = api_client.execute(UPDATE_BOAT_MUTATION, input=variables)

    certificates = executed["data"]["updateBoat"]["boat"].pop("certificates")

    assert Boat.objects.count() == 1
    assert BoatCertificate.objects.count() == 1

    assert len(certificates) == 1

    # Test that all the expected files are in the instance certificates
    cert = certificates[0]
    cert_id = cert.pop("id")

    assert cert_id is not None
    cert_id = from_global_id(cert_id)

    # Check that the old file was removed
    assert get_boat_certificate_media_folder(
        BoatCertificate.objects.get(id=cert_id), file_name_delete
    ) not in cert.get("file")

    # Check that the new file has a valid url
    assert get_boat_certificate_media_folder(
        BoatCertificate.objects.get(id=cert_id), file_name_keep
    ) in cert.pop("file")

    assert cert == {
        "certificateType": variables["addBoatCertificates"][0]["certificateType"],
        "checkedBy": variables["addBoatCertificates"][0]["checkedBy"],
    }

    assert executed["data"]["updateBoat"]["boat"] == {
        "owner": {"id": owner_id},
        "boatType": {"id": boat_type_id},
        "name": variables["name"],
        "length": variables["length"],
        "width": variables["width"],
    }
Esempio n. 9
0
    def find_profile(
        self,
        first_name: str = "",
        last_name: str = "",
        email: str = "",
        phone: str = "",
        force_only_one: bool = True,
    ) -> Union[List[HelsinkiProfileUser], HelsinkiProfileUser]:
        """
        Find the profile based on the passed criteria, the missing parameters
        are replaced by empty values.

        force_only_one: bool -> If more than one profile is found, it will raise an error
        """
        query = f"""
            query FindProfile {{
                profiles(
                    serviceType: BERTH,
                    firstName: "{first_name}",
                    lastName: "{last_name}",
                    emails_Email: "{email}",
                    phones_Phone: "{phone}"
                ) {{
                    edges {{
                        node {{
                            id
                            first_name: firstName
                            last_name: lastName
                            primary_email: primaryEmail {{
                                email
                            }}
                            primary_phone: primaryPhone {{
                                phone
                            }}
                        }}
                    }}
                }}
            }}
        """
        response = self.query(query)
        profiles = (response.get("profiles", {}).get("edges", [])
                    if response and response.get("profiles", {})
                    and response.get("profiles", {}).get("edges") else [])

        if force_only_one:
            if len(profiles) > 1:
                ids = [
                    from_global_id(profile_node.get("node", {}).get("id"))
                    for profile_node in profiles
                ]
                raise MultipleProfilesException(ids=ids)
            elif len(profiles) == 0:
                raise NoProfilesException

        users = []
        for profile_edge in profiles:
            users.append(self.parse_user_edge(profile_edge))

        if force_only_one:
            return users[0]

        return users
Esempio n. 10
0
 def resolve_order_refunds(self, info, order_id, **kwargs):
     return OrderRefund.objects.filter(
         order_id=from_global_id(order_id, OrderNode))
class UpdateBerthApplication(graphene.ClientIDMutation):
    class Input(UpdateBerthApplicationInput):
        pass

    berth_application = graphene.Field(BerthApplicationNode)

    @classmethod
    def validate_application_status(cls, application, info, input):
        if application.status != ApplicationStatus.PENDING:
            if is_customer(info.context.user):
                raise VenepaikkaGraphQLError(
                    _("Cannot modify the application once it has been processed"
                      ))

            # If the input receives explicitly customerId: None
            if "customer_id" in input and input.get("customer_id") is None:
                raise VenepaikkaGraphQLError(
                    _("Customer cannot be disconnected from processed applications"
                      ))

    def get_nodes_to_check(info, **input):
        application = get_node_from_global_id(info,
                                              input.get("id"),
                                              only_type=BerthApplicationNode,
                                              nullable=True)
        return [application]

    @classmethod
    @check_user_is_authorised(
        get_nodes_to_check=get_nodes_to_check,
        model_checks=[
            user_has_view_permission(CustomerProfile, BerthLease),
            user_has_change_permission(BerthApplication),
        ],
    )
    @transaction.atomic
    def mutate_and_get_payload(cls, root, info, **input):
        from customers.schema import ProfileNode

        application = get_node_from_global_id(info,
                                              input.pop("id"),
                                              only_type=BerthApplicationNode)

        cls.validate_application_status(application, info, input)

        # This allows for getting explicit None values
        if "customer_id" in input:
            customer_id = input.pop("customer_id", None)

            if is_customer(info.context.user):
                raise VenepaikkaGraphQLError(
                    _("A customer cannot modify the customer connected to the application"
                      ))

            input["customer"] = get_node_from_global_id(info,
                                                        customer_id,
                                                        only_type=ProfileNode,
                                                        nullable=True)

        if remove_choices := input.pop("remove_choices", []):
            for choice_id in remove_choices:
                try:
                    choice = HarborChoice.objects.get(id=from_global_id(
                        choice_id, node_type=HarborChoiceType))
                    choice.delete()
                except HarborChoice.DoesNotExist:
                    pass

        if add_choices := input.pop("add_choices", []):
            for choice in add_choices:
                HarborChoice.objects.get_or_create(
                    harbor_id=from_global_id(choice.get("harbor_id")),
                    priority=choice.get("priority"),
                    application=application,
                )