Skip to content

Utils

hypha.apply.funds.models.utils

REVIEW_GROUPS module-attribute

LIMIT_TO_STAFF module-attribute

LIMIT_TO_STAFF = {'groups__name': STAFF_GROUP_NAME, 'is_active': True}

LIMIT_TO_REVIEWERS module-attribute

LIMIT_TO_REVIEWERS = {'groups__name': REVIEWER_GROUP_NAME, 'is_active': True}

LIMIT_TO_PARTNERS module-attribute

LIMIT_TO_PARTNERS = {'groups__name': PARTNER_GROUP_NAME, 'is_active': True}

LIMIT_TO_COMMUNITY_REVIEWERS module-attribute

LIMIT_TO_COMMUNITY_REVIEWERS = {'groups__name': COMMUNITY_REVIEWER_GROUP_NAME, 'is_active': True}

LIMIT_TO_REVIEWER_GROUPS module-attribute

LIMIT_TO_REVIEWER_GROUPS = {'groups__name__in': REVIEW_GROUPS, 'is_active': True}

WorkflowHelpers

Bases: Model

Defines the common methods and fields for working with Workflows within Django models

WORKFLOW_CHOICES class-attribute instance-attribute

WORKFLOW_CHOICES = {name: _v1efor (name, workflow) in items()}

workflow_name class-attribute instance-attribute

workflow_name = CharField(choices=items(), max_length=100, default='single', verbose_name=gettext_lazy('Workflow'))

workflow property

workflow

Meta

abstract class-attribute instance-attribute
abstract = True

SubmittableStreamForm

Bases: AbstractStreamForm

Controls how stream forms are submitted. Any Page allowing submissions should inherit from here.

submission_form_class class-attribute instance-attribute

submission_form_class = PageStreamBaseForm

wagtail_reference_index_ignore class-attribute instance-attribute

wagtail_reference_index_ignore = True

Meta

abstract class-attribute instance-attribute
abstract = True

from_db classmethod

from_db(db, field_names, values)
Source code in hypha/apply/stream_forms/models.py
@classmethod
def from_db(cls, db, field_names, values):
    instance = super().from_db(db, field_names, values)
    if "form_data" in field_names:
        instance.form_data = cls.deserialize_form_data(
            instance, instance.form_data, instance.form_fields
        )
    return instance

deserialize_form_data classmethod

deserialize_form_data(instance, form_data, form_fields)
Source code in hypha/apply/stream_forms/models.py
@classmethod
def deserialize_form_data(cls, instance, form_data, form_fields):
    data = form_data.copy()
    # PERFORMANCE NOTE:
    # Do not attempt to iterate over form_fields - that will fully instantiate the form_fields
    # including any sub queries that they do
    for _i, field_data in enumerate(form_fields.raw_data):
        block = form_fields.stream_block.child_blocks[field_data["type"]]
        field_id = field_data.get("id")
        try:
            value = data[field_id]
        except KeyError:
            pass
        else:
            data[field_id] = block.decode(value)
    return data

get_defined_fields

get_defined_fields()
Source code in hypha/apply/stream_forms/models.py
def get_defined_fields(self):
    return self.form_fields

get_form_fields

