diff --git a/src/Altinn.App.Core/Features/IInstanceDataAccessor.cs b/src/Altinn.App.Core/Features/IInstanceDataAccessor.cs
index f814b70e18..cbeac60344 100644
--- a/src/Altinn.App.Core/Features/IInstanceDataAccessor.cs
+++ b/src/Altinn.App.Core/Features/IInstanceDataAccessor.cs
@@ -76,7 +76,7 @@ public interface IInstanceDataAccessor
/// directly in the expression evaluator.
///
///
- internal LayoutEvaluatorState? GetLayoutEvaluatorState();
+ internal LayoutEvaluatorState GetLayoutEvaluatorState();
///
/// Set the authentication method used when reading and writing data of the given data type.
diff --git a/src/Altinn.App.Core/Internal/Data/CleanInstanceDataAccessor.cs b/src/Altinn.App.Core/Internal/Data/CleanInstanceDataAccessor.cs
index 7ff465cf1b..5f502909de 100644
--- a/src/Altinn.App.Core/Internal/Data/CleanInstanceDataAccessor.cs
+++ b/src/Altinn.App.Core/Internal/Data/CleanInstanceDataAccessor.cs
@@ -144,7 +144,7 @@ public DataElement GetDataElement(DataElementIdentifier dataElementIdentifier)
return _dataAccessor.GetDataElement(dataElementIdentifier);
}
- public LayoutEvaluatorState? GetLayoutEvaluatorState()
+ public LayoutEvaluatorState GetLayoutEvaluatorState()
{
throw new NotImplementedException(
"GetLayoutEvaluatorState is not implemented in CleanInstanceDataAccessor, because LayoutEvaluatorState will be deprecated."
diff --git a/src/Altinn.App.Core/Internal/Data/InstanceDataUnitOfWork.cs b/src/Altinn.App.Core/Internal/Data/InstanceDataUnitOfWork.cs
index 737a8a4fcf..2c1a4b30f8 100644
--- a/src/Altinn.App.Core/Internal/Data/InstanceDataUnitOfWork.cs
+++ b/src/Altinn.App.Core/Internal/Data/InstanceDataUnitOfWork.cs
@@ -181,19 +181,15 @@ public IInstanceDataAccessor GetPreviousDataAccessor()
private LayoutEvaluatorState? _layoutEvaluatorStateCache;
- public LayoutEvaluatorState? GetLayoutEvaluatorState()
+ public LayoutEvaluatorState GetLayoutEvaluatorState()
{
- if (TaskId is null)
- {
- return null;
- }
if (_layoutEvaluatorStateCache is not null)
{
return _layoutEvaluatorStateCache;
}
// Could use a double lock here, but a deadlock is more problematic than creating the state twice
- var layouts = _appResources.GetLayoutModelForTask(TaskId);
+ var layouts = TaskId is null ? null : _appResources.GetLayoutModelForTask(TaskId);
_layoutEvaluatorStateCache = new LayoutEvaluatorState(
this,
diff --git a/src/Altinn.App.Core/Internal/Data/PreviousDataAccessor.cs b/src/Altinn.App.Core/Internal/Data/PreviousDataAccessor.cs
index e2f8eae169..df9f67e893 100644
--- a/src/Altinn.App.Core/Internal/Data/PreviousDataAccessor.cs
+++ b/src/Altinn.App.Core/Internal/Data/PreviousDataAccessor.cs
@@ -19,7 +19,7 @@ internal class PreviousDataAccessor : IInstanceDataAccessor
private readonly FrontEndSettings _frontEndSettings;
private readonly ITranslationService _translationService;
private readonly Telemetry? _telemetry;
- private readonly Lazy _layoutEvaluatorState;
+ private readonly Lazy _layoutEvaluatorState;
private readonly ConcurrentDictionary> _previousDataCache = new();
@@ -41,7 +41,7 @@ public PreviousDataAccessor(
_layoutEvaluatorState = new(() =>
{
var originalState = _dataAccessor.GetLayoutEvaluatorState();
- return originalState?.WithDataAccessor(this);
+ return originalState.WithDataAccessor(this);
});
}
@@ -106,7 +106,7 @@ public IInstanceDataAccessor GetPreviousDataAccessor()
return this;
}
- public LayoutEvaluatorState? GetLayoutEvaluatorState()
+ public LayoutEvaluatorState GetLayoutEvaluatorState()
{
return _layoutEvaluatorState.Value;
}
diff --git a/src/Altinn.App.Core/Internal/Expressions/LayoutEvaluatorState.cs b/src/Altinn.App.Core/Internal/Expressions/LayoutEvaluatorState.cs
index ec766380f3..e06f0b8dbc 100644
--- a/src/Altinn.App.Core/Internal/Expressions/LayoutEvaluatorState.cs
+++ b/src/Altinn.App.Core/Internal/Expressions/LayoutEvaluatorState.cs
@@ -445,7 +445,7 @@ public async Task TranslateText(string textKey, ComponentContext context
return _componentModel?.DefaultDataType;
}
- internal LayoutEvaluatorState? WithDataAccessor(IInstanceDataAccessor dataAccessor)
+ internal LayoutEvaluatorState WithDataAccessor(IInstanceDataAccessor dataAccessor)
{
return new LayoutEvaluatorState(
dataAccessor,
diff --git a/src/Altinn.App.Core/Internal/Expressions/LayoutEvaluatorStateInitializer.cs b/src/Altinn.App.Core/Internal/Expressions/LayoutEvaluatorStateInitializer.cs
index 8e07cc1df9..c64712acae 100644
--- a/src/Altinn.App.Core/Internal/Expressions/LayoutEvaluatorStateInitializer.cs
+++ b/src/Altinn.App.Core/Internal/Expressions/LayoutEvaluatorStateInitializer.cs
@@ -115,7 +115,7 @@ public IInstanceDataAccessor GetPreviousDataAccessor()
throw new NotSupportedException("Legacy single data accessor does not implement GetPreviousDataAccessor");
}
- public LayoutEvaluatorState? GetLayoutEvaluatorState()
+ public LayoutEvaluatorState GetLayoutEvaluatorState()
{
return new LayoutEvaluatorState(
this,
diff --git a/src/Altinn.App.Core/Internal/Pdf/PdfService.cs b/src/Altinn.App.Core/Internal/Pdf/PdfService.cs
index 613638cf94..67cca960d4 100644
--- a/src/Altinn.App.Core/Internal/Pdf/PdfService.cs
+++ b/src/Altinn.App.Core/Internal/Pdf/PdfService.cs
@@ -1,9 +1,12 @@
using System.Globalization;
+using System.Text.Json;
using Altinn.App.Core.Configuration;
using Altinn.App.Core.Features;
using Altinn.App.Core.Features.Auth;
using Altinn.App.Core.Helpers.Extensions;
+using Altinn.App.Core.Internal.App;
using Altinn.App.Core.Internal.Data;
+using Altinn.App.Core.Internal.Expressions;
using Altinn.App.Core.Internal.Texts;
using Altinn.App.Core.Models;
using Altinn.App.Core.Models.Expressions;
@@ -21,6 +24,14 @@ namespace Altinn.App.Core.Internal.Pdf;
///
public class PdfService : IPdfService
{
+ private static readonly JsonSerializerOptions _jsonSerializerOptions = new()
+ {
+ AllowTrailingCommas = true,
+ ReadCommentHandling = JsonCommentHandling.Skip,
+ PropertyNameCaseInsensitive = true,
+ PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
+ };
+
private readonly IDataClient _dataClient;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IPdfGeneratorClient _pdfGeneratorClient;
@@ -29,6 +40,7 @@ public class PdfService : IPdfService
private readonly IAuthenticationContext _authenticationContext;
private readonly ITranslationService _translationService;
private readonly GeneralSettings _generalSettings;
+ private readonly IAppResources _resources;
private readonly InstanceDataUnitOfWorkInitializer? _instanceDataUnitOfWorkInitializer;
private readonly Telemetry? _telemetry;
internal const string PdfElementType = "ref-data-as-pdf";
@@ -46,6 +58,7 @@ public PdfService(
ILogger logger,
IAuthenticationContext authenticationContext,
ITranslationService translationService,
+ IAppResources resources,
IServiceProvider? serviceProvider = null,
Telemetry? telemetry = null
)
@@ -58,6 +71,7 @@ public PdfService(
_logger = logger;
_authenticationContext = authenticationContext;
_translationService = translationService;
+ _resources = resources;
_instanceDataUnitOfWorkInitializer = serviceProvider?.GetService();
_telemetry = telemetry;
}
@@ -206,7 +220,7 @@ CancellationToken ct
}
else if (displayFooter)
{
- footerContent = await GetFooterContent(instance, language);
+ footerContent = await GetFooterContent(instance, taskId, language);
}
Stream pdfContent = await _pdfGeneratorClient.GeneratePdf(uri, footerContent, ct);
@@ -338,7 +352,7 @@ private async Task GetPreviewFooter(string language)
";
}
- private async Task GetFooterContent(Instance instance, string? language)
+ private async Task GetFooterContent(Instance instance, string taskId, string? language)
{
TimeZoneInfo timeZone = TimeZoneInfo.Utc;
try
@@ -353,15 +367,19 @@ private async Task GetFooterContent(Instance instance, string? language)
DateTimeOffset now = TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow, timeZone);
- string title = await _translationService.TranslateTextKey("appName", language) ?? "Altinn";
+ bool hideAppName = await GetHideAppNameInPdf(instance, taskId, language);
string dateGenerated = now.ToString("dd.MM.yyyy HH:mm", new CultureInfo("nb-NO"));
string altinnReferenceId = instance.Id.Split("/")[1].Split("-")[4];
+ string title = hideAppName
+ ? string.Empty
+ : $"{await _translationService.TranslateTextKey("appName", language) ?? "Altinn"}";
+
string footerTemplate =
$@"