class ScheduleTriggerForm(BaseScheduleForm, forms.ModelForm): repeat_period = forms.ChoiceField(choices=Schedule.REPEAT_CHOICES, label="Repeat", required=False) repeat_days_of_week = forms.CharField(required=False) start = forms.ChoiceField(choices=(("stop", "Stop Schedule"), ("later", "Schedule for later"))) start_datetime_value = forms.IntegerField(required=False) flow = forms.ModelChoiceField( Flow.objects.filter(pk__lt=0), label=_("Flow"), required=True, widget=SelectWidget(attrs={"placeholder": _("Select a flow")}), empty_label=None, ) omnibox = JSONField( label=_("Contacts"), required=True, help_text=_("The groups and contacts the flow will be broadcast to"), widget=OmniboxChoice( attrs={"placeholder": _("Recipients, enter contacts or groups"), "groups": True, "contacts": True} ), ) def __init__(self, user, *args, **kwargs): super().__init__(*args, **kwargs) self.user = user flows = Flow.get_triggerable_flows(user.get_org()) self.fields["flow"].queryset = flows def clean_omnibox(self): return omnibox_deserialize(self.user.get_org(), self.cleaned_data["omnibox"]) class Meta: model = Trigger fields = ("flow", "omnibox", "repeat_period", "repeat_days_of_week", "start", "start_datetime_value")
class BroadcastForm(forms.ModelForm): message = forms.CharField( required=True, widget=CompletionTextarea(attrs={"placeholder": _("Hi @contact.name!")}), max_length=Broadcast.MAX_TEXT_LEN, ) omnibox = JSONField( label=_("Recipients"), required=False, help_text=_("The contacts to send the message to"), widget=OmniboxChoice( attrs={ "placeholder": _("Recipients, enter contacts or groups"), "groups": True, "contacts": True, "urns": True, } ), ) def is_valid(self): valid = super().is_valid() if valid: if "omnibox" not in self.data or len(self.data["omnibox"].strip()) == 0: # pragma: needs cover self.errors["__all__"] = self.error_class([_("At least one recipient is required")]) return False return valid class Meta: model = Broadcast fields = "__all__"
class Form(BaseTriggerForm, ScheduleFormMixin): contacts = JSONField( label=_("Contacts To Include"), required=False, help_text=_("Additional specific contacts that will be started in the flow."), widget=OmniboxChoice(attrs={"placeholder": _("Optional: Search for contacts"), "contacts": True}), ) def __init__(self, user, *args, **kwargs): super().__init__(user, Trigger.TYPE_SCHEDULE, *args, **kwargs) self.set_user(user) def clean_contacts(self): return omnibox_deserialize(self.org, self.cleaned_data["contacts"])["contacts"] def clean(self): cleaned_data = super().clean() # schedule triggers must use specific groups or contacts if not cleaned_data["groups"] and not cleaned_data["contacts"]: raise forms.ValidationError(_("Must provide at least one group or contact to include.")) ScheduleFormMixin.clean(self) return cleaned_data class Meta(BaseTriggerForm.Meta): fields = ScheduleFormMixin.Meta.fields + ("flow", "groups", "contacts", "exclude_groups") help_texts = { "groups": _("The groups that will be started in the flow."), "exclude_groups": _("Any contacts in these groups will not be started in the flow."), }
class SendMessageForm(Form): omnibox = JSONField( label=_("Recipients"), required=False, help_text=_("The contacts to send the message to"), widget=OmniboxChoice( attrs={ "placeholder": _("Recipients, enter contacts or groups"), "groups": True, "contacts": True, "urns": True, }), ) text = forms.CharField(widget=CompletionTextarea( attrs={ "placeholder": _("Hi @contact.name!"), "widget_only": True })) schedule = forms.BooleanField( widget=CheckboxWidget(attrs={"widget_only": True}), required=False, label=_("Schedule for later"), help_text=None, ) step_node = forms.CharField(widget=forms.HiddenInput, max_length=36, required=False) def __init__(self, user, *args, **kwargs): super().__init__(*args, **kwargs) self.user = user def is_valid(self): valid = super().is_valid() if valid: if ("step_node" not in self.data or not self.data["step_node"] ) and ("omnibox" not in self.data or len(self.data["omnibox"].strip()) == 0): self.errors["__all__"] = self.error_class( [str(_("At least one recipient is required"))]) return False return valid def clean(self): cleaned = super().clean() org = self.user.get_org() if org.is_suspended: raise ValidationError( _("Sorry, your account is currently suspended. To enable sending messages, please contact support." )) if org.is_flagged: raise ValidationError( _("Sorry, your account is currently flagged. To enable sending messages, please contact support." )) return cleaned
class ScheduleTriggerForm(BaseScheduleForm, forms.ModelForm): repeat_period = forms.ChoiceField(choices=Schedule.REPEAT_CHOICES, label="Repeat", required=False, widget=SelectWidget()) repeat_days_of_week = forms.MultipleChoiceField( choices=Schedule.REPEAT_DAYS_CHOICES, label="Repeat Days", required=False, widget=SelectMultipleWidget( attrs=({ "placeholder": _("Select days to repeat on") })), ) start_datetime = forms.DateTimeField( required=False, label=_("Start Time"), widget=InputWidget( attrs={ "datetimepicker": True, "placeholder": "Select a time to start the flow" }), ) flow = forms.ModelChoiceField( Flow.objects.filter(pk__lt=0), label=_("Flow"), required=True, widget=SelectWidget(attrs={ "placeholder": _("Select a flow"), "searchable": True }), empty_label=None, ) omnibox = JSONField( label=_("Contacts"), required=True, help_text=_("The groups and contacts the flow will be broadcast to"), widget=OmniboxChoice( attrs={ "placeholder": _("Recipients, enter contacts or groups"), "groups": True, "contacts": True }), ) def __init__(self, user, *args, **kwargs): super().__init__(*args, **kwargs) self.user = user org = user.get_org() flows = Flow.get_triggerable_flows(org) self.fields["start_datetime"].help_text = _("%s Time Zone" % org.timezone) self.fields["flow"].queryset = flows def clean_repeat_days_of_week(self): return "".join(self.cleaned_data["repeat_days_of_week"]) def clean_omnibox(self): return omnibox_deserialize(self.user.get_org(), self.cleaned_data["omnibox"]) class Meta: model = Trigger fields = ("flow", "omnibox", "repeat_period", "repeat_days_of_week", "start_datetime")