示例#1
0
class CampaignEventReadSerializer(ReadSerializer):
    UNITS = extract_constants(CampaignEvent.UNIT_CONFIG)

    campaign = fields.CampaignField()
    flow = serializers.SerializerMethodField()
    relative_to = fields.ContactFieldField()
    unit = serializers.SerializerMethodField()
    created_on = serializers.DateTimeField(default_timezone=pytz.UTC)

    def get_flow(self, obj):
        if obj.event_type == CampaignEvent.TYPE_FLOW:
            return {"uuid": obj.flow.uuid, "name": obj.flow.name}
        else:
            return None

    def get_unit(self, obj):
        return self.UNITS.get(obj.unit)

    class Meta:
        model = CampaignEvent
        fields = (
            "uuid",
            "campaign",
            "relative_to",
            "offset",
            "unit",
            "delivery_hour",
            "flow",
            "message",
            "created_on",
        )
示例#2
0
class ContactFieldWriteSerializer(WriteSerializer):
    VALUE_TYPES = extract_constants(Value.TYPE_CONFIG, reverse=True)

    label = serializers.CharField(
        required=True,
        max_length=ContactField.MAX_LABEL_LEN,
        validators=[
            UniqueForOrgValidator(
                ContactField.user_fields.filter(is_active=True),
                ignore_case=True)
        ],
    )
    value_type = serializers.ChoiceField(required=True,
                                         choices=list(VALUE_TYPES.keys()))

    def validate_label(self, value):
        if not ContactField.is_valid_label(value):
            raise serializers.ValidationError(
                "Can only contain letters, numbers and hypens.")

        key = ContactField.make_key(value)
        if not ContactField.is_valid_key(key):
            raise serializers.ValidationError(
                'Generated key "%s" is invalid or a reserved name.' % key)

        return value

    def validate_value_type(self, value):
        return self.VALUE_TYPES.get(value)

    def validate(self, data):

        field_count = ContactField.user_fields.count_active_for_org(
            org=self.context["org"])
        if not self.instance and field_count >= settings.MAX_ACTIVE_CONTACTFIELDS_PER_ORG:
            raise serializers.ValidationError(
                "This org has %s contact fields and the limit is %s. "
                "You must delete existing ones before you can "
                "create new ones." %
                (field_count, settings.MAX_ACTIVE_CONTACTFIELDS_PER_ORG))

        return data

    def save(self):
        label = self.validated_data.get("label")
        value_type = self.validated_data.get("value_type")

        if self.instance:
            key = self.instance.key
        else:
            key = ContactField.make_key(label)

        return ContactField.get_or_create(self.context["org"],
                                          self.context["user"],
                                          key,
                                          label,
                                          value_type=value_type)
示例#3
0
class ContactFieldReadSerializer(ReadSerializer):
    VALUE_TYPES = extract_constants(Value.TYPE_CONFIG)

    value_type = serializers.SerializerMethodField()

    def get_value_type(self, obj):
        return self.VALUE_TYPES.get(obj.value_type)

    class Meta:
        model = ContactField
        fields = ("key", "label", "value_type")
示例#4
0
class ContactGroupReadSerializer(ReadSerializer):
    status = serializers.SerializerMethodField()
    count = serializers.SerializerMethodField()

    STATUSES = extract_constants(ContactGroup.STATUS_CONFIG)

    def get_status(self, obj):
        return self.STATUSES[obj.status]

    def get_count(self, obj):
        # count may be cached on the object
        return obj.count if hasattr(obj, "count") else obj.get_member_count()

    class Meta:
        model = ContactGroup
        fields = ("uuid", "name", "query", "status", "count")
