Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions Controllers/UserTaskController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,18 @@ public ActionResult<UserTaskOverviewResponse> GetTaskOverview([FromBody] UserTas
{
var userTasks = _context.UserTasks.Where(t => t.Username == request.Username).ToList();

var laAssigned = userTasks.Count(t => t.TaskType == "LA");
var laCompleted = userTasks.Count(t => t.TaskType == "LA" && t.IsCompleted);
var mrAssigned = userTasks.Count(t => t.TaskType == "MR");
var mrCompleted = userTasks.Count(t => t.TaskType == "MR" && t.IsCompleted);
var lmAssigned = userTasks.Count(t => t.TaskType == "LM");
var lmCompleted = userTasks.Count(t => t.TaskType == "LM" && t.IsCompleted);
// Debug log: print all userTasks for this user
Console.WriteLine($"UserTasks for {request.Username}: {string.Join(", ", userTasks.Select(t => $"{t.TaskType}:{t.IsCompleted}"))}");

var laAssigned = userTasks.Count(t => t.TaskType != null && t.TaskType.ToUpper() == "LA");
var laCompleted = userTasks.Count(t => t.TaskType != null && t.TaskType.ToUpper() == "LA" && t.IsCompleted);
var mrAssigned = userTasks.Count(t => t.TaskType != null && t.TaskType.ToUpper() == "MR");
var mrCompleted = userTasks.Count(t => t.TaskType != null && t.TaskType.ToUpper() == "MR" && t.IsCompleted);
var lmAssigned = userTasks.Count(t => t.TaskType != null && t.TaskType.ToUpper() == "LM");
var lmCompleted = userTasks.Count(t => t.TaskType != null && t.TaskType.ToUpper() == "LM" && t.IsCompleted);

// Debug log: print computed counts
Console.WriteLine($"LA: {laAssigned}, MR: {mrAssigned}, LM: {lmAssigned}, LA Done: {laCompleted}, MR Done: {mrCompleted}, LM Done: {lmCompleted}");

return Ok(new UserTaskOverviewResponse
{
Expand Down
204 changes: 204 additions & 0 deletions Controllers/iteration2/OfficesRatingCardController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using ValuationBackend.Models.iteration2.DTOs;
using ValuationBackend.services.iteration2;

namespace ValuationBackend.Controllers.iteration2
{
[Route("api/[controller]")]
[ApiController]
public class OfficesRatingCardController : ControllerBase
{
private readonly IOfficesRatingCardService _service;
private readonly ILogger<OfficesRatingCardController> _logger;

public OfficesRatingCardController(
IOfficesRatingCardService service,
ILogger<OfficesRatingCardController> logger)
{
_service = service;
_logger = logger;
}

/// <summary>
/// Get all offices rating cards
/// </summary>
[HttpGet]
public async Task<ActionResult<IEnumerable<OfficesRatingCardDto>>> GetAll()
{
try
{
var result = await _service.GetAllAsync();
return Ok(result);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error retrieving all offices rating cards");
return StatusCode(500, "An error occurred while retrieving offices rating cards.");
}
}

/// <summary>
/// Get offices rating card by ID
/// </summary>
[HttpGet("{id}")]
public async Task<ActionResult<OfficesRatingCardDto>> GetById(int id)
{
try
{
var result = await _service.GetByIdAsync(id);
return Ok(result);
}
catch (KeyNotFoundException)
{
return NotFound($"OfficesRatingCard with ID {id} not found.");
}
catch (Exception ex)
{
_logger.LogError(ex, "Error retrieving offices rating card with ID {Id}", id);
return StatusCode(500, "An error occurred while retrieving the offices rating card.");
}
}

/// <summary>
/// Get offices rating card by Asset ID
/// </summary>
[HttpGet("asset/{assetId}")]
public async Task<ActionResult<OfficesRatingCardDto>> GetByAssetId(int assetId)
{
try
{
var result = await _service.GetByAssetIdAsync(assetId);
return Ok(result);
}
catch (KeyNotFoundException)
{
return NotFound($"OfficesRatingCard for Asset ID {assetId} not found.");
}
catch (Exception ex)
{
_logger.LogError(ex, "Error retrieving offices rating card for Asset ID {AssetId}", assetId);
return StatusCode(500, "An error occurred while retrieving the offices rating card.");
}
}

/// <summary>
/// Create a new offices rating card
/// </summary>
[HttpPost("asset/{assetId}")]
public async Task<ActionResult<OfficesRatingCardDto>> Create(int assetId, [FromBody] CreateOfficesRatingCardDto dto)
{
try
{
if (dto == null)
{
return BadRequest("Invalid offices rating card data.");
}

// Ensure the assetId from route matches the one in the body
dto.AssetId = assetId;

if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}

var result = await _service.CreateAsync(dto);
return CreatedAtAction(nameof(GetById), new { id = result.Id }, result);
}
catch (InvalidOperationException ex)
{
return Conflict(ex.Message);
}
catch (KeyNotFoundException ex)
{
return NotFound(ex.Message);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error creating offices rating card for Asset ID {AssetId}", assetId);
return StatusCode(500, "An error occurred while creating the offices rating card.");
}
}

/// <summary>
/// Update an existing offices rating card
/// </summary>
[HttpPut("{id}")]
public async Task<ActionResult<OfficesRatingCardDto>> Update(int id, [FromBody] UpdateOfficesRatingCardDto dto)
{
try
{
if (dto == null)
{
return BadRequest("Invalid offices rating card data.");
}

if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}

var result = await _service.UpdateAsync(id, dto);
return Ok(result);
}
catch (KeyNotFoundException)
{
return NotFound($"OfficesRatingCard with ID {id} not found.");
}
catch (Exception ex)
{
_logger.LogError(ex, "Error updating offices rating card with ID {Id}", id);
return StatusCode(500, "An error occurred while updating the offices rating card.");
}
}

/// <summary>
/// Delete an offices rating card
/// </summary>
[HttpDelete("{id}")]
public async Task<ActionResult> Delete(int id)
{
try
{
var result = await _service.DeleteAsync(id);
if (!result)
{
return NotFound($"OfficesRatingCard with ID {id} not found.");
}

return NoContent();
}
catch (Exception ex)
{
_logger.LogError(ex, "Error deleting offices rating card with ID {Id}", id);
return StatusCode(500, "An error occurred while deleting the offices rating card.");
}
}

/// <summary>
/// Get autofill data for offices rating card
/// </summary>
[HttpGet("autofill/{assetId}")]
public async Task<ActionResult<OfficesRatingCardAutofillDto>> GetAutofillData(int assetId)
{
try
{
var result = await _service.GetAutofillDataAsync(assetId);
return Ok(result);
}
catch (KeyNotFoundException)
{
return NotFound($"Asset with ID {assetId} not found.");
}
catch (Exception ex)
{
_logger.LogError(ex, "Error retrieving autofill data for Asset ID {AssetId}", assetId);
return StatusCode(500, "An error occurred while retrieving autofill data.");
}
}
}
}
3 changes: 3 additions & 0 deletions Data/AppDbContext.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Microsoft.EntityFrameworkCore;
using ValuationBackend.Models;
using ValuationBackend.Models.iteration2.RatingCards;

namespace ValuationBackend.Data
{
Expand Down Expand Up @@ -55,6 +56,8 @@ public AppDbContext(DbContextOptions<AppDbContext> options)

public DbSet<DomesticRatingCard> DomesticRatingCards { get; set; }

public DbSet<OfficesRatingCard> OfficesRatingCards { get; set; }

public DbSet<Asset> Assets { get; set; }

public DbSet<PropertyCategory> PropertyCategories { get; set; }
Expand Down
3 changes: 3 additions & 0 deletions Extensions/RepositoryExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using ValuationBackend.Repositories;
using ValuationBackend.repositories;
using ValuationBackend.repositories.iteration2;

namespace ValuationBackend.Extensions
{
Expand All @@ -22,6 +24,7 @@ public static IServiceCollection AddRepositories(this IServiceCollection service
services.AddScoped<IAssetDivisionRepository, AssetDivisionRepository>();
services.AddScoped<IReconciliationRepository, ReconciliationRepository>();
services.AddScoped<IDomesticRatingCardRepository, DomesticRatingCardRepository>();
services.AddScoped<IOfficesRatingCardRepository, OfficesRatingCardRepository>();
services.AddScoped<ILAMasterfileRepository, LAMasterfileRepository>();
services.AddScoped<IRequestTypeRepository, RequestTypeRepository>();
services.AddScoped<IRequestRepository, RequestRepository>();
Expand Down
2 changes: 2 additions & 0 deletions Extensions/ServiceExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using ValuationBackend.Services;
using ValuationBackend.services.iteration2;

namespace ValuationBackend.Extensions
{
Expand All @@ -15,6 +16,7 @@ public static IServiceCollection AddServices(this IServiceCollection services)
services.AddScoped<ILandMiscellaneousService, LandMiscellaneousService>();
services.AddScoped<ILMBuildingRatesService, LMBuildingRatesService>();
services.AddScoped<IDomesticRatingCardService, DomesticRatingCardService>();
services.AddScoped<IOfficesRatingCardService, OfficesRatingCardService>();
services.AddScoped<ILMRentalEvidenceService, LMRentalEvidenceService>();
services.AddScoped<ILMSalesEvidenceService, LMSalesEvidenceService>();
services.AddScoped<IReportService, ReportService>();
Expand Down
77 changes: 77 additions & 0 deletions Migrations/AddOfficesRatingCardTable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;

namespace ValuationBackend.Migrations
{
public partial class AddOfficesRatingCardTable : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "OfficesRatingCards",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
AssetId = table.Column<int>(nullable: false),
BuildingSelection = table.Column<string>(maxLength: 100, nullable: true),
LocalAuthority = table.Column<string>(maxLength: 200, nullable: true),
LocalAuthorityCode = table.Column<string>(maxLength: 50, nullable: true),
AssessmentNumber = table.Column<string>(maxLength: 50, nullable: true),
NewNumber = table.Column<string>(maxLength: 50, nullable: true),
ObsoleteNumber = table.Column<string>(maxLength: 50, nullable: true),
Owner = table.Column<string>(maxLength: 200, nullable: true),
Description = table.Column<string>(maxLength: 500, nullable: true),
WallType = table.Column<string>(maxLength: 100, nullable: true),
FloorType = table.Column<string>(maxLength: 100, nullable: true),
Conveniences = table.Column<string>(maxLength: 100, nullable: true),
Condition = table.Column<string>(maxLength: 50, nullable: true),
Age = table.Column<int>(nullable: true),
AccessType = table.Column<string>(maxLength: 100, nullable: true),
OfficeGrade = table.Column<string>(maxLength: 50, nullable: true),
ParkingSpace = table.Column<string>(maxLength: 200, nullable: true),
PropertySubCategory = table.Column<string>(maxLength: 100, nullable: true),
PropertyType = table.Column<string>(maxLength: 100, nullable: true),
WardNumber = table.Column<int>(nullable: true),
RoadName = table.Column<string>(maxLength: 200, nullable: true),
Date = table.Column<DateTime>(nullable: true),
Occupier = table.Column<string>(maxLength: 200, nullable: true),
RentPM = table.Column<decimal>(type: "decimal(18,2)", nullable: true),
Terms = table.Column<string>(maxLength: 500, nullable: true),
FloorNumber = table.Column<int>(nullable: true),
CeilingHeight = table.Column<decimal>(type: "decimal(18,2)", nullable: true),
OfficeSuite = table.Column<string>(maxLength: 1000, nullable: true),
TotalArea = table.Column<decimal>(type: "decimal(18,2)", nullable: true),
UsableFloorArea = table.Column<decimal>(type: "decimal(18,2)", nullable: true),
SuggestedRate = table.Column<decimal>(type: "decimal(18,2)", nullable: true),
Notes = table.Column<string>(maxLength: 2000, nullable: true),
CreatedAt = table.Column<DateTime>(nullable: false),
UpdatedAt = table.Column<DateTime>(nullable: true),
CreatedBy = table.Column<string>(nullable: true),
UpdatedBy = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_OfficesRatingCards", x => x.Id);
table.ForeignKey(
name: "FK_OfficesRatingCards_Assets_AssetId",
column: x => x.AssetId,
principalTable: "Assets",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});

migrationBuilder.CreateIndex(
name: "IX_OfficesRatingCards_AssetId",
table: "OfficesRatingCards",
column: "AssetId",
unique: true);
}

protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "OfficesRatingCards");
}
}
}
3 changes: 3 additions & 0 deletions Models/UserTask.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using System.ComponentModel.DataAnnotations.Schema;

namespace ValuationBackend.Models
{
[Table("UserTasks")]
public class UserTask
{
public int Id { get; set; }
Expand Down
Loading