def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        XDSoftYearMonthDayPickerInput.set_format_to_field(self.fields['published_date'])

        self.helper = FormHelper()
        self.helper.form_tag = False
        self.helper.disable_csrf = True  # checked in the higher form level

        self.helper.layout = Layout(
            Div(
                Div('project', hidden=True),
                Div('id', hidden=True),
                Div(Field('DELETE', hidden=True)),
                css_class='row', hidden=True
            ),
            Div(
                Div('title', css_class='col-12'),
                css_class='row'
            ),
            Div(
                Div('reference', css_class='col-12'),
                css_class='row'
            ),
            Div(
                Div('doi', css_class='col-6'),
                Div('published_date', css_class='col-6'),
                css_class='row'
            )
        )
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        XDSoftYearMonthDayPickerInput.set_format_to_field(
            self.fields['due_date'])
        XDSoftYearMonthDayPickerInput.set_format_to_field(
            self.fields['received_date'])

        self.helper = FormHelper()
        self.helper.form_tag = False
        self.helper.disable_csrf = True  # checked in the higher form level

        self.helper.layout = Layout(
            Div(Div('project', hidden=True),
                Div('id', hidden=True),
                Div(Field('DELETE', hidden=True)),
                css_class='row',
                hidden=True),
            Div(Div('due_date', css_class='col-4'),
                Div('received_date', css_class='col-4'),
                css_class='row'),
            Div(Div('text', css_class='col-12'), css_class='row'),
            Div(Div('author', css_class='col-6'),
                Div('lay_summary_type', css_class='col-6'),
                css_class='row'))
Пример #3
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        XDSoftYearMonthDayPickerInput.set_format_to_field(
            self.fields['due_date'])
        XDSoftYearMonthDayPickerInput.set_format_to_field(
            self.fields['received_date'])

        self.helper = FormHelper()
        self.helper.form_tag = False
        self.helper.disable_csrf = True  # checked in the higher form level

        self.fields['author'].help_text += new_person_message()

        media = "{% include 'grant_management/_enumeration_of_media.tmpl' %}"

        self.helper.layout = Layout(
            Div(Div('project', hidden=True),
                Div('id', hidden=True),
                Div(Field('DELETE', hidden=True)),
                css_class='row',
                hidden=True),
            Div(Div('due_date', css_class='col-4'),
                Div('received_date', css_class='col-4'),
                css_class='row'),
            Div(Div('title', css_class='col-12'), css_class='row'),
            Div(Div('text', css_class='col-12'), css_class='row'),
            Div(Div('author', css_class='col-6'),
                Div(HTML(media), css_class='col-6'),
                css_class='row'))
    def __init__(self, *args, **kwargs):
        project = kwargs.pop('project')
        super().__init__(*args, **kwargs)

        XDSoftYearMonthDayPickerInput.set_format_to_field(
            self.fields['received_date'])

        self.fields['blog_posts'] = BlogPostMultipleChoiceField(
            queryset=project.blogpost_set.all().order_by('received_date'),
            widget=CheckboxSelectMultiple,
            required=False,
            help_text=
            'Please select the relevant blog posts for this media file')

        self.fields['key_image'] = forms.BooleanField(
            required=False,
            help_text='Select as a key image to be displayed on website')

        self.fields['primary_image'] = forms.BooleanField(
            required=False, help_text='Select as a primary image on website')

        self.fields['photographer'].help_text += new_person_message()

        self.fields['license'].queryset = self.fields[
            'license'].queryset.order_by('name')

        self.helper = FormHelper()
        self.helper.form_tag = False
        self.helper.disable_csrf = True  # checked in the higher form level

        self.helper.layout = Layout(
            Div(Div('project', hidden=True),
                Div('id', hidden=True),
                Div(Field('DELETE', hidden=True)),
                css_class='row',
                hidden=True),
            Div(Div('photographer', css_class='col-4'),
                Div('license', css_class='col-4'),
                Div('copyright', css_class='col-4'),
                css_class='row'),
            Div(Div('file', css_class='col-4'),
                Div('received_date', css_class='col-4'),
                css_class='row'),
            Div(Div('descriptive_text', css_class='col-6'),
                Div(
                    Div('blog_posts'),
                    Div('key_image'),
                    Div('primary_image'),
                ),
                css_class='row'),
        )
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        final_fields = ['approved_by', 'approval_date']

        for field_name, field in self.fields.items():
            if type(field) == forms.DateField:
                XDSoftYearMonthDayPickerInput.set_format_to_field(field)

        self.fields['can_be_deleted'] = forms.CharField(initial=1,
                                                        required=False)

        self.fields['approved_by'].help_text += new_person_message()

        message = ''
        # Final fields are all or none - it checks for the first one
        if self.instance and getattr(self.instance,
                                     final_fields[0]) is not None:
            message = '''<strong>This report has been signed and can no longer be changed. 
            To edit any of the fields, delete the signed by and date signed, 
            click on <em>Save Financial Reports</em> and come back again.</strong>'''
            self.fields['can_be_deleted'].initial = 0
            for field_name in self.fields:
                if field_name not in AbstractReportItemModelForm.BASIC_FIELDS and field_name not in final_fields:
                    self.fields[field_name].disabled = True

        self.helper = FormHelper()
        self.helper.form_tag = False

        # It's included in the main formset, it avoids problems when adding new invoices and the jquery.formset.js
        self.helper.disable_csrf = True

        self.helper.layout = Layout(
            Div(Div('project', hidden=True),
                Div('id', hidden=True),
                Div(Field('DELETE', hidden=True)),
                Div('can_be_deleted', hidden=True, css_class='can_be_deleted'),
                css_class='row',
                hidden=True),
            Div(Div(HTML(message), css_class='col-12'),
                css_class='row to-delete'),
            Div(Div('due_date', css_class='col-4'),
                Div('received_date', css_class='col-4'),
                Div('file', css_class='col-4'),
                css_class='row'),
            Div(Div('sent_for_approval_date', css_class='col-4'),
                Div('approved_by', css_class='col-4'),
                Div('approval_date', css_class='col-4'),
                css_class='row'))
