Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/LageBuch.App/Services/IncidentHostController.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Globalization;
using System.Net;
using LageBuch.AppLogic;
using LageBuch.AppLogic.Services;
Expand Down Expand Up @@ -39,7 +40,7 @@ public async Task StartAsync(LocalIncidentSession session)
// A fresh 4-digit PIN per share session: the host reads it out, joiners type it (§ #64).
// Cryptographic RNG so the PIN isn't predictable from a seeded/observed sequence — cheap
// hardening even though a 4-digit space is small (brute-force is the accepted, documented risk).
var pin = System.Security.Cryptography.RandomNumberGenerator.GetInt32(0, 10_000).ToString("D4");
var pin = System.Security.Cryptography.RandomNumberGenerator.GetInt32(0, 10_000).ToString("D4", CultureInfo.InvariantCulture);
var host = new IncidentHost(session, _clock, _appVersion, _ui, pin);
await host.StartAsync(IPAddress.Any);
_host = host;
Expand Down
3 changes: 2 additions & 1 deletion src/LageBuch.AppLogic/ViewModels/HomeViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.ObjectModel;
using System.Globalization;
using System.Net.Sockets;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
Expand Down Expand Up @@ -81,7 +82,7 @@ private async Task NewIncidentAsync(NewIncidentRequest request)
// Date + time + Stichwort, e.g. "20260819-2217-B3P.fwincident" -- the Einsatznummer is
// unknown at creation (#69) and no longer part of the filename; it can be added later from
// the workspace header. No Stichwort at all just leaves the timestamp alone.
var timestamp = _clock.Now.ToString("yyyyMMdd-HHmm");
var timestamp = _clock.Now.ToString("yyyyMMdd-HHmm", CultureInfo.InvariantCulture);
var stem = string.IsNullOrWhiteSpace(request.Keyword)
? timestamp
: $"{timestamp}-{StripInvalidFileNameChars(request.Keyword.Trim())}";
Expand Down
3 changes: 2 additions & 1 deletion src/LageBuch.AppLogic/ViewModels/ScbaViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.ObjectModel;
using System.Globalization;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using LageBuch.AppLogic.Services;
Expand Down Expand Up @@ -70,7 +71,7 @@ public ScbaTruppRow(
public bool IsAlarm => _trupp.IsAlarm(_clock.Now);
public bool IsControlDue => _trupp.IsControlDue(_clock.Now);

public string StartTimeDisplay => _trupp.StartTime is { } s ? s.ToString("HH:mm") : "—";
public string StartTimeDisplay => _trupp.StartTime is { } s ? s.ToString("HH:mm", CultureInfo.InvariantCulture) : "—";
public string? PressureDisplay => _trupp.LatestPressure is { } p ? $"{p} bar" : null;

public string ElapsedDisplay => _trupp.HasStarted ? Clock(_trupp.Elapsed(_clock.Now)) : "—";
Expand Down
4 changes: 2 additions & 2 deletions src/LageBuch.AppLogic/ViewModels/TasksViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,13 @@ public TasksViewModel(
// Shared with TaskDialogViewModel (same assembly) so picker wording matches everywhere.
internal static IReadOnlyList<ImportanceOption> ImportanceLevels() =>
Enum.GetValues<TaskImportance>()
.OrderByDescending(v => Convert.ToInt32(v))
.OrderByDescending(v => (int)v)
.Select(v => new ImportanceOption(v, Formatting.Level(v)))
.ToArray();

internal static IReadOnlyList<UrgencyOption> UrgencyLevels() =>
Enum.GetValues<TaskUrgency>()
.OrderByDescending(v => Convert.ToInt32(v))
.OrderByDescending(v => (int)v)
.Select(v => new UrgencyOption(v, Formatting.Level(v)))
.ToArray();

Expand Down
5 changes: 3 additions & 2 deletions src/LageBuch.Documents/Sections/ForcesSection.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Globalization;
using LageBuch.Domain;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
Expand Down Expand Up @@ -40,7 +41,7 @@ public static void Compose(IContainer container, Incident incident)
table.Cell().Element(Cells.Body).Text(Formatting.OrDash(unit.CallSign));
// Stärke im 1/1/2-Format: Führungskräfte/Mannschaft/Gesamt (#76).
table.Cell().Element(Cells.Body).Text(unit.StrengthText);
table.Cell().Element(Cells.Body).Text(unit.ScbaCount.ToString());
table.Cell().Element(Cells.Body).Text(unit.ScbaCount.ToString(CultureInfo.InvariantCulture));
table.Cell().Element(Cells.Body).Text(Formatting.OrDash(unit.Status));
table.Cell().Element(Cells.Body).Text(Formatting.OrDash(unit.Notes));
}
Expand All @@ -56,7 +57,7 @@ public static void Compose(IContainer container, Incident incident)
t.Span("Gesamtstärke: ").SemiBold();
t.Span($"{incident.TotalOfficer}/{incident.TotalPersonnel - incident.TotalOfficer}/{incident.TotalPersonnel}");
t.Span(" davon Atemschutzgeräteträger: ").SemiBold();
t.Span(incident.TotalScba.ToString());
t.Span(incident.TotalScba.ToString(CultureInfo.InvariantCulture));
});
});
}
Expand Down
11 changes: 6 additions & 5 deletions src/LageBuch.Persistence/IncidentRepository.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Globalization;
using LageBuch.Domain;
using LageBuch.Persistence.Sqlite;
using Microsoft.Data.Sqlite;
Expand Down Expand Up @@ -277,7 +278,7 @@ private static void WriteChecklist(SqliteConnection cn, SqliteTransaction tx, IR
using var cmd = cn.CreateCommand();
cmd.CommandText = "SELECT state FROM incident_meta LIMIT 1;";
var raw = cmd.ExecuteScalar();
return raw is null ? null : (IncidentState)Convert.ToInt32(raw);
return raw is null ? null : (IncidentState)Convert.ToInt32(raw, CultureInfo.InvariantCulture);
}
catch
{
Expand Down Expand Up @@ -308,7 +309,7 @@ public Incident Load(string path)
{
cmd.CommandText = "SELECT state FROM incident_meta LIMIT 1;";
var raw = cmd.ExecuteScalar() ?? throw new InvalidOperationException("No incident in file.");
state = (IncidentState)Convert.ToInt32(raw);
state = (IncidentState)Convert.ToInt32(raw, CultureInfo.InvariantCulture);
}

using var cn = state == IncidentState.Closed
Expand Down Expand Up @@ -408,15 +409,15 @@ public Incident Load(string path)
var fd = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, string?>>(fdJson)
?? new Dictionary<string, string?>();
var fdDict = fd.ToDictionary(
kv => int.Parse(kv.Key),
kv => int.Parse(kv.Key, CultureInfo.InvariantCulture),
kv => kv.Value);
// apartment_labels is null on rows written before this column existed.
var alJson = Str(r, 6);
var alDict = alJson is null
? new Dictionary<int, string?>()
: (System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, string?>>(alJson)
?? new Dictionary<string, string?>())
.ToDictionary(kv => int.Parse(kv.Key), kv => kv.Value);
.ToDictionary(kv => int.Parse(kv.Key, CultureInfo.InvariantCulture), kv => kv.Value);
return Domain.CoMeasurement.Building.Rehydrate(Guid.Parse(r.GetString(0)), r.GetString(1),
r.GetInt32(2), r.GetInt32(3), fdDict, r.GetInt32(5), alDict);
});
Expand Down Expand Up @@ -449,7 +450,7 @@ public Incident Load(string path)
return Incident.Rehydrate(
Guid.Parse((string)meta[0]!),
ParseDate((string)meta[1]!),
(IncidentState)Convert.ToInt32(meta[2]),
(IncidentState)Convert.ToInt32(meta[2], CultureInfo.InvariantCulture),
incidentNumber,
meta[5] as string,
meta[6] as string,
Expand Down
3 changes: 2 additions & 1 deletion src/LageBuch.Persistence/Sqlite/Migrations.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Globalization;
using LageBuch.Domain.Atemschutz;
using Microsoft.Data.Sqlite;

Expand All @@ -18,7 +19,7 @@ public static int GetVersion(SqliteConnection cn)
using var read = cn.CreateCommand();
read.CommandText = "SELECT version FROM schema_version LIMIT 1;";
var result = read.ExecuteScalar();
return result is null ? 0 : Convert.ToInt32(result);
return result is null ? 0 : Convert.ToInt32(result, CultureInfo.InvariantCulture);
}

