示例#1
0
class PrivateCategorySerializer(HALSerializer):
    serializer_url_field = PrivateCategoryHyperlinkedIdentityField
    _display = DisplayField()
    handling_message = serializers.SerializerMethodField()
    sla = serializers.SerializerMethodField()
    new_sla = PrivateCategorySLASerializer(write_only=True)

    class Meta:
        model = Category
        fields = (
            '_links',
            '_display',
            'id',
            'name',
            'slug',
            'is_active',
            'description',
            'handling_message',
            'sla',
            'new_sla',
        )
        read_only_fields = (
            'id',
            'slug',
            'handling_message',
            'sla',
        )

    def get_handling_message(self, obj):
        return ALL_AFHANDELING_TEXT[obj.handling]

    def get_sla(self, obj):
        return PrivateCategorySLASerializer(
            obj.slo.all().order_by('-created_at').first()).data

    def update(self, instance, validated_data):
        new_sla = validated_data.pop(
            'new_sla') if 'new_sla' in validated_data else None
        if new_sla:
            ServiceLevelObjective.objects.create(category=instance, **new_sla)
            instance.refresh_from_db()

        return super(PrivateCategorySerializer,
                     self).update(instance, validated_data)
示例#2
0
class ParentCategoryHALSerializer(HALSerializer):
    serializer_url_field = ParentCategoryHyperlinkedIdentityField
    _display = DisplayField()
    sub_categories = CategoryHALSerializer(many=True, source='children')

    class Meta:
        model = Category
        fields = (
            '_links',
            '_display',
            'name',
            'slug',
            'sub_categories',
            'category_level_name1',
            'category_level_name2',
            'category_level_name3',
            'category_level_name4',
            'filter_label',
        )
示例#3
0
class PublicQuestionSerializer(HALSerializer):
    serializer_url_field = QuestionHyperlinkedIdentityField
    next_rules = serializers.SerializerMethodField()
    _display = DisplayField()
    key = serializers.CharField(source='retrieval_key')

    class Meta:
        model = Question
        fields = (
            '_links',
            '_display',
            'key',
            'retrieval_key',
            'analysis_key',
            'uuid',
            'label',
            'short_label',
            'field_type',
            'next_rules',
            'required',
        )
        read_only_fields = fields  # No create or update allowed

    def get_next_rules(self, obj):
        # For backwards compatibility with earlier REST API version, this is
        # candidate for removal. This also only makes sense for questions seen
        # as part of a QuestionGraph, as the next_rules are no longer on the
        # Question object --- graph structure is now explicitly modelled in the
        # QuestionGraph and Edge objects.
        next_rules = None
        if graph := self.context.get('graph', None):
            outgoing_edges = Edge.objects.filter(graph=graph, question=obj)

            next_rules = []
            for edge in outgoing_edges:
                payload = edge.choice.payload if edge.choice else None
                next_rules.append({
                    'key': edge.next_question.ref,
                    'payload': payload
                })

        return next_rules
示例#4
0
class SignalAttachmentSerializer(HALSerializer):
    _display = DisplayField()
    location = serializers.FileField(source='file', required=False)

    class Meta:
        model = Attachment
        fields = (
            '_display',
            '_links',
            'location',
            'is_image',
            'created_at',
            'file',
            'is_issue_finish_image',
        )

        read_only = (
            '_display',
            '_links',
            'location',
            'is_image',
            'created_at',
        )

        extra_kwargs = {'file': {'write_only': True}, 'is_issue_finish_image': {'required': False}}

    def create(self, validated_data):
        is_issue_finish_image = validated_data['is_issue_finish_image'] if 'is_issue_finish_image' in validated_data else False
        attachment = Signal.actions.add_attachment(validated_data['file'],
                                                   self.context['view'].get_object(), issue_finish=is_issue_finish_image)

        if self.context['request'].user:
            attachment.created_by = self.context['request'].user.email
            attachment.save()

        return attachment

    def validate_file(self, file):
        if file.size > SIGNALS_API_MAX_UPLOAD_SIZE:
            msg = f'Bestand mag maximaal {SIGNALS_API_MAX_UPLOAD_SIZE} bytes groot zijn.'
            raise ValidationError(msg)
        return file
示例#5
0
class PrivateDepartmentSerializerList(HALSerializer):
    _display = DisplayField()
    category_names = serializers.SerializerMethodField()

    class Meta:
        model = Department
        fields = (
            '_links',
            '_display',
            'id',
            'name',
            'code',
            'is_intern',
            'category_names',
        )

    def get_category_names(self, obj):
        return list(
            obj.category_set.filter(is_active=True).values_list('name',
                                                                flat=True))
示例#6
0
class PublicSessionSerializer(HALSerializer):
    serializer_url_field = SessionPublicHyperlinkedIdentityField

    _display = DisplayField()

    class Meta:
        model = Session
        fields = (
            '_links',
            '_display',
            'uuid',
            'started_at',
            'submit_before',
            'duration',
            'created_at',
        )
        read_only_fields = (
            'id',
            'uuid',
            'created_at',
        )
示例#7
0
class CategoryHALSerializer(HALSerializer):
    serializer_url_field = CategoryHyperlinkedIdentityField
    _display = DisplayField()
    departments = _NestedDepartmentSerializer(many=True)
    handling_message = serializers.SerializerMethodField()

    class Meta:
        model = Category
        fields = (
            '_links',
            '_display',
            'name',
            'slug',
            'handling',
            'departments',
            'is_active',
            'handling_message',
        )

    def get_handling_message(self, obj):
        return ALL_AFHANDELING_TEXT[obj.handling]
示例#8
0
class ContainerSerializer(FlexFieldsModelSerializer, HALSerializer):
    _display = DisplayField()

    container_type = ContainerTypeSerializer()

    address = serializers.SerializerMethodField()

    # well = WellModelSerializer()
    # geometrie = serializers.SerializerMethodField()

    class Meta(object):
        model = Container
        fields = [
            "_links",
            "_display",
            "id",
            "id_number",
            "owner",
            "active",
            "waste_type",
            "waste_name",
            "container_type",
            "warranty_date",
            "operational_date",
            "placing_date",
            "well",
            "address",
        ]

    expandable_fields = {
        'well': (WellModelSerializer, {
            'source':
            'well',
            'fields': ['id', 'id_number', 'geometrie', 'site', 'buurt_code']
        }),
    }

    def get_address(self, obj):
        if obj.well:
            return obj.well.address.get('summary')
