Implemented delivery model and filtering
This commit is contained in:
parent
9d232598cd
commit
8ffdea83c8
11 changed files with 124 additions and 39 deletions
3
.idea/.idea.EffetiveTask/.idea/dictionaries/egor.xml
Normal file
3
.idea/.idea.EffetiveTask/.idea/dictionaries/egor.xml
Normal file
|
@ -0,0 +1,3 @@
|
|||
<component name="ProjectDictionaryState">
|
||||
<dictionary name="egor" />
|
||||
</component>
|
|
@ -9,8 +9,8 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.10"/>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="9.0.0-rc.2.24474.1" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.0-rc.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="8.0.10" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.10" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2"/>
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace DeliveryWebApi.Model;
|
||||
|
||||
public class BaseEntity
|
||||
{
|
||||
public Guid Id { get; init; } = Guid.NewGuid();
|
||||
public long Id { get; init; }
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace DeliveryWebApi.Model;
|
||||
|
||||
public class DeliveryContext(DbContextOptions<DeliveryContext> options) : DbContext(options)
|
||||
{
|
||||
public DbSet<District> Districts { get; init; }
|
||||
public DbSet<Order> Orders { get; init; }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<District>()
|
||||
.HasMany(e => e.Orders)
|
||||
.WithOne(e => e.District)
|
||||
.HasForeignKey(e => e.DistrictId)
|
||||
.IsRequired();
|
||||
}
|
||||
}
|
46
DeliveryWebApi/Model/DeliveryDbContext.cs
Normal file
46
DeliveryWebApi/Model/DeliveryDbContext.cs
Normal file
|
@ -0,0 +1,46 @@
|
|||
using System.Collections.Immutable;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace DeliveryWebApi.Model;
|
||||
|
||||
public class DeliveryDbContext(DbContextOptions<DeliveryDbContext> options) : DbContext(options)
|
||||
{
|
||||
public DbSet<District> Districts { get; init; }
|
||||
public DbSet<Order> Orders { get; init; }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<District>()
|
||||
.HasMany(d => d.Orders)
|
||||
.WithOne(o => o.District)
|
||||
.HasForeignKey(o => o.DistrictId)
|
||||
.IsRequired();
|
||||
|
||||
modelBuilder.Entity<District>()
|
||||
.HasIndex(d => d.Name)
|
||||
.IsUnique();
|
||||
|
||||
// random districts
|
||||
var districtNames = new List<string>
|
||||
{
|
||||
"Viborgskiy", "Primorskiy", "Kalininskiy", "Petrogradskiy", "Center", "Admiralteyskiy", "Vasileostrovskiy",
|
||||
"Kirovskiy", "Krasnoselskiy", "Moskovskiy", "Frunzenskiy", "Nevskiy", "Krasnogvardeyskiy", "Kolpinskiy",
|
||||
"Pushkinskiy", "Pavlovskiy", "Petrodvortsoviy", "Lomonosovskiy", "Kurortniy", "Kronshtadskiy"
|
||||
};
|
||||
modelBuilder.Entity<District>()
|
||||
.HasData(districtNames.Select((n, i) => new District { Id = i + 1, Name = n }));
|
||||
|
||||
// random orders
|
||||
var rnd = new Random();
|
||||
var startDate = new DateTime(2020, 1, 1);
|
||||
var range = (DateTime.Today - startDate).Days;
|
||||
modelBuilder.Entity<Order>()
|
||||
.HasData(Enumerable.Range(1, 100).Select(i =>
|
||||
{
|
||||
var districtId = rnd.Next(0, districtNames.Count) + 1;
|
||||
var weight = rnd.NextSingle() * 10 + 0.1f;
|
||||
var date = startDate.AddDays(rnd.Next(range));
|
||||
return new Order { Id = i, DistrictId = districtId, Weight = weight, DeliveryDate = date };
|
||||
}));
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
namespace DeliveryWebApi.Model;
|
||||
|
||||
public class District(string name) : BaseEntity
|
||||
public class District : BaseEntity
|
||||
{
|
||||
public string Name { get; init; }
|
||||
public ICollection<Order> Orders { get; init; } = new List<Order>();
|
||||
|
|
|
@ -3,7 +3,7 @@ namespace DeliveryWebApi.Model;
|
|||
public class Order : BaseEntity
|
||||
{
|
||||
public float Weight { get; init; }
|
||||
public Guid DistrictId { get; init; }
|
||||
public long DistrictId { get; init; }
|
||||
public District District { get; init; } = null!;
|
||||
public DateTime DeliveryDate { get; init; }
|
||||
}
|
|
@ -1,38 +1,86 @@
|
|||
using DeliveryWebApi.Model;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Internal;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen();
|
||||
if (builder.Configuration.GetValue<bool>("UseInMemoryDatabase"))
|
||||
builder.Services.AddDbContext<DeliveryContext>(options => options.UseInMemoryDatabase("Delivery"));
|
||||
else
|
||||
|
||||
// storage setup
|
||||
// either use in-memory storage or postgres depending on cfg
|
||||
builder.Services.AddDbContext<DeliveryDbContext>(options =>
|
||||
{
|
||||
builder.Services.AddDbContext<DeliveryContext>(options =>
|
||||
if (builder.Configuration.GetValue<bool>("UseInMemoryDatabase"))
|
||||
options.UseInMemoryDatabase("Delivery");
|
||||
else
|
||||
{
|
||||
var connectionString = builder.Configuration.GetConnectionString("DatabaseConnection");
|
||||
options.UseNpgsql(connectionString);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// swagger setup
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
// swagger setup
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI();
|
||||
|
||||
// migrate model to seed random test values for developers
|
||||
app.Services.CreateScope().ServiceProvider.GetRequiredService<DeliveryDbContext>().Database.EnsureCreated();
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
app.MapPut("/addOrder", (float weight, long districtId, DateTime deliveryTime) =>
|
||||
{
|
||||
app.MapPut("/addDistrict", (DeliveryDbContext context, string name) =>
|
||||
{
|
||||
if (context.Districts.Any(d => d.Name == name))
|
||||
return Results.BadRequest(new { Error = "District with the same name already exists" });
|
||||
var district = new District{ Name = name };
|
||||
context.Districts.Add(district);
|
||||
var updated = context.SaveChanges();
|
||||
if (updated <= 0)
|
||||
return Results.Json(new { Error = "Something went wrong while adding a new district" }, statusCode: 500);
|
||||
return Results.Ok(new { district.Id });
|
||||
});
|
||||
|
||||
})
|
||||
.WithName("GetWeatherForecast")
|
||||
.WithOpenApi();
|
||||
app.MapGet("/getDistrict/{id:long}", (DeliveryDbContext context, long id) =>
|
||||
{
|
||||
var district = context.Districts.FirstOrDefault(d => d.Id == id);
|
||||
if (district == null)
|
||||
return Results.NotFound(new { Error = "District with the given id does not exist" });
|
||||
return Results.Ok(new { district.Id, district.Name });
|
||||
});
|
||||
|
||||
app.MapPut("/addOrder", (DeliveryDbContext context, long districtId, float weight, DateTime deliveryDate) =>
|
||||
{
|
||||
var order = new Order{ DistrictId = districtId, Weight = weight, DeliveryDate = deliveryDate };
|
||||
context.Orders.Add(order);
|
||||
var updated = context.SaveChanges();
|
||||
if (updated <= 0)
|
||||
return Results.Json(new { Error = "Something went wrong while adding a new order" }, statusCode: 500);
|
||||
return Results.Ok(new { order.Id });
|
||||
});
|
||||
|
||||
app.MapGet("/getOrder/{id:long}", (DeliveryDbContext context, long id) =>
|
||||
{
|
||||
var order = context.Orders.FirstOrDefault(o => o.Id == id);
|
||||
if (order == null)
|
||||
return Results.NotFound(new { Error = "Order with the given id does not exist" });
|
||||
return Results.Ok(new { order.Id, order.DistrictId, order.Weight, order.DeliveryDate });
|
||||
});
|
||||
|
||||
app.MapGet("/getOrders", (DeliveryDbContext context, string? districtName, DateTime? firstDeliveryDate) =>
|
||||
{
|
||||
var orders = context.Districts
|
||||
.Where(d => districtName == null || d.Name == districtName)
|
||||
.SelectMany(d => d.Orders)
|
||||
.Where(o => firstDeliveryDate == null || o.DeliveryDate >= firstDeliveryDate)
|
||||
.OrderBy(o => o.DeliveryDate)
|
||||
.Select(o => new { o.Id, o.District.Name, o.DeliveryDate, o.Weight });
|
||||
return Results.Ok(orders);
|
||||
});
|
||||
|
||||
app.Run();
|
||||
|
|
|
@ -4,5 +4,6 @@
|
|||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
},
|
||||
"UseInMemoryDatabase": true
|
||||
}
|
||||
|
|
|
@ -5,5 +5,6 @@
|
|||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
"AllowedHosts": "*",
|
||||
"UseInMemoryDatabase": true
|
||||
}
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADateTime_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F14a2b70486934722acea07b38045413ab2d200_003F3e_003F15560e7c_003FDateTime_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AResults_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F18bfc57084254648b9740270d0ce5e20ed10_003Fea_003Fc087adef_003FResults_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AWebApplication_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F847c7bc70f83436e9c281d8cea5531a17d10_003F7f_003F26f6c2e2_003FWebApplication_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>
|
Loading…
Reference in a new issue