Пример #6
0
    def __init__(self, *args, **kwargs):
        project = kwargs.pop('project')
        super().__init__(*args, **kwargs)

        XDSoftYearMonthDayPickerInput.set_format_to_field(
            self.fields['signed_date'])
        self.fields['project'].initial = project.id

        self.helper = FormHelper(self)
        cancel_url = reverse('logged-grant_management-project-detail',
                             kwargs={'pk': project.id})

        self.helper.layout = Layout(
            Div(Div('project', hidden=True),
                Div('file', css_class='col-6'),
                css_class='row'),
            Div(Div('signed_date', css_class='col-6'), css_class='row'),
            Div(Div('signed_by', css_class='col-6'), css_class='row'),
            FormActions(Submit('save', 'Save Grant Agreement'),
                        cancel_edit_button(cancel_url)))
Пример #7
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        XDSoftYearMonthDayPickerInput.set_format_to_field(
            self.fields['start_date'])
        XDSoftYearMonthDayPickerInput.set_format_to_field(
            self.fields['end_date'])

        self.helper = FormHelper(self)
        cancel_url = reverse('logged-project-detail',
                             kwargs={'pk': self.instance.id})

        self.helper.layout = Layout(
            Div(Div('title', css_class='col-12'), css_class='row'),
            Div(Div('keywords', css_class='col-12'), css_class='row'),
            Div(Div('geographical_areas', css_class='col-12'),
                css_class='row'),
            Div(Div('location', css_class='col-12'), css_class='row'),
            Div(Div('start_date', css_class='col-6'), css_class='row'),
            Div(Div('end_date', css_class='col-6'), css_class='row'),
            FormActions(Submit('save', 'Save Project'),
                        cancel_edit_button(cancel_url)))
Пример #8
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        XDSoftYearMonthDayPickerInput.set_format_to_field(
            self.fields['start_date'])
        XDSoftYearMonthDayPickerInput.set_format_to_field(
            self.fields['end_date'])

        self.fields['allocated_budget'].disabled = True
        self.fields[
            'allocated_budget'].help_text = 'The allocated budget cannot be changed after the project is created'

        self.helper = FormHelper(self)
        cancel_url = reverse('logged-grant_management-project-detail',
                             kwargs={'pk': self.instance.id})

        self.helper.layout = Layout(
            Div(Div('allocated_budget', css_class='col-6'), css_class='row'),
            Div(Div('start_date', css_class='col-6'), css_class='row'),
            Div(Div('end_date', css_class='col-6'), css_class='row'),
            FormActions(Submit('save', 'Save Information'),
                        cancel_edit_button(cancel_url)))
