mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-10-07 03:32:11 +00:00
Add LocationController with full CRUD and extended model
- Extend Locations model with Address, City, State, ZipCode, Phone, Contact, ContactEmail, Status, AccountId
- Update Location DTOs to match new fields
- Create LocationController with paged list, get by ID, create, update, delete
- Support both REST-style routes (/api/Location/{id}) and legacy query routes (/api/Location/DeleteLocation?id=)
- Add migration for new Location columns
This commit is contained in:
parent
51b52a7fb5
commit
534f97d6f1
7 changed files with 2560 additions and 3 deletions
184
Api.SeaHavenIndustries/Controllers/LocationController.cs
Normal file
184
Api.SeaHavenIndustries/Controllers/LocationController.cs
Normal file
|
|
@ -0,0 +1,184 @@
|
||||||
|
using Api.SeaHavenIndustries.DTOs;
|
||||||
|
using Data.SeaHavenIndustries;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace Api.SeaHavenIndustries.Controllers
|
||||||
|
{
|
||||||
|
[Authorize]
|
||||||
|
[ApiController]
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
public class LocationController : Controller
|
||||||
|
{
|
||||||
|
private readonly ApplicationDbContext _db;
|
||||||
|
|
||||||
|
public LocationController(ApplicationDbContext db)
|
||||||
|
{
|
||||||
|
_db = db;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("GetLocationList")]
|
||||||
|
public IActionResult GetLocationList(string? search = "", int page = 1, int pageSize = 10)
|
||||||
|
{
|
||||||
|
var query = _db.Locations.AsQueryable();
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(search))
|
||||||
|
{
|
||||||
|
var s = search.ToLower();
|
||||||
|
query = query.Where(l =>
|
||||||
|
(l.Name ?? "").ToLower().Contains(s) ||
|
||||||
|
(l.Title ?? "").ToLower().Contains(s) ||
|
||||||
|
(l.Address ?? "").ToLower().Contains(s) ||
|
||||||
|
(l.City ?? "").ToLower().Contains(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
var totalCount = query.Count();
|
||||||
|
|
||||||
|
var data = query
|
||||||
|
.OrderByDescending(l => l.Id)
|
||||||
|
.Skip((page - 1) * pageSize)
|
||||||
|
.Take(pageSize)
|
||||||
|
.Select(l => new
|
||||||
|
{
|
||||||
|
l.Id,
|
||||||
|
l.Name,
|
||||||
|
l.Title,
|
||||||
|
l.Address,
|
||||||
|
l.City,
|
||||||
|
l.State,
|
||||||
|
l.ZipCode,
|
||||||
|
l.Phone,
|
||||||
|
l.Contact,
|
||||||
|
l.ContactEmail,
|
||||||
|
l.Status,
|
||||||
|
l.AccountId
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var viewModel = new Pagination_DTO
|
||||||
|
{
|
||||||
|
Data = data,
|
||||||
|
PageNumber = page,
|
||||||
|
PageSize = pageSize,
|
||||||
|
TotalCount = totalCount,
|
||||||
|
TotalPages = (int)Math.Ceiling(totalCount / (double)pageSize)
|
||||||
|
};
|
||||||
|
|
||||||
|
return Ok(viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{id}")]
|
||||||
|
public async Task<IActionResult> GetLocationById(int id)
|
||||||
|
{
|
||||||
|
var location = await _db.Locations
|
||||||
|
.Where(l => l.Id == id)
|
||||||
|
.Select(l => new
|
||||||
|
{
|
||||||
|
l.Id,
|
||||||
|
l.Name,
|
||||||
|
l.Title,
|
||||||
|
l.Address,
|
||||||
|
l.City,
|
||||||
|
l.State,
|
||||||
|
l.ZipCode,
|
||||||
|
l.Phone,
|
||||||
|
l.Contact,
|
||||||
|
l.ContactEmail,
|
||||||
|
l.Status,
|
||||||
|
l.AccountId
|
||||||
|
})
|
||||||
|
.FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
if (location == null)
|
||||||
|
return NotFound(new Response { Status = "Error", Message = "Location not found" });
|
||||||
|
|
||||||
|
return Ok(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> AddLocation([FromBody] Location_DTO model)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var location = new Locations
|
||||||
|
{
|
||||||
|
Name = model.Name,
|
||||||
|
Title = model.Title,
|
||||||
|
Address = model.Address,
|
||||||
|
City = model.City,
|
||||||
|
State = model.State,
|
||||||
|
ZipCode = model.ZipCode,
|
||||||
|
Phone = model.Phone,
|
||||||
|
Contact = model.Contact,
|
||||||
|
ContactEmail = model.ContactEmail,
|
||||||
|
Status = model.Status,
|
||||||
|
AccountId = model.AccountId
|
||||||
|
};
|
||||||
|
|
||||||
|
_db.Locations.Add(location);
|
||||||
|
await _db.SaveChangesAsync();
|
||||||
|
return Ok(new DataResponse { Message = "Location Created Successfully", Status = "200" });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPut("{id}")]
|
||||||
|
public async Task<IActionResult> EditLocation(int id, [FromBody] EditLocation_DTO model)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var exist = await _db.Locations.Where(l => l.Id == id).FirstOrDefaultAsync();
|
||||||
|
if (exist == null)
|
||||||
|
return BadRequest(new Response { Status = "Error", Message = "Location not found" });
|
||||||
|
|
||||||
|
exist.Name = model.Name;
|
||||||
|
exist.Title = model.Title;
|
||||||
|
exist.Address = model.Address;
|
||||||
|
exist.City = model.City;
|
||||||
|
exist.State = model.State;
|
||||||
|
exist.ZipCode = model.ZipCode;
|
||||||
|
exist.Phone = model.Phone;
|
||||||
|
exist.Contact = model.Contact;
|
||||||
|
exist.ContactEmail = model.ContactEmail;
|
||||||
|
exist.Status = model.Status;
|
||||||
|
exist.AccountId = model.AccountId;
|
||||||
|
|
||||||
|
await _db.SaveChangesAsync();
|
||||||
|
return Ok(new DataResponse { Message = "Location Updated Successfully", Status = "200" });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpDelete("{id}")]
|
||||||
|
public async Task<IActionResult> DeleteLocation(int id)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var exist = await _db.Locations.Where(l => l.Id == id).FirstOrDefaultAsync();
|
||||||
|
if (exist == null)
|
||||||
|
return BadRequest(new Response { Status = "Error", Message = "Location not found" });
|
||||||
|
|
||||||
|
_db.Locations.Remove(exist);
|
||||||
|
await _db.SaveChangesAsync();
|
||||||
|
return Ok(new DataResponse { Message = "Location Deleted Successfully", Status = "200" });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("DeleteLocation")]
|
||||||
|
public async Task<IActionResult> DeleteLocationByQuery(int id)
|
||||||
|
{
|
||||||
|
return await DeleteLocation(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,18 @@
|
||||||
namespace Api.SeaHavenIndustries.DTOs
|
namespace Api.SeaHavenIndustries.DTOs
|
||||||
{
|
{
|
||||||
public class EditLocation_DTO
|
public class EditLocation_DTO
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
public string? Title { get; set; }
|
public string? Title { get; set; }
|
||||||
public string? Name { get; set; }
|
public string? Name { get; set; }
|
||||||
|
public string? Address { get; set; }
|
||||||
|
public string? City { get; set; }
|
||||||
|
public string? State { get; set; }
|
||||||
|
public string? ZipCode { get; set; }
|
||||||
|
public string? Phone { get; set; }
|
||||||
|
public string? Contact { get; set; }
|
||||||
|
public string? ContactEmail { get; set; }
|
||||||
|
public string? Status { get; set; }
|
||||||
|
public int? AccountId { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,17 @@
|
||||||
namespace Api.SeaHavenIndustries.DTOs
|
namespace Api.SeaHavenIndustries.DTOs
|
||||||
{
|
{
|
||||||
public class Location_DTO
|
public class Location_DTO
|
||||||
{
|
{
|
||||||
public string? Title { get; set; }
|
public string? Title { get; set; }
|
||||||
public string? Name { get; set; }
|
public string? Name { get; set; }
|
||||||
|
public string? Address { get; set; }
|
||||||
|
public string? City { get; set; }
|
||||||
|
public string? State { get; set; }
|
||||||
|
public string? ZipCode { get; set; }
|
||||||
|
public string? Phone { get; set; }
|
||||||
|
public string? Contact { get; set; }
|
||||||
|
public string? ContactEmail { get; set; }
|
||||||
|
public string? Status { get; set; }
|
||||||
|
public int? AccountId { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2177
Data.SeaHavenIndustries/Migrations/20260416210833_AddLocationFields.Designer.cs
generated
Normal file
2177
Data.SeaHavenIndustries/Migrations/20260416210833_AddLocationFields.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,129 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Data.SeaHavenIndustries.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AddLocationFields : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "AccountId",
|
||||||
|
table: "Locations",
|
||||||
|
type: "int",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "Address",
|
||||||
|
table: "Locations",
|
||||||
|
type: "nvarchar(max)",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "City",
|
||||||
|
table: "Locations",
|
||||||
|
type: "nvarchar(max)",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "Contact",
|
||||||
|
table: "Locations",
|
||||||
|
type: "nvarchar(max)",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "ContactEmail",
|
||||||
|
table: "Locations",
|
||||||
|
type: "nvarchar(max)",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "Phone",
|
||||||
|
table: "Locations",
|
||||||
|
type: "nvarchar(max)",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "State",
|
||||||
|
table: "Locations",
|
||||||
|
type: "nvarchar(max)",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "Status",
|
||||||
|
table: "Locations",
|
||||||
|
type: "nvarchar(max)",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "ZipCode",
|
||||||
|
table: "Locations",
|
||||||
|
type: "nvarchar(max)",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_Locations_AccountId",
|
||||||
|
table: "Locations",
|
||||||
|
column: "AccountId");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "FK_Locations_Accounts_AccountId",
|
||||||
|
table: "Locations",
|
||||||
|
column: "AccountId",
|
||||||
|
principalTable: "Accounts",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Restrict);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "FK_Locations_Accounts_AccountId",
|
||||||
|
table: "Locations");
|
||||||
|
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "IX_Locations_AccountId",
|
||||||
|
table: "Locations");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "AccountId",
|
||||||
|
table: "Locations");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Address",
|
||||||
|
table: "Locations");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "City",
|
||||||
|
table: "Locations");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Contact",
|
||||||
|
table: "Locations");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "ContactEmail",
|
||||||
|
table: "Locations");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Phone",
|
||||||
|
table: "Locations");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "State",
|
||||||
|
table: "Locations");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Status",
|
||||||
|
table: "Locations");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "ZipCode",
|
||||||
|
table: "Locations");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -979,6 +979,21 @@ namespace Data.SeaHavenIndustries.Migrations
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<int?>("AccountId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("Address")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("City")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("Contact")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("ContactEmail")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.Property<DateTime?>("CreatedDate")
|
b.Property<DateTime?>("CreatedDate")
|
||||||
.HasColumnType("datetime2");
|
.HasColumnType("datetime2");
|
||||||
|
|
||||||
|
|
@ -1006,14 +1021,28 @@ namespace Data.SeaHavenIndustries.Migrations
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("Phone")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("State")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("Status")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.Property<string>("Title")
|
b.Property<string>("Title")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("ZipCode")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.Property<string>("createdby")
|
b.Property<string>("createdby")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("AccountId");
|
||||||
|
|
||||||
b.ToTable("Locations");
|
b.ToTable("Locations");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1863,6 +1892,16 @@ namespace Data.SeaHavenIndustries.Migrations
|
||||||
b.Navigation("WorkOrder");
|
b.Navigation("WorkOrder");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Data.SeaHavenIndustries.Locations", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Data.SeaHavenIndustries.Accounts", "Account")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("AccountId")
|
||||||
|
.OnDelete(DeleteBehavior.Restrict);
|
||||||
|
|
||||||
|
b.Navigation("Account");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Data.SeaHavenIndustries.PMSchedules", b =>
|
modelBuilder.Entity("Data.SeaHavenIndustries.PMSchedules", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("Data.SeaHavenIndustries.Assets", "Asset")
|
b.HasOne("Data.SeaHavenIndustries.Assets", "Asset")
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,20 @@ namespace Data.SeaHavenIndustries
|
||||||
{
|
{
|
||||||
public string? Title { get; set; }
|
public string? Title { get; set; }
|
||||||
public string? Name { get; set; }
|
public string? Name { get; set; }
|
||||||
|
public string? Address { get; set; }
|
||||||
|
public string? City { get; set; }
|
||||||
|
public string? State { get; set; }
|
||||||
|
public string? ZipCode { get; set; }
|
||||||
|
public string? Phone { get; set; }
|
||||||
|
public string? Contact { get; set; }
|
||||||
|
public string? ContactEmail { get; set; }
|
||||||
|
public string? Status { get; set; }
|
||||||
public string? Latitude { get; set; }
|
public string? Latitude { get; set; }
|
||||||
public string? Longitude { get; set; }
|
public string? Longitude { get; set; }
|
||||||
|
public int? AccountId { get; set; }
|
||||||
|
[ForeignKey("AccountId")]
|
||||||
|
public Accounts? Account { get; set; }
|
||||||
public ICollection<Template>? Templates { get; set; }
|
public ICollection<Template>? Templates { get; set; }
|
||||||
public ICollection<WorkOrder>? workOrders { get; set; }
|
public ICollection<WorkOrder>? workOrders { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue