Skip to content

Commit

Permalink
Merge pull request #81 from dyatlov-a/hotfix-269
Browse files Browse the repository at this point in the history
 Stabilization of the main scenarios
  • Loading branch information
dyatlov-a authored Sep 27, 2024
2 parents f67d744 + b1a2148 commit 1800624
Show file tree
Hide file tree
Showing 102 changed files with 1,264 additions and 939 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
using Inc.TeamAssistant.Appraiser.Domain;
using Inc.TeamAssistant.Primitives.FeatureProperties;
using Inc.TeamAssistant.Primitives.Languages;

namespace Inc.TeamAssistant.Appraiser.Application.Services;

internal sealed class AppraiserSettingSectionProvider : ISettingSectionProvider
{
private readonly IReadOnlyDictionary<StoryType, string> _storyType = new Dictionary<StoryType, string>
private readonly IReadOnlyDictionary<StoryType, MessageId> _storyType = new Dictionary<StoryType, MessageId>
{
[StoryType.Fibonacci] = "Constructor_FormSectionSetSettingsFibonacciDescription",
[StoryType.TShirt] = "Constructor_FormSectionSetSettingsTShirtDescription",
[StoryType.PowerOfTwo] = "Constructor_FormSectionSetSettingsPowerOfTwoDescription"
[StoryType.Fibonacci] = new("Constructor_FormSectionSetSettingsFibonacciDescription"),
[StoryType.TShirt] = new("Constructor_FormSectionSetSettingsTShirtDescription"),
[StoryType.PowerOfTwo] = new("Constructor_FormSectionSetSettingsPowerOfTwoDescription")
};

public string FeatureName => "Appraiser";
Expand All @@ -19,12 +20,12 @@ public IReadOnlyCollection<SettingSection> GetSections()
return
[
new SettingSection(
"Constructor_FormSectionSetSettingsAppraiserHeader",
"Constructor_FormSectionSetSettingsAppraiserHelp",
new("Constructor_FormSectionSetSettingsAppraiserHeader"),
new("Constructor_FormSectionSetSettingsAppraiserHelp"),
[
new(
AppraiserProperties.StoryTypeKey,
"Constructor_FormSectionSetSettingsStoryTypeFieldLabel",
new("Constructor_FormSectionSetSettingsStoryTypeFieldLabel"),
GetValuesForStoryType().ToArray())
])
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,7 @@ public Estimation GetValue(int value)
if (Estimations.TryGetValue(value, out var estimation))
return estimation;

throw new ArgumentOutOfRangeException(
nameof(value),
value,
$"Value is not valid for {nameof(FibonacciEstimationStrategy)}.");
throw new ArgumentOutOfRangeException(nameof(value), value, "State out of range.");
}

public int GetWeight(Story story)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,7 @@ public Estimation GetValue(int value)
if (Estimations.TryGetValue(value, out var estimation))
return estimation;

throw new ArgumentOutOfRangeException(
nameof(value),
value,
$"Value is not valid for {nameof(FibonacciEstimationStrategy)}.");
throw new ArgumentOutOfRangeException(nameof(value), value, "State out of range.");
}

public int GetWeight(Story story)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,7 @@ public Estimation GetValue(int value)
if (Estimations.TryGetValue(value, out var estimation))
return estimation;

throw new ArgumentOutOfRangeException(
nameof(value),
value,
$"Value is not valid for {nameof(TShirtEstimationStrategy)}.");
throw new ArgumentOutOfRangeException(nameof(value), value, "State out of range.");
}

public int GetWeight(Story story)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ public static IEstimationStrategy Create(StoryType storyType)
{
return Strategies.TryGetValue(storyType, out var strategy)
? strategy
: throw new ArgumentOutOfRangeException(nameof(storyType),
storyType,
$"StoryType is not valid for {nameof(EstimationStrategyFactory)}.");
: throw new ArgumentOutOfRangeException(nameof(storyType), storyType, "State out of range.");
}
}
54 changes: 0 additions & 54 deletions src/Inc.TeamAssistant.CheckIn.Geo/GeoJsonParser.cs

This file was deleted.

31 changes: 31 additions & 0 deletions src/Inc.TeamAssistant.CheckIn.Geo/GeoParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Text.Json;
using Inc.TeamAssistant.CheckIn.Application.Contracts;
using Inc.TeamAssistant.CheckIn.Geo.Models;

