508 lines
18 KiB
Python
508 lines
18 KiB
Python
from django import forms
|
|
from django.urls import reverse, reverse_lazy
|
|
from django.utils.safestring import mark_safe
|
|
from django.utils.text import format_lazy
|
|
from django.utils.translation import ugettext_lazy as _
|
|
|
|
from crispy_forms.helper import FormHelper
|
|
from crispy_forms.layout import Submit, Layout, HTML, Fieldset, Div
|
|
from crispy_forms.bootstrap import Tab, TabHolder, PrependedText, FormActions
|
|
from dal import autocomplete
|
|
from leaflet.forms.widgets import LeafletWidget
|
|
|
|
from apps.files.models import File, ImageFile
|
|
|
|
from .models import CaseStudy, SpatialRefSys, PointOfInterest
|
|
from .widgets import JSONFileListWidget
|
|
|
|
|
|
SECTOR_HELP = {
|
|
'RN': _("Including electricity, heat or combined heat and power generation"),
|
|
'PG': '',
|
|
'ST': _('Biological, chemical, electrical, electromagnetic, electrochemical,'
|
|
' mechanical including gravitational potential, thermal, etc.'),
|
|
'SM': _("Including supply of minerals"),
|
|
'MA': '',
|
|
}
|
|
|
|
POWER_TECHNOLOGY_HELP = {
|
|
'PT': _('Lines, transformers, machinery, etc.'),
|
|
'HN': _('District heating/cooling, etc.'),
|
|
'OT': '',
|
|
}
|
|
|
|
def add_explanatory_text(model_choices, explanatory_text):
|
|
return [
|
|
(
|
|
choice[0],
|
|
mark_safe('<b>%s</b><br><span class="text-muted">%s</span>' %
|
|
(choice[1], explanatory_text[choice[0]])
|
|
)
|
|
) for choice in model_choices
|
|
]
|
|
|
|
|
|
|
|
class MinimumZoomWidget(LeafletWidget):
|
|
geometry_field_class = 'MinimumZoomField'
|
|
|
|
|
|
class PointOfInterest(forms.models.ModelForm):
|
|
def __init__(self, *args, **kwargs):
|
|
super(PointOfInterest, self).__init__(*args, **kwargs)
|
|
self.helper = FormHelper(self)
|
|
self.helper.form_id = 'case-study-form'
|
|
self.helper.form_class = 'form-horizontal'
|
|
self.helper.form_method = 'post'
|
|
self.helper.form_action = 'add'
|
|
self.helper.label_class = 'col-lg-2'
|
|
self.helper.field_class = 'col-lg-10'
|
|
self.helper.include_media = False
|
|
|
|
self.helper.form_action = reverse('point-of-interest-form')
|
|
self.helper.add_input(
|
|
Submit('submit', _('Submit'), css_class='btn-success center-block')
|
|
)
|
|
|
|
class Meta:
|
|
model = PointOfInterest
|
|
|
|
widgets = {
|
|
'location': MinimumZoomWidget(attrs={
|
|
'settings_overrides': {
|
|
'SCALE': False
|
|
}
|
|
}),
|
|
}
|
|
|
|
fields = [
|
|
'title',
|
|
'location',
|
|
'synopsis',
|
|
'link',
|
|
]
|
|
|
|
|
|
class BaseCaseStudyForm(forms.models.ModelForm):
|
|
"""Base form class for the CaseStudy model."""
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(BaseCaseStudyForm, self).__init__(*args, **kwargs)
|
|
self.helper = FormHelper(self)
|
|
self.helper.form_id = 'case-study-form'
|
|
self.helper.form_class = 'form-horizontal'
|
|
self.helper.form_method = 'post'
|
|
self.helper.label_class = 'col-md-3'
|
|
self.helper.field_class = 'col-md-9'
|
|
self.helper.include_media = False
|
|
|
|
class Meta:
|
|
model = CaseStudy
|
|
fields = '__all__'
|
|
widgets = {
|
|
'location': MinimumZoomWidget(attrs={
|
|
'settings_overrides': {
|
|
'SCALE': False
|
|
}
|
|
}),
|
|
}
|
|
|
|
|
|
class ShortCaseStudyForm(BaseCaseStudyForm):
|
|
"""Short version of the CaseStudy form."""
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(ShortCaseStudyForm, self).__init__(*args, **kwargs)
|
|
self.helper.add_input(Submit('submit', _('Submit'), css_class='btn-success center-block'))
|
|
|
|
# Duplicate code from long form, below...
|
|
self.fields['sector_of_economy'] = forms.ChoiceField(
|
|
widget=forms.RadioSelect(),
|
|
choices=add_explanatory_text(
|
|
CaseStudy.SECTOR_CHOICES,
|
|
SECTOR_HELP
|
|
),
|
|
required=False
|
|
)
|
|
|
|
class Meta(BaseCaseStudyForm.Meta):
|
|
fields = [
|
|
'entry_name',
|
|
'location',
|
|
'sector_of_economy',
|
|
'positive_or_negative',
|
|
'country',
|
|
'area_of_land',
|
|
'land_ownership',
|
|
'land_ownership_details',
|
|
'location_context',
|
|
'type_of_ecosystem',
|
|
'describe_ecosystem',
|
|
'affected_communities',
|
|
'project_status',
|
|
'synopsis',
|
|
'full_description',
|
|
'video',
|
|
'media_coverage_mainstream',
|
|
'media_coverage_independent',
|
|
'community_voices'
|
|
]
|
|
|
|
|
|
class BootstrapClearableFileInput(forms.ClearableFileInput):
|
|
template_name = 'map/forms/widgets/file.html'
|
|
|
|
|
|
def PreviousButton():
|
|
return HTML(
|
|
format_lazy(
|
|
"<a class='btn btn-primary btnPrevious'>{prev}</a>",
|
|
prev=_("Previous")
|
|
)
|
|
)
|
|
|
|
|
|
def NextButton():
|
|
return HTML(
|
|
format_lazy(
|
|
"<a class='btn btn-primary btnNext pull-right'>{next}</a>",
|
|
next=_("Next")
|
|
)
|
|
)
|
|
|
|
|
|
class LongCaseStudyForm(BaseCaseStudyForm):
|
|
"""Long version of the CaseStudy form."""
|
|
|
|
images = forms.FileField(
|
|
widget=BootstrapClearableFileInput(attrs={
|
|
'url': reverse_lazy('files:upload'),
|
|
'field': 'images_files',
|
|
}), required=False
|
|
)
|
|
|
|
images_files = forms.ModelMultipleChoiceField(
|
|
queryset=ImageFile.objects.all(),
|
|
widget=JSONFileListWidget(),
|
|
required=False
|
|
)
|
|
|
|
official_project_documents = forms.FileField(
|
|
widget=BootstrapClearableFileInput(attrs={
|
|
'url': reverse_lazy('files:upload'),
|
|
'field': 'official_project_documents_files',
|
|
}), required=False
|
|
)
|
|
|
|
official_project_documents_files = forms.ModelMultipleChoiceField(
|
|
queryset=File.objects.all(),
|
|
widget=JSONFileListWidget(),
|
|
required=False
|
|
)
|
|
|
|
other_documents = forms.FileField(
|
|
widget=BootstrapClearableFileInput(attrs={
|
|
'url': reverse_lazy('files:upload'),
|
|
'field': 'other_documents_files',
|
|
}), required=False
|
|
)
|
|
|
|
other_documents_files = forms.ModelMultipleChoiceField(
|
|
queryset=File.objects.all(),
|
|
widget=JSONFileListWidget(),
|
|
required=False
|
|
)
|
|
|
|
shapefiles = forms.FileField(
|
|
label=CaseStudy.shapefiles_label,
|
|
help_text=CaseStudy.shapefiles_help_text,
|
|
widget=BootstrapClearableFileInput(attrs={
|
|
'url': reverse_lazy('files:upload'),
|
|
'field': 'shapefiles_files',
|
|
}), required=False
|
|
)
|
|
|
|
shapefiles_files = forms.ModelMultipleChoiceField(
|
|
queryset=File.objects.all(),
|
|
widget=JSONFileListWidget(),
|
|
required=False
|
|
)
|
|
|
|
coordinate_reference_system = forms.ModelChoiceField(
|
|
queryset=SpatialRefSys.objects.all(),
|
|
widget=autocomplete.ModelSelect2(url='srs-autocomplete'),
|
|
initial=4326,
|
|
)
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(LongCaseStudyForm, self).__init__(*args, **kwargs)
|
|
|
|
self.fields['positive_case_type'].label = ""
|
|
self.fields['negative_case_reasons'].label = ""
|
|
|
|
self.fields['sector_of_economy'] = forms.ChoiceField(
|
|
widget=forms.RadioSelect(),
|
|
choices=add_explanatory_text(
|
|
CaseStudy.SECTOR_CHOICES,
|
|
SECTOR_HELP
|
|
),
|
|
required=False
|
|
)
|
|
|
|
self.fields['power_technology'] = forms.ChoiceField(
|
|
widget=forms.RadioSelect(),
|
|
choices=add_explanatory_text(
|
|
CaseStudy.POWER_TECHNOLOGY_CHOICES,
|
|
POWER_TECHNOLOGY_HELP
|
|
),
|
|
required=False
|
|
)
|
|
|
|
self.fields['project_owners'].required = True
|
|
self.fields['shareholders'].required = True
|
|
|
|
organising_vs_label = _(
|
|
'Socio-environmental impacts (negative and potentially positive)')
|
|
organising_pro_label = _(
|
|
'Socio-environmental impacts (positive and potentially negative)')
|
|
organising_other_label = _(
|
|
'Socio-environmental impacts (positive and negative)')
|
|
|
|
self.fields['socioeconomic_benefits'].label = format_lazy(
|
|
(
|
|
'<span class="organising organising-vs">{vs}</span>'
|
|
'<span class="organising organising-pro">{pro}</span>'
|
|
'<span class="organising organising-none organising-idk">{other}</span>'
|
|
),
|
|
vs=organising_vs_label,
|
|
pro=organising_pro_label,
|
|
other=organising_other_label
|
|
)
|
|
|
|
organising_other_text = _(
|
|
'Please expand on your response given in the full description on page one.'
|
|
' For example, for positive impacts you need to go beyond emissions'
|
|
' savings, paying rent for land, or complying with environmental or social'
|
|
' legislation. For negative impacts you need to focus on substantive'
|
|
' impacts on vulnerable groups, violations of land rights or abusive labour'
|
|
' practices.')
|
|
|
|
organising_vs_text = _(
|
|
'Please expand on your response given in the description. Note that we aim'
|
|
' to focus on violation of land rights / human rights / collective rights,'
|
|
' substantive negative impacts on vulnerable groups, aggression / threats /'
|
|
' violence severe environmental and/or cultural impacts, abusive labor '
|
|
' practices, and corruption / governance issues, but feel free to cover any'
|
|
' additional aspect that you consider relevant. Please also describe and'
|
|
' analyze socio-environmental impacts that could be presented or considered'
|
|
' as positive.')
|
|
|
|
organising_pro_text = _(
|
|
'Please expand on your response given in the description. Please also'
|
|
' describe and analyze socio-environmental impacts that could be considered'
|
|
' as negative.')
|
|
|
|
self.fields['socioeconomic_benefits'].help_text = format_lazy(
|
|
(
|
|
'<span class="organising organising-none organising-idk">{other}</span>'
|
|
'<span class="organising organising-vs">{vs}</span>'
|
|
'<span class="organising organising-pro">{pro}</span>'
|
|
),
|
|
vs=organising_vs_text,
|
|
pro=organising_pro_text,
|
|
other=organising_other_text
|
|
)
|
|
|
|
|
|
self.helper.form_action = reverse('long-form')
|
|
self.helper.layout = Layout(
|
|
TabHolder(
|
|
Tab(_("Basic information"),
|
|
'entry_name',
|
|
'location',
|
|
'country',
|
|
'shapefiles',
|
|
'shapefiles_files',
|
|
'coordinate_reference_system',
|
|
'name_of_territory_or_area',
|
|
'area_of_land',
|
|
'land_ownership',
|
|
'land_ownership_details',
|
|
'location_context',
|
|
'type_of_ecosystem',
|
|
'describe_ecosystem',
|
|
'affected_communities',
|
|
'people_affected_other',
|
|
'project_status',
|
|
'start_year',
|
|
'completion_year',
|
|
'synopsis',
|
|
'full_description',
|
|
'images',
|
|
'images_files',
|
|
'video',
|
|
'video_caption',
|
|
'video_credit',
|
|
Fieldset(
|
|
_("Owners and financiers"),
|
|
'project_owners',
|
|
'consultants_contractors',
|
|
'shareholders',
|
|
'financial_institutions',
|
|
'financial_institutions_other',
|
|
),
|
|
Fieldset(
|
|
_("Media reports and other communications"),
|
|
'media_coverage_mainstream',
|
|
'media_coverage_independent',
|
|
'community_voices',
|
|
'direct_comms',
|
|
'social_media_links'
|
|
),
|
|
FormActions(
|
|
NextButton()
|
|
)
|
|
),
|
|
Tab(
|
|
_("Technical and economic analysis"),
|
|
'sector_of_economy',
|
|
Div(
|
|
'generation_type',
|
|
'generation_technology',
|
|
css_class='power_generation_questions'
|
|
),
|
|
Div(
|
|
'power_technology',
|
|
css_class='energy_network_questions'
|
|
),
|
|
Div(
|
|
'energy_details',
|
|
css_class='energy_generation_network_and_storage_questions'
|
|
),
|
|
Div(
|
|
'biomass_detail',
|
|
'total_generation_capacity',
|
|
css_class='power_generation_questions'
|
|
),
|
|
Div(
|
|
'energy_transmission_capacity',
|
|
css_class='energy_network_questions'
|
|
),
|
|
Div(
|
|
'energy_storage_capacity',
|
|
css_class='energy_storage_questions'
|
|
),
|
|
Div(
|
|
PrependedText('total_investment', 'USD $'),
|
|
'contractor_or_supplier_of_technology',
|
|
'energy_customers',
|
|
'additional_technical_details',
|
|
css_class='energy_generation_network_and_storage_questions'
|
|
),
|
|
|
|
Div(
|
|
'minerals_or_commodities',
|
|
'minerals_or_commodities_other',
|
|
'use_in_energy_economy',
|
|
'use_in_energy_economy_other',
|
|
'project_life_span',
|
|
'size_of_concessions',
|
|
'projected_production_of_commodities',
|
|
'type_of_extraction',
|
|
'associated_infrastructure',
|
|
css_class="mineral_commodity_questions"
|
|
),
|
|
Div(
|
|
'manufacturing_type',
|
|
'manufacturing_description',
|
|
'manufacturing_related_tech',
|
|
'manufacturing_factors',
|
|
'manufacturing_factors_description',
|
|
'manufacturing_ownership',
|
|
css_class="manufacturing_questions"
|
|
),
|
|
FormActions(
|
|
PreviousButton(),
|
|
NextButton()
|
|
)
|
|
),
|
|
Tab(
|
|
_("Socio-environmental analysis"),
|
|
HTML(
|
|
format_lazy(
|
|
"<p>{text}</p>",
|
|
text=_(
|
|
"In the following, we expect the analysis to reflect "
|
|
" the perspective of the organization(s) or person(s) "
|
|
" describing the case.")
|
|
)
|
|
),
|
|
'positive_or_negative',
|
|
Div(
|
|
HTML(
|
|
format_lazy(
|
|
"<label class='col-md-3 control-label'>{text}</label>",
|
|
text=_("What kind of case is this entry about?")
|
|
)
|
|
),
|
|
Div(
|
|
'positive_case_type',
|
|
'negative_case_reasons',
|
|
css_class='col-md-9',
|
|
),
|
|
css_class='form-group',
|
|
),
|
|
'negative_case_reasons_other',
|
|
'socioeconomic_benefits',
|
|
'isolated_or_widespread',
|
|
'key_actors_involved',
|
|
'project_status_detail',
|
|
'obstacles_and_hindrances',
|
|
'negative_socioenvironmental_impacts',
|
|
'when_did_organising_start',
|
|
'who_has_been_involved',
|
|
'participation_mechanisms',
|
|
'identified_partnerships',
|
|
Div(
|
|
css_class="common_questions"
|
|
),
|
|
FormActions(
|
|
PreviousButton(),
|
|
NextButton()
|
|
)
|
|
),
|
|
Tab(
|
|
_("Contact details"),
|
|
'contact_email',
|
|
'contact_phone',
|
|
'contact_website',
|
|
PrependedText('contact_twitter', '@', placeholder='username'),
|
|
'contact_facebook',
|
|
'contact_other',
|
|
'shown_on_other_platforms',
|
|
'shown_on_other_platforms_detail',
|
|
FormActions(
|
|
PreviousButton(),
|
|
NextButton()
|
|
)
|
|
),
|
|
Tab(
|
|
_("Uploads"),
|
|
'official_project_documents',
|
|
'official_project_documents_files',
|
|
'other_documents',
|
|
'other_documents_files',
|
|
FormActions(
|
|
PreviousButton(),
|
|
Submit('submit', _('Submit'), css_class="btn-success pull-right")
|
|
)
|
|
)))
|
|
|
|
class Meta(BaseCaseStudyForm.Meta):
|
|
exclude = ('approved',)
|
|
|
|
class Media:
|
|
js = (
|
|
'files/upload.js',
|
|
)
|