Changed the Approve task API to Able update compeleted task field

This commit is contained in:
ashutosh.nehete 2025-06-14 11:30:11 +05:30
parent 453150e24d
commit d841cd2385
8 changed files with 3473 additions and 17 deletions

View File

@ -68,6 +68,7 @@ namespace Marco.Pms.DataAccess.Data
public DbSet<Document> Documents { get; set; } public DbSet<Document> Documents { get; set; }
public DbSet<TicketTag> TicketTags { get; set; } public DbSet<TicketTag> TicketTags { get; set; }
public DbSet<WorkCategoryMaster> WorkCategoryMasters { get; set; } public DbSet<WorkCategoryMaster> WorkCategoryMasters { get; set; }
public DbSet<WorkStatusMaster> WorkStatusMasters { get; set; }
public DbSet<Contact> Contacts { get; set; } public DbSet<Contact> Contacts { get; set; }
public DbSet<ContactCategoryMaster> ContactCategoryMasters { get; set; } public DbSet<ContactCategoryMaster> ContactCategoryMasters { get; set; }
public DbSet<ContactEmail> ContactsEmails { get; set; } public DbSet<ContactEmail> ContactsEmails { get; set; }

View File

@ -0,0 +1,81 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Marco.Pms.DataAccess.Migrations
{
/// <inheritdoc />
public partial class Added_WorkStatusMaster_Table_And_Forigne_Key_In_TaskAllocation : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "TaskStatus",
table: "TaskAllocations");
migrationBuilder.AddColumn<Guid>(
name: "WorkStatusId",
table: "TaskAllocations",
type: "char(36)",
nullable: true,
collation: "ascii_general_ci");
migrationBuilder.CreateTable(
name: "WorkStatusMasters",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Name = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Description = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
IsSystem = table.Column<bool>(type: "tinyint(1)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_WorkStatusMasters", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateIndex(
name: "IX_TaskAllocations_WorkStatusId",
table: "TaskAllocations",
column: "WorkStatusId");
migrationBuilder.AddForeignKey(
name: "FK_TaskAllocations_WorkStatusMasters_WorkStatusId",
table: "TaskAllocations",
column: "WorkStatusId",
principalTable: "WorkStatusMasters",
principalColumn: "Id");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_TaskAllocations_WorkStatusMasters_WorkStatusId",
table: "TaskAllocations");
migrationBuilder.DropTable(
name: "WorkStatusMasters");
migrationBuilder.DropIndex(
name: "IX_TaskAllocations_WorkStatusId",
table: "TaskAllocations");
migrationBuilder.DropColumn(
name: "WorkStatusId",
table: "TaskAllocations");
migrationBuilder.AddColumn<int>(
name: "TaskStatus",
table: "TaskAllocations",
type: "int",
nullable: false,
defaultValue: 0);
}
}
}

View File

