<commit_before>from cornflake.sqlalchemy_orm import ModelSerializer
from cornflake import fields
from cornflake.exceptions import ValidationError

from radar.api.serializers.common import PatientMixin, MetaMixin, GroupField
from radar.exceptions import PermissionDenied
from radar.models.groups import GroupPatient, check_dependencies, DependencyError
from radar.permissions import has_permission_for_patient, has_permission_for_group
from radar.roles import PERMISSION


class GroupPatientSerializer(PatientMixin, MetaMixin, ModelSerializer):
    group = GroupField()
    from_date = fields.DateField()
    to_date = fields.DateField(required=False)
    created_group = GroupField()
    current = fields.BooleanField(read_only=True)

    class Meta(object):
        model_class = GroupPatient
        exclude = ['group_id', 'created_group_id']

    def is_duplicate(self, data):
        group = data['group']
        patient = data['patient']
        instance = self.instance

        duplicate = any(
            group == x.group and
            (instance is None or instance != x)
            for x in patient.current_group_patients
        )

        return duplicate

    def check_dependencies(self, data):
        group = data['group']
        patient = data['patient']

        groups = patient.groups

        instance = self.root.instance

        if instance is not None:
            groups.remove(instance.group)

        groups.append(group)

        try:
            check_dependencies(groups)
        except DependencyError as e:
            raise ValidationError({'group': e.message})

    def validate(self, data):
        data = super(GroupPatientSerializer, self).validate(data)

        current_user = self.context['user']
        instance = self.instance

        if not has_permission_for_patient(current_user, data['patient'], PERMISSION.VIEW_DEMOGRAPHICS):
            raise PermissionDenied()

        if not has_permission_for_group(current_user, data['group'], PERMISSION.EDIT_PATIENT_MEMBERSHIP):
            raise PermissionDenied()

        check_old_created_group = (
            instance is not None and
            instance.created_group != data['created_group']
        )

        check_new_created_group = (
            instance is None or
            instance.group != data['group'] or
            instance.created_group != data['created_group']
        )

        if (
            check_old_created_group and
            not has_permission_for_group(
                current_user,
                data['created_group'],
                PERMISSION.EDIT_PATIENT_MEMBERSHIP,
                explicit=True
            )
        ) or (
            check_new_created_group and
            not has_permission_for_group(
                current_user,
                data['created_group'],
                PERMISSION.EDIT_PATIENT_MEMBERSHIP,
                explicit=True
            )
        ):
            raise PermissionDenied()

        self.check_dependencies(data)

        # Check that the patient doesn't already belong to this group
        # Note: it's important this check happens after the permission checks to prevent membership enumeration
        if self.is_duplicate(data):
            raise ValidationError({'group': 'Patient already belongs to this group.'})

        return data<commit_msg>Check from date is not before registration date<commit_after>from cornflake.sqlalchemy_orm import ModelSerializer
from cornflake import fields
from cornflake.exceptions import ValidationError

from radar.api.serializers.common import PatientMixin, MetaMixin, GroupField
from radar.exceptions import PermissionDenied
from radar.models.groups import GroupPatient, check_dependencies, DependencyError
from radar.permissions import has_permission_for_patient, has_permission_for_group
from radar.roles import PERMISSION


class GroupPatientSerializer(PatientMixin, MetaMixin, ModelSerializer):
    group = GroupField()
    from_date = fields.DateField()
    to_date = fields.DateField(required=False)
    created_group = GroupField()
    current = fields.BooleanField(read_only=True)

    class Meta(object):
        model_class = GroupPatient
        exclude = ['group_id', 'created_group_id']

    def is_duplicate(self, data):
        group = data['group']
        patient = data['patient']
        instance = self.instance

        duplicate = any(
            group == x.group and
            (instance is None or instance != x)
            for x in patient.current_group_patients
        )

        return duplicate

    def check_dependencies(self, data):
        group = data['group']
        patient = data['patient']

        groups = patient.groups

        instance = self.root.instance

        if instance is not None:
            groups.remove(instance.group)

        groups.append(group)

        try:
            check_dependencies(groups)
        except DependencyError as e:
            raise ValidationError({'group': e.message})

    def validate(self, data):
        data = super(GroupPatientSerializer, self).validate(data)

        current_user = self.context['user']
        instance = self.instance

        if not has_permission_for_patient(current_user, data['patient'], PERMISSION.VIEW_DEMOGRAPHICS):
            raise PermissionDenied()

        if not has_permission_for_group(current_user, data['group'], PERMISSION.EDIT_PATIENT_MEMBERSHIP):
            raise PermissionDenied()

        check_old_created_group = (
            instance is not None and
            instance.created_group != data['created_group']
        )

        check_new_created_group = (
            instance is None or
            instance.group != data['group'] or
            instance.created_group != data['created_group']
        )

        if (
            check_old_created_group and
            not has_permission_for_group(
                current_user,
                data['created_group'],
                PERMISSION.EDIT_PATIENT_MEMBERSHIP,
                explicit=True
            )
        ) or (
            check_new_created_group and
            not has_permission_for_group(
                current_user,
                data['created_group'],
                PERMISSION.EDIT_PATIENT_MEMBERSHIP,
                explicit=True
            )
        ):
            raise PermissionDenied()

        self.check_dependencies(data)

        # Check that the patient doesn't already belong to this group
        # Note: it's important this check happens after the permission checks to prevent membership enumeration
        if self.is_duplicate(data):
            raise ValidationError({'group': 'Patient already belongs to this group.'})

        # Check the from date isn't before the date the patient was added to RaDaR
        if not data['group'].is_radar():
            recruited_date = data['patient'].recruited_date

            if recruited_date is not None and data['from_date'] < recruited_date.date():
                raise ValidationError({'from_date': "Must be on or after the recruitment date."})

        return data
{'fraction_non_alphanumeric': 0.07323267955411317, 'fraction_numerical': 0.0, 'mean_word_length': 2.404418828049952, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3210756', 'n_tokens_mistral': 1880, 'n_tokens_neox': 1762, 'n_words': 463}