Skip to content

Forms

hypha.apply.determinations.forms

User module-attribute

User = get_user_model()

BaseDeterminationForm

BaseDeterminationForm(*args, user, initial, action, edit=False, **kwargs)
Source code in hypha/apply/determinations/forms.py
def __init__(self, *args, user, initial, action, edit=False, **kwargs):
    if "site" in kwargs:
        site = kwargs.pop("site")
        self.form_settings = DeterminationFormSettings.for_site(site)
    try:
        initial.update(outcome=TRANSITION_DETERMINATION[action])
    except KeyError:
        pass
    initial.update(author=user.id)
    super().__init__(*args, initial=initial, **kwargs)

form_settings instance-attribute

form_settings = for_site(site)

data_fields

data_fields()
Source code in hypha/apply/determinations/forms.py
def data_fields(self):
    return []

clean_outcome

clean_outcome()
Source code in hypha/apply/determinations/forms.py
def clean_outcome(self):
    # Enforce outcome as an int
    return int(self.cleaned_data["outcome"])

clean

clean()
Source code in hypha/apply/determinations/forms.py
def clean(self):
    cleaned_data = super().clean()
    cleaned_data["data"] = {
        key: value
        for key, value in cleaned_data.items()
        if key in self.data_fields()
    }
    return cleaned_data

apply_form_settings

apply_form_settings(application_type, fields)
Source code in hypha/apply/determinations/forms.py
def apply_form_settings(self, application_type, fields):
    for field in fields:
        try:
            self.fields[field].label = getattr(
                self.form_settings, f"{application_type}_{field}_label"
            )
        except AttributeError:
            pass
        try:
            self.fields[field].help_text = getattr(
                self.form_settings, f"{application_type}_{field}_help_text"
            )
        except AttributeError:
            pass
    return fields

get_detailed_response classmethod

get_detailed_response(saved_data)
Source code in hypha/apply/determinations/forms.py
@classmethod
def get_detailed_response(cls, saved_data):
    data = {}
    for group, title in cls.titles.items():
        data.setdefault(group, {"title": title, "questions": []})

    for name, field in cls.base_fields.items():
        try:
            value = saved_data[name]
        except KeyError:
            # The field is not stored in the data
            pass
        else:
            data[field.group]["questions"].append((field.label, str(value)))

    return data

BaseNormalDeterminationForm

BaseNormalDeterminationForm(*args, user, initial, action, edit=False, **kwargs)

Bases: BaseDeterminationForm, ModelForm

Source code in hypha/apply/determinations/forms.py
def __init__(self, *args, user, initial, action, edit=False, **kwargs):
    if "site" in kwargs:
        site = kwargs.pop("site")
        self.form_settings = DeterminationFormSettings.for_site(site)
    try:
        initial.update(outcome=TRANSITION_DETERMINATION[action])
    except KeyError:
        pass
    initial.update(author=user.id)
    super().__init__(*args, initial=initial, **kwargs)

form_settings instance-attribute

form_settings = for_site(site)

draft_button_name class-attribute instance-attribute

draft_button_name = 'save_draft'

Meta

model class-attribute instance-attribute
model = Determination
fields class-attribute instance-attribute
fields = ['outcome', 'message', 'submission', 'author', 'data', 'send_notice']
widgets class-attribute instance-attribute
widgets = {'submission': HiddenInput(), 'author': HiddenInput(), 'data': HiddenInput()}
error_messages class-attribute instance-attribute
error_messages = {NON_FIELD_ERRORS: {'unique_together': 'You have already created a determination for this submission'}}

clean_outcome

clean_outcome()
Source code in hypha/apply/determinations/forms.py
def clean_outcome(self):
    # Enforce outcome as an int
    return int(self.cleaned_data["outcome"])

clean

clean()
Source code in hypha/apply/determinations/forms.py
def clean(self):
    cleaned_data = super().clean()
    cleaned_data["data"] = {
        key: value
        for key, value in cleaned_data.items()
        if key in self.data_fields()
    }
    return cleaned_data

apply_form_settings

apply_form_settings(application_type, fields)
Source code in hypha/apply/determinations/forms.py
def apply_form_settings(self, application_type, fields):
    for field in fields:
        try:
            self.fields[field].label = getattr(
                self.form_settings, f"{application_type}_{field}_label"
            )
        except AttributeError:
            pass
        try:
            self.fields[field].help_text = getattr(
                self.form_settings, f"{application_type}_{field}_help_text"
            )
        except AttributeError:
            pass
    return fields

get_detailed_response classmethod

get_detailed_response(saved_data)
Source code in hypha/apply/determinations/forms.py
@classmethod
def get_detailed_response(cls, saved_data):
    data = {}
    for group, title in cls.titles.items():
        data.setdefault(group, {"title": title, "questions": []})

    for name, field in cls.base_fields.items():
        try:
            value = saved_data[name]
        except KeyError:
            # The field is not stored in the data
            pass
        else:
            data[field.group]["questions"].append((field.label, str(value)))

    return data

data_fields

data_fields()
Source code in hypha/apply/determinations/forms.py
def data_fields(self):
    return [field for field in self.fields if field not in self._meta.fields]

outcome_choices_for_phase

outcome_choices_for_phase(submission, user)

Outcome choices correspond to Phase transitions. We need to filter out non-matching choices. i.e. a transition to In Review is not a determination, while Needs more info or Rejected are.

Source code in hypha/apply/determinations/forms.py
def outcome_choices_for_phase(self, submission, user):
    """
    Outcome choices correspond to Phase transitions.
    We need to filter out non-matching choices.
    i.e. a transition to In Review is not a determination, while Needs more info or Rejected are.
    """
    available_choices = [("", _("-- No determination selected -- "))]
    choices = dict(self.fields["outcome"].choices)

    for transition_name in determination_actions(user, submission):
        try:
            determination_type = TRANSITION_DETERMINATION[transition_name]
        except KeyError:
            pass
        else:
            available_choices.append(
                (determination_type, choices[determination_type])
            )
    return available_choices

save

save(commit=True)
Source code in hypha/apply/determinations/forms.py
def save(self, commit=True):
    self.instance.is_draft = self.draft_button_name in self.data

    return super().save(commit)

BaseBatchDeterminationForm

BaseBatchDeterminationForm(*args, user, initial, action, edit=False, **kwargs)