public static void Migrate(SqliteConnection cn)
Expand Down
9 changes: 5 additions & 4 deletions src/LageBuch.Sync/SnapshotMapper.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Globalization;
using LageBuch.Domain;
using LageBuch.Domain.Atemschutz;
using LageBuch.Domain.CoMeasurement;
Expand Down Expand Up @@ -47,9 +48,9 @@ public static IncidentSnapshot ToSnapshot(Incident incident)
t.CreatedBy, t.CreatedAt, t.DueAt, t.CompletedAt, t.CompletedBy)).ToList(),
incident.Buildings.Select(b => new BuildingDto(
b.Id, b.Name, b.FloorCount, b.ApartmentsPerFloor,
b.FloorDescriptions.ToDictionary(kv => kv.Key.ToString(), kv => kv.Value),
b.FloorDescriptions.ToDictionary(kv => kv.Key.ToString(CultureInfo.InvariantCulture), kv => kv.Value),
b.Ordinal,
b.ApartmentLabels.ToDictionary(kv => kv.Key.ToString(), kv => kv.Value))).ToList(),
b.ApartmentLabels.ToDictionary(kv => kv.Key.ToString(CultureInfo.InvariantCulture), kv => kv.Value))).ToList(),
incident.Dwellings.Select(d => new DwellingDto(
d.Id, d.BuildingId, d.FloorOrdinal, d.ApartmentNumber,
d.ResidentName, d.Status, d.KeyAvailable, d.CoValue)).ToList());
Expand Down Expand Up @@ -86,11 +87,11 @@ public static Incident FromSnapshot(IncidentSnapshot snapshot)
snapshot.Buildings.Select(b => Building.Rehydrate(
b.Id, b.Name, b.FloorCount, b.ApartmentsPerFloor,
b.FloorDescriptions.ToDictionary(
kv => int.Parse(kv.Key),
kv => int.Parse(kv.Key, CultureInfo.InvariantCulture),
kv => kv.Value),
b.Ordinal,
b.ApartmentLabels?.ToDictionary(
kv => int.Parse(kv.Key),
kv => int.Parse(kv.Key, CultureInfo.InvariantCulture),
kv => kv.Value))),
snapshot.Dwellings.Select(d => Dwelling.Rehydrate(
d.Id, d.BuildingId, d.FloorOrdinal, d.ApartmentNumber,
Expand Down
3 changes: 2 additions & 1 deletion tests/LageBuch.Acceptance.Tests/ModuleTabsScrollingTests.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Globalization;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Presenters;
Expand Down Expand Up @@ -56,7 +57,7 @@ public void Nav_rail_stays_one_column_and_scrolls_on_a_short_viewport()
.ToArray();
Assert.True(columns.Length == 1,
$"nav rail wrapped into {columns.Length} columns at x=" +
string.Join(", ", columns.Select(c => c.ToString("F0"))) +
string.Join(", ", columns.Select(c => c.ToString("F0", CultureInfo.InvariantCulture))) +
" -- it must overflow into a scrollbar instead.");

// The overflow lands in a ScrollViewer, not silent clipping.
Expand Down
Loading