1+ from datetime import date
2+
13from django import forms
4+ from django .conf import settings
25from django .contrib .auth import get_user_model
36from django .db .models import Count , Q
47from django .utils .text import slugify
1013 get_project_default_status ,
1114 get_project_status_options ,
1215)
16+ from hypha .apply .projects .templatetags .project_tags import show_start_date
1317from hypha .apply .stream_forms .fields import SingleFileField
1418from hypha .apply .stream_forms .forms import StreamBaseForm
1519from hypha .apply .users .roles import STAFF_GROUP_NAME
@@ -86,16 +90,20 @@ class ProjectCreateForm(forms.Form):
8690 )
8791
8892 project_lead = forms .ModelChoiceField (
89- label = _ ("Select Project Lead " ), queryset = User .objects .all ()
93+ label = _ ("Select project lead " ), queryset = User .objects .all ()
9094 )
9195
9296 # Set the initial value to the settings default if valid, otherwise fall back to draft
9397 project_initial_status = forms .ChoiceField (
94- label = _ ("Initial Project Status " ),
98+ label = _ ("Initial project status " ),
9599 choices = get_project_status_options (),
96100 initial = get_project_default_status (),
97101 )
98102
103+ project_end = forms .DateField (
104+ label = _ ("Project end date" ),
105+ )
106+
99107 def __init__ (self , * args , instance = None , ** kwargs ):
100108 super ().__init__ (* args , ** kwargs )
101109
@@ -119,7 +127,24 @@ def save(self, *args, **kwargs):
119127 submission = self .cleaned_data ["submission" ]
120128 lead = self .cleaned_data ["project_lead" ]
121129 status = self .cleaned_data ["project_initial_status" ]
122- return Project .create_from_submission (submission , lead = lead , status = status )
130+ end_date = self .cleaned_data ["project_end" ]
131+
132+ start_date = None
133+
134+ if not settings .PROJECTS_START_AFTER_CONTRACTING or status in [
135+ INVOICING_AND_REPORTING ,
136+ CLOSING ,
137+ COMPLETE ,
138+ ]:
139+ start_date = date .today ()
140+
141+ return Project .create_from_submission (
142+ submission ,
143+ lead = lead ,
144+ status = status ,
145+ end_date = end_date ,
146+ start_date = start_date ,
147+ )
123148
124149
125150class MixedMetaClass (type (StreamBaseForm ), type (forms .ModelForm )):
@@ -444,3 +469,28 @@ class Meta:
444469
445470 def __init__ (self , * args , user = None , ** kwargs ):
446471 super ().__init__ (* args , ** kwargs )
472+
473+
474+ class UpdateProjectDatesForm (forms .ModelForm ):
475+ class Meta :
476+ fields = ["proposed_start" , "proposed_end" ]
477+ model = Project
478+
479+ def clean (self ):
480+ cleaned_data = super ().clean ()
481+ if (
482+ show_start_date (self .instance )
483+ and cleaned_data ["proposed_start" ] >= cleaned_data ["proposed_end" ]
484+ ):
485+ self .add_error (
486+ "proposed_end" , _ ("The end date must be after the start date." )
487+ )
488+
489+ def __init__ (self , * args , user = None , ** kwargs ):
490+ super ().__init__ (* args , ** kwargs )
491+ # Only show the start date field if relevant
492+ if not show_start_date (self .instance ):
493+ proposed_start = self .fields ["proposed_start" ]
494+ proposed_start .disabled = True
495+ proposed_start .required = False
496+ proposed_start .widget = proposed_start .hidden_widget ()
0 commit comments