item mng with sync
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Distribution.Features.Brand;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/brands")]
|
||||
[Authorize]
|
||||
public class BrandController(BrandService service) : ControllerBase
|
||||
{
|
||||
[HttpGet]
|
||||
[Authorize(Policy = "items.view")]
|
||||
public async Task<IActionResult> GetAll() =>
|
||||
Ok(await service.GetAllAsync());
|
||||
|
||||
[HttpGet("{id:guid}")]
|
||||
[Authorize(Policy = "items.view")]
|
||||
public async Task<IActionResult> GetById(Guid id)
|
||||
{
|
||||
var result = await service.GetByIdAsync(id);
|
||||
return result is null ? NotFound() : Ok(result);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Authorize(Policy = "items.create")]
|
||||
public async Task<IActionResult> Create(CreateBrandRequest request, CancellationToken ct)
|
||||
{
|
||||
var result = await service.CreateAsync(request, ct);
|
||||
return CreatedAtAction(nameof(GetById), new { id = result.Id }, result);
|
||||
}
|
||||
|
||||
[HttpPut("{id:guid}")]
|
||||
[Authorize(Policy = "items.update")]
|
||||
public async Task<IActionResult> Update(Guid id, UpdateBrandRequest request, CancellationToken ct)
|
||||
{
|
||||
var result = await service.UpdateAsync(id, request, ct);
|
||||
return result is null ? NotFound() : Ok(result);
|
||||
}
|
||||
|
||||
[HttpDelete("{id:guid}")]
|
||||
[Authorize(Policy = "items.delete")]
|
||||
public async Task<IActionResult> Delete(Guid id, CancellationToken ct)
|
||||
{
|
||||
var deleted = await service.DeleteAsync(id, ct);
|
||||
return deleted ? NoContent() : NotFound();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
namespace Distribution.Features.Brand;
|
||||
|
||||
public record CreateBrandRequest(string Name);
|
||||
public record UpdateBrandRequest(string Name);
|
||||
public record BrandResponse(Guid Id, string Name, bool IsActive, DateTime CreatedAt);
|
||||
@@ -0,0 +1,31 @@
|
||||
using Distribution.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Distribution.Features.Brand;
|
||||
|
||||
public class BrandRepository(AppDBContext context) : IBrandRepository
|
||||
{
|
||||
public async Task<Models.Brand?> GetByIdAsync(Guid id) =>
|
||||
await context.Brands.FindAsync(id);
|
||||
|
||||
public async Task<List<Models.Brand>> GetAllAsync() =>
|
||||
await context.Brands.ToListAsync();
|
||||
|
||||
public async Task<Models.Brand?> GetByExternalErpIdAsync(int erpId) =>
|
||||
await context.Brands.FirstOrDefaultAsync(b => b.ExternalErpId == erpId);
|
||||
|
||||
public async Task<bool> HasActiveItemsAsync(Guid id) =>
|
||||
await context.Items.AnyAsync(i => i.FK_BrandId == id && i.IsActive);
|
||||
|
||||
public async Task AddAsync(Models.Brand entity) =>
|
||||
await context.Brands.AddAsync(entity);
|
||||
|
||||
public void Update(Models.Brand entity) =>
|
||||
context.Brands.Update(entity);
|
||||
|
||||
public void Remove(Models.Brand entity)
|
||||
{
|
||||
entity.IsActive = false;
|
||||
context.Brands.Update(entity);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using Distribution.Infra.UoW;
|
||||
|
||||
namespace Distribution.Features.Brand;
|
||||
|
||||
public class BrandService(IBrandRepository repo, IUnitOfWork uow)
|
||||
{
|
||||
public async Task<List<BrandResponse>> GetAllAsync() =>
|
||||
(await repo.GetAllAsync())
|
||||
.Where(b => b.IsActive)
|
||||
.Select(b => new BrandResponse(b.Id, b.Name, b.IsActive, b.CreatedAt))
|
||||
.ToList();
|
||||
|
||||
public async Task<BrandResponse?> GetByIdAsync(Guid id)
|
||||
{
|
||||
var brand = await repo.GetByIdAsync(id);
|
||||
if (brand is null || !brand.IsActive) return null;
|
||||
return new BrandResponse(brand.Id, brand.Name, brand.IsActive, brand.CreatedAt);
|
||||
}
|
||||
|
||||
public async Task<BrandResponse> CreateAsync(CreateBrandRequest request, CancellationToken ct = default)
|
||||
{
|
||||
var brand = new Models.Brand { Name = request.Name };
|
||||
await uow.BeginAsync(ct);
|
||||
try { await repo.AddAsync(brand); await uow.CommitAsync(ct); }
|
||||
catch { await uow.RollbackAsync(ct); throw; }
|
||||
return new BrandResponse(brand.Id, brand.Name, brand.IsActive, brand.CreatedAt);
|
||||
}
|
||||
|
||||
public async Task<BrandResponse?> UpdateAsync(Guid id, UpdateBrandRequest request, CancellationToken ct = default)
|
||||
{
|
||||
var brand = await repo.GetByIdAsync(id);
|
||||
if (brand is null || !brand.IsActive) return null;
|
||||
if (brand.ExternalErpId.HasValue) return null;
|
||||
brand.Name = request.Name;
|
||||
await uow.BeginAsync(ct);
|
||||
try { repo.Update(brand); await uow.CommitAsync(ct); }
|
||||
catch { await uow.RollbackAsync(ct); throw; }
|
||||
return new BrandResponse(brand.Id, brand.Name, brand.IsActive, brand.CreatedAt);
|
||||
}
|
||||
|
||||
public async Task<bool> DeleteAsync(Guid id, CancellationToken ct = default)
|
||||
{
|
||||
var brand = await repo.GetByIdAsync(id);
|
||||
if (brand is null || !brand.IsActive) return false;
|
||||
if (brand.ExternalErpId.HasValue) return false;
|
||||
if (await repo.HasActiveItemsAsync(id)) return false;
|
||||
await uow.BeginAsync(ct);
|
||||
try { repo.Remove(brand); await uow.CommitAsync(ct); }
|
||||
catch { await uow.RollbackAsync(ct); throw; }
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace Distribution.Features.Brand;
|
||||
|
||||
public interface IBrandRepository
|
||||
{
|
||||
Task<Models.Brand?> GetByIdAsync(Guid id);
|
||||
Task<List<Models.Brand>> GetAllAsync();
|
||||
Task<Models.Brand?> GetByExternalErpIdAsync(int erpId);
|
||||
Task<bool> HasActiveItemsAsync(Guid id);
|
||||
Task AddAsync(Models.Brand entity);
|
||||
void Update(Models.Brand entity);
|
||||
void Remove(Models.Brand entity);
|
||||
}
|
||||
Reference in New Issue
Block a user