@@ -24,19 +24,27 @@ public class ApplicationPreviewModel : PageModel
2424
2525 private readonly IFieldRendererService _renderer ;
2626 private readonly IFormTemplateProvider _templateProvider ;
27+ private readonly IFormTemplateParser _templateParser ;
2728 private readonly IApplicationResponseService _applicationResponseService ;
2829 private readonly IApplicationsClient _applicationsClient ;
2930 private readonly ILogger < ApplicationPreviewModel > _logger ;
3031
32+ /// <summary>
33+ /// Stores the current application data to access template schema for existing applications
34+ /// </summary>
35+ private ApplicationDto ? _currentApplication ;
36+
3137 public ApplicationPreviewModel (
3238 IFieldRendererService renderer ,
3339 IFormTemplateProvider templateProvider ,
40+ IFormTemplateParser templateParser ,
3441 IApplicationResponseService applicationResponseService ,
3542 IApplicationsClient applicationsClient ,
3643 ILogger < ApplicationPreviewModel > logger )
3744 {
3845 _renderer = renderer ;
3946 _templateProvider = templateProvider ;
47+ _templateParser = templateParser ;
4048 _applicationResponseService = applicationResponseService ;
4149 _applicationsClient = applicationsClient ;
4250 _logger = logger ;
@@ -145,9 +153,56 @@ public bool IsApplicationEditable()
145153 return ApplicationStatus . Equals ( "InProgress" , StringComparison . OrdinalIgnoreCase ) ;
146154 }
147155
156+ /// <summary>
157+ /// Loads the appropriate template schema based on whether this is a new or existing application.
158+ /// For new applications, loads the latest template schema.
159+ /// For existing applications, loads the template schema version that was used when the application was created.
160+ /// </summary>
148161 private async Task LoadTemplateAsync ( )
149162 {
150- Template = await _templateProvider . GetTemplateAsync ( TemplateId ) ;
163+ try
164+ {
165+ // If we have an existing application with template schema, use that version
166+ if ( _currentApplication ? . TemplateSchema != null )
167+ {
168+ _logger . LogDebug ( "Using template schema from existing application {ApplicationId} with template version {TemplateVersionId}" ,
169+ _currentApplication . ApplicationId , _currentApplication . TemplateVersionId ) ;
170+
171+ Template = await LoadTemplateFromSchemaAsync ( _currentApplication . TemplateSchema . JsonSchema ) ;
172+ }
173+ else
174+ {
175+ // For new applications or when template schema is not available, use the latest template
176+ _logger . LogDebug ( "Loading latest template schema for template {TemplateId}" , TemplateId ) ;
177+ Template = await _templateProvider . GetTemplateAsync ( TemplateId ) ;
178+ }
179+ }
180+ catch ( Exception ex )
181+ {
182+ _logger . LogError ( ex , "Failed to load template {TemplateId}" , TemplateId ) ;
183+ throw ;
184+ }
185+ }
186+
187+ /// <summary>
188+ /// Converts a TemplateSchemaDto to a FormTemplate using the template parser.
189+ /// This ensures consistent parsing logic regardless of the template source.
190+ /// </summary>
191+ private async Task < FormTemplate > LoadTemplateFromSchemaAsync ( string templateSchema )
192+ {
193+ try
194+ {
195+ // Convert to stream for parser
196+ using var stream = new MemoryStream ( System . Text . Encoding . UTF8 . GetBytes ( templateSchema ) ) ;
197+
198+ // Use the same parser that's used for API templates to ensure consistency
199+ return await _templateParser . ParseAsync ( stream ) ;
200+ }
201+ catch ( Exception ex )
202+ {
203+ _logger . LogError ( ex , "Failed to parse template schema from application" ) ;
204+ throw new InvalidOperationException ( "Failed to parse template schema from application" , ex ) ;
205+ }
151206 }
152207
153208 public string GetFieldValue ( string fieldId )
@@ -483,9 +538,18 @@ public bool AreAllTasksCompleted()
483538 return result ;
484539 }
485540
486- private async Task EnsureApplicationIdAsync ( )
541+ private async Task EnsureApplicationIdAsync ( )
487542 {
488- // First try to get ApplicationId from session (for newly created applications)
543+ // First check if we have template schema stored in session for this reference
544+ var templateSchemaKey = $ "TemplateSchema_{ ReferenceNumber } ";
545+ var templateVersionIdKey = $ "TemplateVersionId_{ ReferenceNumber } ";
546+ var templateVersionNoKey = $ "TemplateVersionNo_{ ReferenceNumber } ";
547+ var storedTemplateSchema = HttpContext . Session . GetString ( templateSchemaKey ) ;
548+ var storedTemplateVersionId = HttpContext . Session . GetString ( templateVersionIdKey ) ;
549+ var storedTemplateId = HttpContext . Session . GetString ( "TemplateId" ) ;
550+ var storedTemplateVersionNo = HttpContext . Session . GetString ( templateVersionNoKey ) ;
551+
552+ // Check if we have basic application data in session
489553 var applicationIdString = HttpContext . Session . GetString ( "ApplicationId" ) ;
490554 var sessionReference = HttpContext . Session . GetString ( "ApplicationReference" ) ;
491555
@@ -496,22 +560,62 @@ private async Task EnsureApplicationIdAsync()
496560 if ( Guid . TryParse ( applicationIdString , out var sessionAppId ) )
497561 {
498562 ApplicationId = sessionAppId ;
499- return ;
563+
564+ // If we have template schema in session, create a minimal ApplicationDto
565+ if ( ! string . IsNullOrEmpty ( storedTemplateSchema ) && ! string . IsNullOrEmpty ( storedTemplateVersionId ) )
566+ {
567+ _currentApplication = new ApplicationDto
568+ {
569+ ApplicationId = sessionAppId ,
570+ ApplicationReference = sessionReference ,
571+ TemplateVersionId = Guid . Parse ( storedTemplateVersionId ) ,
572+ TemplateSchema = new TemplateSchemaDto
573+ {
574+ JsonSchema = storedTemplateSchema ,
575+ TemplateVersionId = new Guid ( storedTemplateVersionId ) ,
576+ TemplateId = new Guid ( storedTemplateId ) ,
577+ VersionNumber = storedTemplateVersionNo ?? String . Empty
578+
579+ }
580+ } ;
581+
582+ _logger . LogDebug ( "Using cached template schema for application {ApplicationId} with template version {TemplateVersionId}" ,
583+ sessionAppId , storedTemplateVersionId ) ;
584+ return ;
585+ }
586+ else
587+ {
588+ // For newly created applications, we don't have template schema
589+ _logger . LogDebug ( "Using session-based application {ApplicationId} (no template schema available)" , sessionAppId ) ;
590+ return ;
591+ }
500592 }
501593 }
502594
503- // If not in session or different reference, try to get from API
595+ // If not in session or incomplete data, fetch from API
504596 try
505597 {
506598 var application = await _applicationsClient . GetApplicationByReferenceAsync ( ReferenceNumber ) ;
507599
508600 if ( application != null )
509601 {
510602 ApplicationId = application . ApplicationId ;
511- // Store in session for future use
603+ _currentApplication = application ; // Store for template loading
604+
605+ // Store application data in session for future use
512606 HttpContext . Session . SetString ( "ApplicationId" , application . ApplicationId . ToString ( ) ) ;
513607 HttpContext . Session . SetString ( "ApplicationReference" , application . ApplicationReference ) ;
514-
608+
609+ // Store template schema in session for future use
610+ if ( application . TemplateSchema ? . JsonSchema != null )
611+ {
612+ HttpContext . Session . SetString ( templateSchemaKey , application . TemplateSchema . JsonSchema ) ;
613+ HttpContext . Session . SetString ( templateVersionIdKey , application . TemplateVersionId . ToString ( ) ) ;
614+
615+ _logger . LogDebug ( "Cached template schema for reference {ReferenceNumber} with template version {TemplateVersionId}" ,
616+ ReferenceNumber , application . TemplateVersionId ) ;
617+ }
618+
515619 // Store application status in session
516620 if ( application . Status != null )
517621 {
@@ -521,6 +625,10 @@ private async Task EnsureApplicationIdAsync()
521625
522626 // Load existing response data into session for existing applications
523627 await LoadResponseDataIntoSessionAsync ( application ) ;
628+
629+ _logger . LogDebug ( "Loaded application {ApplicationId} from API with template version {TemplateVersionId}" ,
630+ application . ApplicationId , application . TemplateVersionId ) ;
631+ return ;
524632 }
525633 else
526634 {
@@ -529,8 +637,10 @@ private async Task EnsureApplicationIdAsync()
529637 }
530638 catch ( Exception ex )
531639 {
532- _logger . LogError ( ex , "Failed to retrieve application information for reference {ReferenceNumber}" , ReferenceNumber ) ;
640+ _logger . LogError ( ex , "Failed to retrieve application information from API for reference {ReferenceNumber}" , ReferenceNumber ) ;
533641 }
642+
643+ _logger . LogWarning ( "Could not determine ApplicationId for reference {ReferenceNumber}" , ReferenceNumber ) ;
534644 }
535645
536646 private async Task LoadResponseDataIntoSessionAsync ( ApplicationDto application )
0 commit comments