Bases: BaseDeterminationForm, Form

Source code in hypha/apply/determinations/forms.py
def __init__(self, *args, user, initial, action, edit=False, **kwargs):
    if "site" in kwargs:
        site = kwargs.pop("site")
        self.form_settings = DeterminationFormSettings.for_site(site)
    try:
        initial.update(outcome=TRANSITION_DETERMINATION[action])
    except KeyError:
        pass
    initial.update(author=user.id)
    super().__init__(*args, initial=initial, **kwargs)

form_settings instance-attribute

form_settings = for_site(site)

submissions class-attribute instance-attribute

submissions = ModelMultipleChoiceField(queryset=all(), widget=hidden_widget)

author class-attribute instance-attribute

author = ModelChoiceField(queryset=active(), widget=hidden_widget, required=True)

clean_outcome

clean_outcome()
Source code in hypha/apply/determinations/forms.py
def clean_outcome(self):
    # Enforce outcome as an int
    return int(self.cleaned_data["outcome"])

clean

clean()
Source code in hypha/apply/determinations/forms.py
def clean(self):
    cleaned_data = super().clean()
    cleaned_data["data"] = {
        key: value
        for key, value in cleaned_data.items()
        if key in self.data_fields()
    }
    return cleaned_data

apply_form_settings

apply_form_settings(application_type, fields)
Source code in hypha/apply/determinations/forms.py
def apply_form_settings(self, application_type, fields):
    for field in fields:
        try:
            self.fields[field].label = getattr(
                self.form_settings, f"{application_type}_{field}_label"
            )
        except AttributeError:
            pass
        try:
            self.fields[field].help_text = getattr(
                self.form_settings, f"{application_type}_{field}_help_text"
            )
        except AttributeError:
            pass
    return fields

get_detailed_response classmethod

get_detailed_response(saved_data)
Source code in hypha/apply/determinations/forms.py
@classmethod
def get_detailed_response(cls, saved_data):
    data = {}
    for group, title in cls.titles.items():
        data.setdefault(group, {"title": title, "questions": []})

    for name, field in cls.base_fields.items():
        try:
            value = saved_data[name]
        except KeyError:
            # The field is not stored in the data
            pass
        else:
            data[field.group]["questions"].append((field.label, str(value)))

    return data

data_fields

data_fields()
Source code in hypha/apply/determinations/forms.py
def data_fields(self):
    return [
        field
        for field in self.fields
        if field
        not in ["submissions", "outcome", "author", "send_notice", "message"]
    ]

save

save()
Source code in hypha/apply/determinations/forms.py
def save(self):
    determinations = Determination.objects.bulk_create(self.instances)
    self.instances = determinations
    return determinations

BaseConceptDeterminationForm

Bases: Form

titles class-attribute instance-attribute

titles = {1: 'Feedback'}

outcome class-attribute instance-attribute

outcome = ChoiceField(choices=DETERMINATION_CHOICES, label=gettext_lazy('Determination'), help_text='Do you recommend requesting a proposal based on this concept note?')

message class-attribute instance-attribute

message = RichTextField(label=gettext_lazy('Determination message'), help_text='This text will be e-mailed to the applicant. Ones when text is first added and then every time the text is changed.')

principles class-attribute instance-attribute

principles = RichTextField(label=gettext_lazy('Goals and principles'), help_text='Does the project contribute and/or have relevance to OTF goals and principles?Are the goals and objectives of the project clear? Is it a technology research, development, or deployment project? Can project’s effort be explained to external audiences and non-technical people? What problem are they trying to solve and is the solution strategical or tactical? Is the project strategically or tactically important to OTF’s goals, principles and rationale and other OTF efforts? Is it clear how? What tools, if any, currently exist to solve this problem? How is this project different? Does the effort have any overlap with existing OTF and/or USG supported projects? Is the overlap complementary or duplicative? If complementary, can it be explained clearly? I.e. geographic focus, technology, organization profile, etc. What are the liabilities and risks of taking on this project? I.e. political personalities, financial concerns, technical controversial, etc. Is the organization or its members known within any relevant communities? If yes, what is their reputation and why? What is the entity’s motivation and principles? What are the entity member(s) motivations and principles? Where is the organization physically and legally based? If the organization is distributed, where is the main point of contact? Does the organization have any conflicts of interest with RFA, OTF, the Advisory Council, or other RFA-OTF projects? Is the project team an organization, community or an individual?')

technical class-attribute instance-attribute

technical = RichTextField(label=gettext_lazy('Technical merit'), help_text='Does the project clearly articulate the technical problem, solution, and approach? Is the problem clearly justifiable? Does the project clearly articulate the technological objectives? Is it an open or closed development project? I.e. Open source like Android or open source like Firefox OS or closed like iOS. Does a similar technical solution already exist? If so, what are the differentiating factors? Is the effort to sustain an existing technical approach? If so, are these considered successful? Is the effort a new technical approach or improvement to an existing solution? If so, how? Is the effort a completely new technical approach fostering new solutions in the field? Does the project’s technical approach solve the problem? What are the limitations of the project’s technical approach and solution? What are the unintended or illicit uses and consequences of this technology? Has the project identified and/or developed any safeguards for these consequences?')

sustainable class-attribute instance-attribute

sustainable = RichTextField(label=gettext_lazy('Reasonable, realistic and sustainable'), help_text='Is the requested amount reasonable, realistic, and justified? If OTF doesn’t support the project, is it likely to be realized? Does the project provide a detailed and realistic description of effort and schedule? I.e. is the project capable of creating a work plan including objectives, activities, and deliverable(s)? Does the project have a clear support model? Is there a known sustainability plan for the future? What in-kind support or other revenue streams is the project receiving? I.e. volunteer developers, service or product sales. Is the project receiving any financial support from the USG? Is this information disclosed? Is the project receiving any other financial support? Is this information disclosed? Are existing supporters approachable? Are they likely aware and/or comfortable with the Intellectual property language within USG contracts?')

comments class-attribute instance-attribute

comments = RichTextField(label=gettext_lazy('Other comments'), help_text='')

BaseProposalDeterminationForm

Bases: Form

titles class-attribute instance-attribute

titles = {1: 'A. Determination', 2: 'B. General thoughts', 3: 'C. Specific aspects', 4: 'D. Rationale and appropriateness consideration', 5: 'E. General recommendation'}

outcome class-attribute instance-attribute

outcome = ChoiceField(choices=DETERMINATION_CHOICES, label=gettext_lazy('Determination'), help_text='Do you recommend requesting a proposal based on this concept note?')

message class-attribute instance-attribute

message = RichTextField(label=gettext_lazy('Determination message'), help_text='This text will be e-mailed to the applicant. Ones when text is first added and then every time the text is changed.')

liked class-attribute instance-attribute

liked = RichTextField(label=gettext_lazy('Positive aspects'), help_text='Any general or specific aspects that got you really excited or that you like about this proposal.')

concerns class-attribute instance-attribute

concerns = RichTextField(label=gettext_lazy('Concerns'), help_text='Any general or specific aspects that concern you or leave you feeling uneasy about this proposal.')

red_flags class-attribute instance-attribute

red_flags = RichTextField(label=gettext_lazy('Items that must be addressed'), help_text='Anything you think should be flagged for our attention.')

overview class-attribute instance-attribute

overview = RichTextField(label=gettext_lazy('Project overview questions and comments'))

objectives class-attribute instance-attribute

objectives = RichTextField(label=gettext_lazy('Objectives questions and comments'))

strategy class-attribute instance-attribute

strategy = RichTextField(label=gettext_lazy('Methods and strategy questions and comments'))

technical class-attribute instance-attribute

technical = RichTextField(label=gettext_lazy('Technical feasibility questions and comments'))

alternative class-attribute instance-attribute

alternative = RichTextField(label=gettext_lazy('Alternative analysis - "red teaming" questions and comments'))

usability class-attribute instance-attribute

usability = RichTextField(label=gettext_lazy('Usability questions and comments'))

sustainability class-attribute instance-attribute

sustainability = RichTextField(label=gettext_lazy('Sustainability questions and comments'))

collaboration class-attribute instance-attribute

collaboration = RichTextField(label=gettext_lazy('Collaboration questions and comments'))

realism class-attribute instance-attribute

realism = RichTextField(label=gettext_lazy('Cost realism questions and comments'))

qualifications class-attribute instance-attribute

qualifications = RichTextField(label=gettext_lazy('Qualifications questions and comments'))

evaluation class-attribute instance-attribute

evaluation = RichTextField(label=gettext_lazy('Evaluation questions and comments'))

rationale class-attribute instance-attribute

rationale = RichTextField(label=gettext_lazy('Rationale and appropriateness questions and comments'))

ConceptDeterminationForm

ConceptDeterminationForm(*args, submission, user, edit=False, initial=None, instance=None, **kwargs)

Bases: BaseConceptDeterminationForm, BaseNormalDeterminationForm

Source code in hypha/apply/determinations/forms.py
def __init__(
    self, *args, submission, user, edit=False, initial=None, instance=None, **kwargs
):
    initial = initial or {}
    initial.update(submission=submission.id)

    if instance:
        for key, value in instance.data.items():
            if key not in self._meta.fields:
                initial[key] = value

    super(BaseNormalDeterminationForm, self).__init__(
        *args, initial=initial, user=user, instance=instance, edit=edit, **kwargs
    )

    # convert a python dict to orderedDict, to use move_to_end method
    self.fields = OrderedDict(self.fields)

    for field in self._meta.widgets:
        self.fields[field].disabled = True

    self.fields["outcome"].choices = self.outcome_choices_for_phase(
        submission, user
    )

    if self.draft_button_name in self.data:
        for field in self.fields.values():
            field.required = False

    self.fields = self.apply_form_settings("concept", self.fields)
    self.fields.move_to_end("send_notice")

    action = kwargs.get("action")
    stages_num = len(submission.workflow.stages)

    if stages_num > 1:
        second_stage_forms = submission.get_from_parent("forms").filter(stage=2)
        if second_stage_forms.count() > 1:
            proposal_form_choices = [
                (index, form.form.name)
                for index, form in enumerate(second_stage_forms)
            ]
            proposal_form_choices.insert(
                0, ("", _("-- No proposal form selected -- "))
            )
            proposal_form_help_text = _(
                "Select the proposal form only for determination approval"
            )
            if action == "invited_to_proposal":
                proposal_form_help_text = _(
                    "Select the proposal form to use for proposal stage."
                )
            self.fields["proposal_form"] = forms.ChoiceField(
                label=_("Proposal Form"),
                choices=proposal_form_choices,
                help_text=proposal_form_help_text,
                required=True if action == "invited_to_proposal" else False,
                disabled=False if action == "invited_to_proposal" else True,
            )
            self.fields["proposal_form"].group = 1
            self.fields.move_to_end("proposal_form", last=False)

    if edit:
        self.fields.pop("outcome")
        self.draft_button_name = None

form_settings instance-attribute

form_settings = for_site(site)

titles class-attribute instance-attribute

titles = {1: 'Feedback'}

outcome class-attribute instance-attribute

outcome = ChoiceField(choices=DETERMINATION_CHOICES, label=gettext_lazy('Determination'), help_text='Do you recommend requesting a proposal based on this concept note?')

message class-attribute instance-attribute

message = RichTextField(label=gettext_lazy('Determination message'), help_text='This text will be e-mailed to the applicant. Ones when text is first added and then every time the text is changed.')

principles class-attribute instance-attribute

principles = RichTextField(label=gettext_lazy('Goals and principles'), help_text='Does the project contribute and/or have relevance to OTF goals and principles?Are the goals and objectives of the project clear? Is it a technology research, development, or deployment project? Can project’s effort be explained to external audiences and non-technical people? What problem are they trying to solve and is the solution strategical or tactical? Is the project strategically or tactically important to OTF’s goals, principles and rationale and other OTF efforts? Is it clear how? What tools, if any, currently exist to solve this problem? How is this project different? Does the effort have any overlap with existing OTF and/or USG supported projects? Is the overlap complementary or duplicative? If complementary, can it be explained clearly? I.e. geographic focus, technology, organization profile, etc. What are the liabilities and risks of taking on this project? I.e. political personalities, financial concerns, technical controversial, etc. Is the organization or its members known within any relevant communities? If yes, what is their reputation and why? What is the entity’s motivation and principles? What are the entity member(s) motivations and principles? Where is the organization physically and legally based? If the organization is distributed, where is the main point of contact? Does the organization have any conflicts of interest with RFA, OTF, the Advisory Council, or other RFA-OTF projects? Is the project team an organization, community or an individual?')

technical class-attribute instance-attribute

technical = RichTextField(label=gettext_lazy('Technical merit'), help_text='Does the project clearly articulate the technical problem, solution, and approach? Is the problem clearly justifiable? Does the project clearly articulate the technological objectives? Is it an open or closed development project? I.e. Open source like Android or open source like Firefox OS or closed like iOS. Does a similar technical solution already exist? If so, what are the differentiating factors? Is the effort to sustain an existing technical approach? If so, are these considered successful? Is the effort a new technical approach or improvement to an existing solution? If so, how? Is the effort a completely new technical approach fostering new solutions in the field? Does the project’s technical approach solve the problem? What are the limitations of the project’s technical approach and solution? What are the unintended or illicit uses and consequences of this technology? Has the project identified and/or developed any safeguards for these consequences?')

sustainable class-attribute instance-attribute

sustainable = RichTextField(label=gettext_lazy('Reasonable, realistic and sustainable'), help_text='Is the requested amount reasonable, realistic, and justified? If OTF doesn’t support the project, is it likely to be realized? Does the project provide a detailed and realistic description of effort and schedule? I.e. is the project capable of creating a work plan including objectives, activities, and deliverable(s)? Does the project have a clear support model? Is there a known sustainability plan for the future? What in-kind support or other revenue streams is the project receiving? I.e. volunteer developers, service or product sales. Is the project receiving any financial support from the USG? Is this information disclosed? Is the project receiving any other financial support? Is this information disclosed? Are existing supporters approachable? Are they likely aware and/or comfortable with the Intellectual property language within USG contracts?')

comments class-attribute instance-attribute

comments = RichTextField(label=gettext_lazy('Other comments'), help_text='')

fields instance-attribute

fields = apply_form_settings('concept', fields)

draft_button_name instance-attribute

draft_button_name = None

Meta

model class-attribute instance-attribute
model = Determination
fields class-attribute instance-attribute
fields = ['outcome', 'message', 'submission', 'author', 'data', 'send_notice']
widgets class-attribute instance-attribute
widgets = {'submission': HiddenInput(), 'author': HiddenInput(), 'data': HiddenInput()}
error_messages class-attribute instance-attribute
error_messages = {NON_FIELD_ERRORS: {'unique_together': 'You have already created a determination for this submission'}}

data_fields

data_fields()
Source code in hypha/apply/determinations/forms.py
def data_fields(self):
    return [field for field in self.fields if field not in self._meta.fields]

clean_outcome

clean_outcome()
Source code in hypha/apply/determinations/forms.py
def clean_outcome(self):
    # Enforce outcome as an int
    return int(self.cleaned_data["outcome"])

clean

clean()
Source code in hypha/apply/determinations/forms.py
def clean(self):
    cleaned_data = super().clean()
    cleaned_data["data"] = {
        key: value
        for key, value in cleaned_data.items()
        if key in self.data_fields()
    }
    return cleaned_data

apply_form_settings

apply_form_settings(application_type, fields)
Source code in hypha/apply/determinations/forms.py
def apply_form_settings(self, application_type, fields):
    for field in fields:
        try:
            self.fields[field].label = getattr(
                self.form_settings, f"{application_type}_{field}_label"
            )
        except AttributeError:
            pass
        try:
            self.fields[field].help_text = getattr(
                self.form_settings, f"{application_type}_{field}_help_text"
            )
        except AttributeError:
            pass
    return fields

get_detailed_response classmethod

get_detailed_response(saved_data)
Source code in hypha/apply/determinations/forms.py
@classmethod
def get_detailed_response(cls, saved_data):
    data = {}
    for group, title in cls.titles.items():
        data.setdefault(group, {"title": title, "questions": []})

    for name, field in cls.base_fields.items():
        try:
            value = saved_data[name]
        except KeyError:
            # The field is not stored in the data
            pass
        else:
            data[field.group]["questions"].append((field.label, str(value)))

    return data

outcome_choices_for_phase

outcome_choices_for_phase(submission, user)

Outcome choices correspond to Phase transitions. We need to filter out non-matching choices. i.e. a transition to In Review is not a determination, while Needs more info or Rejected are.

Source code in hypha/apply/determinations/forms.py
def outcome_choices_for_phase(self, submission, user):
    """
    Outcome choices correspond to Phase transitions.
    We need to filter out non-matching choices.
    i.e. a transition to In Review is not a determination, while Needs more info or Rejected are.
    """
    available_choices = [("", _("-- No determination selected -- "))]
    choices = dict(self.fields["outcome"].choices)

    for transition_name in determination_actions(user, submission):
        try:
            determination_type = TRANSITION_DETERMINATION[transition_name]
        except KeyError:
            pass
        else:
            available_choices.append(
                (determination_type, choices[determination_type])
            )
    return available_choices

save

save(commit=True)
Source code in hypha/apply/determinations/forms.py
def save(self, commit=True):
    self.instance.is_draft = self.draft_button_name in self.data

    return super().save(commit)

ProposalDeterminationForm

ProposalDeterminationForm(*args, submission, user, edit=False, initial=None, instance=None, **kwargs)

Bases: BaseProposalDeterminationForm, BaseNormalDeterminationForm

Source code in hypha/apply/determinations/forms.py
def __init__(
    self, *args, submission, user, edit=False, initial=None, instance=None, **kwargs
):
    if initial is None:
        initial = {}
    initial.update(submission=submission.id)

    if instance:
        for key, value in instance.data.items():
            if key not in self._meta.fields:
                initial[key] = value

    super(BaseNormalDeterminationForm, self).__init__(
        *args, initial=initial, user=user, instance=instance, edit=edit, **kwargs
    )

    # convert a python dict to orderedDict, to use move_to_end method
    self.fields = OrderedDict(self.fields)

    for field in self._meta.widgets:
        self.fields[field].disabled = True

    self.fields["outcome"].choices = self.outcome_choices_for_phase(
        submission, user
    )
    self.fields.move_to_end("send_notice")

    if self.draft_button_name in self.data:
        for field in self.fields.values():
            field.required = False

    self.fields = self.apply_form_settings("proposal", self.fields)

    if edit:
        self.fields.pop("outcome")
        self.draft_button_name = None

form_settings instance-attribute

form_settings = for_site(site)