Пример #9
0
    def __init__(self, *args, **kwargs):
        call = kwargs.pop('call', None)
        super().__init__(*args, **kwargs)

        self.helper = FormHelper(self)

        if self.instance.id:
            self.helper.form_action = reverse('logged-call-evaluation-update', kwargs={'pk': self.instance.id})
            self.fields['call'].initial = call = self.instance.call
        else:
            self.helper.form_action = reverse('logged-call-evaluation-add') + f'?call={call.id}'
            self.fields['call'].initial = call

        XDSoftYearMonthDayPickerInput.set_format_to_field(self.fields['panel_date'])

        if hasattr(call, 'callevaluation'):
            cancel_edit_url = reverse('logged-call-evaluation-detail', kwargs={'pk': call.callevaluation.id})
            initial_reviewers = call.reviewer_set.all()
        else:
            cancel_edit_url = reverse('logged-call-evaluation-add') + f'?call={call.id}'
            initial_reviewers = []

        self.fields['reviewers'] = ReviewerMultipleChoiceField(initial=initial_reviewers,
                                                               queryset=Reviewer.objects.all(),
                                                               required=True,
                                                               widget=FilteredSelectMultiple(
                                                                   is_stacked=True,
                                                                   verbose_name='reviewers'),
                                                               help_text=self.Meta.help_texts['reviewers'])

        criterion_choices, criterion_initial = CheckboxSelectMultipleSortable.get_choices_initial(
            CriterionCallEvaluation,
            self.instance, 'call_evaluation',
            Criterion, 'criterion',
            label_from_instance=lambda obj: format_html('{} <small>({})</small>', obj.name, obj.description)
        )

        self.fields['criteria'] = forms.MultipleChoiceField(choices=criterion_choices,
                                                            initial=criterion_initial,
                                                            widget=CheckboxSelectMultipleSortable,
                                                            label='Criteria (drag and drop to order them)',
                                                            help_text='These criteria are used in the Excel Evaluation sheet'
                                                            )

        self.criteria_order_key = f'criteria-{CheckboxSelectMultipleSortable.order_of_values_name}'

        self.helper.layout = Layout(
            Div(
                Div('call', css_class='col-12', hidden=True),
                css_class='row'
            ),
            Div(
                Div('reviewers', css_class='col-12'),
                css_class='row'
            ),
            Div(
                Div('panel_date', css_class='col-12'),
                css_class='row'
            ),
            Div(
                Div('criteria', css_class='col-12'),
                css_class='row'
            ),
            Div(
                Div('post_panel_management_table', css_class='col-12'),
                css_class='row'
            ),
            FormActions(
                Submit('save', 'Save Call Evaluation'),
                cancel_edit_button(cancel_edit_url)
            )
        )
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        XDSoftYearMonthDayPickerInput.set_format_to_field(self.fields['start_date'])
        XDSoftYearMonthDayPickerInput.set_format_to_field(self.fields['end_date'])

        self.helper = FormHelper(self)

        is_standalone_project = self.instance.id is None or self.instance.call is None

        if self.instance.id:
            submit_text = 'Save Project'
            cancel_button_html = cancel_edit_button(reverse('logged-project-detail', kwargs={'pk': self.instance.id}))

            grant_management_deliverables_url = reverse('logged-grant_management-project-detail',
                                                        kwargs={'pk': self.instance.id})

            locations_link = f'{grant_management_deliverables_url}?tab=other#locations'
            locations_message = f'Use the <a href="{locations_link}">"Other" tab under grant management</a> to edit the project locations.'

        else:
            submit_text = 'Create Project'
            cancel_button_html = cancel_button(reverse('logged-project-list'))
            locations_message = 'Use the "Other" tab under grant management to add the project locations after creating it. '

        # Applicants need to enter 5 keywords in the proposal, SPI at the moment can create or save them without keywords
        self.fields['keywords'].required = False

        if is_standalone_project:
            self.fields['funding_instrument'].queryset = FundingInstrument.objects.order_by('long_name')
            self.fields['geographical_areas'].required = False

            principal_investigator_div = Div(
                Div('principal_investigator', css_class='col-12'),
                css_class='row'
            )

            self.fields[
                'principal_investigator'].help_text += new_person_message()

            create_funding_instrument_url = reverse('logged-funding-instrument-add')
            self.fields[
                'funding_instrument'].help_text += f'. If the funding instrument is not found <a href="{create_funding_instrument_url}">create</a> the funding instrument, reload the page, then try again'

            funding_instrument_div = Div(
                Div('funding_instrument', css_class='col-12'),
                css_class='row'
            )
            finance_year_div = Div(
                Div('finance_year', css_class='col-6'),
                css_class='row'
            )
            allocated_budget_div = Div(
                Div('allocated_budget', css_class='col-6'),
                css_class='row'
            )

        else:
            principal_investigator_div = None
            funding_instrument_div = None
            finance_year_div = None

            allocated_budget_div = Div(
                Div('allocated_budget', css_class='col-6'),
                css_class='row'
            )

            if self.instance and self.instance.id and self.instance.status != Project.ONGOING:
                self.fields['allocated_budget'].disabled = True
                self.fields['allocated_budget'].help_text += '. Can only be changed for ONGOING projects.'

            # Used when the project is standalone (not coming from a call)
            # In Meta.fields they are added - IMHO it's easier to delete them
            # than add them here
            del self.fields['principal_investigator']
            del self.fields['finance_year']
            del self.fields['funding_instrument']

        self.helper.layout = Layout(
            Div(
                Div('title', css_class='col-12'),
                css_class='row'
            ),
            principal_investigator_div,
            funding_instrument_div,
            finance_year_div,
            allocated_budget_div,
            Div(
                Div('keywords', css_class='col-12'),
                css_class='row'
            ),
            Div(
                Div('geographical_areas', css_class='col-12'),
                css_class='row'
            ),
            Div(
                Div('location', css_class='col-12'),
                css_class='row'
            ),
            Div(
                Div(HTML('Locations'), css_class='col-12'),
                css_class='row'
            ),
            Div(
                Div(HTML(
                    locations_message),
                    css_class='col-12'),
                css_class='row'
            ),
            Div(
                Div(HTML('<br>'), css_class='col-12'),
                css_class='row'
            ),
            Div(
                Div('start_date', css_class='col-6'),
                css_class='row'
            ),
            Div(
                Div('end_date', css_class='col-6'),
                css_class='row'
            ),
            Div(
                Div('on_website', css_class='col-6'),
                css_class='row'
            ),
            FormActions(
                Submit('save', submit_text),
                cancel_button_html
            )
        )
    def __init__(self, *args, **kwargs):
        call = kwargs.pop('call', None)
        super().__init__(*args, **kwargs)

        self.helper = FormHelper(self)

        if self.instance.id:
            self.helper.form_action = reverse('logged-call-evaluation-update', kwargs={'pk': self.instance.id})
            self.fields['call'].initial = call = self.instance.call
        else:
            self.helper.form_action = reverse('logged-call-evaluation-add') + f'?call={call.id}'
            self.fields['call'].initial = call

        XDSoftYearMonthDayPickerInput.set_format_to_field(self.fields['panel_date'])

        if hasattr(call, 'callevaluation'):
            cancel_edit_url = reverse('logged-call-evaluation-detail', kwargs={'pk': call.callevaluation.id})
            initial_reviewers = call.reviewer_set.all()
        else:
            cancel_edit_url = reverse('logged-call-evaluation-add') + f'?call={call.id}'
            initial_reviewers = []

        reviewer_add_url = reverse('logged-user-add')

        reviewers_help_text = \
            f'Select the reviewers that you would like to be added for this call. This is everyone that ' \
            f'will review individual proposals and be on the review panel. If you cannot find the person ' \
            f'you are looking for, please <a href="{reviewer_add_url}">add a Reviewer type of user</a> and reload ' \
            f'this page.'

        self.fields['reviewers'] = ReviewerMultipleChoiceField(initial=initial_reviewers,
                                                               queryset=Reviewer.objects.all(),
                                                               required=True,
                                                               widget=FilteredSelectMultiple(
                                                                   is_stacked=True,
                                                                   verbose_name='reviewers'),
                                                               help_text=reviewers_help_text)

        criterion_choices, criterion_initial = CheckboxSelectMultipleSortable.get_choices_initial(
            CriterionCallEvaluation,
            self.instance, 'call_evaluation',
            Criterion, 'criterion',
            label_from_instance=lambda obj: format_html('{} <small>({})</small>', obj.name, obj.description)
        )

        evaluation_criteria_list_url = reverse('logged-evaluation_criteria-list')
        list_edit_criteria = f'You can list and create criteria in <a href="{evaluation_criteria_list_url}">Evaluation criteria list</a>.'

        self.fields['criteria'] = forms.MultipleChoiceField(choices=criterion_choices,
                                                            initial=criterion_initial,
                                                            widget=CheckboxSelectMultipleSortable,
                                                            label='Criteria (drag and drop to order them)',
                                                            help_text=f'These criteria are used in the Excel Evaluation sheet. '
                                                                      f'{list_edit_criteria}'
                                                            )

        self.criteria_order_key = f'criteria-{CheckboxSelectMultipleSortable.order_of_values_name}'

        self.helper.layout = Layout(
            Div(
                Div('call', css_class='col-12', hidden=True),
                css_class='row'
            ),
            Div(
                Div('reviewers', css_class='col-12'),
                css_class='row'
            ),
            Div(
                Div('panel_date', css_class='col-12'),
                css_class='row'
            ),
            Div(
                Div('criteria', css_class='col-12'),
                css_class='row'
            ),
            Div(
                Div('post_panel_management_table', css_class='col-12'),
                css_class='row'
            ),
            FormActions(
                Submit('save', 'Save Call Evaluation'),
                cancel_edit_button(cancel_edit_url)
            )
        )