示例#9
0
class SignalCityObjectSerializerDetail(HALSerializer):
    _display = DisplayField()
    signal_id = serializers.CharField()
    city_obj_id = serializers.CharField()
    signal = serializers.SerializerMethodField()
    city_object = serializers.SerializerMethodField()

    class Meta:
        model = SignalCityObject
        fields = ('_display', 'id', 'signal_id', 'signal', 'city_object',
                  'city_obj_id', 'complainID', 'complainIDall', 'reportCount',
                  'is_Orac')

    def get_city_object(self, obj):
        if obj.city_obj_id:
            return CityObjectSerializer(
                CityObject.objects.get(id=obj.city_obj_id)).data

        return None

    def get_signal(self, obj):
        if obj.signal_id:
            return PublicSignalSerializerDetail(
                Signal.objects.get(id=obj.signal_id)).data

        return None

    def create(self, validated_data):
        signal_id = validated_data.pop('signal_id')
        city_obj_id = validated_data.pop('city_obj_id')
        signal = Signal.objects.get(id=signal_id)
        city_obj = CityObject.objects.get(id=city_obj_id)

        instance = super(SignalCityObjectSerializerDetail,
                         self).create(validated_data)
        instance.signal = signal
        instance.city_obj = city_obj
        instance.save()

        return instance
示例#10
0
class SignalCityObjectSerializerList(HALSerializer):
    _display = DisplayField()
    city_obj = serializers.SerializerMethodField()
    signal = serializers.SerializerMethodField()

    class Meta:
        model = SignalCityObject
        fields = ('_display', 'id', 'complainID', 'complainIDall',
                  'reportCount', 'is_Orac', 'city_obj', 'signal')

    def get_city_obj(self, obj):
        if obj.city_obj_id:
            return CityObjectSerializer(
                CityObject.objects.get(id=obj.city_obj_id)).data

        return None

    def get_signal(self, obj):
        if obj.signal:
            return PublicSignalSerializerDetail(
                Signal.objects.get(id=obj.signal.id)).data

        return None
示例#11
0
class CategoryHALSerializer(HALSerializer):
    serializer_url_field = CategoryHyperlinkedIdentityField
    _display = DisplayField()
    departments = serializers.SerializerMethodField()

    class Meta:
        model = Category
        fields = (
            '_links',
            '_display',
            'name',
            'slug',
            'handling',
            'departments',
            'is_active',
            'description',
            'handling_message',
        )

    def get_departments(self, obj):
        return _NestedPublicDepartmentSerializer(
            obj.departments.filter(categorydepartment__is_responsible=True),
            many=True).data
示例#12
0
class WellSerializer(HALSerializer):
    _display = DisplayField()

    containers = RelatedSummaryField()

    class Meta(object):
        model = Well
        fields = [
            "_links",
            "_display",
            "id",
            "id_number",
            "serial_number",
            "buurt_code",
            "stadsdeel",
            "geometrie",
            "created_at",
            "warranty_date",
            "operational_date",
            "containers",
            "address",
            "site",
        ]
示例#13
0
class PrivateCategorySerializer(HALSerializer):
    serializer_url_field = PrivateCategoryHyperlinkedIdentityField
    _display = DisplayField()
    sla = serializers.SerializerMethodField()
    new_sla = PrivateCategorySLASerializer(write_only=True)

    departments = _NestedPrivateCategoryDepartmentSerializer(source='categorydepartment_set', many=True, read_only=True)

    class Meta:
        model = Category
        fields = (
            '_links',
            '_display',
            'id',
            'name',
            'slug',
            'is_active',
            'description',
            'handling_message',
            'sla',
            'new_sla',
            'departments',
        )
        read_only_fields = (
            'slug',
        )

    def get_sla(self, obj):
        return PrivateCategorySLASerializer(obj.slo.first()).data

    def update(self, instance, validated_data):
        new_sla = validated_data.pop('new_sla') if 'new_sla' in validated_data else None
        if new_sla:
            ServiceLevelObjective.objects.create(category=instance, **new_sla)
            instance.refresh_from_db()

        return super(PrivateCategorySerializer, self).update(instance, validated_data)
示例#14
0
class PriorityHALSerializer(AddExtrasMixin, HALSerializer):
    _display = DisplayField()
    _signal = serializers.PrimaryKeyRelatedField(queryset=Signal.objects.all())
    serializer_url_field = PriorityLinksField

    class Meta:
        model = Priority
        fields = (
            '_links',
            '_display',
            'id',
            '_signal',
            'priority',
            'created_at',
            'created_by',
        )

    def create(self, validated_data):
        validated_data = self.add_user(validated_data)
        validated_data['created_by'] = validated_data.pop('user')

        signal = validated_data.pop('_signal')
        priority = Signal.actions.update_priority(validated_data, signal)
        return priority
示例#15
0
class SignalStatusOnlyHALSerializer(HALSerializer):
    _display = DisplayField()
    signal_id = serializers.CharField(label='SIGNAL_ID', read_only=True)
    status = _NestedStatusUnauthenticatedModelSerializer(read_only=True)

    _links = SignalUnauthenticatedLinksField('signal-detail')

    class Meta(object):
        model = Signal
        fields = (
            '_links',
            '_display',
            'signal_id',
            'status',
            'created_at',
            'updated_at',
            'incident_date_start',
            'incident_date_end',
            'operational_date',
        )
        read_only_fields = (
            'created_at',
            'updated_at',
        )
示例#16
0
class PrivateQuestionSerializer(HALSerializer):
    serializer_url_field = QuestionHyperlinkedIdentityField
    _display = DisplayField()

    class Meta:
        model = Question
        fields = (
            '_links',
            '_display',
            'id',
            'key',
            'uuid',
            'label',
            'short_label',
            'field_type',
            'next_rules',
            'required',
            'created_at',
        )
        read_only_fields = (
            'id',
            'uuid',
            'created_at',
        )
示例#17
0
class PrivateDepartmentSerializerDetail(HALSerializer):
    _display = DisplayField()

    categories = CategoryDepartmentSerializer(
        source='active_categorydepartment_set', many=True, required=False)

    country = CountrySerializer(required=False)
    city = CitySerializer(required=False)

    class Meta:
        model = Department
        fields = (
            '_links',
            '_display',
            'id',
            'name',
            'code',
            'is_intern',
            'categories',
            'country',
            'city',
            'app',
        )

    def _save_category_department(self, instance, validated_data):
        instance.category_set.clear()
        for category_department_validated_data in validated_data:
            category_department_validated_data['department'] = instance
            category_department = CategoryDepartment(
                **category_department_validated_data)
            category_department.save()

    def create(self, validated_data):
        country_data = validated_data.pop('country', None)
        city_data = validated_data.pop('city', None)

        categorydepartment_set_validated_data = None
        if 'active_categorydepartment_set' in validated_data:
            categorydepartment_set_validated_data = validated_data.pop(
                'active_categorydepartment_set')

        instance = super(PrivateDepartmentSerializerDetail,
                         self).create(validated_data)

        # get country object if exists else create new
        if country_data and country_data["country_name"]:
            if Country.objects.filter(
                    country_name__iexact=country_data["country_name"]).exists(
                    ):
                instance.country = Country.objects.get(
                    country_name__iexact=country_data["country_name"])
            else:
                country = Country.objects.create(
                    country_name=country_data["country_name"])
                instance.country = country

        if city_data and city_data["city_name"]:
            if City.objects.filter(
                    city_name__iexact=city_data["city_name"]).exists():
                instance.city = City.objects.get(
                    city_name__iexact=city_data["city_name"])
            else:
                city = City.objects.create(city_name=city_data["city_name"])
                instance.city = city

        if categorydepartment_set_validated_data:
            self._save_category_department(
                instance=instance,
                validated_data=categorydepartment_set_validated_data)

        instance.save()

        instance.refresh_from_db()
        return instance

    def update(self, instance, validated_data):
        if 'active_categorydepartment_set' in validated_data:
            self._save_category_department(
                instance=instance,
                validated_data=validated_data.pop(
                    'active_categorydepartment_set'))

        instance = super(PrivateDepartmentSerializerDetail,
                         self).update(instance, validated_data)
        instance.refresh_from_db()
        return instance
示例#18
0
class CategoryHALSerializer(AddExtrasMixin, HALSerializer):
    serializer_url_field = CategoryLinksField
    _display = DisplayField()

    _signal = serializers.PrimaryKeyRelatedField(queryset=Signal.objects.all())

    # Should be required, but to make it work with the backwards compatibility fix it's not required
    # at the moment..
    sub_category = CategoryHyperlinkedRelatedField(write_only=True, required=False, source='category')

    sub = serializers.CharField(source='category.name', read_only=True)
    sub_slug = serializers.CharField(source='category.slug', read_only=True)
    main = serializers.CharField(source='category.parent.name', read_only=True)
    main_slug = serializers.CharField(source='category.parent.slug', read_only=True)

    # Backwards compatibility fix for departments, should be retrieved from category terms resource.
    department = serializers.SerializerMethodField(source='category.departments',
                                                   read_only=True)

    class Meta(object):
        model = CategoryAssignment
        fields = (
            '_links',
            '_display',
            '_signal',
            'sub_category',
            'sub',
            'sub_slug',
            'main',
            'main_slug',
            'department',
            'created_by',
            'created_at',
        )

    def get_department(self, obj):
        return ', '.join(obj.category.departments.values_list('code', flat=True))

    def to_internal_value(self, data):
        internal_data = super().to_internal_value(data)

        if 'sub_category' in data:
            # Fix for renaming sub_category to category internally
            data['category'] = data['sub_category']
            del data['sub_category']

        # Backwards compatibility fix to let this endpoint work with `sub` as key.
        is_main_name_posted = 'main' in data
        is_sub_name_posted = 'sub' in data
        is_category_not_posted = 'category' not in data
        if is_main_name_posted and is_sub_name_posted and is_category_not_posted:
            try:
                category = Category.objects.get(parent__name__iexact=data['main'],
                                                name__iexact=data['sub'])
            except Category.DoesNotExist:
                internal_data['category'] = Category.objects.get(id=76)  # Overig
            else:
                internal_data['category'] = category

        return internal_data

    def validate(self, attrs):
        if 'category' in attrs:
            if attrs['_signal'].category_assignment.category.id == attrs['category'].id:
                raise ValidationError('Cannot assign the same category twice')

        return super(CategoryHALSerializer, self).validate(attrs=attrs)

    def create(self, validated_data):
        validated_data = self.add_user(validated_data)
        validated_data['created_by'] = validated_data.pop('user')

        signal = validated_data.pop('_signal')
        category = Signal.actions.update_category_assignment(validated_data, signal)
        return category
示例#19
0
class PublicSessionSerializer(HALSerializer):
    serializer_url_field = SessionPublicHyperlinkedIdentityField

    _display = DisplayField()

    can_freeze = serializers.SerializerMethodField()
    path_questions = serializers.SerializerMethodField()
    path_answered_question_uuids = serializers.SerializerMethodField()
    path_unanswered_question_uuids = serializers.SerializerMethodField()
    path_validation_errors_by_uuid = serializers.SerializerMethodField()

    class Meta:
        model = Session
        fields = (
            '_links',
            '_display',
            'uuid',
            'started_at',
            'submit_before',
            'duration',
            'created_at',
            # generated using the SessionService in serializer context:
            'can_freeze',
            'path_questions',
            'path_answered_question_uuids',
            'path_unanswered_question_uuids',
            'path_validation_errors_by_uuid')
        read_only_fields = (
            'id',
            'uuid',
            'created_at',
            # generated using the SessionService in serializer context:
            'can_freeze',
            'path_questions',
            'path_path_answered_question_uuids',
            'path_unanswered_question_uuids',
            'path_validation_errors_by_uuid')

    def get_can_freeze(self, obj):
        session_service = self.context.get('session_service')
        return session_service.can_freeze

    def get_path_questions(self, obj):
        session_service = self.context.get('session_service')
        serializer = PublicQuestionSerializer(session_service.path_questions,
                                              many=True,
                                              context=self.context)
        return serializer.data

    def get_path_answered_question_uuids(self, obj):
        session_service = self.context.get('session_service')
        return session_service.path_answered_question_uuids

    def get_path_unanswered_question_uuids(self, obj):
        session_service = self.context.get('session_service')
        return session_service.path_unanswered_question_uuids

    def get_path_validation_errors_by_uuid(self, obj):
        session_service = self.context.get('session_service')
        # Possibly turn all UUIDs into str(UUID)s in SessionService.
        return {
            str(k): v
            for k, v in session_service.path_validation_errors_by_uuid.items()
        }

    def create(self, validated_data):
        """
        This serializer cannot be used to create Session instances
        """
        raise NotImplementedError

    def update(self, instance, validated_data):
        """
        This serializer cannot be used to update Session instances
        """
        raise NotImplementedError
