From ce56a42bd1d4608e54d959905aefe4d63cc5c713 Mon Sep 17 00:00:00 2001 From: Christian Arenas Date: Tue, 6 Jun 2017 14:18:46 +0200 Subject: [PATCH] Redesign marketing campaign api in two different controllers (campaigns/locations) --- .../Controllers/CampaignsController.cs | 63 ++------ .../Controllers/LocationsController.cs | 146 ++++++++++++++++++ .../Marketing.API/Dto/CampaignDTO.cs | 8 - .../Marketing/Marketing.API/Dto/RuleDTO.cs | 20 --- .../Marketing.API/Dto/UserLocationRuleDTO.cs | 11 ++ .../Infrastructure/MarketingContext.cs | 6 +- .../Marketing.API/Marketing.API.csproj | 3 + .../Marketing/Marketing.API/Model/Rule.cs | 14 +- .../{Dto => Model}/RuleTypeEnum.cs | 8 +- 9 files changed, 189 insertions(+), 90 deletions(-) create mode 100644 src/Services/Marketing/Marketing.API/Controllers/LocationsController.cs delete mode 100644 src/Services/Marketing/Marketing.API/Dto/RuleDTO.cs create mode 100644 src/Services/Marketing/Marketing.API/Dto/UserLocationRuleDTO.cs rename src/Services/Marketing/Marketing.API/{Dto => Model}/RuleTypeEnum.cs (71%) diff --git a/src/Services/Marketing/Marketing.API/Controllers/CampaignsController.cs b/src/Services/Marketing/Marketing.API/Controllers/CampaignsController.cs index 0082ee71f..f3dde55ef 100644 --- a/src/Services/Marketing/Marketing.API/Controllers/CampaignsController.cs +++ b/src/Services/Marketing/Marketing.API/Controllers/CampaignsController.cs @@ -10,7 +10,7 @@ using Microsoft.AspNetCore.Authorization; [Route("api/v1/[controller]")] - //[Authorize] + [Authorize] public class CampaignsController : Controller { private readonly MarketingContext _context; @@ -24,9 +24,13 @@ public async Task GetAllCampaigns() { var campaignList = await _context.Campaigns - .Include(c => c.Rules) .ToListAsync(); + if (campaignList is null) + { + return Ok(); + } + var campaignDtoList = MapCampaignModelListToDtoList(campaignList); return Ok(campaignDtoList); @@ -36,7 +40,6 @@ public async Task GetCampaignById(int id) { var campaign = await _context.Campaigns - .Include(c => c.Rules) .SingleOrDefaultAsync(c => c.Id == id); if (campaign is null) @@ -57,16 +60,16 @@ return BadRequest(); } - var campaingToCreate = MapCampaignDtoToModel(campaignDto); + var campaign = MapCampaignDtoToModel(campaignDto); - await _context.Campaigns.AddAsync(campaingToCreate); + await _context.Campaigns.AddAsync(campaign); await _context.SaveChangesAsync(); - return CreatedAtAction(nameof(GetCampaignById), new { id = campaingToCreate.Id }, null); + return CreatedAtAction(nameof(GetCampaignById), new { id = campaign.Id }, null); } [HttpPut("{id:int}")] - public async Task UpdateCampaign(int id, [FromBody]CampaignDTO campaignDto) + public async Task UpdateCampaign(int id, [FromBody] CampaignDTO campaignDto) { if (id < 1 || campaignDto is null) { @@ -123,7 +126,7 @@ private CampaignDTO MapCampaignModelToDto(Campaign campaign) { - var campaignDto = new CampaignDTO + return new CampaignDTO { Id = campaign.Id, Description = campaign.Description, @@ -131,34 +134,11 @@ To = campaign.To, Url = campaign.Url, }; - - campaign.Rules.ForEach(rule => - { - var ruleDto = new RuleDTO - { - Id = rule.Id, - RuleTypeId = rule.RuleTypeId, - Description = rule.Description, - CampaignId = rule.CampaignId - }; - - switch (RuleType.From(rule.RuleTypeId)) - { - case RuleTypeEnum.UserLocationRule: - var userLocationRule = rule as UserLocationRule; - ruleDto.LocationId = userLocationRule.LocationId; - break; - } - - campaignDto.Rules.Add(ruleDto); - }); - - return campaignDto; } private Campaign MapCampaignDtoToModel(CampaignDTO campaignDto) { - var campaingModel = new Campaign + return new Campaign { Id = campaignDto.Id, Description = campaignDto.Description, @@ -166,25 +146,6 @@ To = campaignDto.To, Url = campaignDto.Url }; - - campaignDto.Rules.ForEach(ruleDto => - { - switch (RuleType.From(ruleDto.RuleTypeId)) - { - case RuleTypeEnum.UserLocationRule: - campaingModel.Rules.Add(new UserLocationRule - { - Id = ruleDto.Id, - LocationId = ruleDto.LocationId.Value, - RuleTypeId = ruleDto.RuleTypeId, - Description = ruleDto.Description, - Campaign = campaingModel - }); - break; - } - }); - - return campaingModel; } } } \ No newline at end of file diff --git a/src/Services/Marketing/Marketing.API/Controllers/LocationsController.cs b/src/Services/Marketing/Marketing.API/Controllers/LocationsController.cs new file mode 100644 index 000000000..843e58030 --- /dev/null +++ b/src/Services/Marketing/Marketing.API/Controllers/LocationsController.cs @@ -0,0 +1,146 @@ +namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers +{ + using Microsoft.AspNetCore.Authorization; + using Microsoft.AspNetCore.Mvc; + using Microsoft.eShopOnContainers.Services.Marketing.API.Dto; + using Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure; + using Microsoft.eShopOnContainers.Services.Marketing.API.Model; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + + [Authorize] + public class LocationsController : Controller + { + private readonly MarketingContext _context; + + public LocationsController(MarketingContext context) + { + _context = context; + } + + [HttpGet] + [Route("api/v1/campaigns/{campaignId:int}/locations/{userLocationRuleId:int}")] + public IActionResult GetLocationByCampaignAndLocationRuleId(int campaignId, + int userLocationRuleId) + { + if (campaignId < 1 || userLocationRuleId < 1) + { + return BadRequest(); + } + + var location = _context.Rules + .OfType() + .SingleOrDefault(c => c.CampaignId == campaignId && c.Id == userLocationRuleId); + + if (location is null) + { + return NotFound(); + } + + var locationDto = MapUserLocationRuleModelToDto(location); + + return Ok(locationDto); + } + + [HttpGet] + [Route("api/v1/campaigns/{campaignId:int}/locations")] + public IActionResult GetAllLocationsByCampaignId(int campaignId) + { + if (campaignId < 1) + { + return BadRequest(); + } + + var locationList = _context.Rules + .OfType() + .Where(c => c.CampaignId == campaignId) + .ToList(); + + if(locationList is null) + { + return Ok(); + } + + var locationDtoList = MapUserLocationRuleModelListToDtoList(locationList); + + return Ok(locationDtoList); + } + + [HttpPost] + [Route("api/v1/campaigns/{campaignId:int}/locations")] + public async Task CreateLocation(int campaignId, + [FromBody] UserLocationRuleDTO locationRuleDto) + { + if (campaignId < 1 || locationRuleDto is null) + { + return BadRequest(); + } + + var locationRule = MapUserLocationRuleDtoToModel(locationRuleDto); + locationRule.CampaignId = campaignId; + + await _context.Rules.AddAsync(locationRule); + await _context.SaveChangesAsync(); + + return CreatedAtAction(nameof(GetLocationByCampaignAndLocationRuleId), + new { campaignId = campaignId, locationRuleId = locationRule.Id }, null); + } + + [HttpDelete] + [Route("api/v1/campaigns/{campaignId:int}/locations/{userLocationRuleId:int}")] + public async Task DeleteLocationById(int campaignId, int userLocationRuleId) + { + if (campaignId < 1 || userLocationRuleId < 1) + { + return BadRequest(); + } + + var locationToDelete = _context.Rules + .OfType() + .SingleOrDefault(c => c.CampaignId == campaignId && c.Id == userLocationRuleId); + + if (locationToDelete is null) + { + return NotFound(); + } + + _context.Rules.Remove(locationToDelete); + await _context.SaveChangesAsync(); + + return NoContent(); + } + + + + private List MapUserLocationRuleModelListToDtoList(List userLocationRuleList) + { + var userLocationRuleDtoList = new List(); + + userLocationRuleList.ForEach(userLocationRule => userLocationRuleDtoList + .Add(MapUserLocationRuleModelToDto(userLocationRule))); + + return userLocationRuleDtoList; + } + + private UserLocationRuleDTO MapUserLocationRuleModelToDto(UserLocationRule userLocationRule) + { + return new UserLocationRuleDTO + { + Id = userLocationRule.Id, + Description = userLocationRule.Description, + LocationId = userLocationRule.LocationId + }; + } + + private UserLocationRule MapUserLocationRuleDtoToModel(UserLocationRuleDTO userLocationRuleDto) + { + return new UserLocationRule + { + Id = userLocationRuleDto.Id, + Description = userLocationRuleDto.Description, + LocationId = userLocationRuleDto.LocationId + }; + } + } +} \ No newline at end of file diff --git a/src/Services/Marketing/Marketing.API/Dto/CampaignDTO.cs b/src/Services/Marketing/Marketing.API/Dto/CampaignDTO.cs index b5676db63..a43dcdbda 100644 --- a/src/Services/Marketing/Marketing.API/Dto/CampaignDTO.cs +++ b/src/Services/Marketing/Marketing.API/Dto/CampaignDTO.cs @@ -1,7 +1,6 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Dto { using System; - using System.Collections.Generic; public class CampaignDTO { @@ -14,12 +13,5 @@ public DateTime To { get; set; } public string Url { get; set; } - - public List Rules { get; set; } - - public CampaignDTO() - { - Rules = new List(); - } } } \ No newline at end of file diff --git a/src/Services/Marketing/Marketing.API/Dto/RuleDTO.cs b/src/Services/Marketing/Marketing.API/Dto/RuleDTO.cs deleted file mode 100644 index a79756e9c..000000000 --- a/src/Services/Marketing/Marketing.API/Dto/RuleDTO.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure.Exceptions; -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Microsoft.eShopOnContainers.Services.Marketing.API.Dto -{ - public class RuleDTO - { - public int Id { get; set; } - - public int RuleTypeId { get; set; } - - public int CampaignId { get; set; } - - public int? LocationId { get; set; } - - public string Description { get; set; } - } -} \ No newline at end of file diff --git a/src/Services/Marketing/Marketing.API/Dto/UserLocationRuleDTO.cs b/src/Services/Marketing/Marketing.API/Dto/UserLocationRuleDTO.cs new file mode 100644 index 000000000..a76eb90a0 --- /dev/null +++ b/src/Services/Marketing/Marketing.API/Dto/UserLocationRuleDTO.cs @@ -0,0 +1,11 @@ +namespace Microsoft.eShopOnContainers.Services.Marketing.API.Dto +{ + public class UserLocationRuleDTO + { + public int Id { get; set; } + + public int LocationId { get; set; } + + public string Description { get; set; } + } +} \ No newline at end of file diff --git a/src/Services/Marketing/Marketing.API/Infrastructure/MarketingContext.cs b/src/Services/Marketing/Marketing.API/Infrastructure/MarketingContext.cs index 2fb45868b..15be03431 100644 --- a/src/Services/Marketing/Marketing.API/Infrastructure/MarketingContext.cs +++ b/src/Services/Marketing/Marketing.API/Infrastructure/MarketingContext.cs @@ -64,9 +64,9 @@ .IsRequired(); builder.HasDiscriminator("RuleTypeId") - .HasValue(1) - .HasValue(2) - .HasValue(3); + .HasValue((int)RuleTypeEnum.UserProfileRule) + .HasValue((int)RuleTypeEnum.PurchaseHistoryRule) + .HasValue((int)RuleTypeEnum.UserLocationRule); builder.Property(r => r.Description) .HasColumnName("Description") diff --git a/src/Services/Marketing/Marketing.API/Marketing.API.csproj b/src/Services/Marketing/Marketing.API/Marketing.API.csproj index bd8e5a871..34d594e51 100644 --- a/src/Services/Marketing/Marketing.API/Marketing.API.csproj +++ b/src/Services/Marketing/Marketing.API/Marketing.API.csproj @@ -19,6 +19,7 @@ + @@ -36,6 +37,8 @@ + + diff --git a/src/Services/Marketing/Marketing.API/Model/Rule.cs b/src/Services/Marketing/Marketing.API/Model/Rule.cs index 03686bf86..e02128fa6 100644 --- a/src/Services/Marketing/Marketing.API/Model/Rule.cs +++ b/src/Services/Marketing/Marketing.API/Model/Rule.cs @@ -4,24 +4,30 @@ { public int Id { get; set; } - public int RuleTypeId { get; set; } - public int CampaignId { get; set; } public Campaign Campaign { get; set; } public string Description { get; set; } + + public abstract int RuleTypeId { get;} } public class UserProfileRule : Rule - { } + { + public override int RuleTypeId => (int)RuleTypeEnum.UserProfileRule; + } public class PurchaseHistoryRule : Rule - { } + { + public override int RuleTypeId => (int)RuleTypeEnum.PurchaseHistoryRule; + } public class UserLocationRule : Rule { + public override int RuleTypeId => (int)RuleTypeEnum.UserLocationRule; + public int LocationId { get; set; } } } \ No newline at end of file diff --git a/src/Services/Marketing/Marketing.API/Dto/RuleTypeEnum.cs b/src/Services/Marketing/Marketing.API/Model/RuleTypeEnum.cs similarity index 71% rename from src/Services/Marketing/Marketing.API/Dto/RuleTypeEnum.cs rename to src/Services/Marketing/Marketing.API/Model/RuleTypeEnum.cs index f00b7fbf9..c58dbf75c 100644 --- a/src/Services/Marketing/Marketing.API/Dto/RuleTypeEnum.cs +++ b/src/Services/Marketing/Marketing.API/Model/RuleTypeEnum.cs @@ -1,8 +1,8 @@ -using Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure.Exceptions; -using System; - -namespace Microsoft.eShopOnContainers.Services.Marketing.API.Dto +namespace Microsoft.eShopOnContainers.Services.Marketing.API.Model { + using Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure.Exceptions; + using System; + public enum RuleTypeEnum { UserProfileRule = 1, PurchaseHistoryRule = 2, UserLocationRule = 3 } public static class RuleType