112 lines
4.1 KiB
C#
112 lines
4.1 KiB
C#
|
|
using Meezi.API.Models.Taxes;
|
||
|
|
using Meezi.Core.Entities;
|
||
|
|
using Meezi.Infrastructure.Data;
|
||
|
|
using Microsoft.EntityFrameworkCore;
|
||
|
|
|
||
|
|
namespace Meezi.API.Services;
|
||
|
|
|
||
|
|
public interface ITaxService
|
||
|
|
{
|
||
|
|
Task<IReadOnlyList<TaxDto>> GetAllAsync(string cafeId, CancellationToken cancellationToken = default);
|
||
|
|
Task<TaxDto?> CreateAsync(string cafeId, CreateTaxRequest request, CancellationToken cancellationToken = default);
|
||
|
|
Task<TaxDto?> UpdateAsync(string cafeId, string id, UpdateTaxRequest request, CancellationToken cancellationToken = default);
|
||
|
|
Task<bool> DeleteAsync(string cafeId, string id, CancellationToken cancellationToken = default);
|
||
|
|
}
|
||
|
|
|
||
|
|
public class TaxService : ITaxService
|
||
|
|
{
|
||
|
|
private readonly AppDbContext _db;
|
||
|
|
|
||
|
|
public TaxService(AppDbContext db) => _db = db;
|
||
|
|
|
||
|
|
public async Task<IReadOnlyList<TaxDto>> GetAllAsync(string cafeId, CancellationToken cancellationToken = default)
|
||
|
|
{
|
||
|
|
return await _db.Taxes
|
||
|
|
.Where(t => t.CafeId == cafeId)
|
||
|
|
.OrderBy(t => t.Name)
|
||
|
|
.Select(t => ToDto(t))
|
||
|
|
.ToListAsync(cancellationToken);
|
||
|
|
}
|
||
|
|
|
||
|
|
public async Task<TaxDto?> CreateAsync(string cafeId, CreateTaxRequest request, CancellationToken cancellationToken = default)
|
||
|
|
{
|
||
|
|
if (request.IsDefault)
|
||
|
|
{
|
||
|
|
var existing = await _db.Taxes.Where(t => t.CafeId == cafeId && t.IsDefault).ToListAsync(cancellationToken);
|
||
|
|
foreach (var t in existing) t.IsDefault = false;
|
||
|
|
}
|
||
|
|
|
||
|
|
var entity = new Tax
|
||
|
|
{
|
||
|
|
CafeId = cafeId,
|
||
|
|
Name = request.Name,
|
||
|
|
Rate = request.Rate,
|
||
|
|
IsDefault = request.IsDefault,
|
||
|
|
IsRequired = request.IsRequired,
|
||
|
|
IsCompound = request.IsCompound
|
||
|
|
};
|
||
|
|
_db.Taxes.Add(entity);
|
||
|
|
await _db.SaveChangesAsync(cancellationToken);
|
||
|
|
return ToDto(entity);
|
||
|
|
}
|
||
|
|
|
||
|
|
public async Task<TaxDto?> UpdateAsync(
|
||
|
|
string cafeId,
|
||
|
|
string id,
|
||
|
|
UpdateTaxRequest request,
|
||
|
|
CancellationToken cancellationToken = default)
|
||
|
|
{
|
||
|
|
var entity = await _db.Taxes.FirstOrDefaultAsync(t => t.Id == id && t.CafeId == cafeId, cancellationToken);
|
||
|
|
if (entity is null) return null;
|
||
|
|
|
||
|
|
if (request.Name is not null) entity.Name = request.Name;
|
||
|
|
if (request.Rate.HasValue) entity.Rate = request.Rate.Value;
|
||
|
|
if (request.IsDefault == true)
|
||
|
|
{
|
||
|
|
var others = await _db.Taxes.Where(t => t.CafeId == cafeId && t.Id != id).ToListAsync(cancellationToken);
|
||
|
|
foreach (var t in others) t.IsDefault = false;
|
||
|
|
entity.IsDefault = true;
|
||
|
|
}
|
||
|
|
else if (request.IsDefault.HasValue) entity.IsDefault = request.IsDefault.Value;
|
||
|
|
|
||
|
|
if (request.IsRequired.HasValue) entity.IsRequired = request.IsRequired.Value;
|
||
|
|
if (request.IsCompound.HasValue) entity.IsCompound = request.IsCompound.Value;
|
||
|
|
|
||
|
|
await _db.SaveChangesAsync(cancellationToken);
|
||
|
|
return ToDto(entity);
|
||
|
|
}
|
||
|
|
|
||
|
|
public async Task<bool> DeleteAsync(string cafeId, string id, CancellationToken cancellationToken = default)
|
||
|
|
{
|
||
|
|
var entity = await _db.Taxes.FirstOrDefaultAsync(t => t.Id == id && t.CafeId == cafeId, cancellationToken);
|
||
|
|
if (entity is null) return false;
|
||
|
|
|
||
|
|
var wasDefault = entity.IsDefault;
|
||
|
|
entity.DeletedAt = DateTime.UtcNow;
|
||
|
|
entity.IsDefault = false;
|
||
|
|
|
||
|
|
var categories = await _db.MenuCategories
|
||
|
|
.Where(c => c.CafeId == cafeId && c.TaxId == id)
|
||
|
|
.ToListAsync(cancellationToken);
|
||
|
|
|
||
|
|
Tax? replacementDefault = null;
|
||
|
|
if (wasDefault)
|
||
|
|
{
|
||
|
|
replacementDefault = await _db.Taxes
|
||
|
|
.Where(t => t.CafeId == cafeId && t.Id != id)
|
||
|
|
.OrderBy(t => t.Name)
|
||
|
|
.FirstOrDefaultAsync(cancellationToken);
|
||
|
|
if (replacementDefault is not null)
|
||
|
|
replacementDefault.IsDefault = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
foreach (var category in categories)
|
||
|
|
category.TaxId = replacementDefault?.Id;
|
||
|
|
|
||
|
|
await _db.SaveChangesAsync(cancellationToken);
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static TaxDto ToDto(Tax t) => new(t.Id, t.Name, t.Rate, t.IsDefault, t.IsRequired, t.IsCompound);
|
||
|
|
}
|