get_form_fields(draft=False, form_data=None, user=None)
Source code in hypha/apply/stream_forms/models.py
def get_form_fields(self, draft=False, form_data=None, user=None):
    if form_data is None:
        form_data = {}

    form_fields = OrderedDict()
    field_blocks = self.get_defined_fields()
    group_counter = 1
    is_in_group = False

    # If true option 1 is selected
    grouped_fields_visible = False
    for struct_child in field_blocks:
        block = struct_child.block
        struct_value = struct_child.value
        if isinstance(block, FormFieldBlock):
            field_from_block = block.get_field(struct_value)
            disabled_help_text = _(
                "You are logged in so this information is fetched from your user account."
            )
            if isinstance(block, FullNameBlock) and user and user.is_authenticated:
                if user.full_name:
                    field_from_block.disabled = True
                    field_from_block.initial = user.full_name
                    field_from_block.help_text = disabled_help_text
                else:
                    field_from_block.help_text = _(
                        "You are logged in but your user account does not have a "
                        "full name. We'll update your user account with the name you provide here."
                    )
            if isinstance(block, EmailBlock) and user and user.is_authenticated:
                field_from_block.disabled = True
                field_from_block.initial = user.email
                field_from_block.help_text = disabled_help_text
            if draft and not issubclass(
                block.__class__, ApplicationMustIncludeFieldBlock
            ):
                field_from_block.required = False
            field_from_block.help_link = struct_value.get("help_link")
            field_from_block.group_number = group_counter if is_in_group else 1
            if isinstance(block, GroupToggleBlock) and not is_in_group:
                field_from_block.group_number = 1
                field_from_block.grouper_for = group_counter + 1
                group_counter += 1
                is_in_group = True
                grouped_fields_visible = (
                    form_data.get(struct_child.id) == field_from_block.choices[0][0]
                )
            if isinstance(block, TextFieldBlock):
                field_from_block.word_limit = struct_value.get("word_limit")
            if isinstance(block, MultiInputCharFieldBlock):
                number_of_inputs = struct_value.get("number_of_inputs")
                for index in range(number_of_inputs):
                    form_fields[struct_child.id + "_" + str(index)] = (
                        field_from_block
                    )
                    field_from_block.multi_input_id = struct_child.id
                    field_from_block.add_button_text = struct_value.get(
                        "add_button_text"
                    )
                    if (
                        index == number_of_inputs - 1
                    ):  # Add button after last input field
                        field_from_block.multi_input_add_button = True
                        # Index for field until which fields will be visible to applicant.
                        # Initially only the first field with id UUID_0 will be visible.
                        field_from_block.visibility_index = 0
                        field_from_block.max_index = index
                    if index != 0:
                        field_from_block.multi_input_field = True
                        field_from_block.required = False
                        field_from_block.initial = None
                    field_from_block = copy.copy(field_from_block)
            else:
                if is_in_group and not isinstance(block, GroupToggleBlock):
                    field_from_block.required_when_visible = (
                        field_from_block.required
                    )
                    field_from_block.required = (
                        field_from_block.required & grouped_fields_visible
                    )
                    field_from_block.visible = grouped_fields_visible
                form_fields[struct_child.id] = field_from_block
        elif isinstance(block, GroupToggleEndBlock):
            # Group toggle end block is used only to group fields and not used in actual form.
            # Todo: Use streamblock to create nested form field blocks, a more elegant method to group form fields.
            is_in_group = False
        else:
            field_wrapper = BlockFieldWrapper(struct_child)
            field_wrapper.group_number = group_counter if is_in_group else 1
            form_fields[struct_child.id] = field_wrapper

    return form_fields

get_form_class

get_form_class(draft=False, form_data=None, user=None)
Source code in hypha/apply/stream_forms/models.py
def get_form_class(self, draft=False, form_data=None, user=None):
    return type(
        "WagtailStreamForm",
        (self.submission_form_class,),
        self.get_form_fields(draft, form_data, user),
    )

get_submission_class

get_submission_class()
Source code in hypha/apply/funds/models/utils.py
def get_submission_class(self):
    return self.submission_class

process_form_submission

process_form_submission(form, draft=False)
Source code in hypha/apply/funds/models/utils.py
def process_form_submission(self, form, draft=False):
    if not form.user.is_authenticated:
        form.user = None
    if draft:
        return self.get_submission_class().objects.create(
            form_data=form.cleaned_data,
            form_fields=self.get_defined_fields(),
            **self.get_submit_meta_data(user=form.user),
            status=DRAFT_STATE,
        )
    else:
        return self.get_submission_class().objects.create(
            form_data=form.cleaned_data,
            form_fields=self.get_defined_fields(),
            **self.get_submit_meta_data(user=form.user),
        )

get_submit_meta_data

get_submit_meta_data(**kwargs)
Source code in hypha/apply/funds/models/utils.py
def get_submit_meta_data(self, **kwargs):
    return kwargs

WorkflowStreamForm

Bases: WorkflowHelpers, AbstractStreamForm

Defines the common methods and fields for working with Workflows within Wagtail pages

submission_form_class class-attribute instance-attribute

submission_form_class = PageStreamBaseForm

WORKFLOW_CHOICES class-attribute instance-attribute

WORKFLOW_CHOICES = {name: _lo8for (name, workflow) in items()}

workflow_name class-attribute instance-attribute

workflow_name = CharField(choices=items(), max_length=100, default='single', verbose_name=gettext_lazy('Workflow'))

workflow property

workflow

wagtail_reference_index_ignore class-attribute instance-attribute

wagtail_reference_index_ignore = True

content_panels class-attribute instance-attribute

content_panels = content_panels + [FieldPanel('workflow_name'), InlinePanel('forms', label=gettext_lazy('Application forms')), InlinePanel('review_forms', label=gettext_lazy('Internal Review Forms')), InlinePanel('external_review_forms', label=gettext_lazy('External Review Forms'), max_num=1, help_text='Add a form to be used by external reviewers.'), InlinePanel('determination_forms', label=gettext_lazy('Determination Forms'))]

Meta

abstract class-attribute instance-attribute
abstract = True

from_db classmethod

from_db(db, field_names, values)
Source code in hypha/apply/stream_forms/models.py
@classmethod
def from_db(cls, db, field_names, values):
    instance = super().from_db(db, field_names, values)
    if "form_data" in field_names:
        instance.form_data = cls.deserialize_form_data(
            instance, instance.form_data, instance.form_fields
        )
    return instance

deserialize_form_data classmethod

deserialize_form_data(instance, form_data, form_fields)
Source code in hypha/apply/stream_forms/models.py
@classmethod
def deserialize_form_data(cls, instance, form_data, form_fields):
    data = form_data.copy()
    # PERFORMANCE NOTE:
    # Do not attempt to iterate over form_fields - that will fully instantiate the form_fields
    # including any sub queries that they do
    for _i, field_data in enumerate(form_fields.raw_data):
        block = form_fields.stream_block.child_blocks[field_data["type"]]
        field_id = field_data.get("id")
        try:
            value = data[field_id]
        except KeyError:
            pass
        else:
            data[field_id] = block.decode(value)
    return data

get_form_fields

get_form_fields(draft=False, form_data=None, user=None)
Source code in hypha/apply/stream_forms/models.py
def get_form_fields(self, draft=False, form_data=None, user=None):
    if form_data is None:
        form_data = {}

    form_fields = OrderedDict()
    field_blocks = self.get_defined_fields()
    group_counter = 1
    is_in_group = False

    # If true option 1 is selected
    grouped_fields_visible = False
    for struct_child in field_blocks:
        block = struct_child.block
        struct_value = struct_child.value
        if isinstance(block, FormFieldBlock):
            field_from_block = block.get_field(struct_value)
            disabled_help_text = _(
                "You are logged in so this information is fetched from your user account."
            )
            if isinstance(block, FullNameBlock) and user and user.is_authenticated:
                if user.full_name:
                    field_from_block.disabled = True
                    field_from_block.initial = user.full_name
                    field_from_block.help_text = disabled_help_text
                else:
                    field_from_block.help_text = _(
                        "You are logged in but your user account does not have a "
                        "full name. We'll update your user account with the name you provide here."
                    )
            if isinstance(block, EmailBlock) and user and user.is_authenticated:
                field_from_block.disabled = True
                field_from_block.initial = user.email
                field_from_block.help_text = disabled_help_text
            if draft and not issubclass(
                block.__class__, ApplicationMustIncludeFieldBlock
            ):
                field_from_block.required = False
            field_from_block.help_link = struct_value.get("help_link")
            field_from_block.group_number = group_counter if is_in_group else 1
            if isinstance(block, GroupToggleBlock) and not is_in_group:
                field_from_block.group_number = 1
                field_from_block.grouper_for = group_counter + 1
                group_counter += 1
                is_in_group = True
                grouped_fields_visible = (
                    form_data.get(struct_child.id) == field_from_block.choices[0][0]
                )
            if isinstance(block, TextFieldBlock):
                field_from_block.word_limit = struct_value.get("word_limit")
            if isinstance(block, MultiInputCharFieldBlock):
                number_of_inputs = struct_value.get("number_of_inputs")
                for index in range(number_of_inputs):
                    form_fields[struct_child.id + "_" + str(index)] = (
                        field_from_block
                    )
                    field_from_block.multi_input_id = struct_child.id
                    field_from_block.add_button_text = struct_value.get(
                        "add_button_text"
                    )
                    if (
                        index == number_of_inputs - 1
                    ):  # Add button after last input field
                        field_from_block.multi_input_add_button = True
                        # Index for field until which fields will be visible to applicant.
                        # Initially only the first field with id UUID_0 will be visible.
                        field_from_block.visibility_index = 0
                        field_from_block.max_index = index
                    if index != 0:
                        field_from_block.multi_input_field = True
                        field_from_block.required = False
                        field_from_block.initial = None
                    field_from_block = copy.copy(field_from_block)
            else:
                if is_in_group and not isinstance(block, GroupToggleBlock):
                    field_from_block.required_when_visible = (
                        field_from_block.required
                    )
                    field_from_block.required = (
                        field_from_block.required & grouped_fields_visible
                    )
                    field_from_block.visible = grouped_fields_visible
                form_fields[struct_child.id] = field_from_block
        elif isinstance(block, GroupToggleEndBlock):
            # Group toggle end block is used only to group fields and not used in actual form.
            # Todo: Use streamblock to create nested form field blocks, a more elegant method to group form fields.
            is_in_group = False
        else:
            field_wrapper = BlockFieldWrapper(struct_child)
            field_wrapper.group_number = group_counter if is_in_group else 1
            form_fields[struct_child.id] = field_wrapper

    return form_fields

