diff --git a/BreweryAPI/BreweryAPI schema.PNG b/BreweryAPI/BreweryAPI schema.PNG new file mode 100644 index 0000000..5fd29da Binary files /dev/null and b/BreweryAPI/BreweryAPI schema.PNG differ diff --git a/BreweryAPI/BreweryAPI.sln b/BreweryAPI/BreweryAPI.sln new file mode 100644 index 0000000..749fa3a --- /dev/null +++ b/BreweryAPI/BreweryAPI.sln @@ -0,0 +1,39 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.7.34009.444 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BreweryAPI", "BreweryAPI\BreweryAPI.csproj", "{2776268A-0281-4010-9B3A-1DCBA2B86F37}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntegrationTests", "IntegrationTests\IntegrationTests.csproj", "{3DF4EAFA-2635-47BA-A626-0662DC447DA6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BreweryMaui", "BreweryMaui\BreweryMaui.csproj", "{23C06012-5E13-4AD4-9AB1-4FB8B75B3F8C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2776268A-0281-4010-9B3A-1DCBA2B86F37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2776268A-0281-4010-9B3A-1DCBA2B86F37}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2776268A-0281-4010-9B3A-1DCBA2B86F37}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2776268A-0281-4010-9B3A-1DCBA2B86F37}.Release|Any CPU.Build.0 = Release|Any CPU + {3DF4EAFA-2635-47BA-A626-0662DC447DA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3DF4EAFA-2635-47BA-A626-0662DC447DA6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3DF4EAFA-2635-47BA-A626-0662DC447DA6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3DF4EAFA-2635-47BA-A626-0662DC447DA6}.Release|Any CPU.Build.0 = Release|Any CPU + {23C06012-5E13-4AD4-9AB1-4FB8B75B3F8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {23C06012-5E13-4AD4-9AB1-4FB8B75B3F8C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {23C06012-5E13-4AD4-9AB1-4FB8B75B3F8C}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {23C06012-5E13-4AD4-9AB1-4FB8B75B3F8C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {23C06012-5E13-4AD4-9AB1-4FB8B75B3F8C}.Release|Any CPU.Build.0 = Release|Any CPU + {23C06012-5E13-4AD4-9AB1-4FB8B75B3F8C}.Release|Any CPU.Deploy.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {ACB2614C-8CD0-4665-BAB7-E03D00321141} + EndGlobalSection +EndGlobal diff --git a/BreweryAPI/BreweryAPI/BreweryAPI.csproj b/BreweryAPI/BreweryAPI/BreweryAPI.csproj new file mode 100644 index 0000000..c83fb52 --- /dev/null +++ b/BreweryAPI/BreweryAPI/BreweryAPI.csproj @@ -0,0 +1,25 @@ + + + + net7.0 + enable + enable + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + diff --git a/BreweryAPI/BreweryAPI/Context.cs b/BreweryAPI/BreweryAPI/Context.cs new file mode 100644 index 0000000..f7e6ec4 --- /dev/null +++ b/BreweryAPI/BreweryAPI/Context.cs @@ -0,0 +1,19 @@ +using BreweryAPI.Models; +using Microsoft.EntityFrameworkCore; + +namespace BreweryAPI +{ + public class Context : DbContext + { + public DbSet Breweries { get; set; } + public DbSet Beers { get; set; } + public DbSet BrewerySales { get; set; } + public DbSet Wholesalers { get; set; } + public DbSet WholesalerInventories { get; set; } + public DbSet WholesalerQuotes { get; set; } + + public Context (DbContextOptions options) : base (options) + { + } + } +} diff --git a/BreweryAPI/BreweryAPI/Controllers/BeerController.cs b/BreweryAPI/BreweryAPI/Controllers/BeerController.cs new file mode 100644 index 0000000..9ff0684 --- /dev/null +++ b/BreweryAPI/BreweryAPI/Controllers/BeerController.cs @@ -0,0 +1,156 @@ +using AutoMapper; +using BreweryAPI.DTOs; +using BreweryAPI.Interface; +using BreweryAPI.Models; +using Microsoft.AspNetCore.Mvc; + +namespace BreweryAPI.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class BeerController : Controller + { + private readonly IBeerRepository _beerRepository; + private readonly IBreweryRepository _breweryRepository; + private readonly IMapper _mapper; + + public BeerController(IBeerRepository beerRepository, IBreweryRepository breweryRepository, IMapper mapper) + { + _breweryRepository = breweryRepository; + _beerRepository = beerRepository; + _mapper = mapper; + } + + [HttpGet] + [ProducesResponseType(200, Type = typeof(IEnumerable))] + public IActionResult GetBeers() + { + var beers = _mapper.Map>(_beerRepository.GetBeers()); + + if (!ModelState.IsValid) + return BadRequest(ModelState); + + return Ok(beers); + } + + [HttpGet("singular/{beerId}")] + [ProducesResponseType(200, Type = typeof(BeerModel))] + [ProducesResponseType(400)] + public IActionResult GetBeer(int beerId) + { + if (!_beerRepository.BeerExists(beerId)) + return NotFound(); + + var beer = _mapper.Map(_beerRepository.GetBeer(beerId)); + + if (!ModelState.IsValid) + return BadRequest(ModelState); + + return Ok(beer); + } + + [HttpGet("{breweryId}")] + [ProducesResponseType(200, Type = typeof(IEnumerable))] + [ProducesResponseType(400)] + public IActionResult GetBeersByBrewery(int breweryId) + { + if (!_breweryRepository.BreweryExists(breweryId)) + return NotFound(); + + var beersByBrewery = _mapper.Map>(_beerRepository.GetBeersByBrewery(breweryId)); + + if(beersByBrewery.Count == 0) + return NotFound(); + + if (!ModelState.IsValid) + return BadRequest(ModelState); + + return Ok(beersByBrewery); + } + + [HttpPost] + [ProducesResponseType(204)] + [ProducesResponseType(400)] + public IActionResult CreateBeer([FromBody] BeerDTO beerCreate) + { + if (beerCreate == null) + return BadRequest(ModelState); + + var beer = _beerRepository.GetBeers() + .Where(b => b.BeerName.Trim().ToUpper() == beerCreate.BeerName.TrimEnd().ToUpper()) + .FirstOrDefault(); + + if (beer != null) + { + ModelState.AddModelError("", "Beer already exists"); + return StatusCode(422, ModelState); + } + + if (!ModelState.IsValid) + return BadRequest(ModelState); + + var beerMap = _mapper.Map(beerCreate); + + if (!_beerRepository.CreateBeer(beerMap)) + { + ModelState.AddModelError("", "something went wrong while saving"); + return StatusCode(500, ModelState); + } + + return Ok("Succesfully created"); + } + + [HttpPut("{beerId}")] + [ProducesResponseType(400)] + [ProducesResponseType(204)] + [ProducesResponseType(404)] + public IActionResult UpdateBeer(int beerId, [FromBody] BeerDTO updatedBeer) + { + if (updatedBeer == null) + return BadRequest(ModelState); + + if (beerId != updatedBeer.BeerId) + return BadRequest(ModelState); + + if (!_beerRepository.BeerExists(beerId)) + return NotFound(); + + if (!ModelState.IsValid) + return BadRequest(); + + var beerMap = _mapper.Map(updatedBeer); + + if (!_beerRepository.UpdateBeer(beerMap)) + { + ModelState.AddModelError("", "Something went wrong updating beer"); + return StatusCode(500, ModelState); + } + + return NoContent(); + } + + [HttpDelete("{beerId}")] + [ProducesResponseType(400)] + [ProducesResponseType(204)] + [ProducesResponseType(404)] + public IActionResult DeleteBeer(int beerId) + { + if (!_beerRepository.BeerExists(beerId)) + { + return NotFound(); + } + + var beerToDelete = _beerRepository.GetBeer(beerId); + + if (!ModelState.IsValid) + return BadRequest(ModelState); + + if (!_beerRepository.DeleteBeer(beerToDelete)) + { + ModelState.AddModelError("", "Something went wrong deleting beer"); + } + + return NoContent(); + } + } +} diff --git a/BreweryAPI/BreweryAPI/Controllers/BreweryController.cs b/BreweryAPI/BreweryAPI/Controllers/BreweryController.cs new file mode 100644 index 0000000..ee56dde --- /dev/null +++ b/BreweryAPI/BreweryAPI/Controllers/BreweryController.cs @@ -0,0 +1,135 @@ +using AutoMapper; +using BreweryAPI.DTOs; +using BreweryAPI.Interface; +using BreweryAPI.Models; +using Microsoft.AspNetCore.Mvc; + +namespace BreweryAPI.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class BreweryController : Controller + { + private readonly IBreweryRepository _breweryRepository; + private readonly IMapper _mapper; + + public BreweryController(IBreweryRepository breweryRepository, IMapper mapper) + { + _breweryRepository = breweryRepository; + _mapper = mapper; + } + + [HttpGet] + [ProducesResponseType(200, Type = typeof(IEnumerable))] + public IActionResult GetBreweries() + { + var breweries = _mapper.Map>(_breweryRepository.GetBreweries()); + + if (!ModelState.IsValid) + return BadRequest(ModelState); + + return Ok(breweries); + } + + [HttpGet("{breweryId}")] + [ProducesResponseType(200, Type = typeof(BreweryModel))] + [ProducesResponseType(400)] + public IActionResult GetBrewery(int breweryId) + { + if (!_breweryRepository.BreweryExists(breweryId)) + return NotFound(); + + var brewery = _mapper.Map(_breweryRepository.GetBrewery(breweryId)); + + if (!ModelState.IsValid) + return BadRequest(ModelState); + + return Ok(brewery); + } + + [HttpPost] + [ProducesResponseType(204)] + [ProducesResponseType(400)] + public IActionResult CreateBrewery([FromBody] BreweryDTO breweryCreate) + { + if (breweryCreate == null) + return BadRequest(ModelState); + + var brewery = _breweryRepository.GetBreweries() + .Where(b => b.BreweryName.Trim().ToUpper() == breweryCreate.BreweryName.TrimEnd().ToUpper()) + .FirstOrDefault(); + + if (brewery != null) + { + ModelState.AddModelError("", "Brewery already exists"); + return StatusCode(422, ModelState); + } + + if (!ModelState.IsValid) + return BadRequest(ModelState); + + var breweryMap = _mapper.Map(breweryCreate); + + if (!_breweryRepository.CreateBrewery(breweryMap)) + { + ModelState.AddModelError("", "something went wrong while saving"); + return StatusCode(500, ModelState); + } + + return Ok("Succesfully created"); + } + + [HttpPut("{breweryId}")] + [ProducesResponseType(400)] + [ProducesResponseType(204)] + [ProducesResponseType(404)] + public IActionResult UpdateBrewery(int breweryId, [FromBody] BreweryDTO updatedBrewery) + { + if (updatedBrewery == null) + return BadRequest(ModelState); + + if (breweryId != updatedBrewery.BreweryId) + return BadRequest(ModelState); + + if (!_breweryRepository.BreweryExists(breweryId)) + return NotFound(); + + if (!ModelState.IsValid) + return BadRequest(); + + var breweryMap = _mapper.Map(updatedBrewery); + + if (!_breweryRepository.UpdateBrewery(breweryMap)) + { + ModelState.AddModelError("", "Something went wrong updating brewery"); + return StatusCode(500, ModelState); + } + + return NoContent(); + } + + [HttpDelete("{breweryId}")] + [ProducesResponseType(400)] + [ProducesResponseType(204)] + [ProducesResponseType(404)] + public IActionResult DeleteBrewery(int breweryId) + { + if (!_breweryRepository.BreweryExists(breweryId)) + { + return NotFound(); + } + + var breweryToDelete = _breweryRepository.GetBrewery(breweryId); + + if (!ModelState.IsValid) + return BadRequest(ModelState); + + if (!_breweryRepository.DeleteBrewery(breweryToDelete)) + { + ModelState.AddModelError("", "Something went wrong deleting brewery"); + } + + return NoContent(); + } + } +} \ No newline at end of file diff --git a/BreweryAPI/BreweryAPI/Controllers/BrewerySalesController.cs b/BreweryAPI/BreweryAPI/Controllers/BrewerySalesController.cs new file mode 100644 index 0000000..a84b25f --- /dev/null +++ b/BreweryAPI/BreweryAPI/Controllers/BrewerySalesController.cs @@ -0,0 +1,171 @@ +using AutoMapper; +using BreweryAPI.DTOs; +using BreweryAPI.Interface; +using BreweryAPI.Models; +using Microsoft.AspNetCore.Mvc; + +namespace BreweryAPI.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class BrewerySalesController: Controller + { + private readonly IBrewerySalesRepository _brewerySalesRepository; + private readonly IBeerRepository _beerRepository; + private readonly IWholesalerInventoryRepository _wholesalerInventoryRepository; + private readonly IMapper _mapper; + public BrewerySalesController(IWholesalerInventoryRepository wholesalerInventoryRepository, IBrewerySalesRepository brewerySalesRepository, IBeerRepository beerRepository, IMapper mapper) + { + _wholesalerInventoryRepository = wholesalerInventoryRepository; + _beerRepository = beerRepository; + _brewerySalesRepository = brewerySalesRepository; + _mapper = mapper; + } + + [HttpGet] + [ProducesResponseType(200, Type = typeof(IEnumerable))] + public IActionResult GetBrewerySales() + { + var brewerySales = _mapper.Map>(_brewerySalesRepository.GetBrewerySales()); + + if(!ModelState.IsValid) + { + return BadRequest(ModelState); + } + + return Ok(brewerySales); + } + + + [HttpGet("{brewerySalesId}")] + [ProducesResponseType(200, Type = typeof(BrewerySalesModel))] + [ProducesResponseType(400)] + public IActionResult GetBrewerySale(int brewerySalesId) + { + if (!_brewerySalesRepository.BrewerySaleExists(brewerySalesId)) + return NotFound(); + + var brewerySalesMap = _mapper.Map(_brewerySalesRepository.GetBrewerySale(brewerySalesId)); + + if (!ModelState.IsValid) + return BadRequest(ModelState); + + return Ok(brewerySalesMap); + } + + [HttpPost] + [ProducesResponseType(204)] + [ProducesResponseType(400)] + public IActionResult CreateBrewerySale([FromBody] BrewerySalesDTO brewerySaleCreate) + { + if (brewerySaleCreate == null) + return BadRequest(ModelState); + + var beer = _mapper.Map(_beerRepository.GetBeer(brewerySaleCreate.BeerId)); + + if(beer == null) + return BadRequest(ModelState); + + if(brewerySaleCreate.TotalPrice != beer.Price * brewerySaleCreate.Quantity) + return BadRequest(ModelState); + + //Update wholesaler inventory with the quantity of the sale + var wholesalerInventory = _wholesalerInventoryRepository.SelectRecord(brewerySaleCreate.WholeSalerId, brewerySaleCreate.BeerId); + + if(wholesalerInventory != null) + { + wholesalerInventory.Quantity = wholesalerInventory.Quantity + brewerySaleCreate.Quantity; + _wholesalerInventoryRepository.UpdateWholesalerInventory(wholesalerInventory); + } + else + { + //if the wholesaler buying beer does not have any items to update in their inventory, this will create a new item upon purchase. + WholesalerInventoryDTO newInventoryRecord = new WholesalerInventoryDTO + { + WholesalerId = brewerySaleCreate.WholeSalerId, + BeerId = brewerySaleCreate.BeerId, + Quantity = brewerySaleCreate.Quantity + }; + + var InventoryRecordToAdd = _mapper.Map(newInventoryRecord); + + _wholesalerInventoryRepository.CreateWholesalerInventory(InventoryRecordToAdd); + } + + + if (!ModelState.IsValid) + return BadRequest(ModelState); + + var brewerySaleMap = _mapper.Map(brewerySaleCreate); + + if (!_brewerySalesRepository.CreateBrewerySale(brewerySaleMap)) + { + ModelState.AddModelError("", "something went wrong while saving"); + return StatusCode(500, ModelState); + } + + return Ok("Succesfully created"); + } + + [HttpPut("{brewerySaleId}")] + [ProducesResponseType(400)] + [ProducesResponseType(204)] + [ProducesResponseType(404)] + public IActionResult UpdateBrewerySale(int brewerySaleId, [FromBody] BrewerySalesDTO updatedBrewerySale) + { + if (updatedBrewerySale == null) + return BadRequest(ModelState); + + if (brewerySaleId != updatedBrewerySale.SalesId) + return BadRequest(ModelState); + + var beer = _mapper.Map(_beerRepository.GetBeer(updatedBrewerySale.BeerId)); + + if (beer == null) + return BadRequest(ModelState); + + if (updatedBrewerySale.TotalPrice != beer.Price * updatedBrewerySale.Quantity) + return BadRequest(ModelState); + + if (!_brewerySalesRepository.BrewerySaleExists(brewerySaleId)) + return NotFound(); + + if (!ModelState.IsValid) + return BadRequest(); + + var brewerySaleMap = _mapper.Map(updatedBrewerySale); + + if (!_brewerySalesRepository.UpdateBrewerySales(brewerySaleMap)) + { + ModelState.AddModelError("", "Something went wrong updating brewerySale"); + return StatusCode(500, ModelState); + } + + return NoContent(); + } + + [HttpDelete("{brewerySaleId}")] + [ProducesResponseType(400)] + [ProducesResponseType(204)] + [ProducesResponseType(404)] + public IActionResult DeleteBrewerySale(int brewerySaleId) + { + if (!_brewerySalesRepository.BrewerySaleExists(brewerySaleId)) + { + return NotFound(); + } + + var brewerySaleToDelete = _brewerySalesRepository.GetBrewerySale (brewerySaleId); + + if (!ModelState.IsValid) + return BadRequest(ModelState); + + if (!_brewerySalesRepository.DeleteBrewerySales(brewerySaleToDelete)) + { + ModelState.AddModelError("", "Something went wrong deleting brewery"); + } + + return NoContent(); + } + } +} diff --git a/BreweryAPI/BreweryAPI/Controllers/WholesalerController.cs b/BreweryAPI/BreweryAPI/Controllers/WholesalerController.cs new file mode 100644 index 0000000..2b960ff --- /dev/null +++ b/BreweryAPI/BreweryAPI/Controllers/WholesalerController.cs @@ -0,0 +1,134 @@ +using AutoMapper; +using BreweryAPI.DTOs; +using BreweryAPI.Interface; +using BreweryAPI.Models; +using Microsoft.AspNetCore.Mvc; + +namespace BreweryAPI.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class WholesalerController: Controller + { + private readonly IWholesalerRepository _wholesalerRepository; + private readonly IMapper _mapper; + public WholesalerController(IWholesalerRepository wholesalerRepository, IMapper mapper) + { + _wholesalerRepository = wholesalerRepository; + _mapper = mapper; + } + + [HttpGet] + [ProducesResponseType(200, Type = typeof(IEnumerable))] + public IActionResult GetWholesalers() + { + var wholesalers = _mapper.Map>(_wholesalerRepository.GetWholesalers()); + + if (!ModelState.IsValid) + return BadRequest(ModelState); + + return Ok(wholesalers); + } + + [HttpGet("{wholesalerId}")] + [ProducesResponseType(200, Type = typeof(WholesalerModel))] + [ProducesResponseType(400)] + public IActionResult GetWholesaler(int wholesalerId) + { + if (!_wholesalerRepository.WholesalerExists(wholesalerId)) + return NotFound(); + + var wholesaler = _mapper.Map(_wholesalerRepository.GetWholesaler(wholesalerId)); + + if (!ModelState.IsValid) + return BadRequest(ModelState); + + return Ok(wholesaler); + } + + [HttpPost] + [ProducesResponseType(204)] + [ProducesResponseType(400)] + public IActionResult CreateWholesaler([FromBody] WholesalerDTO wholesalerCreate) + { + if (wholesalerCreate == null) + return BadRequest(ModelState); + + var wholesaler = _wholesalerRepository.GetWholesalers() + .Where(b => b.WholesalerName.Trim().ToUpper() == wholesalerCreate.WholesalerName.TrimEnd().ToUpper()) + .FirstOrDefault(); + + if (wholesaler != null) + { + ModelState.AddModelError("", "Wholesaler already exists"); + return StatusCode(422, ModelState); + } + + if (!ModelState.IsValid) + return BadRequest(ModelState); + + var wholesalerMap = _mapper.Map(wholesalerCreate); + + if (!_wholesalerRepository.CreateWholesaler(wholesalerMap)) + { + ModelState.AddModelError("", "something went wrong while saving"); + return StatusCode(500, ModelState); + } + + return Ok("Succesfully created"); + } + + [HttpPut("{wholesalerId}")] + [ProducesResponseType(400)] + [ProducesResponseType(204)] + [ProducesResponseType(404)] + public IActionResult UpdateWholesaler(int wholesalerId, [FromBody] WholesalerDTO updateWholesaler) + { + if (updateWholesaler == null) + return BadRequest(ModelState); + + if (wholesalerId != updateWholesaler.WholesalerID) + return BadRequest(ModelState); + + if (!_wholesalerRepository.WholesalerExists(wholesalerId)) + return NotFound(); + + if (!ModelState.IsValid) + return BadRequest(); + + var wholesalerMap = _mapper.Map(updateWholesaler); + + if (!_wholesalerRepository.UpdateWholesaler(wholesalerMap)) + { + ModelState.AddModelError("", "Something went wrong updating wholesaler"); + return StatusCode(500, ModelState); + } + + return NoContent(); + } + + [HttpDelete("{wholesalerId}")] + [ProducesResponseType(400)] + [ProducesResponseType(204)] + [ProducesResponseType(404)] + public IActionResult DeleteWholesaler(int wholesalerId) + { + if (!_wholesalerRepository.WholesalerExists(wholesalerId)) + { + return NotFound(); + } + + var wholesalerToDelete = _wholesalerRepository.GetWholesaler(wholesalerId); + + if (!ModelState.IsValid) + return BadRequest(ModelState); + + if (!_wholesalerRepository.DeleteWholesaler(wholesalerToDelete)) + { + ModelState.AddModelError("", "Something went wrong deleting wholesaler"); + } + + return NoContent(); + } + } +} diff --git a/BreweryAPI/BreweryAPI/Controllers/WholesalerInventoryController.cs b/BreweryAPI/BreweryAPI/Controllers/WholesalerInventoryController.cs new file mode 100644 index 0000000..29bc32f --- /dev/null +++ b/BreweryAPI/BreweryAPI/Controllers/WholesalerInventoryController.cs @@ -0,0 +1,142 @@ +using AutoMapper; +using BreweryAPI.DTOs; +using BreweryAPI.Interface; +using BreweryAPI.Models; +using Microsoft.AspNetCore.Mvc; + +namespace BreweryAPI.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class WholesalerInventoryController: Controller + { + private readonly IWholesalerInventoryRepository _wholesalerInventoryRepository; + private readonly IBeerRepository _beerRepository; + private readonly IMapper _mapper; + public WholesalerInventoryController(IWholesalerInventoryRepository wholesalerInventoryRepository, IBeerRepository beerRepository, IMapper mapper) + { + _wholesalerInventoryRepository = wholesalerInventoryRepository; + _beerRepository = beerRepository; + _mapper = mapper; + } + + [HttpGet] + [ProducesResponseType(200, Type = typeof(IEnumerable))] + public IActionResult GetWholesalerInventories() + { + var wholesalerInventories = _mapper.Map>(_wholesalerInventoryRepository.GetWholesalerInventories()); + + if (!ModelState.IsValid) + return BadRequest(ModelState); + + return Ok(wholesalerInventories); + } + + [HttpGet("{wholesalerInventoryId}")] + [ProducesResponseType(200, Type = typeof(WholesalerInventory))] + [ProducesResponseType(400)] + public IActionResult GetWholesalerInventory(int wholesalerInventoryId) + { + if (!_wholesalerInventoryRepository.WholesalerInventoryExists(wholesalerInventoryId)) + return NotFound(); + + var wholesaler = _mapper.Map(_wholesalerInventoryRepository.GetWholesalerInventory(wholesalerInventoryId)); + + if (!ModelState.IsValid) + return BadRequest(ModelState); + + return Ok(wholesaler); + } + + [HttpPost] + [ProducesResponseType(204)] + [ProducesResponseType(400)] + public IActionResult createWholesalerInventory([FromBody] WholesalerInventoryDTO wholesalerInventoryCreate) + { + if (wholesalerInventoryCreate == null) + return BadRequest(ModelState); + + var beer = _mapper.Map(_beerRepository.GetBeer(wholesalerInventoryCreate.BeerId)); + + if (beer == null) + return BadRequest(ModelState); + + if (!ModelState.IsValid) + return BadRequest(ModelState); + + var wholesalerInventoryMap = _mapper.Map(wholesalerInventoryCreate); + + if (_wholesalerInventoryRepository.IsUniqueRecord(wholesalerInventoryMap)) + { + ModelState.AddModelError("", "Record already exists"); + return StatusCode(422, ModelState); + } + + if (!_wholesalerInventoryRepository.CreateWholesalerInventory(wholesalerInventoryMap)) + { + ModelState.AddModelError("", "something went wrong while saving"); + return StatusCode(500, ModelState); + } + + return Ok("Succesfully created"); + } + + [HttpPut("{wholesaleInventoryId}")] + [ProducesResponseType(400)] + [ProducesResponseType(204)] + [ProducesResponseType(404)] + public IActionResult updateWholesalerInventory(int wholesaleInventoryId, [FromBody] WholesalerInventoryDTO updateWholesaleInventory) + { + if (updateWholesaleInventory == null) + return BadRequest(ModelState); + + if (wholesaleInventoryId != updateWholesaleInventory.ItemId) + return BadRequest(ModelState); + + var beer = _mapper.Map(_beerRepository.GetBeer(updateWholesaleInventory.BeerId)); + + if (beer == null) + return BadRequest(ModelState); + + if (!_wholesalerInventoryRepository.WholesalerInventoryExists(wholesaleInventoryId)) + return NotFound(); + + if (!ModelState.IsValid) + return BadRequest(); + + var wholesaleInventoryMap = _mapper.Map(updateWholesaleInventory); + + if (!_wholesalerInventoryRepository.UpdateWholesalerInventory(wholesaleInventoryMap)) + { + ModelState.AddModelError("", "Something went wrong updating wholesaleInventory"); + return StatusCode(500, ModelState); + } + + return NoContent(); + } + + [HttpDelete("{wholesaleInventoryId}")] + [ProducesResponseType(400)] + [ProducesResponseType(204)] + [ProducesResponseType(404)] + public IActionResult DeleteWholesaleInventory(int wholesaleInventoryId) + { + if (!_wholesalerInventoryRepository.WholesalerInventoryExists(wholesaleInventoryId)) + { + return NotFound(); + } + + var wholesaleInventoryModel = _wholesalerInventoryRepository.GetWholesalerInventory(wholesaleInventoryId); + + if (!ModelState.IsValid) + return BadRequest(ModelState); + + if (!_wholesalerInventoryRepository.DeleteWholesalerInventory(wholesaleInventoryModel)) + { + ModelState.AddModelError("", "Something went wrong deleting wholesaleInventory"); + } + + return NoContent(); + } + } +} diff --git a/BreweryAPI/BreweryAPI/Controllers/WholesalerQuoteController.cs b/BreweryAPI/BreweryAPI/Controllers/WholesalerQuoteController.cs new file mode 100644 index 0000000..86b1aba --- /dev/null +++ b/BreweryAPI/BreweryAPI/Controllers/WholesalerQuoteController.cs @@ -0,0 +1,128 @@ +using AutoMapper; +using BreweryAPI.DTOs; +using BreweryAPI.Interface; +using BreweryAPI.Models; +using Microsoft.AspNetCore.Mvc; + +namespace BreweryAPI.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class WholesalerQuoteController: Controller + { + private readonly IWholesalerInventoryRepository _wholesalerInventoryRepository; + private readonly IWholesalerQuoteRepository _wholesalerQuoteRepository; + private readonly IMapper _mapper; + + public WholesalerQuoteController(IWholesalerInventoryRepository wholesalerInventoryRepository, IWholesalerQuoteRepository wholesalerQuoteRepository, IMapper mapper) + { + _wholesalerInventoryRepository = wholesalerInventoryRepository; + _wholesalerQuoteRepository = wholesalerQuoteRepository; + _mapper = mapper; + } + + [HttpGet] + [ProducesResponseType(200, Type = typeof(IEnumerable))] + public IActionResult GetWholesalerQuotes() + { + var wholesalerQuotes = _mapper.Map>(_wholesalerQuoteRepository.GetWholesalerQuotes()); + + if (!ModelState.IsValid) + return BadRequest(ModelState); + + return Ok(wholesalerQuotes); + } + + + [HttpGet("{wholesalerQuoteId}")] + [ProducesResponseType(200, Type = typeof(WholesalerQuoteModel))] + [ProducesResponseType(400)] + public IActionResult GetWholesalerQuote(int wholesalerQuoteId) + { + if (!_wholesalerQuoteRepository.WholesalerQuoteExists(wholesalerQuoteId)) + return NotFound(); + + var wholesalerQuoteMap = _mapper.Map(_wholesalerQuoteRepository.GetWholesalerQuote(wholesalerQuoteId)); + + if (!ModelState.IsValid) + return BadRequest(ModelState); + + return Ok(wholesalerQuoteMap); + } + + [HttpPost] + [ProducesResponseType(204)] + [ProducesResponseType(400)] + public IActionResult CreateWholesalerQuote([FromBody] WholesalerQuoteDTO wholesalerQuoteCreate) + { + if (wholesalerQuoteCreate == null) + return BadRequest(ModelState); + + var wholesalerInventoryRecord = _mapper.Map(_wholesalerInventoryRepository.SelectRecord(wholesalerQuoteCreate.WholesalerId, wholesalerQuoteCreate.BeerId)); + + if (wholesalerInventoryRecord == null) + return BadRequest(ModelState); + + if(wholesalerQuoteCreate.Quantity > wholesalerInventoryRecord.Quantity) + { + return BadRequest(ModelState); + } + else + { + wholesalerInventoryRecord.Quantity = wholesalerInventoryRecord.Quantity - wholesalerQuoteCreate.Quantity; + } + + if(wholesalerQuoteCreate.Quantity > 10) + { + wholesalerQuoteCreate.TotalPrice = wholesalerQuoteCreate.TotalPrice * 90; + } + else if (wholesalerQuoteCreate.Quantity > 20) + { + wholesalerQuoteCreate.TotalPrice = wholesalerQuoteCreate.TotalPrice * 80; + } + + if (!ModelState.IsValid) + return BadRequest(ModelState); + + var wholesalerQuoteMap = _mapper.Map(wholesalerQuoteCreate); + + if (!_wholesalerQuoteRepository.CreateWholesalerQuote(wholesalerQuoteMap)) + { + ModelState.AddModelError("", "something went wrong while saving"); + return StatusCode(500, ModelState); + } + + if (!_wholesalerInventoryRepository.UpdateWholesalerInventory(wholesalerInventoryRecord)) + { + ModelState.AddModelError("", "something went wrong while saving"); + return StatusCode(500, ModelState); + } + + return Ok("Succesfully created"); + } + + [HttpDelete("{wholesalerQuoteId}")] + [ProducesResponseType(400)] + [ProducesResponseType(204)] + [ProducesResponseType(404)] + public IActionResult DeleteWholesalerQuote(int wholesalerQuoteId) + { + if (!_wholesalerQuoteRepository.WholesalerQuoteExists(wholesalerQuoteId)) + { + return NotFound(); + } + + var wholesalerQuoteToDelete = _wholesalerQuoteRepository.GetWholesalerQuote(wholesalerQuoteId); + + if (!ModelState.IsValid) + return BadRequest(ModelState); + + if (!_wholesalerQuoteRepository.DeleteWholesalerQuote(wholesalerQuoteToDelete)) + { + ModelState.AddModelError("", "Something went wrong deleting wholesaler"); + } + + return NoContent(); + } + } +} diff --git a/BreweryAPI/BreweryAPI/DTOs/BeerDTO.cs b/BreweryAPI/BreweryAPI/DTOs/BeerDTO.cs new file mode 100644 index 0000000..19c39c1 --- /dev/null +++ b/BreweryAPI/BreweryAPI/DTOs/BeerDTO.cs @@ -0,0 +1,10 @@ +namespace BreweryAPI.DTOs +{ + public class BeerDTO + { + public int BeerId { get; set; } + public string BeerName { get; set; } + public decimal Price { get; set; } + public int BreweryId { get; set; } + } +} diff --git a/BreweryAPI/BreweryAPI/DTOs/BreweryDTO.cs b/BreweryAPI/BreweryAPI/DTOs/BreweryDTO.cs new file mode 100644 index 0000000..849fbf8 --- /dev/null +++ b/BreweryAPI/BreweryAPI/DTOs/BreweryDTO.cs @@ -0,0 +1,9 @@ +namespace BreweryAPI.DTOs +{ + public class BreweryDTO + { + public int BreweryId { get; set; } + public string BreweryName { get; set; } + public string BreweryLocation { get; set; } + } +} diff --git a/BreweryAPI/BreweryAPI/DTOs/BrewerySalesDTO.cs b/BreweryAPI/BreweryAPI/DTOs/BrewerySalesDTO.cs new file mode 100644 index 0000000..5969ba9 --- /dev/null +++ b/BreweryAPI/BreweryAPI/DTOs/BrewerySalesDTO.cs @@ -0,0 +1,11 @@ +namespace BreweryAPI.DTOs +{ + public class BrewerySalesDTO + { + public int SalesId { get; set; } + public int WholeSalerId { get; set; } + public int BeerId { get; set; } + public int Quantity { get; set; } + public decimal TotalPrice { get; set; } + } +} diff --git a/BreweryAPI/BreweryAPI/DTOs/WholesalerDTO.cs b/BreweryAPI/BreweryAPI/DTOs/WholesalerDTO.cs new file mode 100644 index 0000000..4cef0d6 --- /dev/null +++ b/BreweryAPI/BreweryAPI/DTOs/WholesalerDTO.cs @@ -0,0 +1,9 @@ +namespace BreweryAPI.DTOs +{ + public class WholesalerDTO + { + public int WholesalerID { get; set; } + public string WholesalerName { get; set; } + public string WholesalerLocation { get; set; } + } +} diff --git a/BreweryAPI/BreweryAPI/DTOs/WholesalerInventoryDTO.cs b/BreweryAPI/BreweryAPI/DTOs/WholesalerInventoryDTO.cs new file mode 100644 index 0000000..2227893 --- /dev/null +++ b/BreweryAPI/BreweryAPI/DTOs/WholesalerInventoryDTO.cs @@ -0,0 +1,10 @@ +namespace BreweryAPI.DTOs +{ + public class WholesalerInventoryDTO + { + public int ItemId { get; set; } + public int WholesalerId { get; set; } + public int BeerId { get; set; } + public int Quantity { get; set; } + } +} diff --git a/BreweryAPI/BreweryAPI/DTOs/WholesalerQuoteDTO.cs b/BreweryAPI/BreweryAPI/DTOs/WholesalerQuoteDTO.cs new file mode 100644 index 0000000..b9a188c --- /dev/null +++ b/BreweryAPI/BreweryAPI/DTOs/WholesalerQuoteDTO.cs @@ -0,0 +1,12 @@ +namespace BreweryAPI.DTOs +{ + public class WholesalerQuoteDTO + { + public int QuoteId { get; set; } + public string ClientName { get; set; } + public int WholesalerId { get; set; } + public int BeerId { get; set; } + public int Quantity { get; set; } + public decimal TotalPrice { get; set; } + } +} diff --git a/BreweryAPI/BreweryAPI/Helpers/MappingProfiles.cs b/BreweryAPI/BreweryAPI/Helpers/MappingProfiles.cs new file mode 100644 index 0000000..1ac51a5 --- /dev/null +++ b/BreweryAPI/BreweryAPI/Helpers/MappingProfiles.cs @@ -0,0 +1,25 @@ +using AutoMapper; +using BreweryAPI.DTOs; +using BreweryAPI.Models; + +namespace BreweryAPI.Helpers +{ + public class MappingProfiles : Profile + { + public MappingProfiles() + { + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + } + } +} diff --git a/BreweryAPI/BreweryAPI/Interface/IBeerRepository.cs b/BreweryAPI/BreweryAPI/Interface/IBeerRepository.cs new file mode 100644 index 0000000..c2e99cb --- /dev/null +++ b/BreweryAPI/BreweryAPI/Interface/IBeerRepository.cs @@ -0,0 +1,16 @@ +using BreweryAPI.Models; + +namespace BreweryAPI.Interface +{ + public interface IBeerRepository + { + ICollection GetBeers(); + BeerModel GetBeer(int id); + bool CreateBeer(BeerModel beerModel); + bool UpdateBeer(BeerModel beerModel); + bool DeleteBeer(BeerModel beerModel); + public ICollection GetBeersByBrewery(int breweryId); + bool BeerExists(int id); + bool Save(); + } +} diff --git a/BreweryAPI/BreweryAPI/Interface/IBreweryRepository.cs b/BreweryAPI/BreweryAPI/Interface/IBreweryRepository.cs new file mode 100644 index 0000000..2589acb --- /dev/null +++ b/BreweryAPI/BreweryAPI/Interface/IBreweryRepository.cs @@ -0,0 +1,15 @@ +using BreweryAPI.Models; + +namespace BreweryAPI.Interface +{ + public interface IBreweryRepository + { + ICollection GetBreweries(); + BreweryModel GetBrewery(int id); + bool CreateBrewery(BreweryModel breweryModel); + bool UpdateBrewery(BreweryModel breweryModel); + bool DeleteBrewery(BreweryModel breweryModel); + bool BreweryExists(int id); + bool Save(); + } +} diff --git a/BreweryAPI/BreweryAPI/Interface/IBrewerySalesRepository.cs b/BreweryAPI/BreweryAPI/Interface/IBrewerySalesRepository.cs new file mode 100644 index 0000000..37f74c2 --- /dev/null +++ b/BreweryAPI/BreweryAPI/Interface/IBrewerySalesRepository.cs @@ -0,0 +1,15 @@ +using BreweryAPI.Models; + +namespace BreweryAPI.Interface +{ + public interface IBrewerySalesRepository + { + ICollection GetBrewerySales(); + BrewerySalesModel GetBrewerySale(int id); + bool CreateBrewerySale(BrewerySalesModel brewerySalesModel); + bool UpdateBrewerySales(BrewerySalesModel brewerySalesModel); + bool DeleteBrewerySales(BrewerySalesModel brewerySalesModel); + bool BrewerySaleExists(int id); + bool Save(); + } +} diff --git a/BreweryAPI/BreweryAPI/Interface/IWholesalerInventoryRepository.cs b/BreweryAPI/BreweryAPI/Interface/IWholesalerInventoryRepository.cs new file mode 100644 index 0000000..cd42fcb --- /dev/null +++ b/BreweryAPI/BreweryAPI/Interface/IWholesalerInventoryRepository.cs @@ -0,0 +1,17 @@ +using BreweryAPI.Models; + +namespace BreweryAPI.Interface +{ + public interface IWholesalerInventoryRepository + { + ICollection GetWholesalerInventories(); + WholesalerInventory GetWholesalerInventory(int id); + bool CreateWholesalerInventory(WholesalerInventory wholesalerInventory); + bool UpdateWholesalerInventory(WholesalerInventory wholesalerInventory); + bool DeleteWholesalerInventory(WholesalerInventory wholesalerInventory); + bool WholesalerInventoryExists(int id); + bool Save(); + public bool IsUniqueRecord(WholesalerInventory wholesalerInventory); + public WholesalerInventory SelectRecord(int wholesalerId, int beerId); + } +} diff --git a/BreweryAPI/BreweryAPI/Interface/IWholesalerQuoteRepository.cs b/BreweryAPI/BreweryAPI/Interface/IWholesalerQuoteRepository.cs new file mode 100644 index 0000000..aeda2dc --- /dev/null +++ b/BreweryAPI/BreweryAPI/Interface/IWholesalerQuoteRepository.cs @@ -0,0 +1,15 @@ +using BreweryAPI.Models; + +namespace BreweryAPI.Interface +{ + public interface IWholesalerQuoteRepository + { + ICollection GetWholesalerQuotes(); + WholesalerQuoteModel GetWholesalerQuote(int id); + bool CreateWholesalerQuote(WholesalerQuoteModel wholesalerQuote); + bool UpdateWholesalerQuote(WholesalerQuoteModel wholesalerQuote); + bool DeleteWholesalerQuote(WholesalerQuoteModel wholesalerQuote); + bool WholesalerQuoteExists(int id); + bool Save(); + } +} diff --git a/BreweryAPI/BreweryAPI/Interface/IWholesalerRepository.cs b/BreweryAPI/BreweryAPI/Interface/IWholesalerRepository.cs new file mode 100644 index 0000000..3c4cc87 --- /dev/null +++ b/BreweryAPI/BreweryAPI/Interface/IWholesalerRepository.cs @@ -0,0 +1,15 @@ +using BreweryAPI.Models; + +namespace BreweryAPI.Interface +{ + public interface IWholesalerRepository + { + ICollection GetWholesalers(); + WholesalerModel GetWholesaler(int id); + bool CreateWholesaler(WholesalerModel wholesalerModel); + bool UpdateWholesaler(WholesalerModel wholesalerModel); + bool DeleteWholesaler(WholesalerModel wholesalerModel); + bool WholesalerExists(int id); + bool Save(); + } +} diff --git a/BreweryAPI/BreweryAPI/Models/BeerModel.cs b/BreweryAPI/BreweryAPI/Models/BeerModel.cs new file mode 100644 index 0000000..4ac6067 --- /dev/null +++ b/BreweryAPI/BreweryAPI/Models/BeerModel.cs @@ -0,0 +1,16 @@ +using System.ComponentModel.DataAnnotations; + +namespace BreweryAPI.Models +{ + public class BeerModel + { + [Key] + public int BeerId { get; set; } + public string BeerName { get; set; } + public decimal Price { get; set; } + public int BreweryId { get; set; } + + public BreweryModel Brewery { get; set; } + public ICollection WholesalerInventories { get; set; } + } +} diff --git a/BreweryAPI/BreweryAPI/Models/BreweryModel.cs b/BreweryAPI/BreweryAPI/Models/BreweryModel.cs new file mode 100644 index 0000000..65a7262 --- /dev/null +++ b/BreweryAPI/BreweryAPI/Models/BreweryModel.cs @@ -0,0 +1,15 @@ +using System.ComponentModel.DataAnnotations; + +namespace BreweryAPI.Models +{ + public class BreweryModel + { + [Key] + public int BreweryId { get; set; } + public string BreweryName { get; set; } + public string BreweryLocation { get; set; } + + public ICollection Beers{get; set;} + } +} + diff --git a/BreweryAPI/BreweryAPI/Models/BrewerySalesModel.cs b/BreweryAPI/BreweryAPI/Models/BrewerySalesModel.cs new file mode 100644 index 0000000..4d5c723 --- /dev/null +++ b/BreweryAPI/BreweryAPI/Models/BrewerySalesModel.cs @@ -0,0 +1,16 @@ +using System.ComponentModel.DataAnnotations; + +namespace BreweryAPI.Models +{ + public class BrewerySalesModel + { + [Key] + public int SalesId { get; set; } + public int WholeSalerId { get; set; } + public int BeerId { get; set; } + public int Quantity { get; set; } + public decimal TotalPrice { get; set; } + + public WholesalerModel Wholesaler { get; set; } + } +} diff --git a/BreweryAPI/BreweryAPI/Models/WholesalerInventory.cs b/BreweryAPI/BreweryAPI/Models/WholesalerInventory.cs new file mode 100644 index 0000000..0e5aea8 --- /dev/null +++ b/BreweryAPI/BreweryAPI/Models/WholesalerInventory.cs @@ -0,0 +1,15 @@ +using System.ComponentModel.DataAnnotations; + +namespace BreweryAPI.Models +{ + public class WholesalerInventory + { + [Key] + public int ItemId { get; set; } + public int WholesalerId { get; set; } + public int BeerId { get; set; } + public int Quantity { get; set; } + + public WholesalerModel Wholesaler { get; set; } + } +} diff --git a/BreweryAPI/BreweryAPI/Models/WholesalerModel.cs b/BreweryAPI/BreweryAPI/Models/WholesalerModel.cs new file mode 100644 index 0000000..39c0077 --- /dev/null +++ b/BreweryAPI/BreweryAPI/Models/WholesalerModel.cs @@ -0,0 +1,15 @@ +using System.ComponentModel.DataAnnotations; + +namespace BreweryAPI.Models +{ + public class WholesalerModel + { + [Key] + public int WholesalerID { get; set; } + public string WholesalerName { get;set; } + public string WholesalerLocation { get; set; } + + public ICollection WholesalerInventories { get; set; } // One-to-many relationship to Inventories + public ICollection WholesalerQuote { get; set; } + } +} diff --git a/BreweryAPI/BreweryAPI/Models/WholesalerQuoteModel.cs b/BreweryAPI/BreweryAPI/Models/WholesalerQuoteModel.cs new file mode 100644 index 0000000..fd4a8a8 --- /dev/null +++ b/BreweryAPI/BreweryAPI/Models/WholesalerQuoteModel.cs @@ -0,0 +1,17 @@ +using System.ComponentModel.DataAnnotations; + +namespace BreweryAPI.Models +{ + public class WholesalerQuoteModel + { + [Key] + public int QuoteId { get; set; } + public string ClientName { get; set; } + public int WholesalerId { get; set; } + public int BeerId { get; set; } + public int Quantity { get; set; } + public decimal TotalPrice { get; set; } + + public WholesalerModel Wholesaler { get; set; } + } +} diff --git a/BreweryAPI/BreweryAPI/Program.cs b/BreweryAPI/BreweryAPI/Program.cs new file mode 100644 index 0000000..178984d --- /dev/null +++ b/BreweryAPI/BreweryAPI/Program.cs @@ -0,0 +1,71 @@ +using BreweryAPI; + +using BreweryAPI.Interface; +using BreweryAPI.Repositories; + +using Microsoft.EntityFrameworkCore; + +public class Program +{ + private static void Main(string[] args) + { + Context context; + bool isTestEnvironment = Environment.GetEnvironmentVariable("TEST_ENVIRONMENT")?.Equals("true", StringComparison.OrdinalIgnoreCase) ?? false; + + var builder = WebApplication.CreateBuilder(args); + + builder.Services.AddControllers(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); + builder.Services.AddEndpointsApiExplorer(); + builder.Services.AddSwaggerGen(); + builder.Services.AddDbContext(options => + { + options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")); + }); + + var app = builder.Build(); + + using (var scope = app.Services.CreateScope()) + { + context = scope.ServiceProvider.GetService(); + + try + { + if(!isTestEnvironment) + { + SeedData seedData = new SeedData(context); + seedData.SeedDataContext(); + } + + } + catch (Exception ex) + { + Console.WriteLine($"Database creation error: {ex.Message}"); + } + } + if (app.Environment.IsDevelopment()) + { + app.UseSwagger(); + app.UseSwaggerUI(); + } + + app.UseHttpsRedirection(); + + app.UseAuthorization(); + + app.MapControllers(); + + app.Run(); + } + + private static bool IsTestEnvironment(string[] args) + { + return args.Contains("--test-environment"); + } +} \ No newline at end of file diff --git a/BreweryAPI/BreweryAPI/Properties/launchSettings.json b/BreweryAPI/BreweryAPI/Properties/launchSettings.json new file mode 100644 index 0000000..05f6552 --- /dev/null +++ b/BreweryAPI/BreweryAPI/Properties/launchSettings.json @@ -0,0 +1,41 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:48553", + "sslPort": 44355 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5124", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7256;http://localhost:5124", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/BreweryAPI/BreweryAPI/Repositories/BeerRepository.cs b/BreweryAPI/BreweryAPI/Repositories/BeerRepository.cs new file mode 100644 index 0000000..6ac8be2 --- /dev/null +++ b/BreweryAPI/BreweryAPI/Repositories/BeerRepository.cs @@ -0,0 +1,58 @@ +using BreweryAPI.Interface; +using BreweryAPI.Models; + +namespace BreweryAPI.Repositories +{ + public class BeerRepository : IBeerRepository + { + private readonly Context _context; + public BeerRepository(Context context) + { + _context = context; + } + + public bool BeerExists(int id) + { + return _context.Beers.Any(b => b.BeerId == id); + } + + public bool CreateBeer(BeerModel beerModel) + { + _context.Add(beerModel); + return Save(); + } + + public bool DeleteBeer(BeerModel beerModel) + { + _context.Remove(beerModel); + return Save(); + } + + public BeerModel GetBeer(int id) + { + return _context.Beers.Where(b => b.BeerId == id).FirstOrDefault(); + } + + public ICollection GetBeers() + { + return _context.Beers.ToList(); + } + + public ICollection GetBeersByBrewery(int breweryId) + { + return _context.Beers.Where(b => b.BreweryId == breweryId).ToList(); + } + + public bool Save() + { + var saved = _context.SaveChanges(); + return saved > 0 ? true : false; + } + + public bool UpdateBeer(BeerModel beerModel) + { + _context.Update(beerModel); + return Save(); + } + } +} diff --git a/BreweryAPI/BreweryAPI/Repositories/BreweryRepository.cs b/BreweryAPI/BreweryAPI/Repositories/BreweryRepository.cs new file mode 100644 index 0000000..cca8edd --- /dev/null +++ b/BreweryAPI/BreweryAPI/Repositories/BreweryRepository.cs @@ -0,0 +1,53 @@ +using BreweryAPI.Interface; +using BreweryAPI.Models; + +namespace BreweryAPI.Repositories +{ + public class BreweryRepository : IBreweryRepository + { + private readonly Context _context; + public BreweryRepository(Context context) + { + _context = context; + } + + public bool BreweryExists(int id) + { + return _context.Breweries.Any(c => c.BreweryId == id); + } + + public bool CreateBrewery(BreweryModel breweryModel) + { + _context.Add(breweryModel); + return Save(); + } + + public bool DeleteBrewery(BreweryModel breweryModel) + { + _context.Remove(breweryModel); + return Save(); + } + + public BreweryModel GetBrewery(int id) + { + return _context.Breweries.Where(b => b.BreweryId == id).FirstOrDefault(); + } + + public bool Save() + { + var saved = _context.SaveChanges(); + return saved > 0 ? true : false; + } + + public bool UpdateBrewery(BreweryModel breweryModel) + { + _context.Update(breweryModel); + return Save(); + } + + ICollection IBreweryRepository.GetBreweries() + { + return _context.Breweries.ToList(); + } + } +} diff --git a/BreweryAPI/BreweryAPI/Repositories/BrewerySalesRepository.cs b/BreweryAPI/BreweryAPI/Repositories/BrewerySalesRepository.cs new file mode 100644 index 0000000..8697a1e --- /dev/null +++ b/BreweryAPI/BreweryAPI/Repositories/BrewerySalesRepository.cs @@ -0,0 +1,53 @@ +using BreweryAPI.Interface; +using BreweryAPI.Models; + +namespace BreweryAPI.Repositories +{ + public class BrewerySalesRepository : IBrewerySalesRepository + { + private readonly Context _context; + public BrewerySalesRepository(Context context) + { + _context = context; + } + + public bool BrewerySaleExists(int id) + { + return _context.BrewerySales.Any(bs => bs.SalesId == id); + } + + public bool CreateBrewerySale(BrewerySalesModel brewerySalesModel) + { + _context.Add(brewerySalesModel); + return Save(); + } + + public bool DeleteBrewerySales(BrewerySalesModel brewerySalesModel) + { + _context.Remove(brewerySalesModel); + return Save(); + } + + public BrewerySalesModel GetBrewerySale(int id) + { + return _context.BrewerySales.Where(bs => bs.SalesId == id).FirstOrDefault(); + } + + public ICollection GetBrewerySales() + { + return _context.BrewerySales.ToList(); + } + + public bool Save() + { + var saved = _context.SaveChanges(); + return saved > 0 ? true : false; + } + + public bool UpdateBrewerySales(BrewerySalesModel brewerySalesModel) + { + _context.Update(brewerySalesModel); + return Save(); + } + } +} diff --git a/BreweryAPI/BreweryAPI/Repositories/WholesalerInventoryRepository.cs b/BreweryAPI/BreweryAPI/Repositories/WholesalerInventoryRepository.cs new file mode 100644 index 0000000..8f3106b --- /dev/null +++ b/BreweryAPI/BreweryAPI/Repositories/WholesalerInventoryRepository.cs @@ -0,0 +1,63 @@ +using BreweryAPI.Interface; +using BreweryAPI.Models; + +namespace BreweryAPI.Repositories +{ + public class WholesalerInventoryRepository : IWholesalerInventoryRepository + { + private readonly Context _context; + public WholesalerInventoryRepository(Context context) + { + _context = context; + } + public bool CreateWholesalerInventory(WholesalerInventory wholesalerInventory) + { + _context.Add(wholesalerInventory); + return Save(); + } + + public bool DeleteWholesalerInventory(WholesalerInventory wholesalerInventory) + { + _context.Remove(wholesalerInventory); + return Save(); + } + + public ICollection GetWholesalerInventories() + { + return _context.WholesalerInventories.ToList(); + } + + public WholesalerInventory GetWholesalerInventory(int id) + { + return _context.WholesalerInventories.Where(wi => wi.ItemId == id).FirstOrDefault(); + } + + public bool Save() + { + var saved = _context.SaveChanges(); + return saved > 0 ? true : false; + } + + public bool UpdateWholesalerInventory(WholesalerInventory wholesalerInventory) + { + _context.Update(wholesalerInventory); + return Save(); + } + + public bool WholesalerInventoryExists(int id) + { + return _context.WholesalerInventories.Any(wi => wi.ItemId == id); + } + + public WholesalerInventory SelectRecord(int wholesalerId, int beerId) + { + return _context.WholesalerInventories.Where(wi => wi.WholesalerId == wholesalerId) + .Where(wi => wi.BeerId == beerId).FirstOrDefault(); + } + public bool IsUniqueRecord(WholesalerInventory wholesalerInventory) + { + return _context.WholesalerInventories.Where(wi => wi.WholesalerId == wholesalerInventory.WholesalerId) + .Any(wi => wi.BeerId == wholesalerInventory.BeerId); + } + } +} diff --git a/BreweryAPI/BreweryAPI/Repositories/WholesalerQuoteRepository.cs b/BreweryAPI/BreweryAPI/Repositories/WholesalerQuoteRepository.cs new file mode 100644 index 0000000..e216555 --- /dev/null +++ b/BreweryAPI/BreweryAPI/Repositories/WholesalerQuoteRepository.cs @@ -0,0 +1,53 @@ +using BreweryAPI.Interface; +using BreweryAPI.Models; + +namespace BreweryAPI.Repositories +{ + public class WholesalerQuoteRepository : IWholesalerQuoteRepository + { + private readonly Context _context; + public WholesalerQuoteRepository(Context context) + { + _context = context; + } + + public bool CreateWholesalerQuote(WholesalerQuoteModel wholesalerQuote) + { + _context.Add(wholesalerQuote); + return Save(); + } + + public bool DeleteWholesalerQuote(WholesalerQuoteModel wholesalerQuote) + { + _context.Remove(wholesalerQuote); + return Save(); + } + + public bool UpdateWholesalerQuote(WholesalerQuoteModel wholesalerQuote) + { + _context.Update(wholesalerQuote); + return Save(); + } + + public WholesalerQuoteModel GetWholesalerQuote(int id) + { + return _context.WholesalerQuotes.Where(wq => wq.QuoteId == id).FirstOrDefault(); + } + + public ICollection GetWholesalerQuotes() + { + return _context.WholesalerQuotes.ToList(); + } + + public bool Save() + { + var saved = _context.SaveChanges(); + return saved > 0 ? true : false; + } + + public bool WholesalerQuoteExists(int id) + { + return _context.WholesalerQuotes.Any(wq => wq.QuoteId == id); + } + } +} diff --git a/BreweryAPI/BreweryAPI/Repositories/WholesalerRepository.cs b/BreweryAPI/BreweryAPI/Repositories/WholesalerRepository.cs new file mode 100644 index 0000000..78bfa72 --- /dev/null +++ b/BreweryAPI/BreweryAPI/Repositories/WholesalerRepository.cs @@ -0,0 +1,54 @@ +using BreweryAPI.Interface; +using BreweryAPI.Models; + +namespace BreweryAPI.Repositories +{ + public class WholesalerRepository : IWholesalerRepository + { + private readonly Context _context + ; + public WholesalerRepository(Context context + ) + { + _context = context; + } + public bool CreateWholesaler(WholesalerModel wholesalerModel) + { + _context.Add(wholesalerModel ); + return Save(); + } + + public bool DeleteWholesaler(WholesalerModel wholesalerModel) + { + _context.Remove(wholesalerModel); + return Save(); + } + + public WholesalerModel GetWholesaler(int id) + { + return _context.Wholesalers.Where(w => w.WholesalerID == id).FirstOrDefault(); + } + + public ICollection GetWholesalers() + { + return _context.Wholesalers.ToList(); + } + + public bool Save() + { + var saved = _context.SaveChanges(); + return saved > 0 ? true : false; + } + + public bool UpdateWholesaler(WholesalerModel wholesalerModel) + { + _context.Update(wholesalerModel); + return Save(); + } + + public bool WholesalerExists(int id) + { + return _context.Wholesalers.Any(w => w.WholesalerID ==id); + } + } +} diff --git a/BreweryAPI/BreweryAPI/SeedData.cs b/BreweryAPI/BreweryAPI/SeedData.cs new file mode 100644 index 0000000..b08a6c3 --- /dev/null +++ b/BreweryAPI/BreweryAPI/SeedData.cs @@ -0,0 +1,149 @@ +using BreweryAPI.Models; + +namespace BreweryAPI +{ + public class SeedData + { + private readonly Context _context; + + public SeedData(Context context) + { + _context = context; + } + + public void SeedDataContext() + { + _context.Database.EnsureCreated(); + + if(!_context.Breweries.Any()) + { + var brewery1 = new BreweryModel + { + BreweryName = "SuperBock Casa da Cerveja", + BreweryLocation = "Porto" + }; + var brewery2 = new BreweryModel + { + BreweryName = "Sagres", + BreweryLocation = "Algarve" + }; + + _context.Breweries.AddRange(brewery1, brewery2); + _context.SaveChanges(); + } + + if(!_context.Beers.Any()) + { + var beer1 = new BeerModel + { + BeerName = "SuperBock", + Price = 1, + BreweryId = 1, + }; + var beer2 = new BeerModel + { + BeerName = "Abadia", + Price = 2, + BreweryId = 1, + }; + var beer3 = new BeerModel + { + BeerName = "Stout", + Price = 1, + BreweryId = 1, + }; + var beer4 = new BeerModel + { + BeerName = "Original", + Price = 1, + BreweryId = 2, + }; + var beer5 = new BeerModel + { + BeerName = "Bohemia", + Price = 3, + BreweryId = 2, + }; + + _context.Beers.AddRange(beer1, beer2, beer3, beer4, beer5); + _context.SaveChanges(); + } + + if (!_context.Wholesalers.Any()) + { + var wholesaler1 = new WholesalerModel + { + WholesalerName = "Solbel", + WholesalerLocation = "Lisboa" + }; + var wholesaler2 = new WholesalerModel + { + WholesalerName = "KBE", + WholesalerLocation = "Algarve" + }; + _context.Wholesalers.AddRange(wholesaler1, wholesaler2); + _context.SaveChanges(); + } + + if (!_context.BrewerySales.Any()) + { + var brewerySale1 = new BrewerySalesModel + { + WholeSalerId = 1, + BeerId = 1, + Quantity = 10, + TotalPrice = 10 + }; + var brewerySale2 = new BrewerySalesModel + { + WholeSalerId = 2, + BeerId = 2, + Quantity = 10, + TotalPrice = 30 + }; + _context.BrewerySales.AddRange(brewerySale1, brewerySale2); + _context.SaveChanges(); + } + + if (!_context.WholesalerInventories.Any()) + { + var wholesalerInventory1 = new WholesalerInventory + { + WholesalerId = 1, + BeerId = 1, + Quantity = 10, + }; + var wholesalerInventory2 = new WholesalerInventory + { + WholesalerId = 2, + BeerId = 2, + Quantity = 10, + }; + _context.WholesalerInventories.AddRange(wholesalerInventory1, wholesalerInventory2); + _context.SaveChanges(); + } + + if (!_context.WholesalerQuotes.Any()) + { + var wholesalerQuote1 = new WholesalerQuoteModel + { + ClientName = "Cervejeria Lima", + WholesalerId = 1, + BeerId = 1, + Quantity = 10, + TotalPrice = 10 + }; + var wholesalerQuote2 = new WholesalerQuoteModel + { + ClientName = "Bar Fritos", + WholesalerId = 2, + BeerId = 2, + Quantity = 10, + TotalPrice = 30 + }; + _context.WholesalerQuotes.AddRange(wholesalerQuote1, wholesalerQuote2); + _context.SaveChanges(); + } + } + } +} diff --git a/BreweryAPI/BreweryAPI/appsettings.Development.json b/BreweryAPI/BreweryAPI/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/BreweryAPI/BreweryAPI/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/BreweryAPI/BreweryAPI/appsettings.json b/BreweryAPI/BreweryAPI/appsettings.json new file mode 100644 index 0000000..2b6e344 --- /dev/null +++ b/BreweryAPI/BreweryAPI/appsettings.json @@ -0,0 +1,13 @@ +{ + "ConnectionStrings": { + "DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=BreweryDb;Trusted_connection=True;", + "TestConnection": "Server=(localdb)\\MSSQLLocalDB;Database=TestBreweryDb;Trusted_connection=True;", + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/BreweryAPI/BreweryMaui/App.xaml b/BreweryAPI/BreweryMaui/App.xaml new file mode 100644 index 0000000..de7c2b1 --- /dev/null +++ b/BreweryAPI/BreweryMaui/App.xaml @@ -0,0 +1,14 @@ + + + + + + + + + + + diff --git a/BreweryAPI/BreweryMaui/App.xaml.cs b/BreweryAPI/BreweryMaui/App.xaml.cs new file mode 100644 index 0000000..3ee963e --- /dev/null +++ b/BreweryAPI/BreweryMaui/App.xaml.cs @@ -0,0 +1,12 @@ +namespace BreweryMaui +{ + public partial class App : Application + { + public App() + { + InitializeComponent(); + + MainPage = new AppShell(); + } + } +} \ No newline at end of file diff --git a/BreweryAPI/BreweryMaui/AppShell.xaml b/BreweryAPI/BreweryMaui/AppShell.xaml new file mode 100644 index 0000000..0ef6964 --- /dev/null +++ b/BreweryAPI/BreweryMaui/AppShell.xaml @@ -0,0 +1,13 @@ + + + + + + diff --git a/BreweryAPI/BreweryMaui/AppShell.xaml.cs b/BreweryAPI/BreweryMaui/AppShell.xaml.cs new file mode 100644 index 0000000..df058a1 --- /dev/null +++ b/BreweryAPI/BreweryMaui/AppShell.xaml.cs @@ -0,0 +1,10 @@ +namespace BreweryMaui +{ + public partial class AppShell : Shell + { + public AppShell() + { + InitializeComponent(); + } + } +} \ No newline at end of file diff --git a/BreweryAPI/BreweryMaui/BreweryMaui.csproj b/BreweryAPI/BreweryMaui/BreweryMaui.csproj new file mode 100644 index 0000000..800160b --- /dev/null +++ b/BreweryAPI/BreweryMaui/BreweryMaui.csproj @@ -0,0 +1,73 @@ + + + + + $(TargetFrameworks);net7.0-windows10.0.19041.0 + + + Exe + BreweryMaui + true + true + enable + + + BreweryMaui + + + com.companyname.brewerymaui + ecd6b752-e1fe-41da-8bc6-1b60255d003e + + + 1.0 + 1 + + + 10.0.17763.0 + 10.0.17763.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + ..\BreweryAPI\bin\Debug\net7.0\BreweryAPI.dll + + + + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + + diff --git a/BreweryAPI/BreweryMaui/MauiProgram.cs b/BreweryAPI/BreweryMaui/MauiProgram.cs new file mode 100644 index 0000000..6e4439e --- /dev/null +++ b/BreweryAPI/BreweryMaui/MauiProgram.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Logging; + +namespace BreweryMaui +{ + public static class MauiProgram + { + public static MauiApp CreateMauiApp() + { + var builder = MauiApp.CreateBuilder(); + builder + .UseMauiApp() + .ConfigureFonts(fonts => + { + fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); + fonts.AddFont("CroissantOne-Regular.ttf", "CroissantOneRegular"); + }); + +#if DEBUG + builder.Logging.AddDebug(); +#endif + + return builder.Build(); + } + } +} \ No newline at end of file diff --git a/BreweryAPI/BreweryMaui/Pages/BreweryMainPage.xaml b/BreweryAPI/BreweryMaui/Pages/BreweryMainPage.xaml new file mode 100644 index 0000000..a1e1be2 --- /dev/null +++ b/BreweryAPI/BreweryMaui/Pages/BreweryMainPage.xaml @@ -0,0 +1,101 @@ + + + + + + + +