1010
1111from api .models import AccessEnablement , ApprovalWorkflow , BusinessCase , MigrationIntakeSubmission , ProjectResources , StakeholderRegistration
1212from api .permissions .attributes_access import build_access_snapshot , get_request_email , normalize_email
13- from api .services .business_case import online_case_is_approved
13+ from api .services .business_case import approval_progress , build_business_case , case_status , online_case_is_approved
1414from api .services .project_artefacts import (
1515 AREA_FIELDS , BARRIER_TYPES , EXECUTION_FIELDS , HIRING_STATUSES , HIRING_TYPES ,
1616 HR_FIELDS , IT_ITEMS , LANGUAGES , SYSTEM_CATALOGUE , access_summary , date_value ,
2020
2121def _serialize (project , record , kind , email ):
2222 source = scope_source (project )
23+ business_case = BusinessCase .objects .filter (project = project ).first ()
24+ business_case_source = {"locked" : False , "status" : "not_started" , "population" : None }
25+ if business_case :
26+ _ , business_case_scope , _ , fingerprint = build_business_case (project , business_case )
27+ business_case_status = case_status (business_case , fingerprint , approval_progress (project ))
28+ locked = business_case_status in {"submitted" , "approved" }
29+ business_case_source = {
30+ "locked" : locked ,
31+ "status" : business_case_status ,
32+ "population" : sum (line ["finalFte" ] or 0 for line in business_case_scope ["lines" ]) if locked else None ,
33+ }
2334 permissions = project_permissions (project , email , kind )
2435 changed = bool (record and record .source_version != source ["version" ])
2536 result = {
@@ -28,6 +39,7 @@ def _serialize(project, record, kind, email):
2839 "region" : project .region , "areas" : project .areas , "countries" : project .countries ,
2940 "products" : project .products ,
3041 "sites" : (project .default_location_strategies or []) + (project .custom_location_strategies or []),
42+ "businessCase" : business_case_source ,
3143 "source" : source , "sourceChanged" : changed , "permissions" : permissions ,
3244 "saved" : record is not None , "revision" : record .revision if record else 0 ,
3345 "updatedAt" : record .updated_at .isoformat () if record else "" ,
@@ -82,7 +94,7 @@ def _resource_rows(payload, record, permissions, action, email):
8294 value = row .get (field , "" )
8395 normalized [field ] = date_value (value , field ) if field .endswith ("Date" ) or field .endswith ("Doj" ) else text (value , field )
8496 if normalized ["hiringType" ] not in HIRING_TYPES :
85- raise ValueError ("Choose External, IJP or Efficiency for each resource." )
97+ raise ValueError ("Choose Efficiency, Backfill, External or IJP for each resource." )
8698 if normalized ["language" ] and normalized ["language" ] not in LANGUAGES :
8799 raise ValueError ("Choose a language from the catalogue." )
88100 if normalized ["hiringStatus" ] not in HIRING_STATUSES + ["Not Applicable" ]:
@@ -316,7 +328,7 @@ def resource_projects(request):
316328 if any (normalize_email (person .get ("email" )) == email for person in registration .team_members )
317329 ]
318330 projects = projects .filter (Q (requestor__iexact = email ) | Q (pk__in = member_projects ))
319- online = {case .project_id : case for case in BusinessCase .objects .only ( "project_id" , "status" , "review_required " )}
331+ online = {case .project_id : case for case in BusinessCase .objects .select_related ( "project " )}
320332 from api .views .approval_cycle import _progress
321333 legacy_progress = {
322334 workflow .migration_request_id : _progress (workflow )
@@ -326,24 +338,31 @@ def resource_projects(request):
326338 for project in projects .order_by ("-id" ):
327339 source = scope_source (project )
328340 case = online .get (project .pk )
341+ business_case = {"locked" : False , "status" : "not_started" , "population" : None }
329342 if case :
330- approved = case .status == "submitted" and not case .review_required and bool (online_case_is_approved (project ))
343+ _ , business_case_scope , _ , fingerprint = build_business_case (project , case )
344+ business_case_status = case_status (case , fingerprint , approval_progress (project ))
345+ business_case ["locked" ] = business_case_status in {"submitted" , "approved" }
346+ business_case ["status" ] = business_case_status
347+ business_case ["population" ] = sum (line ["finalFte" ] or 0 for line in business_case_scope ["lines" ]) if business_case ["locked" ] else None
348+ approved = business_case ["status" ] == "approved"
331349 else :
332350 progress = legacy_progress .get (project .migration_request_id )
333351 approved = bool (project .business_case_submission_date and progress and progress ["step" ] > progress ["seqLen" ] and progress ["completed" ])
334352 try :
335353 resource = project .resources
336354 except ProjectResources .DoesNotExist :
337355 resource = None
338- population = source ["population" ]
356+ population = business_case ["population" ]
339357 rows .append ({
340358 "projectId" : project .pk , "projectName" : project .project_name ,
341359 "migrationRequestId" : project .migration_request_id , "products" : project .products ,
342360 "region" : project .region , "areas" : project .areas ,
343361 "sites" : (project .default_location_strategies or []) + (project .custom_location_strategies or []),
344362 "approvedFte" : population if approved else None ,
345- "pipelineFte" : population if not approved else None ,
346- "approvalStatus" : "Approved" if approved else "Pipeline" ,
363+ "pipelineFte" : population if business_case ["locked" ] and not approved else None ,
364+ "approvalStatus" : "Approved" if approved else "Pipeline" if business_case ["locked" ] else "Not locked" ,
365+ "businessCase" : business_case ,
347366 "saved" : bool (resource ),
348367 "status" : ("confirmed" if resource .source_version == source ["version" ] else "needs_review" )
349368 if resource and resource .status == "confirmed" else "draft" if resource else "not_started" ,
0 commit comments