示例#20
0
class PrivateSignalSerializerDetail(HALSerializer, AddressValidationMixin):
    """
    This serializer is used for the detail endpoint and when updating the instance
    """
    serializer_url_field = PrivateSignalLinksFieldWithArchives
    _display = DisplayField()

    location = _NestedLocationModelSerializer(
        required=False, permission_classes=(SIAPermissions, ))

    status = _NestedStatusModelSerializer(
        required=False, permission_classes=(SignalChangeStatusPermission, ))

    category = _NestedCategoryModelSerializer(
        source='category_assignment',
        required=False,
        permission_classes=(SignalChangeCategoryPermission, ))

    reporter = _NestedReporterModelSerializer(
        required=False, permission_classes=(SIAPermissions, ))

    priority = _NestedPriorityModelSerializer(
        required=False, permission_classes=(SIAPermissions, ))

    notes = _NestedNoteModelSerializer(
        many=True,
        required=False,
        permission_classes=(SignalCreateNotePermission, ))

    has_attachments = serializers.SerializerMethodField()

    extra_properties = SignalExtraPropertiesField(
        required=False,
        validators=[
            ExtraPropertiesValidator(
                filename=os.path.join(os.path.dirname(__file__), '..',
                                      'json_schema', 'extra_properties.json'))
        ])  # noqa

    class Meta:
        model = Signal
        fields = (
            '_links',
            '_display',
            'category',
            'id',
            'has_attachments',
            'location',
            'status',
            'reporter',
            'priority',
            'notes',
            'source',
            'text',
            'text_extra',
            'extra_properties',
            'created_at',
            'updated_at',
            'incident_date_start',
            'incident_date_end',
        )
        read_only_fields = (
            'id',
            'has_attachments',
        )

    def get_has_attachments(self, obj):
        return obj.attachments.exists()

    def update(self, instance, validated_data):
        """
        Perform update on nested models.

        Note:
        - Reporter cannot be updated via the API.
        - Atomic update (all fail/succeed), django signals on full success (see
          underlying update_multiple method of actions SignalManager).
        """
        user_email = self.context['request'].user.email

        for _property in [
                'location', 'status', 'category_assignment', 'priority'
        ]:
            if _property in validated_data:
                data = validated_data[_property]
                data['created_by'] = user_email

        if 'notes' in validated_data and validated_data['notes']:
            note_data = validated_data['notes'][0]
            note_data['created_by'] = user_email

        signal = Signal.actions.update_multiple(validated_data, instance)
        return signal
示例#21
0
class PrivateSignalSerializerDetail(HALSerializer, AddressValidationMixin):
    """
    This serializer is used for the detail endpoint and when updating the instance
    """
    serializer_url_field = PrivateSignalLinksFieldWithArchives
    _display = DisplayField()

    country = CountrySerializer(required=False,
                                permission_classes=(SIAPermissions, ))

    city = CitySerializer(required=False,
                          permission_classes=(SIAPermissions, ))

    city_object = CityObjectSerializer(many=True, required=False)

    location = _NestedLocationModelSerializer(
        required=False, permission_classes=(SIAPermissions, ))

    status = _NestedStatusModelSerializer(
        required=False, permission_classes=(SignalChangeStatusPermission, ))

    category = _NestedCategoryModelSerializer(
        source='category_assignment',
        required=False,
        permission_classes=(SignalChangeCategoryPermission, ))

    reporter = _NestedReporterModelSerializer(
        required=False, permission_classes=(SIAPermissions, ))

    priority = _NestedPriorityModelSerializer(
        required=False, permission_classes=(SIAPermissions, ))

    notes = _NestedNoteModelSerializer(
        many=True,
        required=False,
        permission_classes=(SignalCreateNotePermission, ))

    type = _NestedTypeModelSerializer(
        required=False,
        permission_classes=(SIAPermissions, ),
        source='type_assignment',
    )

    directing_departments = _NestedDepartmentModelSerializer(
        source='directing_departments_assignment.departments',
        many=True,
        required=False,
        permission_classes=(SIAPermissions, ),
    )

    updates = SignalPlanUpdateSerializer(many=True, required=False)

    mb_mapping = serializers.SerializerMethodField(required=False)
    has_attachments = serializers.SerializerMethodField()
    image_category = ImageCategorySerializer(required=False)

    extra_properties = SignalExtraPropertiesField(
        required=False,
        validators=[
            ExtraPropertiesValidator(
                filename=os.path.join(os.path.dirname(__file__), '..',
                                      'json_schema', 'extra_properties.json'))
        ])  # noqa

    class Meta:
        model = Signal
        fields = (
            '_links',
            '_display',
            'category',
            'id',
            'has_attachments',
            'location',
            'status',
            'reporter',
            'priority',
            'notes',
            'type',
            'source',
            'text',
            'text_extra',
            'extra_properties',
            'created_at',
            'updated_at',
            'incident_date_start',
            'incident_date_end',
            'finished_by',
            'directing_departments',
            'country',
            'city',
            'city_object',
            'webform_kenmark',
            'mb_report_id',
            'facilitator_report_id',
            'report_days',
            'forman_emp_name',
            'urgency',
            'plan_time',
            'updates',
            'mb_mapping',
            'updated_by',
            'image_category',
        )
        read_only_fields = (
            'id',
            'has_attachments',
        )

    def get_mb_mapping(self, obj):
        if IDMapping.objects.filter(seda_signal_id=obj.signal_id).exists():
            return IDMappingSerializer(
                IDMapping.objects.get(seda_signal_id=obj.signal_id)).data

        return None

    def get_has_attachments(self, obj):
        return obj.attachments.exists()

    def update(self, instance, validated_data):
        """
        Perform update on nested models.

        Note:
        - Reporter cannot be updated via the API.
        - Atomic update (all fail/succeed), django signals on full success (see
          underlying update_multiple method of actions SignalManager).
        """
        if not instance.is_parent() and validated_data.get(
                'directing_departments_assignment') is not None:
            raise serializers.ValidationError(
                'Directing departments can only be set on a parent Signal')

        user_email = self.context['request'].user.email

        for _property in [
                'location', 'status', 'category_assignment', 'priority'
        ]:
            if _property in validated_data:
                data = validated_data[_property]
                data['created_by'] = user_email

        if 'type_assignment' in validated_data:
            type_data = validated_data.pop('type_assignment')
            type_data['created_by'] = user_email
            validated_data['type'] = type_data

        if 'notes' in validated_data and validated_data['notes']:
            note_data = validated_data['notes'][0]
            note_data['created_by'] = user_email

        if 'directing_departments_assignment' in validated_data and validated_data[
                'directing_departments_assignment']:
            validated_data['directing_departments_assignment'][
                'created_by'] = user_email

        signal = Signal.actions.update_multiple(validated_data, instance)
        return signal