namespace Inc.TeamAssistant.CheckIn.Geo;

internal sealed class GeoParser
{
private static readonly JsonSerializerOptions JsonSerializerOptions = new()
{
PropertyNameCaseInsensitive = true,
TypeInfoResolver = new GeometryResolver()
};

public IEnumerable<Region> Parse(IEnumerable<string> json)
{
ArgumentNullException.ThrowIfNull(json);

foreach (var line in json)
{
var item = JsonSerializer.Deserialize<GeoItem>(line, JsonSerializerOptions);

if (item is not null)
yield return new Region(
item.Properties.Name,
item.Id,
item.Properties.Type == "country" ? RegionType.Country : RegionType.Ocean,
item.Geometry.GetCoordinates().ToArray());
}
}
}
64 changes: 24 additions & 40 deletions src/Inc.TeamAssistant.CheckIn.Geo/GeoService.cs
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
using GeoTimeZone;
using Inc.TeamAssistant.CheckIn.Application.Contracts;
using Inc.TeamAssistant.CheckIn.Geo.Models;

namespace Inc.TeamAssistant.CheckIn.Geo;

internal sealed class GeoService : IGeoService
{
private readonly GeoJsonParser _geoJsonParser;
private readonly Region[] _regions;

public GeoService(RegionLoader regionLoader, GeoJsonParser geoJsonParser)
public GeoService(RegionLoader regionLoader, GeoParser geoParser)
{
_geoJsonParser = geoJsonParser;
_regions = ParseInput(regionLoader.LoadFile()).ToArray();
ArgumentNullException.ThrowIfNull(regionLoader);
ArgumentNullException.ThrowIfNull(geoParser);

_regions = geoParser.Parse(regionLoader.LoadFile()).ToArray();
}

public Region? FindCountry(double lat, double lng, params RegionType[] types)
{
var coords = new[] { (float)lng, (float)lat };
var subset = types.Any()
ArgumentNullException.ThrowIfNull(types);

var point = new Point((float)lng, (float)lat);
var items = types.Any()
? _regions.Where(x => types.Any(y => y == x.Type))
: _regions;

foreach (var country in subset)
{
if (InPolygon(coords, country.Polygon))
{
return country;
}
}
foreach (var item in items)
if (InPolygon(point, item.Polygon))
return item;

return null;
}
Expand All @@ -38,37 +38,21 @@ public TimeZoneInfo GetTimeZone(double lat, double lng)
return TimeZoneInfo.FindSystemTimeZoneById(timeZoneId.Result);
}

private bool InPolygon(float[] point, float[][] polygon)
private bool InPolygon(Point point, float[][] polygon)
{
var polygonLength = polygon.Length;
var c = false;
ArgumentNullException.ThrowIfNull(point);
ArgumentNullException.ThrowIfNull(polygon);

var result = false;
var i = 0;
var j = 0;
for (i = 0, j = polygonLength - 1; i < polygonLength; j = i++)
{
if (polygon[i][1] > point[1] != (polygon[j][1] > point[1]) &&
point[0] < (polygon[j][0] - polygon[i][0]) * (point[1] - polygon[i][1]) /

for (i = 0, j = polygon.Length - 1; i < polygon.Length; j = i++)
if (polygon[i][1] > point.Lat != polygon[j][1] > point.Lat &&
point.Lng < (polygon[j][0] - polygon[i][0]) * (point.Lat - polygon[i][1]) /
(polygon[j][1] - polygon[i][1]) + polygon[i][0])
{
c = !c;
}
}
result = !result;

return c;
}

private IEnumerable<Region> ParseInput(IEnumerable<string> geojson)
{
foreach (var line in geojson)
{
foreach (var polygon in _geoJsonParser.Convert(line))
{
yield return new Region(
polygon.Properties["name"],
polygon.Id,
polygon.Properties["type"] == "country" ? RegionType.Country : RegionType.Ocean,
polygon.Geometry);
}
}
return result;
}
}
34 changes: 34 additions & 0 deletions src/Inc.TeamAssistant.CheckIn.Geo/GeometryResolver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;
using Inc.TeamAssistant.CheckIn.Geo.Models;