get_form_class

get_form_class(draft=False, form_data=None, user=None)
Source code in hypha/apply/stream_forms/models.py
def get_form_class(self, draft=False, form_data=None, user=None):
    return type(
        "WagtailStreamForm",
        (self.submission_form_class,),
        self.get_form_fields(draft, form_data, user),
    )

get_defined_fields

get_defined_fields(stage=None, form_index=0)
Source code in hypha/apply/funds/models/utils.py
def get_defined_fields(self, stage=None, form_index=0):
    if not stage:
        stage_num = 1
    else:
        stage_num = self.workflow.stages.index(stage) + 1
    return self.forms.filter(stage=stage_num)[form_index].fields

render_landing_page

render_landing_page(request, form_submission=None, *args, **kwargs)
Source code in hypha/apply/funds/models/utils.py
def render_landing_page(self, request, form_submission=None, *args, **kwargs):
    # We only reach this page after creation of a new submission
    # Hook in to notify about new applications and add task for draft submissions
    if form_submission.status == DRAFT_STATE:
        messenger(
            MESSAGES.DRAFT_SUBMISSION,
            request=request,
            user=form_submission.user,
            source=form_submission,
        )
        # add a task of draft submission to applicant dashboard
        add_task_to_user(
            code=SUBMISSION_DRAFT,
            user=form_submission.user,
            related_obj=form_submission,
        )
    else:
        messenger(
            MESSAGES.NEW_SUBMISSION,
            request=request,
            user=form_submission.user,
            source=form_submission,
        )

    return redirect("apply:submissions:success", pk=form_submission.id)

EmailForm

Bases: AbstractEmailForm

Defines the behaviour for pages that hold information about emailing applicants

Email Confirmation Panel should be included to allow admins to make changes.

confirmation_text_extra class-attribute instance-attribute

confirmation_text_extra = TextField(blank=True, help_text=gettext_lazy('Additional text for the application confirmation message.'))

email_confirmation_panels class-attribute instance-attribute

email_confirmation_panels = [MultiFieldPanel([FieldRowPanel([FieldPanel('from_address', classname='col6'), FieldPanel('to_address', classname='col6')]), FieldPanel('subject'), FieldPanel('confirmation_text_extra')], heading=gettext_lazy('Confirmation email'))]

email_tab class-attribute instance-attribute

email_tab = ObjectList(email_confirmation_panels, heading=gettext_lazy('Confirmation email'))

Meta

abstract class-attribute instance-attribute
abstract = True

send_mail

send_mail(submission)
Source code in hypha/apply/funds/models/utils.py
def send_mail(self, submission):
    # Make sure we don't send emails to users here. Messaging handles that
    pass

admin_url

admin_url(page)
Source code in hypha/apply/funds/models/utils.py
def admin_url(page):
    return reverse("wagtailadmin_pages:edit", args=(page.id,))