| @@ -0,0 +1,64 @@ | |||||
| using Microsoft.AspNetCore.Mvc; | |||||
| using Campaign_Tracker.Server.Models; | |||||
| using Campaign_Tracker.Server.Services; | |||||
| namespace Campaign_Tracker.Server.Controllers; | |||||
| [ApiController] | |||||
| [Route(api/[controller])] | |||||
| public class MunicipalityAddressesController : ControllerBase | |||||
| { | |||||
| private readonly IMunicipalityAddressService _addressService; | |||||
| public MunicipalityAddressesController(IMunicipalityAddressService addressService) | |||||
| { | |||||
| _addressService = addressService; | |||||
| } | |||||
| [HttpGet({municipalityId})] | |||||
| public async Task<ActionResult<IEnumerable<MunicipalityAddress>>> GetAddresses(int municipalityId) | |||||
| { | |||||
| var addresses = await _addressService.GetAddressesAsync(municipalityId); | |||||
| return Ok(addresses); | |||||
| } | |||||
| [HttpGet({id})] | |||||
| public async Task<ActionResult<MunicipalityAddress>> GetAddress(int id) | |||||
| { | |||||
| var address = await _addressService.GetAddressAsync(id); | |||||
| if (address == null) | |||||
| return NotFound(); | |||||
| return Ok(address); | |||||
| } | |||||
| [HttpPost] | |||||
| public async Task<ActionResult<MunicipalityAddress>> CreateAddress(MunicipalityAddress address) | |||||
| { | |||||
| var createdAddress = await _addressService.CreateAddressAsync(address); | |||||
| return CreatedAtAction(nameof(GetAddress), new { id = createdAddress.Id }, createdAddress); | |||||
| } | |||||
| [HttpPut({id})] | |||||
| public async Task<IActionResult> UpdateAddress(int id, MunicipalityAddress address) | |||||
| { | |||||
| if (id != address.Id) | |||||
| return BadRequest(); | |||||
| var updatedAddress = await _addressService.UpdateAddressAsync(id, address); | |||||
| if (updatedAddress == null) | |||||
| return NotFound(); | |||||
| return Ok(updatedAddress); | |||||
| } | |||||
| [HttpDelete({id})] | |||||
| public async Task<IActionResult> DeleteAddress(int id) | |||||
| { | |||||
| var result = await _addressService.DeleteAddressAsync(id); | |||||
| if (!result) | |||||
| return NotFound(); | |||||
| return NoContent(); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,45 @@ | |||||
| using System.ComponentModel.DataAnnotations; | |||||
| using System.ComponentModel.DataAnnotations.Schema; | |||||
| namespace Campaign_Tracker.Server.Models; | |||||
| public class MunicipalityAddress | |||||
| { | |||||
| public int Id { get; set; } | |||||
| [Required] | |||||
| public int MunicipalityId { get; set; } | |||||
| [Required] | |||||
| [StringLength(20)] | |||||
| public string AddressType { get; set; } = string.Empty; // "Mailing" or "Delivery" | |||||
| [Required] | |||||
| [StringLength(200)] | |||||
| public string Street { get; set; } = string.Empty; | |||||
| [Required] | |||||
| [StringLength(100)] | |||||
| public string City { get; set; } = string.Empty; | |||||
| [Required] | |||||
| [StringLength(50)] | |||||
| public string State { get; set; } = string.Empty; | |||||
| [Required] | |||||
| [StringLength(20)] | |||||
| public string ZipCode { get; set; } = string.Empty; | |||||
| [Required] | |||||
| public DateTime EffectiveDate { get; set; } | |||||
| public bool IsCurrent { get; set; } = true; | |||||
| public DateTime CreatedAt { get; set; } = DateTime.UtcNow; | |||||
| public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; | |||||
| // Navigation property | |||||
| [ForeignKey("MunicipalityId")] | |||||
| public Municipality Municipality { get; set; } = null!; | |||||
| } | |||||
| @@ -0,0 +1,14 @@ | |||||
| using System.Threading.Tasks; | |||||
| using Campaign_Tracker.Server.Models; | |||||
| using Microsoft.EntityFrameworkCore; | |||||
| namespace Campaign_Tracker.Server.Services; | |||||
| public interface IMunicipalityAddressService | |||||
| { | |||||
| Task<IEnumerable<MunicipalityAddress>> GetAddressesAsync(int municipalityId); | |||||
| Task<MunicipalityAddress> GetAddressAsync(int id); | |||||
| Task<MunicipalityAddress> CreateAddressAsync(MunicipalityAddress address); | |||||
| Task<MunicipalityAddress> UpdateAddressAsync(int id, MunicipalityAddress address); | |||||
| Task<bool> DeleteAddressAsync(int id); | |||||
| } | |||||
| @@ -0,0 +1,94 @@ | |||||
| using System.Threading.Tasks; | |||||
| using Campaign_Tracker.Server.Models; | |||||
| using Microsoft.EntityFrameworkCore; | |||||
| namespace Campaign_Tracker.Server.Services; | |||||
| public class MunicipalityAddressService : IMunicipalityAddressService | |||||
| { | |||||
| private readonly ApplicationDbContext _context; | |||||
| public MunicipalityAddressService(ApplicationDbContext context) | |||||
| { | |||||
| _context = context; | |||||
| } | |||||
| public async Task<IEnumerable<MunicipalityAddress>> GetAddressesAsync(int municipalityId) | |||||
| { | |||||
| return await _context.MunicipalityAddresses | |||||
| .Where(a => a.MunicipalityId == municipalityId) | |||||
| .OrderByDescending(a => a.EffectiveDate) | |||||
| .ToListAsync(); | |||||
| } | |||||
| public async Task<MunicipalityAddress> GetAddressAsync(int id) | |||||
| { | |||||
| return await _context.MunicipalityAddresses.FindAsync(id); | |||||
| } | |||||
| public async Task<MunicipalityAddress> CreateAddressAsync(MunicipalityAddress address) | |||||
| { | |||||
| // Mark previous addresses as not current | |||||
| var existingCurrent = await _context.MunicipalityAddresses | |||||
| .Where(a => a.MunicipalityId == address.MunicipalityId && a.IsCurrent) | |||||
| .FirstOrDefaultAsync(); | |||||
| if (existingCurrent != null) | |||||
| { | |||||
| existingCurrent.IsCurrent = false; | |||||
| existingCurrent.UpdatedAt = DateTime.UtcNow; | |||||
| } | |||||
| address.IsCurrent = true; | |||||
| address.CreatedAt = DateTime.UtcNow; | |||||
| address.UpdatedAt = DateTime.UtcNow; | |||||
| _context.MunicipalityAddresses.Add(address); | |||||
| await _context.SaveChangesAsync(); | |||||
| return address; | |||||
| } | |||||
| public async Task<MunicipalityAddress> UpdateAddressAsync(int id, MunicipalityAddress address) | |||||
| { | |||||
| var existingAddress = await _context.MunicipalityAddresses.FindAsync(id); | |||||
| if (existingAddress == null) | |||||
| return null; | |||||
| // Mark previous addresses as not current | |||||
| var existingCurrent = await _context.MunicipalityAddresses | |||||
| .Where(a => a.MunicipalityId == existingAddress.MunicipalityId && a.IsCurrent && a.Id != id) | |||||
| .FirstOrDefaultAsync(); | |||||
| if (existingCurrent != null) | |||||
| { | |||||
| existingCurrent.IsCurrent = false; | |||||
| existingCurrent.UpdatedAt = DateTime.UtcNow; | |||||
| } | |||||
| existingAddress.AddressType = address.AddressType; | |||||
| existingAddress.Street = address.Street; | |||||
| existingAddress.City = address.City; | |||||
| existingAddress.State = address.State; | |||||
| existingAddress.ZipCode = address.ZipCode; | |||||
| existingAddress.EffectiveDate = address.EffectiveDate; | |||||
| existingAddress.IsCurrent = true; | |||||
| existingAddress.UpdatedAt = DateTime.UtcNow; | |||||
| await _context.SaveChangesAsync(); | |||||
| return existingAddress; | |||||
| } | |||||
| public async Task<bool> DeleteAddressAsync(int id) | |||||
| { | |||||
| var address = await _context.MunicipalityAddresses.FindAsync(id); | |||||
| if (address == null) | |||||
| return false; | |||||
| _context.MunicipalityAddresses.Remove(address); | |||||
| await _context.SaveChangesAsync(); | |||||
| return true; | |||||
| } | |||||
| } | |||||
Powered by TurnKey Linux.