Пример #12
0
    def __init__(self, *args, **kwargs):
        assert 'instance' not in kwargs

        self._proposal = kwargs.pop('proposal')

        try:
            proposal_evaluation = ProposalEvaluation.objects.get(
                proposal=self._proposal)
            kwargs['instance'] = proposal_evaluation
        except ObjectDoesNotExist:
            pass

        super().__init__(*args, **kwargs)

        self.helper = FormHelper(self)
        self.helper.form_action = reverse('logged-proposal-evaluation-update',
                                          kwargs={'pk': self._proposal.id})

        XDSoftYearMonthDayPickerInput.set_format_to_field(
            self.fields['decision_date'])
        XDSoftYearMonthDayPickerInput.set_format_to_field(
            self.fields['decision_letter_date'])
        self.fields['proposal'].initial = self._proposal
        requested_budget = self._proposal.total_budget()

        self.fields['allocated_budget'] = FlexibleDecimalField(required=False)
        self.fields[
            'allocated_budget'].help_text = f'Requested: {thousands_separator(requested_budget)} CHF'
        self.fields['allocated_budget'].label = 'Allocated budget (CHF)'

        if hasattr(self._proposal, 'proposalevaluation'):
            cancel_button_url = reverse(
                'logged-proposal-evaluation-detail',
                kwargs={'pk': self._proposal.proposalevaluation.id})
            initial_reviewers = self._proposal.reviewer_set.all()
        else:
            cancel_button_url = reverse('logged-proposal-evaluation-add'
                                        ) + f'?proposal={self._proposal.id}'
            initial_reviewers = []

        self.fields['reviewers'] = ReviewerMultipleChoiceField(
            initial=initial_reviewers,
            queryset=Reviewer.objects.filter(calls=self._proposal.call),
            required=True,
            widget=FilteredSelectMultiple(is_stacked=True,
                                          verbose_name='reviewers'),
            help_text=self.Meta.help_texts['reviewers'])

        self.helper.layout = Layout(
            Div(Div('proposal', css_class='col-12'), css_class='row'),
            Div(Div('reviewers', css_class='col-12'), css_class='row'),
            Div(Div('panel_remarks', css_class='col-12'), css_class='row'),
            Div(Div('feedback_to_applicant', css_class='col-12'),
                css_class='row'),
            Div(Div('panel_recommendation', css_class='col-6'),
                Div('allocated_budget', css_class='col-6'),
                css_class='row'),
            Div(Div('board_decision', css_class='col-6'),
                Div('decision_date', css_class='col-6'),
                css_class='row'),
            Div(Div('decision_letter', css_class='col-6'),
                Div('decision_letter_date', css_class='col-6'),
                css_class='row'),
            FormActions(Submit('save', 'Save Evaluation'),
                        cancel_edit_button(cancel_button_url)))
