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>>> GetWaybillEntries() { try { var entries = await _context.WaybillEntries .OrderByDescending(w => w.Date) .ThenBy(w => w.StartTime) .ToListAsync(); return Ok(new ApiResponse>(true, "Waybill entries retrieved successfully", entries)); } catch (Exception ex) { return StatusCode(500, new ApiResponse(false, $"Internal server error: {ex.Message}")); } } // GET: api/waybillentries/5 [Authorize] [HttpGet("{id}")] public async Task>> GetWaybillEntry(int id) { try { var waybillEntry = await _context.WaybillEntries .FirstOrDefaultAsync(w => w.Id == id); if (waybillEntry == null) { return NotFound(new ApiResponse(false, "Waybill entry not found")); } return Ok(new ApiResponse(true, "Waybill entry retrieved successfully", waybillEntry)); } catch (Exception ex) { return StatusCode(500, new ApiResponse(false, $"Internal server error: {ex.Message}")); } } // POST: api/waybillentries [Authorize] [HttpPost] public async Task>> PostWaybillEntry(WaybillEntry waybillEntry) { try { if (waybillEntry.VehicleId <= 0) { return BadRequest(new ApiResponse(false, "Valid VehicleId is required")); } if (waybillEntry.OrderId <= 0) { return BadRequest(new ApiResponse(false, "Valid OrderId is required")); } var vehicleExists = await _context.Vehicles.AnyAsync(v => v.Id == waybillEntry.VehicleId); if (!vehicleExists) { return BadRequest(new ApiResponse(false, "Vehicle not found")); } var orderExists = await _context.Orders.AnyAsync(o => o.Id == waybillEntry.OrderId); if (!orderExists) { return BadRequest(new ApiResponse(false, "Order not found")); } if (string.IsNullOrEmpty(waybillEntry.StartTime) || !IsValidTimeFormat(waybillEntry.StartTime)) { return BadRequest(new ApiResponse(false, "StartTime must be in HH:mm format")); } if (string.IsNullOrEmpty(waybillEntry.EndTime) || !IsValidTimeFormat(waybillEntry.EndTime)) { return BadRequest(new ApiResponse(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(true, "Waybill entry created successfully", createdEntry)); } catch (Exception ex) { return StatusCode(500, new ApiResponse(false, $"Internal server error: {ex.Message}")); } } // PUT: api/waybillentries/5 [Authorize] [HttpPut("{id}")] public async Task>> PutWaybillEntry(int id, WaybillEntry waybillEntry) { try { if (id != waybillEntry.Id) { return BadRequest(new ApiResponse(false, "ID mismatch")); } if (waybillEntry.VehicleId <= 0) { return BadRequest(new ApiResponse(false, "Valid VehicleId is required")); } if (waybillEntry.OrderId <= 0) { return BadRequest(new ApiResponse(false, "Valid OrderId is required")); } var vehicleExists = await _context.Vehicles.AnyAsync(v => v.Id == waybillEntry.VehicleId); if (!vehicleExists) { return BadRequest(new ApiResponse(false, "Vehicle not found")); } var orderExists = await _context.Orders.AnyAsync(o => o.Id == waybillEntry.OrderId); if (!orderExists) { return BadRequest(new ApiResponse(false, "Order not found")); } if (string.IsNullOrEmpty(waybillEntry.StartTime) || !IsValidTimeFormat(waybillEntry.StartTime)) { return BadRequest(new ApiResponse(false, "StartTime must be in HH:mm format")); } if (string.IsNullOrEmpty(waybillEntry.EndTime) || !IsValidTimeFormat(waybillEntry.EndTime)) { return BadRequest(new ApiResponse(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(false, "Waybill entry not found")); } else { throw; } } var updatedEntry = await _context.WaybillEntries .FirstOrDefaultAsync(w => w.Id == waybillEntry.Id); return Ok(new ApiResponse(true, "Waybill entry updated successfully", updatedEntry)); } catch (Exception ex) { return StatusCode(500, new ApiResponse(false, $"Internal server error: {ex.Message}")); } } // DELETE: api/waybillentries/5 [Authorize] [HttpDelete("{id}")] public async Task>> DeleteWaybillEntry(int id) { try { var waybillEntry = await _context.WaybillEntries.FindAsync(id); if (waybillEntry == null) { return NotFound(new ApiResponse(false, "Waybill entry not found")); } _context.WaybillEntries.Remove(waybillEntry); await _context.SaveChangesAsync(); return Ok(new ApiResponse(true, "Waybill entry deleted successfully")); } catch (Exception ex) { return StatusCode(500, new ApiResponse(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]$"); } } }