namespace Inc.TeamAssistant.CheckIn.Geo;

internal sealed class GeometryResolver : DefaultJsonTypeInfoResolver
{
public override JsonTypeInfo GetTypeInfo(Type type, JsonSerializerOptions options)
{
ArgumentNullException.ThrowIfNull(type);
ArgumentNullException.ThrowIfNull(options);

var jsonTypeInfo = base.GetTypeInfo(type, options);

if (jsonTypeInfo.Type == typeof(IGeometry))
{
jsonTypeInfo.PolymorphismOptions = new JsonPolymorphismOptions
{
TypeDiscriminatorPropertyName = "type",
IgnoreUnrecognizedTypeDiscriminators = false,
UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FailSerialization,
DerivedTypes =
{
new JsonDerivedType(typeof(PolygonGeometry), "Polygon"),
new JsonDerivedType(typeof(MultiPolygonGeometry), "MultiPolygon"),
}
};
}

return jsonTypeInfo;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
<ProjectReference Include="..\Inc.TeamAssistant.CheckIn.Application\Inc.TeamAssistant.CheckIn.Application.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="GeoTimeZone" Version="5.3.0" />
</ItemGroup>
</Project>
6 changes: 6 additions & 0 deletions src/Inc.TeamAssistant.CheckIn.Geo/Models/GeoItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Inc.TeamAssistant.CheckIn.Geo.Models;

internal sealed record GeoItem(
string Id,
GeoProperties Properties,
IGeometry Geometry);
3 changes: 3 additions & 0 deletions src/Inc.TeamAssistant.CheckIn.Geo/Models/GeoProperties.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace Inc.TeamAssistant.CheckIn.Geo.Models;

internal sealed record GeoProperties(string Type, string Name);
6 changes: 6 additions & 0 deletions src/Inc.TeamAssistant.CheckIn.Geo/Models/IGeometry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Inc.TeamAssistant.CheckIn.Geo.Models;

internal interface IGeometry
{
IEnumerable<float[]> GetCoordinates();
}
12 changes: 12 additions & 0 deletions src/Inc.TeamAssistant.CheckIn.Geo/Models/MultiPolygonGeometry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Inc.TeamAssistant.CheckIn.Geo.Models;

internal sealed record MultiPolygonGeometry(float[][][][] Coordinates)
: IGeometry
{
public IEnumerable<float[]> GetCoordinates()
{
foreach (var coordinate in Coordinates)
foreach (var item in coordinate[0])
yield return [item[0], item[1]];
}
}
3 changes: 3 additions & 0 deletions src/Inc.TeamAssistant.CheckIn.Geo/Models/Point.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace Inc.TeamAssistant.CheckIn.Geo.Models;

internal sealed record Point(float Lng, float Lat);
11 changes: 11 additions & 0 deletions src/Inc.TeamAssistant.CheckIn.Geo/Models/PolygonGeometry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Inc.TeamAssistant.CheckIn.Geo.Models;

internal sealed record PolygonGeometry(float[][][] Coordinates)
: IGeometry
{
public IEnumerable<float[]> GetCoordinates()
{
foreach (var item in Coordinates[0])
yield return [item[0], item[1]];
}
}
8 changes: 0 additions & 8 deletions src/Inc.TeamAssistant.CheckIn.Geo/ParsedGeoJson.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public static IServiceCollection AddCheckInGeo(this IServiceCollection services,

services
.AddSingleton(sp => ActivatorUtilities.CreateInstance<RegionLoader>(sp, webRootPath))
.AddSingleton<GeoJsonParser>()
.AddSingleton<GeoParser>()
.AddSingleton<IGeoService, GeoService>();

return services;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ public static IReadOnlyCollection<WidgetDto> Convert(
ArgumentNullException.ThrowIfNull(features);

return settings.Widgets
.Select(w => new WidgetDto(w.Type, w.Position, CanEnabled(w), w.IsEnabled))
.Select(w => new WidgetDto(
w.Type,
w.Feature,
w.Position,
CanEnabled(w), w.IsEnabled))
.ToArray();

bool CanEnabled(DashboardWidget widget) =>
Expand Down
Loading

0 comments on commit 1800624

Please sign in to comment.