Пример #13
0
    def __init__(self, *args, **kwargs):
        self._user = kwargs.pop(
            'user',
            None)  # When the form is created to visualise user is not needed
        # user is used when saving comments at the moment

        self._project = kwargs.pop('project')

        super().__init__(*args, **kwargs)

        self._comment_form = None

        if self.instance and self.instance.id:
            self.comment_prefix = f'comment-invoice-{self.instance.id}'
            self.comments = self.instance.comments()
            self.comment_count = len(self.comments)
            self.comments_save_text = 'Save Invoices'

            self._comment_form = CommentForm(
                form_action=reverse('logged-proposal-evaluation-comment-add',
                                    kwargs={'pk': self.instance.id}),
                category_queryset=self.instance.comment_object(
                ).category_queryset(),
                prefix=CommentForm.FORM_NAME,
                form_tag=False,
                fields_required=False)
            self.fields.update(self._comment_form.fields)

        self.fields['installment'].queryset = Installment.objects.filter(
            project=self._project).order_by('id')

        XDSoftYearMonthDayPickerInput.set_format_to_field(
            self.fields['due_date'])
        XDSoftYearMonthDayPickerInput.set_format_to_field(
            self.fields['sent_for_payment_date'])
        XDSoftYearMonthDayPickerInput.set_format_to_field(
            self.fields['received_date'])
        XDSoftYearMonthDayPickerInput.set_format_to_field(
            self.fields['paid_date'])

        self.fields['can_be_deleted'] = forms.CharField(initial=1,
                                                        required=False)

        installment_url = reverse(
            'logged-grant_management-installments-update',
            kwargs={'project': self._project.id})
        self.fields['installment'].help_text = f'Select the installment to which this invoice is assigned. ' \
                                               f'<a href="{installment_url}">Create an installment</a> if the one you ' \
                                               f'require does not exist'

        message = ''

        if self.instance:
            if self.instance.invoicecomment_set.exists():
                self.fields['can_be_deleted'].initial = 0
                message = 'This invoice cannot be removed because it has comments.'

            if self.instance.paid_date is not None:
                self.fields['can_be_deleted'].initial = 0
                message = '''<strong>This invoice has been paid and can no longer be changed.
                        To edit any of the fields, delete the date paid, click on <em>Save Invoices</em> 
                        and come back to the invoices page.</strong>'''

                field_names_to_disable = [
                    'due_date', 'received_date', 'sent_for_payment_date',
                    'file', 'amount', 'installment'
                ]

                if 'allow_overbudget' in self.fields:
                    field_names_to_disable.append('allow_overbudget')

                for field_name in field_names_to_disable:
                    self.fields[field_name].disabled = True

        self.helper = FormHelper()
        self.helper.form_tag = False

        # It's included in the main formset, it avoids problems when adding new invoices and the jquery.formset.js
        self.helper.disable_csrf = True

        divs = [
            Div(Div('id', hidden=True),
                Div(Field('DELETE', hidden=True)),
                Div('can_be_deleted', hidden=True, css_class='can_be_deleted'),
                css_class='row',
                hidden=True),
            Div(Div(HTML(f'<h4>{self.title()}</h4>'), css_class='col-12'),
                css_class='row'),
            Div(Div('installment', css_class='col-4'),
                Div(HTML(html_message(message)), css_class='col-8 to-delete'),
                css_class='row'),
            Div(Div('due_date', css_class='col-4'),
                Div('received_date', css_class='col-4'),
                Div('file', css_class='col-4'),
                css_class='row'),
            Div(Div('amount', css_class='col-4'),
                Div('sent_for_payment_date', css_class='col-4'),
                Div('paid_date', css_class='col-4'),
                css_class='row')
        ]

        self._add_allow_overbudget_checkbox(divs)

        if self._comment_form:
            divs += Div(
                HTML(
                    '{% include "comments/_accordion-comment-list-fields-for-new.tmpl" %}'
                ))

        self.helper.layout = Layout(*divs)