示例#5
0
class ChannelEventReadSerializer(ReadSerializer):
    TYPES = extract_constants(ChannelEvent.TYPE_CONFIG)

    type = serializers.SerializerMethodField()
    contact = fields.ContactField()
    channel = fields.ChannelField()
    extra = serializers.SerializerMethodField()

    def get_type(self, obj):
        return self.TYPES.get(obj.event_type)

    def get_extra(self, obj):
        return obj.extra

    class Meta:
        model = ChannelEvent
        fields = ("id", "type", "contact", "channel", "extra", "occurred_on",
                  "created_on")
示例#6
0
class CampaignEventWriteSerializer(WriteSerializer):
    UNITS = extract_constants(CampaignEvent.UNIT_CONFIG, reverse=True)

    campaign = fields.CampaignField(required=True)
    offset = serializers.IntegerField(required=True)
    unit = serializers.ChoiceField(required=True, choices=list(UNITS.keys()))
    delivery_hour = serializers.IntegerField(required=True,
                                             min_value=-1,
                                             max_value=23)
    relative_to = fields.ContactFieldField(required=True)
    message = fields.TranslatableField(required=False,
                                       max_length=Msg.MAX_TEXT_LEN)
    flow = fields.FlowField(required=False)
    new_expressions = serializers.BooleanField(required=False, default=False)

    def validate_unit(self, value):
        return self.UNITS[value]

    def validate_campaign(self, value):
        if self.instance and value and self.instance.campaign != value:
            raise serializers.ValidationError(
                "Cannot change campaign for existing events")
        return value

    def validate(self, data):
        message = data.get("message")
        flow = data.get("flow")

        if message and not flow:
            translations, base_language = message
            if not translations[base_language]:
                raise serializers.ValidationError("Message text is required")

        if (message and flow) or (not message and not flow):
            raise serializers.ValidationError(
                "Flow UUID or a message text required.")

        return data

    def save(self):
        """
        Create or update our campaign event
        """
        campaign = self.validated_data.get("campaign")
        offset = self.validated_data.get("offset")
        unit = self.validated_data.get("unit")
        delivery_hour = self.validated_data.get("delivery_hour")
        relative_to = self.validated_data.get("relative_to")
        message = self.validated_data.get("message")
        flow = self.validated_data.get("flow")

        if self.instance:

            # we dont update, we only create
            self.instance = self.instance.deactivate_and_copy()

            # we are being set to a flow
            if flow:
                self.instance.flow = flow
                self.instance.event_type = CampaignEvent.TYPE_FLOW
                self.instance.message = None

            # we are being set to a message
            else:
                translations, base_language = message

                if not self.validated_data["new_expressions"]:
                    translations = migrate_translations(translations)

                self.instance.message = translations

                # if we aren't currently a message event, we need to create our hidden message flow
                if self.instance.event_type != CampaignEvent.TYPE_MESSAGE:
                    self.instance.flow = Flow.create_single_message(
                        self.context["org"], self.context["user"],
                        translations, base_language)
                    self.instance.event_type = CampaignEvent.TYPE_MESSAGE

                # otherwise, we can just update that flow
                else:
                    # set our single message on our flow
                    self.instance.flow.update_single_message_flow(
                        self.context["user"], translations, base_language)

            # update our other attributes
            self.instance.offset = offset
            self.instance.unit = unit
            self.instance.delivery_hour = delivery_hour
            self.instance.relative_to = relative_to
            self.instance.save()
            self.instance.update_flow_name()

        else:
            if flow:
                self.instance = CampaignEvent.create_flow_event(
                    self.context["org"], self.context["user"], campaign,
                    relative_to, offset, unit, flow, delivery_hour)
            else:
                translations, base_language = message

                if not self.validated_data["new_expressions"]:
                    translations = migrate_translations(translations)

                self.instance = CampaignEvent.create_message_event(
                    self.context["org"],
                    self.context["user"],
                    campaign,
                    relative_to,
                    offset,
                    unit,
                    translations,
                    delivery_hour,
                    base_language,
                )

            self.instance.update_flow_name()

        # create our event fires for this event in the background
        EventFire.create_eventfires_for_event(self.instance)

        return self.instance