@ -55,15 +55,15 @@ namespace Marco.Pms.DataAccess.Migrations
b.Property<DateTime?>("ReportedDate") b.Property<DateTime?>("ReportedDate")
.HasColumnType("datetime(6)"); .HasColumnType("datetime(6)");
b.Property<int>("TaskStatus")
.HasColumnType("int");
b.Property<Guid>("TenantId") b.Property<Guid>("TenantId")
.HasColumnType("char(36)"); .HasColumnType("char(36)");
b.Property<Guid>("WorkItemId") b.Property<Guid>("WorkItemId")
.HasColumnType("char(36)"); .HasColumnType("char(36)");
b.Property<Guid?>("WorkStatusId")
.HasColumnType("char(36)");
b.HasKey("Id"); b.HasKey("Id");
b.HasIndex("ApprovedById"); b.HasIndex("ApprovedById");
@ -76,6 +76,8 @@ namespace Marco.Pms.DataAccess.Migrations
b.HasIndex("WorkItemId"); b.HasIndex("WorkItemId");
b.HasIndex("WorkStatusId");
b.ToTable("TaskAllocations"); b.ToTable("TaskAllocations");
}); });
@ -1919,6 +1921,28 @@ namespace Marco.Pms.DataAccess.Migrations
}); });
}); });
modelBuilder.Entity("Marco.Pms.Model.Master.WorkStatusMaster", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("longtext");
b.Property<bool>("IsSystem")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.HasKey("Id");
b.ToTable("WorkStatusMasters");
});
modelBuilder.Entity("Marco.Pms.Model.Projects.Building", b => modelBuilder.Entity("Marco.Pms.Model.Projects.Building", b =>
{ {
b.Property<Guid>("Id") b.Property<Guid>("Id")
@ -2457,6 +2481,10 @@ namespace Marco.Pms.DataAccess.Migrations
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired(); .IsRequired();
b.HasOne("Marco.Pms.Model.Master.WorkStatusMaster", "WorkStatus")
.WithMany()
.HasForeignKey("WorkStatusId");
b.Navigation("ApprovedBy"); b.Navigation("ApprovedBy");
b.Navigation("Employee"); b.Navigation("Employee");
@ -2466,6 +2494,8 @@ namespace Marco.Pms.DataAccess.Migrations
b.Navigation("Tenant"); b.Navigation("Tenant");
b.Navigation("WorkItem"); b.Navigation("WorkItem");
b.Navigation("WorkStatus");
}); });
modelBuilder.Entity("Marco.Pms.Model.Activities.TaskComment", b => modelBuilder.Entity("Marco.Pms.Model.Activities.TaskComment", b =>

View File

@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using Marco.Pms.Model.Dtos.Activities;
using Marco.Pms.Model.Employees; using Marco.Pms.Model.Employees;
using Marco.Pms.Model.Master;
using Marco.Pms.Model.Projects; using Marco.Pms.Model.Projects;
using Marco.Pms.Model.Utilities; using Marco.Pms.Model.Utilities;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
@ -18,14 +18,13 @@ namespace Marco.Pms.Model.Activities
public double CompletedTask { get; set; } public double CompletedTask { get; set; }
public DateTime? ReportedDate { get; set; } public DateTime? ReportedDate { get; set; }
public DateTime? ApprovedDate { get; set; } public DateTime? ApprovedDate { get; set; }
public TASK_STATUS TaskStatus { get; set; } = TASK_STATUS.PENDING_UC;
public string? Description { get; set; } public string? Description { get; set; }
//public int? WorkItemMappingId { get; set; } public Guid? WorkStatusId { get; set; }
//[ForeignKey("WorkItemMappingId")] [ForeignKey("WorkStatusId")]
//[ValidateNever] [ValidateNever]
//public WorkItemMapping? WorkItemMapping { get; set; } public WorkStatusMaster? WorkStatus { get; set; }
public Guid AssignedBy { get; set; } //Employee Id public Guid AssignedBy { get; set; } //Employee Id
[ForeignKey("AssignedBy")] [ForeignKey("AssignedBy")]

View File

@ -0,0 +1,9 @@
namespace Marco.Pms.Model.Dtos.Activities
{
public class ApproveTaskDto
{
public Guid Id { get; set; }
public Guid WorkStatus { get; set; }
public long ApprovedTask { get; set; }
}
}

View File

@ -0,0 +1,10 @@
namespace Marco.Pms.Model.Master
{
public class WorkStatusMaster
{
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public bool IsSystem { get; set; } = false;
}
}

View File

@ -346,8 +346,8 @@ namespace MarcoBMS.Services.Controllers
/// </summary> /// </summary>
/// <param name="id">The ID of the task to approve.</param> /// <param name="id">The ID of the task to approve.</param>
/// <returns>Returns success or error response based on operation outcome.</returns> /// <returns>Returns success or error response based on operation outcome.</returns>
[HttpPost("approve/{id}")] [HttpPost("approve")]
public async Task<IActionResult> ApproveTask(Guid id) public async Task<IActionResult> ApproveTask(ApproveTaskDto approveTask)
{ {
// Get the current tenant ID from the logged-in user context // Get the current tenant ID from the logged-in user context
Guid tenantId = _userHelper.GetTenantId(); Guid tenantId = _userHelper.GetTenantId();
@ -355,16 +355,17 @@ namespace MarcoBMS.Services.Controllers
// Get the currently logged-in employee // Get the currently logged-in employee
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
_logger.LogInfo("Employee {EmployeeId} is attempting to approve Task {TaskId}", loggedInEmployee.Id, id); _logger.LogInfo("Employee {EmployeeId} is attempting to approve Task {TaskId}", loggedInEmployee.Id, approveTask.Id);
// Fetch the task allocation by ID and tenant // Fetch the task allocation by ID and tenant
var taskAllocation = await _context.TaskAllocations var taskAllocation = await _context.TaskAllocations
.FirstOrDefaultAsync(t => t.Id == id && t.TenantId == tenantId && t.ReportedDate != null); .Include(t => t.WorkItem)
.FirstOrDefaultAsync(t => t.Id == approveTask.Id && t.TenantId == tenantId && t.ReportedDate != null);
// If the task allocation does not exist // If the task allocation does not exist
if (taskAllocation == null) if (taskAllocation == null)
{ {
_logger.LogWarning("Task {TaskId} not found for Tenant {TenantId} by Employee {EmployeeId}", id, tenantId, loggedInEmployee.Id); _logger.LogWarning("Task {TaskId} not found for Tenant {TenantId} by Employee {EmployeeId}", approveTask.Id, tenantId, loggedInEmployee.Id);
return NotFound(ApiResponse<object>.ErrorResponse("Task not found", "Task not found", 404)); return NotFound(ApiResponse<object>.ErrorResponse("Task not found", "Task not found", 404));
} }
@ -372,19 +373,31 @@ namespace MarcoBMS.Services.Controllers
var hasPermission = await _permissionServices.HasPermission(Approve_Task, loggedInEmployee.Id); var hasPermission = await _permissionServices.HasPermission(Approve_Task, loggedInEmployee.Id);
if (!hasPermission) if (!hasPermission)
{ {
_logger.LogWarning("Employee {EmployeeId} attempted to approve Task {TaskId} without proper permissions", loggedInEmployee.Id, id); _logger.LogWarning("Employee {EmployeeId} attempted to approve Task {TaskId} without proper permissions", loggedInEmployee.Id, approveTask.Id);
return StatusCode(403, ApiResponse<object>.ErrorResponse("You don't have access", "Don't have access to take action", 403)); return StatusCode(403, ApiResponse<object>.ErrorResponse("You don't have access", "Don't have access to take action", 403));
} }
// Update completed work in the work item if applicable
if (taskAllocation.WorkItem != null)
{
if (taskAllocation.CompletedTask != 0)
{
taskAllocation.WorkItem.CompletedWork -= taskAllocation.CompletedTask;
}
taskAllocation.WorkItem.CompletedWork += approveTask.ApprovedTask;
}
// Update task allocation with approval details // Update task allocation with approval details
taskAllocation.ApprovedById = loggedInEmployee.Id; taskAllocation.ApprovedById = loggedInEmployee.Id;
taskAllocation.ApprovedDate = DateTime.UtcNow; taskAllocation.ApprovedDate = DateTime.UtcNow;
taskAllocation.TaskStatus = TASK_STATUS.APPROVED; taskAllocation.WorkStatusId = approveTask.WorkStatus;
taskAllocation.CompletedTask = approveTask.ApprovedTask;
// Save changes to the database // Save changes to the database
await _context.SaveChangesAsync(); await _context.SaveChangesAsync();
_logger.LogInfo("Employee {EmployeeId} successfully approved Task {TaskId}", loggedInEmployee.Id, id); _logger.LogInfo("Employee {EmployeeId} successfully approved Task {TaskId}", loggedInEmployee.Id, approveTask.Id);
// Return success response // Return success response
return Ok(ApiResponse<object>.SuccessResponse("Task has been approved", "Task has been approved", 200)); return Ok(ApiResponse<object>.SuccessResponse("Task has been approved", "Task has been approved", 200));