diff --git a/BarAPI/BarAPI.csproj b/BarAPI/BarAPI.csproj index 75daf3d..be0f976 100644 --- a/BarAPI/BarAPI.csproj +++ b/BarAPI/BarAPI.csproj @@ -5,6 +5,7 @@ + diff --git a/BarAPI/Controllers/MenuController.cs b/BarAPI/Controllers/MenuController.cs index b67abbb..4e0c1b8 100644 --- a/BarAPI/Controllers/MenuController.cs +++ b/BarAPI/Controllers/MenuController.cs @@ -1,10 +1,9 @@ -using System; -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc; using System.Threading.Tasks; -using DataAccess; -using DataAccess.Domain; +using DataAccess.Data; +using DataAccess.Repository; +using System.Collections.Generic; -// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 namespace BarAPI.Controllers { @@ -21,37 +20,90 @@ public MenuController(IMenuRepository menuRepository) // GET: api/ [HttpGet] - public Task Get() + [ProducesResponseType(200, Type = typeof(List))] + public async Task> GetAll() { - return _menuRepository.Get(); + return await _menuRepository.GetAllItems(); } - // GET api//name - [HttpGet("{name}")] - public Task Get(string name) + // GET api//id + [HttpGet("{id}")] + [ProducesResponseType(200, Type = typeof(MenuItem))] + [ProducesResponseType(404)] + public async Task Get(int id) { - return _menuRepository.GetItem(name); + MenuItem menuItem = await _menuRepository.GetItem(id); + if(menuItem == null) + { + return NotFound(); + } + else + { + return Ok(menuItem); + } } // POST api/ [HttpPost] - public async Task Post([FromBody] MenuItem item) + [ProducesResponseType(201, Type = typeof(MenuItem))] + [ProducesResponseType(400)] + public async Task Post([FromBody] MenuItem item) { - await _menuRepository.Add(item); + if(item == null) return BadRequest(); + if(!ModelState.IsValid) return BadRequest(ModelState); + MenuItem exist = await _menuRepository.GetItem(item.Id); + if (string.IsNullOrWhiteSpace(item.Name)) return BadRequest("Item name is Null or contain only WhiteSpace"); + if (item.Price <= 0) return BadRequest("Item price must be above zero"); + if (exist != null) return BadRequest($"Item with id = {item.Id} already exists"); + bool isAdded = await _menuRepository.Add(item); + if (isAdded) + { + return CreatedAtAction(nameof(Post), item); + } + else + { + return BadRequest(); + } } // PUT api//5 - [HttpPut("{name}")] - public void Put(string name, [FromBody] string value) + [HttpPut("{id}")] + [ProducesResponseType(204)] + [ProducesResponseType(400)] + public async Task Update(int id, [FromBody] MenuItem item) { - throw new NotImplementedException("Our bar does not allow to modify a menu! (yet)"); + if(item.Id != id) return BadRequest(); + if(!ModelState.IsValid) return BadRequest(ModelState); + if (string.IsNullOrWhiteSpace(item.Name)) return BadRequest("Item name is Null or contain only WhiteSpace"); + if (item.Price <= 0) return BadRequest("Item price must be above zero"); + bool isUpdate = await _menuRepository.Update(item); + if(isUpdate) + { + return new NoContentResult(); + } + else + { + return BadRequest(); + } } - // DELETE api//name - [HttpDelete("{name}")] - public async Task Delete(string name) + // DELETE api//id + [HttpDelete("{id}")] + [ProducesResponseType(204)] + [ProducesResponseType(404)] + public async Task Delete(int id) { - await _menuRepository.Remove(name); + var exist = await _menuRepository.GetItem(id); + if(exist == null) return NotFound(); + bool isDelete = await _menuRepository.Remove(id); + if (isDelete) + { + return new NoContentResult(); + } + else + { + return BadRequest($"Item with id = {id} was found but faild to delete"); + } } } } diff --git a/BarAPI/Controllers/OrderController.cs b/BarAPI/Controllers/OrderController.cs new file mode 100644 index 0000000..08a5945 --- /dev/null +++ b/BarAPI/Controllers/OrderController.cs @@ -0,0 +1,57 @@ +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using DataAccess.Data; +using DataAccess.Repository; + +namespace BarAPI.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class OrderController : Controller + { + private readonly IOrderRepository _orderRepository; + + public OrderController(IOrderRepository orderRepository) + { + _orderRepository = orderRepository; + } + + // GET: api//id + [HttpGet("{id}")] + [ProducesResponseType(200, Type = typeof(Order))] + [ProducesResponseType(404)] + public async Task Get(int id) + { + Order order = await _orderRepository.Get(id); + if(order == null) + { + return NotFound(); + } + else + { + return Ok(order); + } + } + + // POST: api// + [HttpPost] + [ProducesResponseType(200, Type = typeof(Order))] + [ProducesResponseType(400)] + public async Task Upsert([FromBody] Order item) + { + if (!ModelState.IsValid) return BadRequest(ModelState); + bool isUpsert = await _orderRepository.Upsert(item); + if (isUpsert) + { + return Ok(item); + } + else + { + return BadRequest(); + } + } + } +} diff --git a/BarAPI/DataAccess/InMemoryRepository.cs b/BarAPI/DataAccess/InMemoryRepository.cs deleted file mode 100644 index f35c638..0000000 --- a/BarAPI/DataAccess/InMemoryRepository.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using DataAccess; -using DataAccess.Domain; - -namespace BarAPI.DataAccess -{ - public class InMemoryRepository: IMenuRepository - { - private static List _positions = new() - { - new MenuItem - { - Name = "Negroni", - Price = 6.99 - }, - new MenuItem - { - Name = "Margarita", - Price = 8.99 - }, - new MenuItem - { - Name = "Apple Martini", - Price = 7 - } - }; - - public Task Add(MenuItem item) - { - _positions.Add(item); - return Task.CompletedTask; - } - - public Task Get() - { - return Task.FromResult(_positions.ToArray()); - } - - public Task GetItem(string name) - { - return Task.FromResult(_positions.FirstOrDefault(p => p.Name == name)); - } - - public Task Remove(string name) - { - _positions.RemoveAt(_positions.FindIndex(p=>p.Name==name)); - return Task.CompletedTask; - } - } -} diff --git a/BarAPI/Properties/ServiceDependencies/BarService - Zip Deploy/profile.arm.json b/BarAPI/Properties/ServiceDependencies/BarService - Zip Deploy/profile.arm.json new file mode 100644 index 0000000..a9efbb4 --- /dev/null +++ b/BarAPI/Properties/ServiceDependencies/BarService - Zip Deploy/profile.arm.json @@ -0,0 +1,175 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_dependencyType": "function.windows.appService" + }, + "parameters": { + "resourceGroupName": { + "type": "string", + "defaultValue": "Bar-Service-Group", + "metadata": { + "description": "Name of the resource group for the resource. It is recommended to put resources under same resource group for better tracking." + } + }, + "resourceGroupLocation": { + "type": "string", + "defaultValue": "westeurope", + "metadata": { + "description": "Location of the resource group. Resource groups could have different location than resources, however by default we use API versions from latest hybrid profile which support all locations for resource types we support." + } + }, + "resourceName": { + "type": "string", + "defaultValue": "BarService", + "metadata": { + "description": "Name of the main resource to be created by this template." + } + }, + "resourceLocation": { + "type": "string", + "defaultValue": "[parameters('resourceGroupLocation')]", + "metadata": { + "description": "Location of the resource. By default use resource group's location, unless the resource provider is not supported there." + } + } + }, + "resources": [ + { + "type": "Microsoft.Resources/resourceGroups", + "name": "[parameters('resourceGroupName')]", + "location": "[parameters('resourceGroupLocation')]", + "apiVersion": "2019-10-01" + }, + { + "type": "Microsoft.Resources/deployments", + "name": "[concat(parameters('resourceGroupName'), 'Deployment', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId)))]", + "resourceGroup": "[parameters('resourceGroupName')]", + "apiVersion": "2019-10-01", + "dependsOn": [ + "[parameters('resourceGroupName')]" + ], + "properties": { + "mode": "Incremental", + "expressionEvaluationOptions": { + "scope": "inner" + }, + "parameters": { + "resourceGroupName": { + "value": "[parameters('resourceGroupName')]" + }, + "resourceGroupLocation": { + "value": "[parameters('resourceGroupLocation')]" + }, + "resourceName": { + "value": "[parameters('resourceName')]" + }, + "resourceLocation": { + "value": "[parameters('resourceLocation')]" + } + }, + "template": { + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceGroupName": { + "type": "string" + }, + "resourceGroupLocation": { + "type": "string" + }, + "resourceName": { + "type": "string" + }, + "resourceLocation": { + "type": "string" + } + }, + "variables": { + "storage_name": "[toLower(concat('storage', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId))))]", + "appServicePlan_name": "[concat('Plan', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId)))]", + "storage_ResourceId": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', parameters('resourceGroupName'), '/providers/Microsoft.Storage/storageAccounts/', variables('storage_name'))]", + "appServicePlan_ResourceId": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', parameters('resourceGroupName'), '/providers/Microsoft.Web/serverFarms/', variables('appServicePlan_name'))]", + "function_ResourceId": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', parameters('resourceGroupName'), '/providers/Microsoft.Web/sites/', parameters('resourceName'))]" + }, + "resources": [ + { + "location": "[parameters('resourceLocation')]", + "name": "[parameters('resourceName')]", + "type": "Microsoft.Web/sites", + "apiVersion": "2015-08-01", + "tags": { + "[concat('hidden-related:', variables('appServicePlan_ResourceId'))]": "empty" + }, + "dependsOn": [ + "[variables('appServicePlan_ResourceId')]", + "[variables('storage_ResourceId')]" + ], + "kind": "functionapp", + "properties": { + "name": "[parameters('resourceName')]", + "kind": "functionapp", + "httpsOnly": true, + "reserved": false, + "serverFarmId": "[variables('appServicePlan_ResourceId')]", + "siteConfig": { + "alwaysOn": true + } + }, + "identity": { + "type": "SystemAssigned" + }, + "resources": [ + { + "name": "appsettings", + "type": "config", + "apiVersion": "2015-08-01", + "dependsOn": [ + "[variables('function_ResourceId')]" + ], + "properties": { + "AzureWebJobsDashboard": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storage_name'), ';AccountKey=', listKeys(variables('storage_ResourceId'), '2017-10-01').keys[0].value, ';EndpointSuffix=', 'core.windows.net')]", + "AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storage_name'), ';AccountKey=', listKeys(variables('storage_ResourceId'), '2017-10-01').keys[0].value, ';EndpointSuffix=', 'core.windows.net')]", + "FUNCTIONS_EXTENSION_VERSION": "~3", + "FUNCTIONS_WORKER_RUNTIME": "dotnet" + } + } + ] + }, + { + "location": "[parameters('resourceGroupLocation')]", + "name": "[variables('storage_name')]", + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2017-10-01", + "tags": { + "[concat('hidden-related:', concat('/providers/Microsoft.Web/sites/', parameters('resourceName')))]": "empty" + }, + "properties": { + "supportsHttpsTrafficOnly": true + }, + "sku": { + "name": "Standard_LRS" + }, + "kind": "Storage" + }, + { + "location": "[parameters('resourceGroupLocation')]", + "name": "[variables('appServicePlan_name')]", + "type": "Microsoft.Web/serverFarms", + "apiVersion": "2015-08-01", + "sku": { + "name": "S1", + "tier": "Standard", + "family": "S", + "size": "S1" + }, + "properties": { + "name": "[variables('appServicePlan_name')]" + } + } + ] + } + } + } + ] +} \ No newline at end of file diff --git a/BarAPI/Startup.cs b/BarAPI/Startup.cs index 2fc5280..2de8f96 100644 --- a/BarAPI/Startup.cs +++ b/BarAPI/Startup.cs @@ -1,12 +1,10 @@ -using System.Data; -using System.Data.SqlClient; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.OpenApi.Models; -using BarAPI.DataAccess; -using DataAccess; +using DataAccess.Repository; +using DataAccess.Data; namespace BarAPI { @@ -24,11 +22,12 @@ public void ConfigureServices(IServiceCollection services) { services.AddControllers(); + services.AddScoped(); + services.AddScoped(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "BarAPI", Version = "v1" }); }); - services.AddScoped(); //services.AddScoped(sp => new SqlConnection("TMP")); //services.AddScoped(sp => sp.GetRequiredService()); } @@ -40,7 +39,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) app.UseDeveloperExceptionPage(); app.UseSwagger(); app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "BarAPI v1")); - + app.UseHttpsRedirection(); app.UseRouting(); diff --git a/DataAccess/Data/BarDataBase.cs b/DataAccess/Data/BarDataBase.cs new file mode 100644 index 0000000..fa24f06 --- /dev/null +++ b/DataAccess/Data/BarDataBase.cs @@ -0,0 +1,33 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; + +namespace DataAccess.Data +{ + public class BarDataBase : DbContext + { + public DbSet Menu { get; set; } + public DbSet Orders { get; set; } + + public BarDataBase () { } + + public BarDataBase(DbContextOptions options) : base(options) { } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (!optionsBuilder.IsConfigured) + { + optionsBuilder.UseSqlServer(""); + } + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity().Property(order => order.Id).IsRequired().ValueGeneratedOnAdd(); + modelBuilder.Entity().Property(order => order.Status).IsRequired(); + modelBuilder.Entity().Property(order => order.TotalPrice).IsRequired(); + modelBuilder.Entity().Property(menu => menu.Id).IsRequired().ValueGeneratedOnAdd(); + modelBuilder.Entity().Property(menuItem => menuItem.Name).IsRequired().HasMaxLength(50); + modelBuilder.Entity().Property(menuItem => menuItem.Price).IsRequired(); + } + } +} diff --git a/DataAccess/Data/MenuItem.cs b/DataAccess/Data/MenuItem.cs new file mode 100644 index 0000000..90e8ea9 --- /dev/null +++ b/DataAccess/Data/MenuItem.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace DataAccess.Data +{ + public class MenuItem + { + public int Id { get; set; } + public string Name { get; set; } + public double Price { get; set; } + } +} diff --git a/DataAccess/Domain/Order.cs b/DataAccess/Data/Order.cs similarity index 65% rename from DataAccess/Domain/Order.cs rename to DataAccess/Data/Order.cs index e9b02c2..01592e4 100644 --- a/DataAccess/Domain/Order.cs +++ b/DataAccess/Data/Order.cs @@ -1,4 +1,8 @@ -namespace DataAccess.Domain +using System; +using System.Collections.Generic; +using System.Text; + +namespace DataAccess.Data { public class Order { @@ -9,7 +13,7 @@ public class Order public enum OrderStatus { - Initiated=1, + Initiated = 1, Finalized } } diff --git a/DataAccess/DataAccess.csproj b/DataAccess/DataAccess.csproj index 84900bb..8b7073a 100644 --- a/DataAccess/DataAccess.csproj +++ b/DataAccess/DataAccess.csproj @@ -5,7 +5,7 @@ - + diff --git a/DataAccess/Domain/MenuItem.cs b/DataAccess/Domain/MenuItem.cs deleted file mode 100644 index f3709e2..0000000 --- a/DataAccess/Domain/MenuItem.cs +++ /dev/null @@ -1,9 +0,0 @@ - -namespace DataAccess.Domain -{ - public class MenuItem - { - public string Name { get; set; } - public double Price { get; set; } - } -} diff --git a/DataAccess/IMenuRepository.cs b/DataAccess/IMenuRepository.cs deleted file mode 100644 index 96a231b..0000000 --- a/DataAccess/IMenuRepository.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Threading.Tasks; -using DataAccess.Domain; - -namespace DataAccess -{ - public interface IMenuRepository - { - public Task Add(MenuItem item); - public Task GetItem(string name); - public Task Get(); - public Task Remove(string name); - } -} diff --git a/DataAccess/IOrderRepository.cs b/DataAccess/IOrderRepository.cs deleted file mode 100644 index ae30732..0000000 --- a/DataAccess/IOrderRepository.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Threading.Tasks; -using DataAccess.Domain; - -namespace DataAccess -{ - public interface IOrderRepository - { - Task Get(int id); - Task Upsert(Order order); - } -} diff --git a/DataAccess/MenuRepository.cs b/DataAccess/MenuRepository.cs deleted file mode 100644 index 0d7b45d..0000000 --- a/DataAccess/MenuRepository.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System.Data; -using System.Linq; -using System.Threading.Tasks; -using Dapper; -using DataAccess.Domain; - -namespace DataAccess -{ - public class MenuRepository: IMenuRepository - { - private readonly IDbConnection _databaseConnection; - - public MenuRepository(IDbConnection databaseConnection) - { - _databaseConnection = databaseConnection; - } - - public async Task Add(MenuItem item) - { - var query = @"INSERT INTO [dbo].[Menu] ([Name], [Price]) VALUES (@Name, @Price)"; - var queryParameters = new - { - item.Name, item.Price - }; - - await _databaseConnection.ExecuteScalarAsync(query, queryParameters); - } - - public Task GetItem(string name) - { - var query = @"SELECT * FROM [dbo].Menu WHERE Name=@Name"; - var queryParameters = new { Name = name }; - - return _databaseConnection.QueryFirstAsync(query, queryParameters); - } - - public async Task Get() - { - var query = @"SELECT * FROM [dbo].Menu"; - - return (await _databaseConnection.QueryAsync(query)).ToArray(); - } - - public Task Remove(string name) - { - var query = @"DELETE FROM [dbo].[Menu] WHERE Name=@Name"; - var queryParameters = new - { - Name=name - }; - - return _databaseConnection.ExecuteScalarAsync(query, queryParameters); - } - } -} diff --git a/DataAccess/OrderRepository.cs b/DataAccess/OrderRepository.cs deleted file mode 100644 index 8141c95..0000000 --- a/DataAccess/OrderRepository.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System.Data; -using System.Threading.Tasks; -using Dapper; -using DataAccess.Domain; - -namespace DataAccess -{ - public class OrderRepository:IOrderRepository - { - private readonly IDbConnection _databaseConnection; - - public OrderRepository(IDbConnection databaseConnection) - { - _databaseConnection = databaseConnection; - } - - public async Task Get(int id) - { - var query = @"SELECT * FROM [dbo].[Order] WHERE Id=@Id"; - var queryParameters = new { Id = id }; - return await _databaseConnection.QueryFirstAsync(query, queryParameters); - } - - public async Task Upsert(Order order) - { - var query = @" - UPDATE [dbo].[Order] - SET [TotalPrice] = @TotalPrice, - [Status] = @Status - WHERE [Id] = @Id - IF @@ROWCOUNT = 0 - BEGIN - INSERT INTO [dbo].[Order] ([TotalPrice], [Status]) VALUES (@TotalPrice, @Status) - SELECT SCOPE_IDENTITY() - END"; - - var queryParameters = new - { - order.Id, - TotalPrice = order.TotalPrice, - Status = (int)order.Status - }; - - int? id = await _databaseConnection.ExecuteScalarAsync(query, queryParameters); - if (id == null) - { - return order.Id; - } - - return id.Value; - } - } -} diff --git a/DataAccess/Repository/IMenuRepository.cs b/DataAccess/Repository/IMenuRepository.cs new file mode 100644 index 0000000..acea6c2 --- /dev/null +++ b/DataAccess/Repository/IMenuRepository.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using DataAccess.Data; + +namespace DataAccess.Repository +{ + public interface IMenuRepository + { + Task Add(MenuItem item); + Task GetItem(int id); + Task> GetAllItems(); + Task Update(MenuItem menuItem); + Task Remove(int id); + } +} diff --git a/DataAccess/Repository/IOrderRepository.cs b/DataAccess/Repository/IOrderRepository.cs new file mode 100644 index 0000000..d171979 --- /dev/null +++ b/DataAccess/Repository/IOrderRepository.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using DataAccess.Data; + +namespace DataAccess.Repository +{ + public interface IOrderRepository + { + Task Get(int id); + Task> GetOrdersByStatus(OrderStatus status); + Task Upsert(Order order); + } +} diff --git a/DataAccess/Repository/MenuRepository.cs b/DataAccess/Repository/MenuRepository.cs new file mode 100644 index 0000000..9f58473 --- /dev/null +++ b/DataAccess/Repository/MenuRepository.cs @@ -0,0 +1,56 @@ +using System; +using System.Linq; +using System.Collections.Generic; +using System.Threading.Tasks; +using DataAccess.Data; +using Microsoft.EntityFrameworkCore.ChangeTracking; + +namespace DataAccess.Repository +{ + public class MenuRepository : IMenuRepository + { + private BarDataBase _barDataBase; + + public MenuRepository() + { + _barDataBase = new BarDataBase(); + } + + public Task Add(MenuItem item) + { + EntityEntry added = _barDataBase.Add(item); + int affected = _barDataBase.SaveChanges(); + bool isAdded = (affected == 1) ? true : false; + return Task.FromResult(isAdded); + } + + public Task GetItem(int id) + { + MenuItem menuItem = _barDataBase.Menu.Find(id); + return Task.FromResult(menuItem); + } + + public Task> GetAllItems() + { + return Task>.FromResult(_barDataBase.Menu.ToList()); + } + + public Task Update (MenuItem menuItem) + { + _barDataBase.Menu.Update(menuItem); + int affected = _barDataBase.SaveChanges(); + bool isUpdate = (affected == 1) ? true : false; + return Task.FromResult(isUpdate); + } + + public Task Remove(int id) + { + MenuItem menuItem = _barDataBase.Menu.Find(id); + if (menuItem == null) return Task.FromResult(false); + _barDataBase.Menu.Remove(menuItem); + int affected = _barDataBase.SaveChanges(); + bool isRemove = (affected == 1) ? true : false; + return Task.FromResult(isRemove); + } + } +} diff --git a/DataAccess/Repository/OrderRepository.cs b/DataAccess/Repository/OrderRepository.cs new file mode 100644 index 0000000..f35fb5a --- /dev/null +++ b/DataAccess/Repository/OrderRepository.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using DataAccess.Data; +using Microsoft.EntityFrameworkCore.ChangeTracking; + +namespace DataAccess.Repository +{ + public class OrderRepository : IOrderRepository + { + private BarDataBase _barDataBase; + + public OrderRepository() + { + _barDataBase = new BarDataBase(); + } + + public Task Get(int id) + { + Order order = _barDataBase.Orders.Find(id); + return Task.FromResult(order); + } + + public Task> GetOrdersByStatus(OrderStatus status) + { + return Task>.FromResult(_barDataBase.Orders.Where(order => order.Status == status).ToList()); + } + + public Task Upsert(Order order) + { + bool ord = _barDataBase.Orders.Contains(order); + if (ord == false) + { + _barDataBase.Orders.Add(order); + } + else + { + _barDataBase.Orders.Update(order); + } + int affected = _barDataBase.SaveChanges(); + bool isUpsert = (affected == 1) ? true : false; + return Task.FromResult(isUpsert); + } + } +} diff --git a/DataAccess/db.sql b/DataAccess/db.sql deleted file mode 100644 index e65d4cd..0000000 --- a/DataAccess/db.sql +++ /dev/null @@ -1,10 +0,0 @@ -CREATE TABLE [dbo].[Order]( - [Id] [int] NOT NULL IDENTITY(1,1) PRIMARY KEY, - [TotalPrice] float NOT NULL, - [Status] [int] NOT NULL -) - -CREATE TABLE [dbo].[Menu]( - [Name] [varchar](255) NOT NULL, - [Price] float NOT NULL -) ON [PRIMARY] diff --git a/EnqueueCompleteOrderCommandApp/EnqueueCompleteOrderCommandApp.csproj b/EnqueueCompleteOrderCommandApp/EnqueueCompleteOrderCommandApp.csproj index 8282e8f..2c2e2ce 100644 --- a/EnqueueCompleteOrderCommandApp/EnqueueCompleteOrderCommandApp.csproj +++ b/EnqueueCompleteOrderCommandApp/EnqueueCompleteOrderCommandApp.csproj @@ -9,5 +9,4 @@ - diff --git a/EnqueueCompleteOrderCommandApp/Program.cs b/EnqueueCompleteOrderCommandApp/Program.cs index 13abab7..09b674b 100644 --- a/EnqueueCompleteOrderCommandApp/Program.cs +++ b/EnqueueCompleteOrderCommandApp/Program.cs @@ -1,5 +1,4 @@ using System; -using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; diff --git a/OrderTimeOutService/.gitignore b/OrderTimeOutService/.gitignore new file mode 100644 index 0000000..ff5b00c --- /dev/null +++ b/OrderTimeOutService/.gitignore @@ -0,0 +1,264 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# Azure Functions localsettings file +local.settings.json + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +project.fragment.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +#*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc \ No newline at end of file diff --git a/OrderTimeOutService/BlobService/BlobStorage.cs b/OrderTimeOutService/BlobService/BlobStorage.cs new file mode 100644 index 0000000..7a3024e --- /dev/null +++ b/OrderTimeOutService/BlobService/BlobStorage.cs @@ -0,0 +1,32 @@ +using Azure.Storage.Blobs; +using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; +using System.Text; +using System.IO; +using System; +using static System.Environment; + +namespace OrderTimeOutService.BlobService +{ + public class BlobStorage : IBlobStorage + { + private readonly BlobServiceClient _blobServiceClient; + private readonly string _blobContainerName; + + + public BlobStorage() + { + _blobServiceClient = new BlobServiceClient(GetEnvironmentVariable("BlobStorageConnectionString", EnvironmentVariableTarget.Process)); + _blobContainerName = GetEnvironmentVariable("OrderTimeOutReportContainer", EnvironmentVariableTarget.Process); + } + + public async Task UploadContentBlobAsync(string content, string fileName) + { + BlobContainerClient containerClient = _blobServiceClient.GetBlobContainerClient(_blobContainerName); + BlobClient blobClient = containerClient.GetBlobClient(fileName); + byte[] bytes = Encoding.UTF8.GetBytes(content); + MemoryStream memoryStream = new MemoryStream(bytes); + await blobClient.UploadAsync(memoryStream); + } + } +} diff --git a/OrderTimeOutService/BlobService/IBlobStorage.cs b/OrderTimeOutService/BlobService/IBlobStorage.cs new file mode 100644 index 0000000..2091d1d --- /dev/null +++ b/OrderTimeOutService/BlobService/IBlobStorage.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace OrderTimeOutService.BlobService +{ + public interface IBlobStorage + { + Task UploadContentBlobAsync(string content, string fileName); + } +} diff --git a/OrderTimeOutService/OrderTimeOut.cs b/OrderTimeOutService/OrderTimeOut.cs new file mode 100644 index 0000000..31a3fcb --- /dev/null +++ b/OrderTimeOutService/OrderTimeOut.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using DataAccess.Data; +using DataAccess.Repository; +using Microsoft.Azure.WebJobs; +using Microsoft.Extensions.Logging; +using OrderTimeOutService.BlobService; +using System.Globalization; + +using static System.Environment; + +namespace OrderTimeOutService +{ + public class OrderTimeOut + { + private readonly OrderRepository _orderRepository; + private readonly BlobStorage _blobStorage; + + public OrderTimeOut() + { + _orderRepository = new OrderRepository(); + _blobStorage = new BlobStorage(); + + } + + [FunctionName("OrderTimeOut")] + public async Task Run([TimerTrigger("0 0 0 * * *")]TimerInfo myTimer, ILogger log) + { + log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}"); + List initiatedOrders = await _orderRepository.GetOrdersByStatus(OrderStatus.Initiated); + double finalizedOrdersSum = 0; + foreach (var order in initiatedOrders) + { + order.Status = OrderStatus.Finalized; + finalizedOrdersSum += order.TotalPrice; + await _orderRepository.Upsert(order); + } + string reportData = $"{initiatedOrders.Count},{finalizedOrdersSum.ToString(new CultureInfo("en-us", false))}"; + DateTime dateTime = DateTime.Now; + string reportFileName = $"{dateTime.Day}_{dateTime.Month}_{dateTime.Year}_report.csv"; + await _blobStorage.UploadContentBlobAsync(reportData, reportFileName); + } + } +} diff --git a/OrderTimeOutService/OrderTimeOutService.csproj b/OrderTimeOutService/OrderTimeOutService.csproj new file mode 100644 index 0000000..52542f0 --- /dev/null +++ b/OrderTimeOutService/OrderTimeOutService.csproj @@ -0,0 +1,28 @@ + + + netcoreapp3.1 + v3 + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + Never + + + diff --git a/OrderTimeOutService/Properties/ServiceDependencies/OrderTimeOut - Zip Deploy/profile.arm.json b/OrderTimeOutService/Properties/ServiceDependencies/OrderTimeOut - Zip Deploy/profile.arm.json new file mode 100644 index 0000000..d9cbd9b --- /dev/null +++ b/OrderTimeOutService/Properties/ServiceDependencies/OrderTimeOut - Zip Deploy/profile.arm.json @@ -0,0 +1,175 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_dependencyType": "function.windows.appService" + }, + "parameters": { + "resourceGroupName": { + "type": "string", + "defaultValue": "Bar-Service-Group", + "metadata": { + "description": "Name of the resource group for the resource. It is recommended to put resources under same resource group for better tracking." + } + }, + "resourceGroupLocation": { + "type": "string", + "defaultValue": "westeurope", + "metadata": { + "description": "Location of the resource group. Resource groups could have different location than resources, however by default we use API versions from latest hybrid profile which support all locations for resource types we support." + } + }, + "resourceName": { + "type": "string", + "defaultValue": "OrderTimeOut", + "metadata": { + "description": "Name of the main resource to be created by this template." + } + }, + "resourceLocation": { + "type": "string", + "defaultValue": "[parameters('resourceGroupLocation')]", + "metadata": { + "description": "Location of the resource. By default use resource group's location, unless the resource provider is not supported there." + } + } + }, + "resources": [ + { + "type": "Microsoft.Resources/resourceGroups", + "name": "[parameters('resourceGroupName')]", + "location": "[parameters('resourceGroupLocation')]", + "apiVersion": "2019-10-01" + }, + { + "type": "Microsoft.Resources/deployments", + "name": "[concat(parameters('resourceGroupName'), 'Deployment', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId)))]", + "resourceGroup": "[parameters('resourceGroupName')]", + "apiVersion": "2019-10-01", + "dependsOn": [ + "[parameters('resourceGroupName')]" + ], + "properties": { + "mode": "Incremental", + "expressionEvaluationOptions": { + "scope": "inner" + }, + "parameters": { + "resourceGroupName": { + "value": "[parameters('resourceGroupName')]" + }, + "resourceGroupLocation": { + "value": "[parameters('resourceGroupLocation')]" + }, + "resourceName": { + "value": "[parameters('resourceName')]" + }, + "resourceLocation": { + "value": "[parameters('resourceLocation')]" + } + }, + "template": { + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceGroupName": { + "type": "string" + }, + "resourceGroupLocation": { + "type": "string" + }, + "resourceName": { + "type": "string" + }, + "resourceLocation": { + "type": "string" + } + }, + "variables": { + "storage_name": "[toLower(concat('storage', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId))))]", + "appServicePlan_name": "[concat('Plan', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId)))]", + "storage_ResourceId": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', parameters('resourceGroupName'), '/providers/Microsoft.Storage/storageAccounts/', variables('storage_name'))]", + "appServicePlan_ResourceId": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', parameters('resourceGroupName'), '/providers/Microsoft.Web/serverFarms/', variables('appServicePlan_name'))]", + "function_ResourceId": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', parameters('resourceGroupName'), '/providers/Microsoft.Web/sites/', parameters('resourceName'))]" + }, + "resources": [ + { + "location": "[parameters('resourceLocation')]", + "name": "[parameters('resourceName')]", + "type": "Microsoft.Web/sites", + "apiVersion": "2015-08-01", + "tags": { + "[concat('hidden-related:', variables('appServicePlan_ResourceId'))]": "empty" + }, + "dependsOn": [ + "[variables('appServicePlan_ResourceId')]", + "[variables('storage_ResourceId')]" + ], + "kind": "functionapp", + "properties": { + "name": "[parameters('resourceName')]", + "kind": "functionapp", + "httpsOnly": true, + "reserved": false, + "serverFarmId": "[variables('appServicePlan_ResourceId')]", + "siteConfig": { + "alwaysOn": true + } + }, + "identity": { + "type": "SystemAssigned" + }, + "resources": [ + { + "name": "appsettings", + "type": "config", + "apiVersion": "2015-08-01", + "dependsOn": [ + "[variables('function_ResourceId')]" + ], + "properties": { + "AzureWebJobsDashboard": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storage_name'), ';AccountKey=', listKeys(variables('storage_ResourceId'), '2017-10-01').keys[0].value, ';EndpointSuffix=', 'core.windows.net')]", + "AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storage_name'), ';AccountKey=', listKeys(variables('storage_ResourceId'), '2017-10-01').keys[0].value, ';EndpointSuffix=', 'core.windows.net')]", + "FUNCTIONS_EXTENSION_VERSION": "~3", + "FUNCTIONS_WORKER_RUNTIME": "dotnet" + } + } + ] + }, + { + "location": "[parameters('resourceGroupLocation')]", + "name": "[variables('storage_name')]", + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2017-10-01", + "tags": { + "[concat('hidden-related:', concat('/providers/Microsoft.Web/sites/', parameters('resourceName')))]": "empty" + }, + "properties": { + "supportsHttpsTrafficOnly": true + }, + "sku": { + "name": "Standard_LRS" + }, + "kind": "Storage" + }, + { + "location": "[parameters('resourceGroupLocation')]", + "name": "[variables('appServicePlan_name')]", + "type": "Microsoft.Web/serverFarms", + "apiVersion": "2015-08-01", + "sku": { + "name": "S1", + "tier": "Standard", + "family": "S", + "size": "S1" + }, + "properties": { + "name": "[variables('appServicePlan_name')]" + } + } + ] + } + } + } + ] +} \ No newline at end of file diff --git a/OrderTimeOutService/Properties/ServiceDependencies/OrderTimeOut - Zip Deploy/storage1.arm.json b/OrderTimeOutService/Properties/ServiceDependencies/OrderTimeOut - Zip Deploy/storage1.arm.json new file mode 100644 index 0000000..b9b614e --- /dev/null +++ b/OrderTimeOutService/Properties/ServiceDependencies/OrderTimeOut - Zip Deploy/storage1.arm.json @@ -0,0 +1,70 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceGroupName": { + "type": "string", + "defaultValue": "Bar-Service-Group", + "metadata": { + "_parameterType": "resourceGroup", + "description": "Name of the resource group for the resource. It is recommended to put resources under same resource group for better tracking." + } + }, + "resourceGroupLocation": { + "type": "string", + "defaultValue": "westeurope", + "metadata": { + "_parameterType": "location", + "description": "Location of the resource group. Resource groups could have different location than resources." + } + }, + "resourceLocation": { + "type": "string", + "defaultValue": "[parameters('resourceGroupLocation')]", + "metadata": { + "_parameterType": "location", + "description": "Location of the resource. By default use resource group's location, unless the resource provider is not supported there." + } + } + }, + "resources": [ + { + "type": "Microsoft.Resources/resourceGroups", + "name": "[parameters('resourceGroupName')]", + "location": "[parameters('resourceGroupLocation')]", + "apiVersion": "2019-10-01" + }, + { + "type": "Microsoft.Resources/deployments", + "name": "[concat(parameters('resourceGroupName'), 'Deployment', uniqueString(concat('storageaccountbarse99a3', subscription().subscriptionId)))]", + "resourceGroup": "[parameters('resourceGroupName')]", + "apiVersion": "2019-10-01", + "dependsOn": [ + "[parameters('resourceGroupName')]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "sku": { + "name": "Standard_LRS", + "tier": "Standard" + }, + "kind": "Storage", + "name": "storageaccountbarse99a3", + "type": "Microsoft.Storage/storageAccounts", + "location": "[parameters('resourceLocation')]", + "apiVersion": "2017-10-01" + } + ] + } + } + } + ], + "metadata": { + "_dependencyType": "storage.azure" + } +} \ No newline at end of file diff --git a/OrderTimeOutService/Properties/serviceDependencies.OrderTimeOut - Zip Deploy.json b/OrderTimeOutService/Properties/serviceDependencies.OrderTimeOut - Zip Deploy.json new file mode 100644 index 0000000..586e945 --- /dev/null +++ b/OrderTimeOutService/Properties/serviceDependencies.OrderTimeOut - Zip Deploy.json @@ -0,0 +1,9 @@ +{ + "dependencies": { + "storage1": { + "resourceId": "/subscriptions/[parameters('subscriptionId')]/resourceGroups/[parameters('resourceGroupName')]/providers/Microsoft.Storage/storageAccounts/storageaccountbarse99a3", + "type": "storage.azure", + "connectionId": "AzureWebJobsStorage" + } + } +} \ No newline at end of file diff --git a/OrderTimeOutService/Properties/serviceDependencies.json b/OrderTimeOutService/Properties/serviceDependencies.json new file mode 100644 index 0000000..df4dcc9 --- /dev/null +++ b/OrderTimeOutService/Properties/serviceDependencies.json @@ -0,0 +1,11 @@ +{ + "dependencies": { + "appInsights1": { + "type": "appInsights" + }, + "storage1": { + "type": "storage", + "connectionId": "AzureWebJobsStorage" + } + } +} \ No newline at end of file diff --git a/OrderTimeOutService/Properties/serviceDependencies.local.json b/OrderTimeOutService/Properties/serviceDependencies.local.json new file mode 100644 index 0000000..b804a28 --- /dev/null +++ b/OrderTimeOutService/Properties/serviceDependencies.local.json @@ -0,0 +1,11 @@ +{ + "dependencies": { + "appInsights1": { + "type": "appInsights.sdk" + }, + "storage1": { + "type": "storage.emulator", + "connectionId": "AzureWebJobsStorage" + } + } +} \ No newline at end of file diff --git a/OrderTimeOutService/host.json b/OrderTimeOutService/host.json new file mode 100644 index 0000000..beb2e40 --- /dev/null +++ b/OrderTimeOutService/host.json @@ -0,0 +1,11 @@ +{ + "version": "2.0", + "logging": { + "applicationInsights": { + "samplingSettings": { + "isEnabled": true, + "excludedTypes": "Request" + } + } + } +} \ No newline at end of file diff --git a/OrderingService/CompleteOrderFunction.cs b/OrderingService/CompleteOrderFunction.cs index 1175df2..ab1f0bd 100644 --- a/OrderingService/CompleteOrderFunction.cs +++ b/OrderingService/CompleteOrderFunction.cs @@ -1,7 +1,7 @@ using System; using System.Threading.Tasks; -using DataAccess; -using DataAccess.Domain; +using DataAccess.Repository; +using DataAccess.Data; using Microsoft.Azure.WebJobs; using Microsoft.Extensions.Logging; diff --git a/OrderingService/DataAccess/InMemoryOrderRepository.cs b/OrderingService/DataAccess/InMemoryOrderRepository.cs index 920a435..5052a70 100644 --- a/OrderingService/DataAccess/InMemoryOrderRepository.cs +++ b/OrderingService/DataAccess/InMemoryOrderRepository.cs @@ -3,8 +3,8 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -using DataAccess; -using DataAccess.Domain; +using DataAccess.Data; +using DataAccess.Repository; namespace OrderingService.DataAccess { diff --git a/Shellys.sln b/Shellys.sln index c422ab8..14b5804 100644 --- a/Shellys.sln +++ b/Shellys.sln @@ -9,7 +9,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrderingService", "Ordering EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EnqueueCompleteOrderCommandApp", "EnqueueCompleteOrderCommandApp\EnqueueCompleteOrderCommandApp.csproj", "{0625C645-E362-483B-AD2C-884DC48E1BBA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataAccess", "DataAccess\DataAccess.csproj", "{C7322E06-A4DE-47DD-BBD5-7F3D4A729C69}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataAccess", "DataAccess\DataAccess.csproj", "{C7322E06-A4DE-47DD-BBD5-7F3D4A729C69}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OrderTimeOutService", "OrderTimeOutService\OrderTimeOutService.csproj", "{5C481AE0-DE38-48CB-84C6-43EECCC24BE0}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -33,6 +35,10 @@ Global {C7322E06-A4DE-47DD-BBD5-7F3D4A729C69}.Debug|Any CPU.Build.0 = Debug|Any CPU {C7322E06-A4DE-47DD-BBD5-7F3D4A729C69}.Release|Any CPU.ActiveCfg = Release|Any CPU {C7322E06-A4DE-47DD-BBD5-7F3D4A729C69}.Release|Any CPU.Build.0 = Release|Any CPU + {5C481AE0-DE38-48CB-84C6-43EECCC24BE0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5C481AE0-DE38-48CB-84C6-43EECCC24BE0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5C481AE0-DE38-48CB-84C6-43EECCC24BE0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5C481AE0-DE38-48CB-84C6-43EECCC24BE0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE