Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions .idea/encodings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/indexLayout.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 46 additions & 0 deletions Ecommerce-API/ECommerce.API/Controllers/ItemsController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using ECommerce.API.Interfaces;
using ECommerce.API.Models;
using ECommerce.Shared.Models;
using Microsoft.AspNetCore.Mvc;

namespace ECommerce.API.Controllers;

[ApiController]
[Route("api/[controller]")]
public class ItemsController(IItemService itemService) : ControllerBase
{
[HttpPost]
public async Task<IActionResult> PostItem([FromBody] CreateItemDto itemDto)
{
await itemService.PostItemAsync(itemDto);
return Created();
}

[HttpGet]
public async Task<ActionResult<PagedResponse<Item>>> GetItemsAsync([FromQuery] PaginationParams paginationParams)
{
var pagedResponse = await itemService.GetItemsAsync(paginationParams);
if (pagedResponse.TotalRecords == 0) return NotFound();
return Ok(pagedResponse);
}

[HttpGet("{id:int}")]
public async Task<ActionResult<ItemDto>> GetItemByIdAsync(int id)
{
var itemDto = await itemService.GetItemByIdAsync(id);

return itemDto is null ? NotFound() : Ok(itemDto);
}

[HttpDelete("{id:int}")]
public async Task<IActionResult> DeleteItemAsync(int id)
{
var success = await itemService.DeleteItemByIdAsync(id);
if (success is null)
return NotFound();
if (success is false)
return StatusCode(StatusCodes.Status500InternalServerError);

return NoContent();
}
}
43 changes: 43 additions & 0 deletions Ecommerce-API/ECommerce.API/Controllers/SalesController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using ECommerce.API.Interfaces;
using ECommerce.API.Models;
using ECommerce.Shared.Models;
using Microsoft.AspNetCore.Mvc;

namespace ECommerce.API.Controllers;

[ApiController]
[Route("api/[controller]")]
public class SalesController(ISaleService saleService) : ControllerBase
{
[HttpPost]
public async Task<IActionResult> PostSale([FromBody] List<CreateSaleItemDto> saleItems)
{
var success = await saleService.PostSaleAsync(saleItems);
return success switch
{
null => NotFound(),
true => NoContent(),
false => StatusCode(StatusCodes.Status500InternalServerError)
};
}

[HttpGet]
public async Task<ActionResult<PagedResponse<Sale>>> GetItemsAsync([FromQuery] PaginationParams paginationParams)
{
var pagedResponse = await saleService.GetSalesAsync(paginationParams);
if (pagedResponse.TotalRecords == 0) return NotFound();
return Ok(pagedResponse);
}

[HttpDelete]
public async Task<IActionResult> DeleteSaleAsync([FromQuery] int saleId)
{
var success = await saleService.DeleteSaleByIdAsync(saleId);
return success switch
{
null => NotFound(),
true => NoContent(),
false => StatusCode(StatusCodes.Status500InternalServerError)
};
}
}
52 changes: 52 additions & 0 deletions Ecommerce-API/ECommerce.API/Controllers/TagsController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using ECommerce.API.Interfaces;
using ECommerce.API.Models;
using ECommerce.Shared.Models;
using Microsoft.AspNetCore.Mvc;

namespace ECommerce.API.Controllers;

[ApiController]
[Route("api/[controller]")]
public class TagsController(ITagService tagService) : ControllerBase
{
[HttpGet]
public async Task<IActionResult> GetTags([FromQuery] PaginationParams paginationParams)
{
var pagedResponse = await tagService.GetTagsAsync(paginationParams);
if (pagedResponse.TotalRecords == 0)
return NotFound();

return Ok(pagedResponse);
}

[HttpGet("{name}")]
public async Task<ActionResult<int>> GetTagId(string name)
{
var tag = await tagService.GetTagIdByName(name);
return tag switch
{
null => NotFound(),
_ => Ok(tag)
};
}

[HttpPost]
public async Task<IActionResult> PostTag([FromBody] CreateTagDto tagDto)
{
await tagService.PostTagAsync(tagDto);
return Created();
}

[HttpDelete("{tagId:int}")]
public async Task<IActionResult> DeleteTag(int tagId)
{
var success = await tagService.DeleteTagByIdAsync(tagId);

return success switch
{
null => NotFound(),
true => NoContent(),
false => StatusCode(StatusCodes.Status500InternalServerError)
};
}
}
50 changes: 50 additions & 0 deletions Ecommerce-API/ECommerce.API/Data/ApiDbContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using ECommerce.API.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;

namespace ECommerce.API.Data;

public class ApiDbContext(DbContextOptions<ApiDbContext> options) : DbContext(options)
{
public DbSet<Item> Items { get; set; }
public DbSet<Tag> Tags { get; set; }
public DbSet<Sale> Sales { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<SaleItem>()
.HasKey(si => new { si.SaleId, si.ItemId });
modelBuilder.Entity<SaleItem>()
.HasOne(si => si.Sale)
.WithMany(s => s.SoldItems)
.HasForeignKey(si => si.SaleId);
modelBuilder.Entity<SaleItem>()
.HasOne(si => si.Item)
.WithMany()
.HasForeignKey(si => si.ItemId);

modelBuilder.Entity<Item>().HasQueryFilter(i => !i.IsDeleted);
modelBuilder.Entity<Sale>().HasQueryFilter(s => !s.IsDeleted);
modelBuilder.Entity<Tag>().HasQueryFilter(t => !t.IsDeleted);
modelBuilder.Entity<SaleItem>().HasQueryFilter(si => !si.Item.IsDeleted);

modelBuilder.Entity<Sale>().Ignore(s => s.TotalPrice);
}

protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
{
configurationBuilder
.Properties<Enum>()
.HaveConversion<string>();
}
}

public class ApiDbContextFactory : IDesignTimeDbContextFactory<ApiDbContext>
{
public ApiDbContext CreateDbContext(string[] args)
{
var optionsBuilder = new DbContextOptionsBuilder<ApiDbContext>();
optionsBuilder.UseSqlite(DbConfig.GetConnectionString());
return new ApiDbContext(optionsBuilder.Options);
}
}
12 changes: 12 additions & 0 deletions Ecommerce-API/ECommerce.API/Data/DbConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace ECommerce.API.Data;

public class DbConfig
{
public static string GetConnectionString()
{
return $"Data Source={Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"ECommerce",
"api.db")}";
}
}
Loading