140 lines
6.7 KiB
C#
140 lines
6.7 KiB
C#
using Distribution.Data;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace Distribution.Features.Region;
|
|
|
|
public class RegionRepository(AppDBContext context) : IRegionRepository
|
|
{
|
|
public async Task<Models.Region?> GetByIdAsync(Guid id) =>
|
|
await context.Regions.FindAsync(id);
|
|
|
|
public async Task<List<Models.Region>> GetAllAsync() =>
|
|
await context.Regions.ToListAsync();
|
|
|
|
public async Task AddAsync(Models.Region entity) =>
|
|
await context.Regions.AddAsync(entity);
|
|
|
|
public void Update(Models.Region entity) =>
|
|
context.Regions.Update(entity);
|
|
|
|
public void Remove(Models.Region entity)
|
|
{
|
|
entity.IsActive = false;
|
|
context.Regions.Update(entity);
|
|
}
|
|
|
|
// Note: no IsActive filter on any RegionalTarget lookup below — this entity is hard-deleted
|
|
// (see RemoveTarget), so IsActive is always true for rows that still exist. Querying without
|
|
// the filter also means a pre-existing orphaned row (e.g. soft-deleted before this fix
|
|
// shipped) is found and reused/cleaned up here instead of silently blocking a re-add.
|
|
public async Task<Models.RegionalTarget?> GetTargetAsync(Guid regionId, string period) =>
|
|
await context.RegionalTargets.FirstOrDefaultAsync(t =>
|
|
t.FK_RegionId == regionId && t.Period == period);
|
|
|
|
public async Task AddTargetAsync(Models.RegionalTarget target) =>
|
|
await context.RegionalTargets.AddAsync(target);
|
|
|
|
public void UpdateTarget(Models.RegionalTarget target) =>
|
|
context.RegionalTargets.Update(target);
|
|
|
|
public async Task<List<Models.RegionalTarget>> GetAllTargetsAsync() =>
|
|
await context.RegionalTargets.ToListAsync();
|
|
|
|
public async Task<Models.RegionalTarget?> GetTargetByIdAsync(Guid id) =>
|
|
await context.RegionalTargets.FirstOrDefaultAsync(t => t.Id == id);
|
|
|
|
// Hard delete, not the usual IsActive soft-delete: RegionalTarget has a unique index on
|
|
// (FK_RegionId, Period) at the DB level, which doesn't know about IsActive — soft-deleting
|
|
// and then re-adding a target for the same region+period would violate that constraint.
|
|
public void RemoveTarget(Models.RegionalTarget target) =>
|
|
context.RegionalTargets.Remove(target);
|
|
|
|
// No IsActive filter — see GetTargetAsync's comment; same reasoning for RegionalBudget.
|
|
public async Task<Models.RegionalBudget?> GetBudgetAsync(Guid regionId, string period) =>
|
|
await context.RegionalBudgets.FirstOrDefaultAsync(b =>
|
|
b.FK_RegionId == regionId && b.Period == period);
|
|
|
|
public async Task AddBudgetAsync(Models.RegionalBudget budget) =>
|
|
await context.RegionalBudgets.AddAsync(budget);
|
|
|
|
public void UpdateBudget(Models.RegionalBudget budget) =>
|
|
context.RegionalBudgets.Update(budget);
|
|
|
|
public async Task<List<Models.RegionalBudget>> GetAllBudgetsAsync() =>
|
|
await context.RegionalBudgets.ToListAsync();
|
|
|
|
public async Task<Models.RegionalBudget?> GetBudgetByIdAsync(Guid id) =>
|
|
await context.RegionalBudgets.FirstOrDefaultAsync(b => b.Id == id);
|
|
|
|
// Hard delete — see RemoveTarget's comment; same unique-index-vs-soft-delete conflict
|
|
// applies to RegionalBudget's (FK_RegionId, Period) unique index.
|
|
public void RemoveBudget(Models.RegionalBudget budget) =>
|
|
context.RegionalBudgets.Remove(budget);
|
|
|
|
// No IsActive filter — see GetTargetAsync's comment; same reasoning for RegionAgencyMap.
|
|
public async Task<Models.RegionAgencyMap?> GetAgencyMapAsync(Guid regionId, Guid agencyUserId) =>
|
|
await context.RegionAgencyMaps.FirstOrDefaultAsync(m =>
|
|
m.FK_RegionId == regionId && m.FK_AgencyUserId == agencyUserId);
|
|
|
|
public async Task AddAgencyMapAsync(Models.RegionAgencyMap map) =>
|
|
await context.RegionAgencyMaps.AddAsync(map);
|
|
|
|
public void UpdateAgencyMap(Models.RegionAgencyMap map) =>
|
|
context.RegionAgencyMaps.Update(map);
|
|
|
|
public async Task<List<Models.RegionAgencyMap>> GetAgencyMapsForRegionAsync(Guid regionId) =>
|
|
await context.RegionAgencyMaps.Where(m => m.FK_RegionId == regionId).ToListAsync();
|
|
|
|
public async Task<List<Models.RegionAgencyMap>> GetAllAgencyMapsAsync() =>
|
|
await context.RegionAgencyMaps.ToListAsync();
|
|
|
|
public async Task<Models.RegionAgencyMap?> GetAgencyMapByIdAsync(Guid id) =>
|
|
await context.RegionAgencyMaps.FirstOrDefaultAsync(m => m.Id == id);
|
|
|
|
// Hard delete — see RemoveTarget's comment; same conflict applies to RegionAgencyMap's
|
|
// (FK_RegionId, FK_AgencyUserId) unique index.
|
|
public void RemoveAgencyMap(Models.RegionAgencyMap map) =>
|
|
context.RegionAgencyMaps.Remove(map);
|
|
|
|
// No IsActive filter — see GetTargetAsync's comment; same reasoning for RegionalTaxRule.
|
|
public async Task<Models.RegionalTaxRule?> GetTaxRuleAsync(Guid regionId) =>
|
|
await context.RegionalTaxRules.FirstOrDefaultAsync(r => r.FK_RegionId == regionId);
|
|
|
|
public async Task AddTaxRuleAsync(Models.RegionalTaxRule rule) =>
|
|
await context.RegionalTaxRules.AddAsync(rule);
|
|
|
|
public void UpdateTaxRule(Models.RegionalTaxRule rule) =>
|
|
context.RegionalTaxRules.Update(rule);
|
|
|
|
public async Task<List<Models.RegionalTaxRule>> GetAllTaxRulesAsync() =>
|
|
await context.RegionalTaxRules.ToListAsync();
|
|
|
|
public async Task<Models.RegionalTaxRule?> GetTaxRuleByIdAsync(Guid id) =>
|
|
await context.RegionalTaxRules.FirstOrDefaultAsync(r => r.Id == id);
|
|
|
|
// Hard delete — see RemoveTarget's comment; same conflict applies to RegionalTaxRule's
|
|
// unique index on FK_RegionId alone (one tax rule per region).
|
|
public void RemoveTaxRule(Models.RegionalTaxRule rule) =>
|
|
context.RegionalTaxRules.Remove(rule);
|
|
|
|
public async Task<int?> GetUserRoleLevelAsync(Guid userId) =>
|
|
await context.Users
|
|
.Where(u => u.Id == userId && u.IsActive)
|
|
.Select(u => (int?)u.Role.Level)
|
|
.FirstOrDefaultAsync();
|
|
|
|
public async Task<List<Models.Route>> GetRoutesAsync(Guid regionId) =>
|
|
await context.Routes.Where(r => r.FK_RegionId == regionId && r.IsActive).ToListAsync();
|
|
|
|
public async Task<List<Models.Store>> GetStoresByRouteIdsAsync(List<Guid> routeIds) =>
|
|
await context.Stores.Where(s => routeIds.Contains(s.FK_RouteId) && s.IsActive).ToListAsync();
|
|
|
|
public async Task<List<Models.Order>> GetOrdersForDashboardAsync(Guid regionId, DateTime periodStart, DateTime periodEndExclusive) =>
|
|
await (from o in context.Orders
|
|
join s in context.Stores on o.FK_StoreId equals s.Id
|
|
join r in context.Routes on s.FK_RouteId equals r.Id
|
|
where r.FK_RegionId == regionId && o.IsActive && s.IsActive && r.IsActive
|
|
&& o.OrderDate >= periodStart && o.OrderDate < periodEndExclusive
|
|
select o).ToListAsync();
|
|
}
|