Add project files.
This commit is contained in:
52
Controllers/AuthController.cs
Normal file
52
Controllers/AuthController.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using LogisticsApp.Server.Services;
|
||||
using LogisticsApp.Server.DTOs;
|
||||
|
||||
namespace LogisticsApp.Server.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class AuthController : ControllerBase
|
||||
{
|
||||
private readonly IAuthService _authService;
|
||||
|
||||
public AuthController(IAuthService authService)
|
||||
{
|
||||
_authService = authService;
|
||||
}
|
||||
|
||||
[HttpPost("login")]
|
||||
public async Task<ActionResult<ApiResponse<LoginResponse>>> Login(LoginRequest request)
|
||||
{
|
||||
|
||||
if (string.IsNullOrEmpty(request.Username) || string.IsNullOrEmpty(request.Password))
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "Username and password are required"));
|
||||
}
|
||||
|
||||
var result = await _authService.LoginAsync(request);
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
return Unauthorized(new ApiResponse<string>(false, "Invalid username or password"));
|
||||
}
|
||||
|
||||
Response.Cookies.Append("auth_token", result.Token, new CookieOptions
|
||||
{
|
||||
HttpOnly = false,
|
||||
Secure = false,
|
||||
SameSite = SameSiteMode.Strict,
|
||||
Expires = result.Expires
|
||||
});
|
||||
|
||||
return Ok(new ApiResponse<LoginResponse>(true, "Login successful", result));
|
||||
}
|
||||
|
||||
[HttpPost("logout")]
|
||||
public ActionResult<ApiResponse<string>> Logout()
|
||||
{
|
||||
Response.Cookies.Delete("auth_token");
|
||||
return Ok(new ApiResponse<string>(true, "Logout successful"));
|
||||
}
|
||||
}
|
||||
}
|
||||
205
Controllers/OrdersController.cs
Normal file
205
Controllers/OrdersController.cs
Normal file
@@ -0,0 +1,205 @@
|
||||
using LogisticsApp.Server.Data;
|
||||
using LogisticsApp.Server.DTOs;
|
||||
using LogisticsApp.Server.Models;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace LogisticsApp.Server.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class OrdersController : ControllerBase
|
||||
{
|
||||
private readonly ApplicationDbContext _context;
|
||||
|
||||
public OrdersController(ApplicationDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
// GET: api/orders
|
||||
[Authorize]
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<ApiResponse<PagedResult<Order>>>> GetOrders([FromQuery] OrderFilters filters)
|
||||
{
|
||||
try
|
||||
{
|
||||
var query = _context.Orders.AsQueryable();
|
||||
|
||||
|
||||
if (!string.IsNullOrEmpty(filters.ClientName))
|
||||
{
|
||||
query = query.Where(o => o.ClientName.ToLower().Contains(filters.ClientName.ToLower()));
|
||||
}
|
||||
|
||||
if (filters.MinCost.HasValue)
|
||||
{
|
||||
query = query.Where(o => o.OrderCost >= filters.MinCost.Value);
|
||||
}
|
||||
|
||||
if (filters.MaxCost.HasValue)
|
||||
{
|
||||
query = query.Where(o => o.OrderCost <= filters.MaxCost.Value);
|
||||
}
|
||||
|
||||
if (filters.OrderDate.HasValue)
|
||||
{
|
||||
query = query.Where(o => o.OrderDate.Date == filters.OrderDate.Value.Date);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(filters.Status))
|
||||
{
|
||||
query = query.Where(o => o.Status == filters.Status);
|
||||
}
|
||||
|
||||
var totalCount = await query.CountAsync();
|
||||
|
||||
|
||||
var orders = await query
|
||||
.OrderByDescending(o => o.OrderDate)
|
||||
.Skip((filters.Page - 1) * filters.PageSize)
|
||||
.Take(filters.PageSize)
|
||||
.ToListAsync();
|
||||
|
||||
var result = new PagedResult<Order>
|
||||
{
|
||||
Items = orders,
|
||||
TotalCount = totalCount,
|
||||
Page = filters.Page,
|
||||
PageSize = filters.PageSize,
|
||||
TotalPages = (int)Math.Ceiling(totalCount / (double)filters.PageSize)
|
||||
};
|
||||
|
||||
return Ok(new ApiResponse<PagedResult<Order>>(true, "Orders retrieved successfully", result));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return StatusCode(500, new ApiResponse<string>(false, $"Internal server error: {ex.Message}"));
|
||||
}
|
||||
}
|
||||
|
||||
// GET: api/orders/5
|
||||
[Authorize]
|
||||
[HttpGet("{id}")]
|
||||
public async Task<ActionResult<ApiResponse<Order>>> GetOrder(int id)
|
||||
{
|
||||
var order = await _context.Orders.FindAsync(id);
|
||||
|
||||
if (order == null)
|
||||
{
|
||||
return NotFound(new ApiResponse<string>(false, "Order not found"));
|
||||
}
|
||||
|
||||
return Ok(new ApiResponse<Order>(true, "Order retrieved successfully", order));
|
||||
}
|
||||
|
||||
// PUT: api/orders/5
|
||||
[Authorize]
|
||||
[HttpPut("{id}")]
|
||||
public async Task<ActionResult<ApiResponse<Order>>> PutOrder(int id, Order order)
|
||||
{
|
||||
if (id != order.Id)
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "ID mismatch"));
|
||||
}
|
||||
|
||||
|
||||
var validStatuses = new[] { "pending", "in_progress", "completed", "cancelled" };
|
||||
if (!validStatuses.Contains(order.Status))
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "Invalid status"));
|
||||
}
|
||||
|
||||
|
||||
if (order.OrderCost <= 0)
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "Order cost must be positive"));
|
||||
}
|
||||
|
||||
|
||||
_context.Entry(order).State = EntityState.Modified;
|
||||
|
||||
try
|
||||
{
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
catch (DbUpdateConcurrencyException)
|
||||
{
|
||||
if (!OrderExists(id))
|
||||
{
|
||||
return NotFound(new ApiResponse<string>(false, "Order not found"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(new ApiResponse<Order>(true, "Order updated successfully", order));
|
||||
}
|
||||
|
||||
// POST: api/orders
|
||||
[Authorize]
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<ApiResponse<Order>>> PostOrder(Order order)
|
||||
{
|
||||
|
||||
if (string.IsNullOrEmpty(order.ClientName) || order.ClientName.Length > 200)
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "Client name is required and must be less than 200 characters"));
|
||||
}
|
||||
|
||||
if (order.OrderCost <= 0)
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "Order cost must be positive"));
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(order.Address) || order.Address.Length > 500)
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "Address is required and must be less than 500 characters"));
|
||||
}
|
||||
|
||||
var validStatuses = new[] { "pending", "in_progress", "completed", "cancelled" };
|
||||
if (!validStatuses.Contains(order.Status))
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "Invalid status"));
|
||||
}
|
||||
|
||||
_context.Orders.Add(order);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return CreatedAtAction("GetOrder", new { id = order.Id },
|
||||
new ApiResponse<Order>(true, "Order created successfully", order));
|
||||
}
|
||||
|
||||
// DELETE: api/orders/5
|
||||
[Authorize]
|
||||
[HttpDelete("{id}")]
|
||||
public async Task<ActionResult<ApiResponse<Order>>> DeleteOrder(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var order = await _context.Orders.FindAsync(id);
|
||||
if (order == null)
|
||||
{
|
||||
return NotFound(new ApiResponse<string>(false, "Order not found"));
|
||||
}
|
||||
|
||||
_context.Orders.Remove(order);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return Ok(new ApiResponse<string>(true, "Order deleted successfully"));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return StatusCode(500, new ApiResponse<string>(false, $"Internal server error: {ex.Message}"));
|
||||
}
|
||||
}
|
||||
|
||||
private bool OrderExists(int id)
|
||||
{
|
||||
return _context.Orders.Any(e => e.Id == id);
|
||||
}
|
||||
}
|
||||
}
|
||||
214
Controllers/VehiclesController.cs
Normal file
214
Controllers/VehiclesController.cs
Normal file
@@ -0,0 +1,214 @@
|
||||
|
||||
using LogisticsApp.Server.Data;
|
||||
using LogisticsApp.Server.DTOs;
|
||||
using LogisticsApp.Server.Models;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace LogisticsApp.Server.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class VehiclesController : ControllerBase
|
||||
{
|
||||
private readonly ApplicationDbContext _context;
|
||||
|
||||
public VehiclesController(ApplicationDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
// GET: api/vehicles
|
||||
[Authorize]
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<ApiResponse<PagedResult<Vehicle>>>> GetVehicles([FromQuery] VehicleFilters filters)
|
||||
{
|
||||
try
|
||||
{
|
||||
var query = _context.Vehicles.AsQueryable();
|
||||
|
||||
|
||||
if (!string.IsNullOrEmpty(filters.DriverName))
|
||||
{
|
||||
query = query.Where(v => v.DriverName.ToLower().Contains(filters.DriverName.ToLower()));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(filters.VehicleType))
|
||||
{
|
||||
query = query.Where(v => v.VehicleType.ToLower().Contains(filters.VehicleType.ToLower()));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(filters.LicensePlate))
|
||||
{
|
||||
query = query.Where(v => v.LicensePlate.ToLower().Contains(filters.LicensePlate.ToLower()));
|
||||
}
|
||||
|
||||
var totalCount = await query.CountAsync();
|
||||
|
||||
var vehicles = await query
|
||||
.OrderBy(v => v.DriverName)
|
||||
.Skip((filters.Page - 1) * filters.PageSize)
|
||||
.Take(filters.PageSize)
|
||||
.ToListAsync();
|
||||
|
||||
var result = new PagedResult<Vehicle>
|
||||
{
|
||||
Items = vehicles,
|
||||
TotalCount = totalCount,
|
||||
Page = filters.Page,
|
||||
PageSize = filters.PageSize,
|
||||
TotalPages = (int)Math.Ceiling(totalCount / (double)filters.PageSize)
|
||||
};
|
||||
|
||||
return Ok(new ApiResponse<PagedResult<Vehicle>>(true, "Vehicles retrieved successfully", result));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return StatusCode(500, new ApiResponse<string>(false, $"Internal server error: {ex.Message}"));
|
||||
}
|
||||
}
|
||||
|
||||
// GET: api/vehicles/5
|
||||
[Authorize]
|
||||
[HttpGet("{id}")]
|
||||
public async Task<ActionResult<ApiResponse<Vehicle>>> GetVehicle(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var vehicle = await _context.Vehicles
|
||||
.FirstOrDefaultAsync(v => v.Id == id);
|
||||
|
||||
if (vehicle == null)
|
||||
{
|
||||
return NotFound(new ApiResponse<string>(false, "Vehicle not found"));
|
||||
}
|
||||
|
||||
return Ok(new ApiResponse<Vehicle>(true, "Vehicle retrieved successfully", vehicle));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return StatusCode(500, new ApiResponse<string>(false, $"Internal server error: {ex.Message}"));
|
||||
}
|
||||
}
|
||||
|
||||
// POST: api/vehicles
|
||||
[Authorize]
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<ApiResponse<Vehicle>>> PostVehicle(Vehicle vehicle)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
if (string.IsNullOrEmpty(vehicle.DriverName) || vehicle.DriverName.Length > 100)
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "Driver name is required and must be less than 100 characters"));
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(vehicle.VehicleType) || vehicle.VehicleType.Length > 50)
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "Vehicle type is required and must be less than 50 characters"));
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(vehicle.LicensePlate) || vehicle.LicensePlate.Length > 20)
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "License plate is required and must be less than 20 characters"));
|
||||
}
|
||||
|
||||
vehicle.CreatedAt = DateTime.UtcNow;
|
||||
_context.Vehicles.Add(vehicle);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return CreatedAtAction("GetVehicle", new { id = vehicle.Id },
|
||||
new ApiResponse<Vehicle>(true, "Vehicle created successfully", vehicle));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return StatusCode(500, new ApiResponse<string>(false, $"Internal server error: {ex.Message}"));
|
||||
}
|
||||
}
|
||||
|
||||
// PUT: api/vehicles/5
|
||||
[Authorize]
|
||||
[HttpPut("{id}")]
|
||||
public async Task<ActionResult<ApiResponse<Vehicle>>> PutVehicle(int id, Vehicle vehicle)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (id != vehicle.Id)
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "ID mismatch"));
|
||||
}
|
||||
|
||||
|
||||
if (string.IsNullOrEmpty(vehicle.DriverName) || vehicle.DriverName.Length > 100)
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "Driver name is required and must be less than 100 characters"));
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(vehicle.VehicleType) || vehicle.VehicleType.Length > 50)
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "Vehicle type is required and must be less than 50 characters"));
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(vehicle.LicensePlate) || vehicle.LicensePlate.Length > 20)
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "License plate is required and must be less than 20 characters"));
|
||||
}
|
||||
|
||||
_context.Entry(vehicle).State = EntityState.Modified;
|
||||
|
||||
try
|
||||
{
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
catch (DbUpdateConcurrencyException)
|
||||
{
|
||||
if (!VehicleExists(id))
|
||||
{
|
||||
return NotFound(new ApiResponse<string>(false, "Vehicle not found"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(new ApiResponse<Vehicle>(true, "Vehicle updated successfully", vehicle));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return StatusCode(500, new ApiResponse<string>(false, $"Internal server error: {ex.Message}"));
|
||||
}
|
||||
}
|
||||
|
||||
// DELETE: api/vehicles/5
|
||||
[Authorize]
|
||||
[HttpDelete("{id}")]
|
||||
public async Task<ActionResult<ApiResponse<string>>> DeleteVehicle(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var vehicle = await _context.Vehicles.FindAsync(id);
|
||||
if (vehicle == null)
|
||||
{
|
||||
return NotFound(new ApiResponse<string>(false, "Vehicle not found"));
|
||||
}
|
||||
|
||||
_context.Vehicles.Remove(vehicle);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return Ok(new ApiResponse<string>(true, "Vehicle deleted successfully"));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return StatusCode(500, new ApiResponse<string>(false, $"Internal server error: {ex.Message}"));
|
||||
}
|
||||
}
|
||||
|
||||
private bool VehicleExists(int id)
|
||||
{
|
||||
return _context.Vehicles.Any(e => e.Id == id);
|
||||
}
|
||||
}
|
||||
}
|
||||
231
Controllers/WaybillEntriesController.cs
Normal file
231
Controllers/WaybillEntriesController.cs
Normal file
@@ -0,0 +1,231 @@
|
||||
|
||||
using LogisticsApp.Server.Data;
|
||||
using LogisticsApp.Server.DTOs;
|
||||
using LogisticsApp.Server.Models;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace LogisticsApp.Server.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class WaybillEntriesController : ControllerBase
|
||||
{
|
||||
private readonly ApplicationDbContext _context;
|
||||
|
||||
public WaybillEntriesController(ApplicationDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
// GET: api/waybillentries
|
||||
[Authorize]
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<ApiResponse<List<WaybillEntry>>>> GetWaybillEntries()
|
||||
{
|
||||
try
|
||||
{
|
||||
var entries = await _context.WaybillEntries
|
||||
.OrderByDescending(w => w.Date)
|
||||
.ThenBy(w => w.StartTime)
|
||||
.ToListAsync();
|
||||
|
||||
return Ok(new ApiResponse<List<WaybillEntry>>(true, "Waybill entries retrieved successfully", entries));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return StatusCode(500, new ApiResponse<string>(false, $"Internal server error: {ex.Message}"));
|
||||
}
|
||||
}
|
||||
|
||||
// GET: api/waybillentries/5
|
||||
[Authorize]
|
||||
[HttpGet("{id}")]
|
||||
public async Task<ActionResult<ApiResponse<WaybillEntry>>> GetWaybillEntry(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var waybillEntry = await _context.WaybillEntries
|
||||
.FirstOrDefaultAsync(w => w.Id == id);
|
||||
|
||||
if (waybillEntry == null)
|
||||
{
|
||||
return NotFound(new ApiResponse<string>(false, "Waybill entry not found"));
|
||||
}
|
||||
|
||||
return Ok(new ApiResponse<WaybillEntry>(true, "Waybill entry retrieved successfully", waybillEntry));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return StatusCode(500, new ApiResponse<string>(false, $"Internal server error: {ex.Message}"));
|
||||
}
|
||||
}
|
||||
|
||||
// POST: api/waybillentries
|
||||
[Authorize]
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<ApiResponse<WaybillEntry>>> PostWaybillEntry(WaybillEntry waybillEntry)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
if (waybillEntry.VehicleId <= 0)
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "Valid VehicleId is required"));
|
||||
}
|
||||
|
||||
if (waybillEntry.OrderId <= 0)
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "Valid OrderId is required"));
|
||||
}
|
||||
|
||||
|
||||
var vehicleExists = await _context.Vehicles.AnyAsync(v => v.Id == waybillEntry.VehicleId);
|
||||
if (!vehicleExists)
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "Vehicle not found"));
|
||||
}
|
||||
|
||||
var orderExists = await _context.Orders.AnyAsync(o => o.Id == waybillEntry.OrderId);
|
||||
if (!orderExists)
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "Order not found"));
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(waybillEntry.StartTime) || !IsValidTimeFormat(waybillEntry.StartTime))
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "StartTime must be in HH:mm format"));
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(waybillEntry.EndTime) || !IsValidTimeFormat(waybillEntry.EndTime))
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "EndTime must be in HH:mm format"));
|
||||
}
|
||||
|
||||
waybillEntry.CreatedAt = DateTime.UtcNow;
|
||||
_context.WaybillEntries.Add(waybillEntry);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
var createdEntry = await _context.WaybillEntries
|
||||
.FirstOrDefaultAsync(w => w.Id == waybillEntry.Id);
|
||||
|
||||
return CreatedAtAction("GetWaybillEntry", new { id = waybillEntry.Id },
|
||||
new ApiResponse<WaybillEntry>(true, "Waybill entry created successfully", createdEntry));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return StatusCode(500, new ApiResponse<string>(false, $"Internal server error: {ex.Message}"));
|
||||
}
|
||||
}
|
||||
|
||||
// PUT: api/waybillentries/5
|
||||
[Authorize]
|
||||
[HttpPut("{id}")]
|
||||
public async Task<ActionResult<ApiResponse<WaybillEntry>>> PutWaybillEntry(int id, WaybillEntry waybillEntry)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (id != waybillEntry.Id)
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "ID mismatch"));
|
||||
}
|
||||
|
||||
|
||||
if (waybillEntry.VehicleId <= 0)
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "Valid VehicleId is required"));
|
||||
}
|
||||
|
||||
if (waybillEntry.OrderId <= 0)
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "Valid OrderId is required"));
|
||||
}
|
||||
|
||||
var vehicleExists = await _context.Vehicles.AnyAsync(v => v.Id == waybillEntry.VehicleId);
|
||||
if (!vehicleExists)
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "Vehicle not found"));
|
||||
}
|
||||
|
||||
var orderExists = await _context.Orders.AnyAsync(o => o.Id == waybillEntry.OrderId);
|
||||
if (!orderExists)
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "Order not found"));
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(waybillEntry.StartTime) || !IsValidTimeFormat(waybillEntry.StartTime))
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "StartTime must be in HH:mm format"));
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(waybillEntry.EndTime) || !IsValidTimeFormat(waybillEntry.EndTime))
|
||||
{
|
||||
return BadRequest(new ApiResponse<string>(false, "EndTime must be in HH:mm format"));
|
||||
}
|
||||
|
||||
_context.Entry(waybillEntry).State = EntityState.Modified;
|
||||
|
||||
try
|
||||
{
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
catch (DbUpdateConcurrencyException)
|
||||
{
|
||||
if (!WaybillEntryExists(id))
|
||||
{
|
||||
return NotFound(new ApiResponse<string>(false, "Waybill entry not found"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var updatedEntry = await _context.WaybillEntries
|
||||
.FirstOrDefaultAsync(w => w.Id == waybillEntry.Id);
|
||||
|
||||
return Ok(new ApiResponse<WaybillEntry>(true, "Waybill entry updated successfully", updatedEntry));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return StatusCode(500, new ApiResponse<string>(false, $"Internal server error: {ex.Message}"));
|
||||
}
|
||||
}
|
||||
|
||||
// DELETE: api/waybillentries/5
|
||||
[Authorize]
|
||||
[HttpDelete("{id}")]
|
||||
public async Task<ActionResult<ApiResponse<string>>> DeleteWaybillEntry(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var waybillEntry = await _context.WaybillEntries.FindAsync(id);
|
||||
if (waybillEntry == null)
|
||||
{
|
||||
return NotFound(new ApiResponse<string>(false, "Waybill entry not found"));
|
||||
}
|
||||
|
||||
_context.WaybillEntries.Remove(waybillEntry);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return Ok(new ApiResponse<string>(true, "Waybill entry deleted successfully"));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return StatusCode(500, new ApiResponse<string>(false, $"Internal server error: {ex.Message}"));
|
||||
}
|
||||
}
|
||||
|
||||
private bool WaybillEntryExists(int id)
|
||||
{
|
||||
return _context.WaybillEntries.Any(e => e.Id == id);
|
||||
}
|
||||
|
||||
private bool IsValidTimeFormat(string time)
|
||||
{
|
||||
return System.Text.RegularExpressions.Regex.IsMatch(time, @"^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user