titles class-attribute instance-attribute

titles = {1: 'A. Determination', 2: 'B. General thoughts', 3: 'C. Specific aspects', 4: 'D. Rationale and appropriateness consideration', 5: 'E. General recommendation'}

outcome class-attribute instance-attribute

outcome = ChoiceField(choices=DETERMINATION_CHOICES, label=gettext_lazy('Determination'), help_text='Do you recommend requesting a proposal based on this concept note?')

message class-attribute instance-attribute

message = RichTextField(label=gettext_lazy('Determination message'), help_text='This text will be e-mailed to the applicant. Ones when text is first added and then every time the text is changed.')

liked class-attribute instance-attribute

liked = RichTextField(label=gettext_lazy('Positive aspects'), help_text='Any general or specific aspects that got you really excited or that you like about this proposal.')

concerns class-attribute instance-attribute

concerns = RichTextField(label=gettext_lazy('Concerns'), help_text='Any general or specific aspects that concern you or leave you feeling uneasy about this proposal.')

red_flags class-attribute instance-attribute

red_flags = RichTextField(label=gettext_lazy('Items that must be addressed'), help_text='Anything you think should be flagged for our attention.')

overview class-attribute instance-attribute

overview = RichTextField(label=gettext_lazy('Project overview questions and comments'))

objectives class-attribute instance-attribute

objectives = RichTextField(label=gettext_lazy('Objectives questions and comments'))

strategy class-attribute instance-attribute

strategy = RichTextField(label=gettext_lazy('Methods and strategy questions and comments'))

technical class-attribute instance-attribute

technical = RichTextField(label=gettext_lazy('Technical feasibility questions and comments'))

alternative class-attribute instance-attribute

alternative = RichTextField(label=gettext_lazy('Alternative analysis - "red teaming" questions and comments'))

usability class-attribute instance-attribute

usability = RichTextField(label=gettext_lazy('Usability questions and comments'))

sustainability class-attribute instance-attribute

sustainability = RichTextField(label=gettext_lazy('Sustainability questions and comments'))

collaboration class-attribute instance-attribute

collaboration = RichTextField(label=gettext_lazy('Collaboration questions and comments'))

realism class-attribute instance-attribute

realism = RichTextField(label=gettext_lazy('Cost realism questions and comments'))

qualifications class-attribute instance-attribute

qualifications = RichTextField(label=gettext_lazy('Qualifications questions and comments'))

evaluation class-attribute instance-attribute

evaluation = RichTextField(label=gettext_lazy('Evaluation questions and comments'))

rationale class-attribute instance-attribute

rationale = RichTextField(label=gettext_lazy('Rationale and appropriateness questions and comments'))

fields instance-attribute

fields = apply_form_settings('proposal', fields)

draft_button_name instance-attribute

draft_button_name = None

Meta

model class-attribute instance-attribute
model = Determination
fields class-attribute instance-attribute
fields = ['outcome', 'message', 'submission', 'author', 'data', 'send_notice']
widgets class-attribute instance-attribute
widgets = {'submission': HiddenInput(), 'author': HiddenInput(), 'data': HiddenInput()}
error_messages class-attribute instance-attribute
error_messages = {NON_FIELD_ERRORS: {'unique_together': 'You have already created a determination for this submission'}}

data_fields

data_fields()
Source code in hypha/apply/determinations/forms.py
def data_fields(self):
    return [field for field in self.fields if field not in self._meta.fields]

clean_outcome

clean_outcome()
Source code in hypha/apply/determinations/forms.py
def clean_outcome(self):
    # Enforce outcome as an int
    return int(self.cleaned_data["outcome"])

clean

clean()
Source code in hypha/apply/determinations/forms.py
def clean(self):
    cleaned_data = super().clean()
    cleaned_data["data"] = {
        key: value
        for key, value in cleaned_data.items()
        if key in self.data_fields()
    }
    return cleaned_data

apply_form_settings

apply_form_settings(application_type, fields)
Source code in hypha/apply/determinations/forms.py
def apply_form_settings(self, application_type, fields):
    for field in fields:
        try:
            self.fields[field].label = getattr(
                self.form_settings, f"{application_type}_{field}_label"
            )
        except AttributeError:
            pass
        try:
            self.fields[field].help_text = getattr(
                self.form_settings, f"{application_type}_{field}_help_text"
            )
        except AttributeError:
            pass
    return fields

get_detailed_response classmethod

get_detailed_response(saved_data)
Source code in hypha/apply/determinations/forms.py
@classmethod
def get_detailed_response(cls, saved_data):
    data = {}
    for group, title in cls.titles.items():
        data.setdefault(group, {"title": title, "questions": []})

    for name, field in cls.base_fields.items():
        try:
            value = saved_data[name]
        except KeyError:
            # The field is not stored in the data
            pass
        else:
            data[field.group]["questions"].append((field.label, str(value)))

    return data

outcome_choices_for_phase

outcome_choices_for_phase(submission, user)

Outcome choices correspond to Phase transitions. We need to filter out non-matching choices. i.e. a transition to In Review is not a determination, while Needs more info or Rejected are.

Source code in hypha/apply/determinations/forms.py
def outcome_choices_for_phase(self, submission, user):
    """
    Outcome choices correspond to Phase transitions.
    We need to filter out non-matching choices.
    i.e. a transition to In Review is not a determination, while Needs more info or Rejected are.
    """
    available_choices = [("", _("-- No determination selected -- "))]
    choices = dict(self.fields["outcome"].choices)

    for transition_name in determination_actions(user, submission):
        try:
            determination_type = TRANSITION_DETERMINATION[transition_name]
        except KeyError:
            pass
        else:
            available_choices.append(
                (determination_type, choices[determination_type])
            )
    return available_choices

save

save(commit=True)
Source code in hypha/apply/determinations/forms.py
def save(self, commit=True):
    self.instance.is_draft = self.draft_button_name in self.data

    return super().save(commit)

BatchConceptDeterminationForm

BatchConceptDeterminationForm(*args, submissions, initial=None, **kwargs)

Bases: BaseConceptDeterminationForm, BaseBatchDeterminationForm

Source code in hypha/apply/determinations/forms.py
def __init__(self, *args, submissions, initial=None, **kwargs):
    if initial is None:
        initial = {}
    initial.update(submissions=submissions.values_list("id", flat=True))
    super(BaseBatchDeterminationForm, self).__init__(
        *args, initial=initial, **kwargs
    )
    self.fields["outcome"].widget = forms.HiddenInput()

    self.fields = self.apply_form_settings("concept", self.fields)

form_settings instance-attribute

form_settings = for_site(site)

submissions class-attribute instance-attribute

submissions = ModelMultipleChoiceField(queryset=all(), widget=hidden_widget)

author class-attribute instance-attribute

author = ModelChoiceField(queryset=active(), widget=hidden_widget, required=True)

titles class-attribute instance-attribute

titles = {1: 'Feedback'}

outcome class-attribute instance-attribute

outcome = ChoiceField(choices=DETERMINATION_CHOICES, label=gettext_lazy('Determination'), help_text='Do you recommend requesting a proposal based on this concept note?')

message class-attribute instance-attribute

message = RichTextField(label=gettext_lazy('Determination message'), help_text='This text will be e-mailed to the applicant. Ones when text is first added and then every time the text is changed.')

principles class-attribute instance-attribute

principles = RichTextField(label=gettext_lazy('Goals and principles'), help_text='Does the project contribute and/or have relevance to OTF goals and principles?Are the goals and objectives of the project clear? Is it a technology research, development, or deployment project? Can project’s effort be explained to external audiences and non-technical people? What problem are they trying to solve and is the solution strategical or tactical? Is the project strategically or tactically important to OTF’s goals, principles and rationale and other OTF efforts? Is it clear how? What tools, if any, currently exist to solve this problem? How is this project different? Does the effort have any overlap with existing OTF and/or USG supported projects? Is the overlap complementary or duplicative? If complementary, can it be explained clearly? I.e. geographic focus, technology, organization profile, etc. What are the liabilities and risks of taking on this project? I.e. political personalities, financial concerns, technical controversial, etc. Is the organization or its members known within any relevant communities? If yes, what is their reputation and why? What is the entity’s motivation and principles? What are the entity member(s) motivations and principles? Where is the organization physically and legally based? If the organization is distributed, where is the main point of contact? Does the organization have any conflicts of interest with RFA, OTF, the Advisory Council, or other RFA-OTF projects? Is the project team an organization, community or an individual?')

technical class-attribute instance-attribute

technical = RichTextField(label=gettext_lazy('Technical merit'), help_text='Does the project clearly articulate the technical problem, solution, and approach? Is the problem clearly justifiable? Does the project clearly articulate the technological objectives? Is it an open or closed development project? I.e. Open source like Android or open source like Firefox OS or closed like iOS. Does a similar technical solution already exist? If so, what are the differentiating factors? Is the effort to sustain an existing technical approach? If so, are these considered successful? Is the effort a new technical approach or improvement to an existing solution? If so, how? Is the effort a completely new technical approach fostering new solutions in the field? Does the project’s technical approach solve the problem? What are the limitations of the project’s technical approach and solution? What are the unintended or illicit uses and consequences of this technology? Has the project identified and/or developed any safeguards for these consequences?')

sustainable class-attribute instance-attribute

sustainable = RichTextField(label=gettext_lazy('Reasonable, realistic and sustainable'), help_text='Is the requested amount reasonable, realistic, and justified? If OTF doesn’t support the project, is it likely to be realized? Does the project provide a detailed and realistic description of effort and schedule? I.e. is the project capable of creating a work plan including objectives, activities, and deliverable(s)? Does the project have a clear support model? Is there a known sustainability plan for the future? What in-kind support or other revenue streams is the project receiving? I.e. volunteer developers, service or product sales. Is the project receiving any financial support from the USG? Is this information disclosed? Is the project receiving any other financial support? Is this information disclosed? Are existing supporters approachable? Are they likely aware and/or comfortable with the Intellectual property language within USG contracts?')

comments class-attribute instance-attribute

comments = RichTextField(label=gettext_lazy('Other comments'), help_text='')

fields instance-attribute

fields = apply_form_settings('concept', fields)

data_fields

data_fields()
Source code in hypha/apply/determinations/forms.py
def data_fields(self):
    return [
        field
        for field in self.fields
        if field
        not in ["submissions", "outcome", "author", "send_notice", "message"]
    ]

clean_outcome

clean_outcome()
Source code in hypha/apply/determinations/forms.py
def clean_outcome(self):
    # Enforce outcome as an int
    return int(self.cleaned_data["outcome"])

clean

clean()
Source code in hypha/apply/determinations/forms.py
def clean(self):
    cleaned_data = super().clean()
    cleaned_data["data"] = {
        key: value
        for key, value in cleaned_data.items()
        if key in self.data_fields()
    }
    return cleaned_data

apply_form_settings

apply_form_settings(application_type, fields)
Source code in hypha/apply/determinations/forms.py
def apply_form_settings(self, application_type, fields):
    for field in fields:
        try:
            self.fields[field].label = getattr(
                self.form_settings, f"{application_type}_{field}_label"
            )
        except AttributeError:
            pass
        try:
            self.fields[field].help_text = getattr(
                self.form_settings, f"{application_type}_{field}_help_text"
            )
        except AttributeError:
            pass
    return fields

get_detailed_response classmethod

get_detailed_response(saved_data)
Source code in hypha/apply/determinations/forms.py
@classmethod
def get_detailed_response(cls, saved_data):
    data = {}
    for group, title in cls.titles.items():
        data.setdefault(group, {"title": title, "questions": []})

    for name, field in cls.base_fields.items():
        try:
            value = saved_data[name]
        except KeyError:
            # The field is not stored in the data
            pass
        else:
            data[field.group]["questions"].append((field.label, str(value)))

    return data

save

save()
Source code in hypha/apply/determinations/forms.py
def save(self):
    determinations = Determination.objects.bulk_create(self.instances)
    self.instances = determinations
    return determinations

BatchProposalDeterminationForm

BatchProposalDeterminationForm(*args, submissions, initial=None, **kwargs)

Bases: BaseProposalDeterminationForm, BaseBatchDeterminationForm

Source code in hypha/apply/determinations/forms.py
def __init__(self, *args, submissions, initial=None, **kwargs):
    if initial is None:
        initial = {}
    initial.update(submissions=submissions.values_list("id", flat=True))
    super(BaseBatchDeterminationForm, self).__init__(
        *args, initial=initial, **kwargs
    )
    self.fields["outcome"].widget = forms.HiddenInput()

    self.fields = self.apply_form_settings("proposal", self.fields)

form_settings instance-attribute

form_settings = for_site(site)

submissions class-attribute instance-attribute

submissions = ModelMultipleChoiceField(queryset=all(), widget=hidden_widget)

author class-attribute instance-attribute

author = ModelChoiceField(queryset=active(), widget=hidden_widget, required=True)

titles class-attribute instance-attribute

titles = {1: 'A. Determination', 2: 'B. General thoughts', 3: 'C. Specific aspects', 4: 'D. Rationale and appropriateness consideration', 5: 'E. General recommendation'}

outcome class-attribute instance-attribute

outcome = ChoiceField(choices=DETERMINATION_CHOICES, label=gettext_lazy('Determination'), help_text='Do you recommend requesting a proposal based on this concept note?')

message class-attribute instance-attribute

message = RichTextField(label=gettext_lazy('Determination message'), help_text='This text will be e-mailed to the applicant. Ones when text is first added and then every time the text is changed.')

liked class-attribute instance-attribute

liked = RichTextField(label=gettext_lazy('Positive aspects'), help_text='Any general or specific aspects that got you really excited or that you like about this proposal.')

concerns class-attribute instance-attribute

concerns = RichTextField(label=gettext_lazy('Concerns'), help_text='Any general or specific aspects that concern you or leave you feeling uneasy about this proposal.')

red_flags class-attribute instance-attribute

red_flags = RichTextField(label=gettext_lazy('Items that must be addressed'), help_text='Anything you think should be flagged for our attention.')

overview class-attribute instance-attribute

overview = RichTextField(label=gettext_lazy('Project overview questions and comments'))

objectives class-attribute instance-attribute

objectives = RichTextField(label=gettext_lazy('Objectives questions and comments'))

strategy class-attribute instance-attribute

strategy = RichTextField(label=gettext_lazy('Methods and strategy questions and comments'))

technical class-attribute instance-attribute

technical = RichTextField(label=gettext_lazy('Technical feasibility questions and comments'))

alternative class-attribute instance-attribute

alternative = RichTextField(label=gettext_lazy('Alternative analysis - "red teaming" questions and comments'))

usability class-attribute instance-attribute

usability = RichTextField(label=gettext_lazy('Usability questions and comments'))

sustainability class-attribute instance-attribute

sustainability = RichTextField(label=gettext_lazy('Sustainability questions and comments'))

collaboration class-attribute instance-attribute

collaboration = RichTextField(label=gettext_lazy('Collaboration questions and comments'))

realism class-attribute instance-attribute

realism = RichTextField(label=gettext_lazy('Cost realism questions and comments'))

qualifications class-attribute instance-attribute

qualifications = RichTextField(label=gettext_lazy('Qualifications questions and comments'))

evaluation class-attribute instance-attribute

evaluation = RichTextField(label=gettext_lazy('Evaluation questions and comments'))

rationale class-attribute instance-attribute

rationale = RichTextField(label=gettext_lazy('Rationale and appropriateness questions and comments'))

fields instance-attribute

fields = apply_form_settings('proposal', fields)

data_fields

data_fields()
Source code in hypha/apply/determinations/forms.py
def data_fields(self):
    return [
        field
        for field in self.fields
        if field
        not in ["submissions", "outcome", "author", "send_notice", "message"]
    ]

clean_outcome

clean_outcome()
Source code in hypha/apply/determinations/forms.py
def clean_outcome(self):
    # Enforce outcome as an int
    return int(self.cleaned_data["outcome"])

clean

clean()
Source code in hypha/apply/determinations/forms.py
def clean(self):
    cleaned_data = super().clean()
    cleaned_data["data"] = {
        key: value
        for key, value in cleaned_data.items()
        if key in self.data_fields()
    }
    return cleaned_data

apply_form_settings

apply_form_settings(application_type, fields)
Source code in hypha/apply/determinations/forms.py
def apply_form_settings(self, application_type, fields):
    for field in fields:
        try:
            self.fields[field].label = getattr(
                self.form_settings, f"{application_type}_{field}_label"
            )
        except AttributeError:
            pass
        try:
            self.fields[field].help_text = getattr(
                self.form_settings, f"{application_type}_{field}_help_text"
            )
        except AttributeError:
            pass
    return fields

get_detailed_response classmethod

get_detailed_response(saved_data)
Source code in hypha/apply/determinations/forms.py
@classmethod
def get_detailed_response(cls, saved_data):
    data = {}
    for group, title in cls.titles.items():
        data.setdefault(group, {"title": title, "questions": []})

    for name, field in cls.base_fields.items():
        try:
            value = saved_data[name]
        except KeyError:
            # The field is not stored in the data
            pass
        else:
            data[field.group]["questions"].append((field.label, str(value)))

    return data

save

save()
Source code in hypha/apply/determinations/forms.py
def save(self):
    determinations = Determination.objects.bulk_create(self.instances)
    self.instances = determinations
    return determinations

MixedMetaClass

Bases: type(StreamBaseForm), type(ModelForm)

DeterminationModelForm

DeterminationModelForm(*args, submission, action, user=None, edit=False, initial=None, instance=None, site=None, **kwargs)

Bases: StreamBaseForm, ModelForm

Source code in hypha/apply/determinations/forms.py
def __init__(
    self,
    *args,
    submission,
    action,
    user=None,
    edit=False,
    initial=None,
    instance=None,
    site=None,
    **kwargs,
):
    if initial is None:
        initial = {}
    initial.update(submission=submission.id)
    initial.update(author=user.id)
    if instance:
        for key, value in instance.form_data.items():
            if key not in self._meta.fields:
                initial[key] = value
    super().__init__(*args, initial=initial, instance=instance, **kwargs)

    for field in self._meta.widgets:
        # Need to disable the model form fields as these fields would be
        # rendered via streamfield form.
        self.fields[field].disabled = True

    if self.draft_button_name in self.data:
        # A determination must be set for saving a draft,
        # this forces outcome to be validated.
        unreq_fields = [name for name in self.fields if name != "outcome"]
        for name in unreq_fields:
            self.fields[name].required = False

    if edit:
        self.fields.pop("outcome")
        self.draft_button_name = None

draft_button_name class-attribute instance-attribute

draft_button_name = 'save draft'

Meta

