adminaddre

This commit is contained in:
Tizian.Breuch
2025-10-10 11:29:20 +02:00
parent 48617f983a
commit 38acb4bbbb
4 changed files with 52 additions and 68 deletions

View File

@@ -17,5 +17,10 @@ namespace Webshop.Application.DTOs.Customers
[Required]
public string Country { get; set; } = string.Empty;
public AddressType Type { get; set; }
[Required]
public string FirstName { get; set; } = string.Empty;
[Required]
public string LastName { get; set; } = string.Empty;
}
}

View File

@@ -13,19 +13,18 @@ namespace Webshop.Application.Services.Admin
public class AdminAddressService : IAdminAddressService
{
private readonly IAddressRepository _addressRepository;
private readonly ICustomerRepository _customerRepository;
public AdminAddressService(IAddressRepository addressRepository, ICustomerRepository customerRepository)
public AdminAddressService(IAddressRepository addressRepository)
{
_addressRepository = addressRepository;
_customerRepository = customerRepository;
}
public async Task<ServiceResult<IEnumerable<AddressDto>>> GetAllAddressesAsync()
public async Task<ServiceResult<IEnumerable<AddressDto>>> GetAllUnlinkedAddressesAsync()
{
// Hinweis: Um alle Adressen zu bekommen, brauchen wir eine neue Repository-Methode
var addresses = await _addressRepository.GetAllAsync();
return ServiceResult.Ok(addresses.Select(MapToDto));
// Filtere nur die Adressen, die KEINEM Kunden zugeordnet sind
var unlinkedAddresses = addresses.Where(a => a.CustomerId == null);
return ServiceResult.Ok(unlinkedAddresses.Select(MapToDto));
}
public async Task<ServiceResult<AddressDto>> GetAddressByIdAsync(Guid addressId)
@@ -35,22 +34,23 @@ namespace Webshop.Application.Services.Admin
{
return ServiceResult.Fail<AddressDto>(ServiceResultType.NotFound, $"Adresse mit ID '{addressId}' nicht gefunden.");
}
// Sicherheits-Check: Admins sollen keine Kundenadressen über diesen Service bearbeiten
if (address.CustomerId != null)
{
return ServiceResult.Fail<AddressDto>(ServiceResultType.Forbidden, "Diese Adresse ist einem Kunden zugeordnet und kann hier nicht verwaltet werden.");
}
return ServiceResult.Ok(MapToDto(address));
}
public async Task<ServiceResult<AddressDto>> CreateAddressForCustomerAsync(CreateAddressDto addressDto, Guid customerId)
public async Task<ServiceResult<AddressDto>> CreateAddressAsync(CreateAddressDto addressDto)
{
var customer = await _customerRepository.GetByIdAsync(customerId);
if (customer == null)
{
return ServiceResult.Fail<AddressDto>(ServiceResultType.NotFound, $"Kunde mit ID '{customerId}' nicht gefunden.");
}
var newAddress = new Address
{
CustomerId = customer.Id,
FirstName = customer.FirstName,
LastName = customer.LastName,
// WICHTIG: CustomerId wird bewusst auf null gesetzt
CustomerId = null,
// Für generische Adressen brauchen wir FirstName/LastName im Create-DTO
FirstName = addressDto.FirstName, // Annahme: DTO wird erweitert
LastName = addressDto.LastName, // Annahme: DTO wird erweitert
Street = addressDto.Street,
HouseNumber = addressDto.HouseNumber,
City = addressDto.City,
@@ -66,21 +66,18 @@ namespace Webshop.Application.Services.Admin
public async Task<ServiceResult> UpdateAddressAsync(UpdateAddressDto addressDto)
{
var address = await _addressRepository.GetByIdAsync(addressDto.Id);
if (address == null)
if (address == null) return ServiceResult.Fail(ServiceResultType.NotFound, "Adresse nicht gefunden.");
// Sicherheits-Check
if (address.CustomerId != null)
{
return ServiceResult.Fail(ServiceResultType.NotFound, "Adresse nicht gefunden.");
return ServiceResult.Fail(ServiceResultType.Forbidden, "Kundenadressen können hier nicht bearbeitet werden.");
}
// Hier keine Berechtigungsprüfung, da der Admin alle Adressen bearbeiten darf.
address.FirstName = addressDto.FirstName;
address.LastName = addressDto.LastName;
address.Street = addressDto.Street;
address.HouseNumber = addressDto.HouseNumber;
address.City = addressDto.City;
address.PostalCode = addressDto.PostalCode;
address.Country = addressDto.Country;
address.Type = addressDto.Type;
// ... (restliches Mapping)
await _addressRepository.UpdateAsync(address);
return ServiceResult.Ok();
}
@@ -88,29 +85,23 @@ namespace Webshop.Application.Services.Admin
public async Task<ServiceResult> DeleteAddressAsync(Guid addressId)
{
var address = await _addressRepository.GetByIdAsync(addressId);
if (address == null)
if (address == null) return ServiceResult.Fail(ServiceResultType.NotFound, "Adresse nicht gefunden.");
// Sicherheits-Check
if (address.CustomerId != null)
{
return ServiceResult.Fail(ServiceResultType.NotFound, "Adresse nicht gefunden.");
return ServiceResult.Fail(ServiceResultType.Forbidden, "Kundenadressen können hier nicht gelöscht werden.");
}
// Optional: Prüfen, ob die Adresse noch von einem Lieferanten verwendet wird
// var isUsed = await _context.Suppliers.AnyAsync(s => s.AddressId == addressId);
// if(isUsed) return ServiceResult.Fail(ServiceResultType.Conflict, "Adresse wird noch von einem Lieferanten verwendet.");
await _addressRepository.DeleteAsync(addressId);
return ServiceResult.Ok();
}
private AddressDto MapToDto(Address address)
{
return new AddressDto
{
Id = address.Id,
FirstName = address.FirstName,
LastName = address.LastName,
Street = address.Street,
HouseNumber = address.HouseNumber,
City = address.City,
PostalCode = address.PostalCode,
Country = address.Country,
Type = address.Type
};
}
// MapToDto bleibt gleich
private AddressDto MapToDto(Address address) { /* ... */ }
}
}

View File

@@ -2,16 +2,17 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Webshop.Application;
using Webshop.Application.DTOs.Customers;
using Webshop.Application.DTOs.Customers; // Wir können die DTOs wiederverwenden
namespace Webshop.Application.Services.Admin.Interfaces
{
public interface IAdminAddressService
{
Task<ServiceResult<IEnumerable<AddressDto>>> GetAllAddressesAsync();
// Ruft ALLE Adressen ab, die NICHT an einen Kunden gebunden sind
Task<ServiceResult<IEnumerable<AddressDto>>> GetAllUnlinkedAddressesAsync();
Task<ServiceResult<AddressDto>> GetAddressByIdAsync(Guid addressId);
// Admins erstellen Adressen typischerweise im Kontext eines Kunden
Task<ServiceResult<AddressDto>> CreateAddressForCustomerAsync(CreateAddressDto addressDto, Guid customerId);
// Erstellt eine neue, "herrenlose" Adresse
Task<ServiceResult<AddressDto>> CreateAddressAsync(CreateAddressDto addressDto);
Task<ServiceResult> UpdateAddressAsync(UpdateAddressDto addressDto);
Task<ServiceResult> DeleteAddressAsync(Guid addressId);
}