示例#22
0
class PrivateSignalSerializerList(HALSerializer, AddressValidationMixin):
    """
    This serializer is used for the list endpoint and when creating a new instance
    """
    serializer_url_field = PrivateSignalLinksField
    _display = DisplayField()

    country = CountrySerializer(required=False,
                                permission_classes=(SIAPermissions, ))

    city = CitySerializer(required=False,
                          permission_classes=(SIAPermissions, ))

    city_object = CityObjectSerializer(many=True, required=False)

    location = _NestedLocationModelSerializer(
        permission_classes=(SIAPermissions, ))

    status = _NestedStatusModelSerializer(
        required=False, permission_classes=(SignalCreateInitialPermission, ))

    category = _NestedCategoryModelSerializer(
        source='category_assignment',
        permission_classes=(SignalCreateInitialPermission, ))

    reporter = _NestedReporterModelSerializer(
        permission_classes=(SIAPermissions, ))

    priority = _NestedPriorityModelSerializer(
        required=False, permission_classes=(SIAPermissions, ))

    notes = _NestedNoteModelSerializer(
        many=True,
        required=False,
        permission_classes=(SignalCreateInitialPermission, ))

    type = _NestedTypeModelSerializer(
        required=False,
        permission_classes=(SIAPermissions, ),
        source='type_assignment',
    )

    updates = SignalPlanUpdateSerializer(many=True, required=False)

    directing_departments = _NestedDepartmentModelSerializer(
        source='directing_departments_assignment.departments',
        many=True,
        required=False,
        permission_classes=(SIAPermissions, ),
    )

    has_attachments = serializers.SerializerMethodField()

    extra_properties = SignalExtraPropertiesField(
        required=False,
        allow_null=True,
        validators=[
            ExtraPropertiesValidator(
                filename=os.path.join(os.path.dirname(__file__), '..',
                                      'json_schema', 'extra_properties.json'))
        ])

    class Meta:
        model = Signal
        fields = (
            '_links',
            '_display',
            'id',
            'signal_id',
            'source',
            'text',
            'text_extra',
            'status',
            'location',
            'category',
            'reporter',
            'priority',
            'type',
            'created_at',
            'updated_at',
            'incident_date_start',
            'incident_date_end',
            'operational_date',
            'has_attachments',
            'extra_properties',
            'notes',
            'directing_departments',
            'finished_by',
            'country',
            'city',
            'city_object',
            'webform_kenmark',
            'mb_report_id',
            'facilitator_report_id',
            'report_days',
            'forman_emp_name',
            'urgency',
            'plan_time',
            'updates',
            'updated_by',
        )
        read_only_fields = (
            'created_at',
            'updated_at',
            'has_attachments',
        )
        extra_kwargs = {
            'source': {
                'validators': [SignalSourceValidator()]
            },
        }

    def get_has_attachments(self, obj):
        return obj.attachments.exists()

    def create(self, validated_data):
        if validated_data.get('directing_departments_assignment') is not None:
            raise serializers.ValidationError(
                'Directing departments cannot be set on initial creation')

        if validated_data.get('status') is not None:
            raise serializers.ValidationError(
                "Status cannot be set on initial creation")

        # Set default status
        logged_in_user = self.context['request'].user
        INITIAL_STATUS = {
            'state': workflow.GEMELD,  # see models.py is already default
            'text': None,
            'user': logged_in_user.email,
        }

        # We require location and reporter to be set and to be valid.
        reporter_data = validated_data.pop('reporter')

        location_data = validated_data.pop('location')
        location_data['created_by'] = logged_in_user.email

        category_assignment_data = validated_data.pop('category_assignment')
        category_assignment_data['created_by'] = logged_in_user.email

        # We will use the priority and signal type on the incoming message if present.
        priority_data = validated_data.pop(
            'priority', {'priority': Priority.PRIORITY_NORMAL})
        priority_data['created_by'] = logged_in_user.email
        type_data = validated_data.pop('type_assignment', {})
        type_data['created_by'] = logged_in_user.email

        country_data = validated_data.pop('country', None)
        city_data = validated_data.pop('city', None)
        city_object_data = validated_data.pop('city_object', None)

        signal = Signal.actions.create_initial(validated_data, location_data,
                                               INITIAL_STATUS,
                                               category_assignment_data,
                                               reporter_data, country_data,
                                               city_data, city_object_data,
                                               priority_data, type_data)

        return signal
示例#23
0
class PrivateCategorySerializer(HALSerializer):
    serializer_url_field = PrivateCategoryHyperlinkedIdentityField
    _display = DisplayField()
    sla = serializers.SerializerMethodField()
    new_sla = PrivateCategorySLASerializer(write_only=True)

    departments = serializers.SerializerMethodField()
    country = serializers.SerializerMethodField()
    city = serializers.SerializerMethodField()

    class Meta:
        model = Category
        fields = (
            '_links',
            '_display',
            'id',
            'name',
            'slug',
            'is_active',
            'description',
            'handling_message',
            'sla',
            'new_sla',
            'departments',
            'filter_label',
            'category_level_name1',
            'category_level_name2',
            'category_level_name3',
            'category_level_name4',
            'country',
            'city',
        )
        read_only_fields = (
            'id',
            'slug',
            'sla',
            'filter_label'
            'departments',  # noqa Is read-only by default because we use the SerializerMethodField but also added here for readability
        )

    def get_sla(self, obj):
        return PrivateCategorySLASerializer(obj.slo.all().order_by('-created_at').first()).data

    def get_departments(self, obj):
        return _NestedPrivateCategoryDepartmentSerializer(
            CategoryDepartment.objects.filter(category_id=obj.pk).order_by('department__code'),
            many=True
        ).data

    def get_country(self, obj):
        if obj.country:
            return CountrySerializer(
                Country.objects.get(id=obj.country.id)
            ).data

        return None


    def get_city(self, obj):
        if obj.city:
            return CitySerializer(
                City.objects.get(id=obj.city.id)
            ).data

        return None


    def update(self, instance, validated_data):
        new_sla = validated_data.pop('new_sla') if 'new_sla' in validated_data else None
        if new_sla:
            ServiceLevelObjective.objects.create(category=instance, **new_sla)
            instance.refresh_from_db()

        return super(PrivateCategorySerializer, self).update(instance, validated_data)
示例#24
0
class PrivateSignalSerializerList(SignalValidationMixin, HALSerializer):
    """
    This serializer is used for the list endpoint and when creating a new instance
    """
    serializer_url_field = PrivateSignalLinksField
    _display = DisplayField()

    signal_id = serializers.UUIDField(source='uuid', required=False, read_only=True)

    location = _NestedLocationModelSerializer(
        permission_classes=(SIAPermissions,)
    )

    status = _NestedStatusModelSerializer(
        required=False,
        permission_classes=(SignalCreateInitialPermission,)
    )

    category = _NestedCategoryModelSerializer(
        source='category_assignment',
        permission_classes=(SignalCreateInitialPermission,)
    )

    reporter = _NestedReporterModelSerializer(
        permission_classes=(SIAPermissions,)
    )

    priority = _NestedPriorityModelSerializer(
        required=False,
        permission_classes=(SIAPermissions,)
    )

    notes = _NestedNoteModelSerializer(
        many=True,
        required=False,
        permission_classes=(SignalCreateInitialPermission,)
    )

    type = _NestedTypeModelSerializer(
        required=False,
        permission_classes=(SIAPermissions,),
        source='type_assignment',
    )

    directing_departments = _NestedDepartmentModelSerializer(
        source='directing_departments_assignment.departments',
        many=True,
        required=False,
        permission_classes=(SIAPermissions,),
    )

    routing_departments = _NestedDepartmentModelSerializer(
        source='routing_assignment.departments',
        many=True,
        required=False,
        allow_null=True,
        permission_classes=(SIAPermissions,),
    )

    has_attachments = serializers.SerializerMethodField()

    assigned_user_email = serializers.EmailField(source='user_assignment.user.email', required=False, allow_null=True)

    extra_properties = serializers.JSONField(
        required=False,
        allow_null=True,
        validators=[
            ExtraPropertiesValidator(
                filename=os.path.join(
                    os.path.dirname(__file__), '..', 'json_schema', 'extra_properties.json')
            )
        ]
    )

    parent = serializers.PrimaryKeyRelatedField(
        required=False,
        read_only=False,
        write_only=True,
        queryset=Signal.objects.all()
    )
    has_parent = serializers.SerializerMethodField()
    has_children = serializers.SerializerMethodField()

    attachments = PrivateSignalAttachmentRelatedField(view_name='private-signals-attachments-detail', many=True,
                                                      required=False, read_only=False, write_only=True,
                                                      queryset=Attachment.objects.all())

    # The Session containing the given answers of a Questionnaire
    session = serializers.UUIDField(default=None, write_only=True, required=False)

    id_display = serializers.CharField(source='get_id_display', read_only=True)

    class Meta:
        model = Signal
        list_serializer_class = _SignalListSerializer
        fields = (
            '_links',
            '_display',
            'id',
            'id_display',
            'signal_id',
            'source',
            'text',
            'text_extra',
            'status',
            'location',
            'category',
            'reporter',
            'priority',
            'type',
            'created_at',
            'updated_at',
            'incident_date_start',
            'incident_date_end',
            'operational_date',
            'has_attachments',
            'extra_properties',
            'notes',
            'directing_departments',
            'routing_departments',
            'attachments',
            'parent',
            'has_parent',
            'has_children',
            'assigned_user_email',
            'session'
        )
        read_only_fields = (
            'created_at',
            'updated_at',
            'has_attachments',
            'has_parent',
            'has_children',
        )
        extra_kwargs = {
            'source': {'validators': [PrivateSignalSourceValidator()]},
        }

    def get_has_attachments(self, obj):
        return obj.attachments.exists()

    def get_has_parent(self, obj):
        return obj.parent_id is not None  # True is a parent_id is set, False if not

    def get_has_children(self, obj):
        return obj.children.exists()

    def validate(self, attrs):  # noqa C901
        errors = {}
        if attrs.get('directing_departments_assignment') is not None:
            errors.update(
                {'directing_departments_assignment': ['Directing departments cannot be set on initial creation']}
            )

        if attrs.get('routing_assignment') is not None:
            errors.update(
                {'routing_assignment': ['Signal departments relation cannot be set on initial creation']}
            )

        if attrs.get('status') is not None:
            errors.update(
                {'status': ['Status cannot be set on initial creation']}
            )

        attachments = attrs.get('attachments')
        parent = attrs.get('parent')
        if attachments and parent is None:
            errors.update({'attachments': ['Attachments can only be copied when creating a child Signal']})

        if attachments and parent:
            attachments_belong_to_parent = all([parent.pk == attachment._signal_id for attachment in attachments])
            if not attachments_belong_to_parent:
                errors.update({'attachments': ['Attachments can only be copied from the parent Signal']})

        if 'session' in attrs and attrs['session']:
            """
            If a Session UUID is given the following checks must be valid before it can be connected to the Signal that
            is going to be created created.

                - The Session with given UUID must exists
                - The Session cannot be connected to a Signal
                - The Session cannot be expired
                - The Session must be frozen
            """
            try:
                session = Session.objects.get(uuid=attrs['session'])
            except Session.DoesNotExist as e:
                errors.update({'session': [f'{e}']})
            else:
                if session._signal_id:
                    errors.update({'session': ['Session already used']})
                elif not session.frozen and not session.is_expired:
                    errors.update({'session': ['Session not frozen']})
                elif session.too_late:
                    errors.update({'session': ['Session expired']})
                else:
                    attrs['session'] = session

        # SIG-4382 additional check on the extra_properties if the category is lantaarpaal-straatverlichting
        #
        # Disabled additional check. This check prevents the creation of a "child" signal in the
        # lantaarnpaal-straatverlichting category because there is no way to provide the streetlight
        #
        # if attrs.get('category_assignment').get('category').slug == 'lantaarnpaal-straatverlichting':
        #     validator = ExtraPropertiesValidator(filename=os.path.join(os.path.dirname(__file__), '..', 'json_schema',
        #                                                                'extra_properties_streetlights.json'))
        #     try:
        #         validator(attrs.get('extra_properties'))
        #     except ValidationError:
        #         errors.update({'extra_properties': [
        #             'Extra properties not valid for category "lantaarnpaal-straatverlichting"'
        #         ]})

        if errors:
            raise serializers.ValidationError(errors)

        return super().validate(attrs=attrs)

    def create(self, validated_data):
        # Set default status
        logged_in_user = self.context['request'].user
        INITIAL_STATUS = {
            'state': workflow.GEMELD,  # see models.py is already default
            'text': None,
            'user': logged_in_user.email,
        }

        # We require location and reporter to be set and to be valid.
        reporter_data = validated_data.pop('reporter')

        location_data = validated_data.pop('location')
        location_data['created_by'] = logged_in_user.email

        category_assignment_data = validated_data.pop('category_assignment')
        category_assignment_data['created_by'] = logged_in_user.email

        # We will use the priority and signal type on the incoming message if present.
        priority_data = validated_data.pop('priority', {
            'priority': Priority.PRIORITY_NORMAL
        })
        priority_data['created_by'] = logged_in_user.email
        type_data = validated_data.pop('type_assignment', {})
        type_data['created_by'] = logged_in_user.email

        attachments = validated_data.pop('attachments') if 'attachments' in validated_data else None
        session = validated_data.pop('session')

        signal = Signal.actions.create_initial(
            validated_data,
            location_data,
            INITIAL_STATUS,
            category_assignment_data,
            reporter_data,
            priority_data,
            type_data,
            session=session,
        )

        if attachments:
            Signal.actions.copy_attachments(data=attachments, signal=signal, created_by=logged_in_user.email)
            # Add history entries for every attachment that was copied. Only photos allowed for now.
            for attachment in Attachment.objects.filter(_signal=signal).order_by('created_at'):
                filename = os.path.basename(attachment.file.name)
                msg = f'Bijlage gekopieerd van hoofdmelding: {filename}'
                Signal.actions.create_note(data={'text': msg}, signal=signal)

        signal.refresh_from_db()
        return signal