model class-attribute instance-attribute
model = Determination
fields class-attribute instance-attribute
fields = ['outcome', 'message', 'submission', 'author', 'send_notice']
widgets class-attribute instance-attribute
widgets = {'outcome': HiddenInput(), 'message': HiddenInput(), 'submission': HiddenInput(), 'author': HiddenInput(), 'send_notice': HiddenInput()}
error_messages class-attribute instance-attribute
error_messages = {NON_FIELD_ERRORS: {'unique_together': 'You have already created a determination for this submission'}}

swap_fields_for_display

swap_fields_for_display(func)
Source code in hypha/apply/stream_forms/forms.py
def swap_fields_for_display(func):
    def wrapped(self, *args, **kwargs):
        # Replaces the form fields with the display fields
        # should only add new streamblocks and wont affect validation
        fields = self.fields.copy()
        self.fields = self.display
        yield from func(self, *args, **kwargs)
        self.fields = fields

    return wrapped

hidden_fields

hidden_fields()
Source code in hypha/apply/stream_forms/forms.py
def hidden_fields(self):
    # No hidden fields are returned by default because of MixedFieldMetaclass
    return [self[f] for f in self.fields.keys() if self[f].is_hidden]

delete_temporary_files

delete_temporary_files()

Overridden method of django_file_form's FileFormMixin, to handle multiple forms on the same page.

Source code in hypha/apply/stream_forms/forms.py
def delete_temporary_files(self):
    """
    Overridden method of django_file_form's FileFormMixin, to handle multiple forms on the same page.
    """
    form_id = self.data.getlist(self.add_prefix("form_id"))

    if not form_id:
        return

    form_id = form_id[0]
    for field_name, field in self.fields.items():
        if hasattr(field, "delete_file_data"):
            prefixed_field_name = self.add_prefix(field_name)
            field.delete_file_data(prefixed_field_name, form_id)

clean

clean()
Source code in hypha/apply/determinations/forms.py
def clean(self):
    cleaned_data = super().clean()
    cleaned_data["form_data"] = {
        key: value
        for key, value in cleaned_data.items()
        if key not in self._meta.fields
    }

    return cleaned_data

save

save(commit=True)
Source code in hypha/apply/determinations/forms.py
def save(self, commit=True):
    self.instance.send_notice = (
        self.cleaned_data[self.instance.send_notice_field.id]
        if self.instance.send_notice_field
        else True
    )
    self.instance.message = self.cleaned_data[self.instance.message_field.id]
    try:
        self.instance.outcome = int(
            self.cleaned_data[self.instance.determination_field.id]
        )
    except KeyError:
        # Need to catch KeyError as outcome field would not exist in case of edit.
        pass
    self.instance.is_draft = self.draft_button_name in self.data
    self.instance.form_data = self.cleaned_data["form_data"]
    return super().save(commit)

FormMixedMetaClass

Bases: type(StreamBaseForm), type(Form)

BatchDeterminationForm

BatchDeterminationForm(*args, user, submissions, action, initial=None, edit=False, site=None, **kwargs)

Bases: StreamBaseForm, Form

Source code in hypha/apply/determinations/forms.py
def __init__(
    self,
    *args,
    user,
    submissions,
    action,
    initial=None,
    edit=False,
    site=None,
    **kwargs,
):
    if initial is None:
        initial = {}
    initial.update(submissions=submissions.values_list("id", flat=True))
    try:
        initial.update(outcome=TRANSITION_DETERMINATION[action])
    except KeyError:
        pass
    initial.update(author=user.id)
    super().__init__(*args, initial=initial, **kwargs)
    self.fields["submissions"].disabled = True
    self.fields["author"].disabled = True
    self.fields["outcome"].disabled = True

submissions class-attribute instance-attribute

submissions = ModelMultipleChoiceField(queryset=all(), widget=hidden_widget)

author class-attribute instance-attribute

author = ModelChoiceField(queryset=active(), widget=hidden_widget, required=True)

outcome class-attribute instance-attribute

outcome = ChoiceField(choices=DETERMINATION_CHOICES, label=gettext_lazy('Determination'), help_text='Do you recommend requesting a proposal based on this concept note?', widget=HiddenInput())

swap_fields_for_display

swap_fields_for_display(func)
Source code in hypha/apply/stream_forms/forms.py
def swap_fields_for_display(func):
    def wrapped(self, *args, **kwargs):
        # Replaces the form fields with the display fields
        # should only add new streamblocks and wont affect validation
        fields = self.fields.copy()
        self.fields = self.display
        yield from func(self, *args, **kwargs)
        self.fields = fields

    return wrapped

hidden_fields

hidden_fields()
Source code in hypha/apply/stream_forms/forms.py
def hidden_fields(self):
    # No hidden fields are returned by default because of MixedFieldMetaclass
    return [self[f] for f in self.fields.keys() if self[f].is_hidden]

delete_temporary_files

delete_temporary_files()

Overridden method of django_file_form's FileFormMixin, to handle multiple forms on the same page.

Source code in hypha/apply/stream_forms/forms.py
def delete_temporary_files(self):
    """
    Overridden method of django_file_form's FileFormMixin, to handle multiple forms on the same page.
    """
    form_id = self.data.getlist(self.add_prefix("form_id"))

    if not form_id:
        return

    form_id = form_id[0]
    for field_name, field in self.fields.items():
        if hasattr(field, "delete_file_data"):
            prefixed_field_name = self.add_prefix(field_name)
            field.delete_file_data(prefixed_field_name, form_id)

data_fields

data_fields()
Source code in hypha/apply/determinations/forms.py
def data_fields(self):
    return [
        field
        for field in self.fields
        if field not in ["submissions", "outcome", "author", "send_notice"]
    ]

clean

clean()
Source code in hypha/apply/determinations/forms.py
def clean(self):
    cleaned_data = super().clean()
    cleaned_data["form_data"] = {
        key: value
        for key, value in cleaned_data.items()
        if key in self.data_fields()
    }
    return cleaned_data

clean_outcome

clean_outcome()
Source code in hypha/apply/determinations/forms.py
def clean_outcome(self):
    # Enforce outcome as an int
    return int(self.cleaned_data["outcome"])

save

save()
Source code in hypha/apply/determinations/forms.py
def save(self):
    determinations = Determination.objects.bulk_create(self.instances)
    self.instances = determinations
    return determinations