示例#25
0
文件: signal.py 项目: CBuiVNG/signals
class PrivateSignalSerializerDetail(HALSerializer, AddressValidationMixin):
    """
    This serializer is used for the detail endpoint and when updating the instance
    """
    serializer_url_field = PrivateSignalLinksFieldWithArchives
    _display = DisplayField()

    location = _NestedLocationModelSerializer(
        required=False, permission_classes=(SIAPermissions, ))

    status = _NestedStatusModelSerializer(
        required=False, permission_classes=(SignalChangeStatusPermission, ))

    category = _NestedCategoryModelSerializer(
        source='category_assignment',
        required=False,
        permission_classes=(SignalChangeCategoryPermission, ))

    reporter = _NestedReporterModelSerializer(
        required=False, permission_classes=(SIAPermissions, ))

    priority = _NestedPriorityModelSerializer(
        required=False, permission_classes=(SIAPermissions, ))

    notes = _NestedNoteModelSerializer(
        many=True,
        required=False,
        permission_classes=(SignalCreateNotePermission, ))

    type = _NestedTypeModelSerializer(
        required=False,
        permission_classes=(SIAPermissions, ),
        source='type_assignment',
    )

    directing_departments = _NestedDepartmentModelSerializer(
        source='directing_departments_assignment.departments',
        many=True,
        required=False,
        permission_classes=(SIAPermissions, ),
    )

    routing_departments = _NestedDepartmentModelSerializer(
        source='routing_assignment.departments',
        many=True,
        required=False,
        allow_null=True,
        permission_classes=(SIAPermissions, ),
    )

    has_attachments = serializers.SerializerMethodField()

    assigned_user_id = serializers.IntegerField(
        source='user_assignment.user.id', required=False, allow_null=True)

    extra_properties = SignalExtraPropertiesField(
        required=False,
        validators=[
            ExtraPropertiesValidator(
                filename=os.path.join(os.path.dirname(__file__), '..',
                                      'json_schema', 'extra_properties.json'))
        ])

    attachments = PrivateSignalAttachmentRelatedField(
        view_name='private-signals-attachments-detail',
        many=True,
        required=False,
        read_only=True)

    class Meta:
        model = Signal
        fields = (
            '_links',
            '_display',
            'category',
            'id',
            'has_attachments',
            'location',
            'status',
            'reporter',
            'priority',
            'notes',
            'type',
            'source',
            'text',
            'text_extra',
            'extra_properties',
            'created_at',
            'updated_at',
            'incident_date_start',
            'incident_date_end',
            'directing_departments',
            'routing_departments',
            'attachments',
            'assigned_user_id',
        )
        read_only_fields = (
            'id',
            'has_attachments',
        )

    def get_has_attachments(self, obj):
        return obj.attachments.exists()

    def update(self, instance, validated_data):  # noqa
        """
        Perform update on nested models.

        Note:
        - Reporter cannot be updated via the API.
        - Atomic update (all fail/succeed), django signals on full success (see
          underlying update_multiple method of actions SignalManager).
        """
        if not instance.is_parent() and validated_data.get(
                'directing_departments_assignment') is not None:
            raise serializers.ValidationError(
                'Directing departments can only be set on a parent Signal')

        user_email = self.context['request'].user.email

        for _property in [
                'location', 'status', 'category_assignment', 'priority'
        ]:
            if _property in validated_data:
                data = validated_data[_property]
                data['created_by'] = user_email

        if 'type_assignment' in validated_data:
            type_data = validated_data.pop('type_assignment')
            type_data['created_by'] = user_email
            validated_data['type'] = type_data

        if 'notes' in validated_data and validated_data['notes']:
            note_data = validated_data['notes'][0]
            note_data['created_by'] = user_email

        if 'directing_departments_assignment' in validated_data and validated_data[
                'directing_departments_assignment']:
            validated_data['directing_departments_assignment'][
                'created_by'] = user_email

        if 'routing_assignment' in validated_data and validated_data[
                'routing_assignment']:
            validated_data['routing_assignment']['created_by'] = user_email

        if 'user_assignment' in validated_data and validated_data[
                'user_assignment']:
            validated_data['created_by'] = user_email

        signal = Signal.actions.update_multiple(validated_data, instance)
        return signal
示例#26
0
文件: signal.py 项目: CBuiVNG/signals
class PrivateSignalSerializerList(SignalValidationMixin, HALSerializer):
    """
    This serializer is used for the list endpoint and when creating a new instance
    """
    serializer_url_field = PrivateSignalLinksField
    _display = DisplayField()

    location = _NestedLocationModelSerializer(
        permission_classes=(SIAPermissions, ))

    status = _NestedStatusModelSerializer(
        required=False, permission_classes=(SignalCreateInitialPermission, ))

    category = _NestedCategoryModelSerializer(
        source='category_assignment',
        permission_classes=(SignalCreateInitialPermission, ))

    reporter = _NestedReporterModelSerializer(
        permission_classes=(SIAPermissions, ))

    priority = _NestedPriorityModelSerializer(
        required=False, permission_classes=(SIAPermissions, ))

    notes = _NestedNoteModelSerializer(
        many=True,
        required=False,
        permission_classes=(SignalCreateInitialPermission, ))

    type = _NestedTypeModelSerializer(
        required=False,
        permission_classes=(SIAPermissions, ),
        source='type_assignment',
    )

    directing_departments = _NestedDepartmentModelSerializer(
        source='directing_departments_assignment.departments',
        many=True,
        required=False,
        permission_classes=(SIAPermissions, ),
    )

    routing_departments = _NestedDepartmentModelSerializer(
        source='routing_assignment.departments',
        many=True,
        required=False,
        allow_null=True,
        permission_classes=(SIAPermissions, ),
    )

    has_attachments = serializers.SerializerMethodField()

    assigned_user_id = serializers.IntegerField(
        source='user_assignment.user.id', required=False, allow_null=True)

    extra_properties = SignalExtraPropertiesField(
        required=False,
        allow_null=True,
        validators=[
            ExtraPropertiesValidator(
                filename=os.path.join(os.path.dirname(__file__), '..',
                                      'json_schema', 'extra_properties.json'))
        ])

    parent = serializers.PrimaryKeyRelatedField(required=False,
                                                read_only=False,
                                                write_only=True,
                                                queryset=Signal.objects.all())
    has_parent = serializers.SerializerMethodField()
    has_children = serializers.SerializerMethodField()

    attachments = PrivateSignalAttachmentRelatedField(
        view_name='private-signals-attachments-detail',
        many=True,
        required=False,
        read_only=False,
        write_only=True,
        queryset=Attachment.objects.all())

    class Meta:
        model = Signal
        list_serializer_class = _SignalListSerializer
        fields = ('_links', '_display', 'id', 'signal_id', 'source', 'text',
                  'text_extra', 'status', 'location', 'category', 'reporter',
                  'priority', 'type', 'created_at', 'updated_at',
                  'incident_date_start', 'incident_date_end',
                  'operational_date', 'has_attachments', 'extra_properties',
                  'notes', 'directing_departments', 'routing_departments',
                  'attachments', 'parent', 'has_parent', 'has_children',
                  'assigned_user_id')
        read_only_fields = (
            'created_at',
            'updated_at',
            'has_attachments',
            'has_parent',
            'has_children',
        )
        extra_kwargs = {
            'source': {
                'validators': [SignalSourceValidator()]
            },
        }

    def get_has_attachments(self, obj):
        return obj.attachments.exists()

    def get_has_parent(self, obj):
        return obj.parent_id is not None  # True is a parent_id is set, False if not

    def get_has_children(self, obj):
        return obj.children.exists()

    def validate(self, attrs):
        errors = {}
        if attrs.get('directing_departments_assignment') is not None:
            errors.update({
                'directing_departments_assignment':
                ['Directing departments cannot be set on initial creation']
            })

        if attrs.get('routing_assignment') is not None:
            errors.update({
                'routing_assignment': [
                    'Signal departments relation cannot be set on initial creation'
                ]
            })

        if attrs.get('status') is not None:
            errors.update(
                {'status': ['Status cannot be set on initial creation']})

        attachments = attrs.get('attachments')
        parent = attrs.get('parent')
        if attachments and parent is None:
            errors.update({
                'attachments': [
                    'Attachments can only be copied when creating a child Signal'
                ]
            })

        if attachments and parent:
            attachments_belong_to_parent = all([
                parent.pk == attachment._signal_id
                for attachment in attachments
            ])
            if not attachments_belong_to_parent:
                errors.update({
                    'attachments':
                    ['Attachments can only be copied from the parent Signal']
                })

        if errors:
            raise serializers.ValidationError(errors)

        return super(PrivateSignalSerializerList, self).validate(attrs=attrs)

    def create(self, validated_data):
        # Set default status
        logged_in_user = self.context['request'].user
        INITIAL_STATUS = {
            'state': workflow.GEMELD,  # see models.py is already default
            'text': None,
            'user': logged_in_user.email,
        }

        # We require location and reporter to be set and to be valid.
        reporter_data = validated_data.pop('reporter')

        location_data = validated_data.pop('location')
        location_data['created_by'] = logged_in_user.email

        category_assignment_data = validated_data.pop('category_assignment')
        category_assignment_data['created_by'] = logged_in_user.email

        # We will use the priority and signal type on the incoming message if present.
        priority_data = validated_data.pop(
            'priority', {'priority': Priority.PRIORITY_NORMAL})
        priority_data['created_by'] = logged_in_user.email
        type_data = validated_data.pop('type_assignment', {})
        type_data['created_by'] = logged_in_user.email

        attachments = validated_data.pop(
            'attachments') if 'attachments' in validated_data else None

        signal = Signal.actions.create_initial(validated_data, location_data,
                                               INITIAL_STATUS,
                                               category_assignment_data,
                                               reporter_data, priority_data,
                                               type_data)

        if attachments:
            Signal.actions.copy_attachments(data=attachments, signal=signal)

        signal.refresh_from_db()
        return signal