Added the project branch in job ticket table
This commit is contained in:
parent
dad135571d
commit
4108915b92
@ -1286,8 +1286,8 @@ namespace Marco.Pms.DataAccess.Data
|
|||||||
new JobStatus { Id = Guid.Parse("32d76a02-8f44-4aa0-9b66-c3716c45a918"), Name = "New", DisplayName = "New", Level = 1 },
|
new JobStatus { Id = Guid.Parse("32d76a02-8f44-4aa0-9b66-c3716c45a918"), Name = "New", DisplayName = "New", Level = 1 },
|
||||||
new JobStatus { Id = Guid.Parse("cfa1886d-055f-4ded-84c6-42a2a8a14a66"), Name = "Assigned", DisplayName = "Assigned", Level = 2 },
|
new JobStatus { Id = Guid.Parse("cfa1886d-055f-4ded-84c6-42a2a8a14a66"), Name = "Assigned", DisplayName = "Assigned", Level = 2 },
|
||||||
new JobStatus { Id = Guid.Parse("5a6873a5-fed7-4745-a52f-8f61bf3bd72d"), Name = "In Progress", DisplayName = "In Progress", Level = 3 },
|
new JobStatus { Id = Guid.Parse("5a6873a5-fed7-4745-a52f-8f61bf3bd72d"), Name = "In Progress", DisplayName = "In Progress", Level = 3 },
|
||||||
new JobStatus { Id = Guid.Parse("aab71020-2fb8-44d9-9430-c9a7e9bf33b0"), Name = "Review", DisplayName = "Review", Level = 4 },
|
new JobStatus { Id = Guid.Parse("aab71020-2fb8-44d9-9430-c9a7e9bf33b0"), Name = "Work Done", DisplayName = "Work Done", Level = 4 },
|
||||||
new JobStatus { Id = Guid.Parse("ed10ab57-dbaa-4ca5-8ecd-56745dcbdbd7"), Name = "Done", DisplayName = "Done", Level = 5 },
|
new JobStatus { Id = Guid.Parse("ed10ab57-dbaa-4ca5-8ecd-56745dcbdbd7"), Name = "Review Done", DisplayName = "Review Done", Level = 5 },
|
||||||
new JobStatus { Id = Guid.Parse("3ddeefb5-ae3c-4e10-a922-35e0a452bb69"), Name = "Closed", DisplayName = "Closed", Level = 6 },
|
new JobStatus { Id = Guid.Parse("3ddeefb5-ae3c-4e10-a922-35e0a452bb69"), Name = "Closed", DisplayName = "Closed", Level = 6 },
|
||||||
new JobStatus { Id = Guid.Parse("75a0c8b8-9c6a-41af-80bf-b35bab722eb2"), Name = "On Hold", DisplayName = "On Hold", Level = 7 }
|
new JobStatus { Id = Guid.Parse("75a0c8b8-9c6a-41af-80bf-b35bab722eb2"), Name = "On Hold", DisplayName = "On Hold", Level = 7 }
|
||||||
);
|
);
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,78 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Marco.Pms.DataAccess.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class Added_ProjectBranch_As_ForignKey_In_JobTickets_Table : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<Guid>(
|
||||||
|
name: "ProjectBranchId",
|
||||||
|
table: "JobTickets",
|
||||||
|
type: "char(36)",
|
||||||
|
nullable: true,
|
||||||
|
collation: "ascii_general_ci");
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "JobStatus",
|
||||||
|
keyColumn: "Id",
|
||||||
|
keyValue: new Guid("aab71020-2fb8-44d9-9430-c9a7e9bf33b0"),
|
||||||
|
columns: new[] { "DisplayName", "Name" },
|
||||||
|
values: new object[] { "Work Done", "Work Done" });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "JobStatus",
|
||||||
|
keyColumn: "Id",
|
||||||
|
keyValue: new Guid("ed10ab57-dbaa-4ca5-8ecd-56745dcbdbd7"),
|
||||||
|
columns: new[] { "DisplayName", "Name" },
|
||||||
|
values: new object[] { "Review Done", "Review Done" });
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_JobTickets_ProjectBranchId",
|
||||||
|
table: "JobTickets",
|
||||||
|
column: "ProjectBranchId");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "FK_JobTickets_ProjectBranches_ProjectBranchId",
|
||||||
|
table: "JobTickets",
|
||||||
|
column: "ProjectBranchId",
|
||||||
|
principalTable: "ProjectBranches",
|
||||||
|
principalColumn: "Id");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "FK_JobTickets_ProjectBranches_ProjectBranchId",
|
||||||
|
table: "JobTickets");
|
||||||
|
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "IX_JobTickets_ProjectBranchId",
|
||||||
|
table: "JobTickets");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "ProjectBranchId",
|
||||||
|
table: "JobTickets");
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "JobStatus",
|
||||||
|
keyColumn: "Id",
|
||||||
|
keyValue: new Guid("aab71020-2fb8-44d9-9430-c9a7e9bf33b0"),
|
||||||
|
columns: new[] { "DisplayName", "Name" },
|
||||||
|
values: new object[] { "Review", "Review" });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "JobStatus",
|
||||||
|
keyColumn: "Id",
|
||||||
|
keyValue: new Guid("ed10ab57-dbaa-4ca5-8ecd-56745dcbdbd7"),
|
||||||
|
columns: new[] { "DisplayName", "Name" },
|
||||||
|
values: new object[] { "Done", "Done" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5261,16 +5261,16 @@ namespace Marco.Pms.DataAccess.Migrations
|
|||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("aab71020-2fb8-44d9-9430-c9a7e9bf33b0"),
|
Id = new Guid("aab71020-2fb8-44d9-9430-c9a7e9bf33b0"),
|
||||||
DisplayName = "Review",
|
DisplayName = "Work Done",
|
||||||
Level = 4,
|
Level = 4,
|
||||||
Name = "Review"
|
Name = "Work Done"
|
||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("ed10ab57-dbaa-4ca5-8ecd-56745dcbdbd7"),
|
Id = new Guid("ed10ab57-dbaa-4ca5-8ecd-56745dcbdbd7"),
|
||||||
DisplayName = "Done",
|
DisplayName = "Review Done",
|
||||||
Level = 5,
|
Level = 5,
|
||||||
Name = "Done"
|
Name = "Review Done"
|
||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
@ -5494,6 +5494,9 @@ namespace Marco.Pms.DataAccess.Migrations
|
|||||||
b.Property<bool>("IsActive")
|
b.Property<bool>("IsActive")
|
||||||
.HasColumnType("tinyint(1)");
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<Guid?>("ProjectBranchId")
|
||||||
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.Property<Guid>("ProjectId")
|
b.Property<Guid>("ProjectId")
|
||||||
.HasColumnType("char(36)");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
@ -5527,6 +5530,8 @@ namespace Marco.Pms.DataAccess.Migrations
|
|||||||
|
|
||||||
b.HasIndex("CreatedById");
|
b.HasIndex("CreatedById");
|
||||||
|
|
||||||
|
b.HasIndex("ProjectBranchId");
|
||||||
|
|
||||||
b.HasIndex("ProjectId");
|
b.HasIndex("ProjectId");
|
||||||
|
|
||||||
b.HasIndex("StatusId");
|
b.HasIndex("StatusId");
|
||||||
@ -8478,6 +8483,10 @@ namespace Marco.Pms.DataAccess.Migrations
|
|||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Marco.Pms.Model.ServiceProject.ProjectBranch", "ProjectBranch")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ProjectBranchId");
|
||||||
|
|
||||||
b.HasOne("Marco.Pms.Model.ServiceProject.ServiceProject", "Project")
|
b.HasOne("Marco.Pms.Model.ServiceProject.ServiceProject", "Project")
|
||||||
.WithMany()
|
.WithMany()
|
||||||
.HasForeignKey("ProjectId")
|
.HasForeignKey("ProjectId")
|
||||||
@ -8504,6 +8513,8 @@ namespace Marco.Pms.DataAccess.Migrations
|
|||||||
|
|
||||||
b.Navigation("Project");
|
b.Navigation("Project");
|
||||||
|
|
||||||
|
b.Navigation("ProjectBranch");
|
||||||
|
|
||||||
b.Navigation("Status");
|
b.Navigation("Status");
|
||||||
|
|
||||||
b.Navigation("Tenant");
|
b.Navigation("Tenant");
|
||||||
|
|||||||
@ -8,6 +8,7 @@ namespace Marco.Pms.Model.Dtos.ServiceProject
|
|||||||
public required string Title { get; set; }
|
public required string Title { get; set; }
|
||||||
public required string Description { get; set; }
|
public required string Description { get; set; }
|
||||||
public required Guid ProjectId { get; set; }
|
public required Guid ProjectId { get; set; }
|
||||||
|
public Guid? ProjectBranchId { get; set; }
|
||||||
public List<BasicEmployeeDto>? Assignees { get; set; }
|
public List<BasicEmployeeDto>? Assignees { get; set; }
|
||||||
public required DateTime StartDate { get; set; }
|
public required DateTime StartDate { get; set; }
|
||||||
public required DateTime DueDate { get; set; }
|
public required DateTime DueDate { get; set; }
|
||||||
|
|||||||
@ -7,7 +7,6 @@ namespace Marco.Pms.Model.Dtos.ServiceProject
|
|||||||
{
|
{
|
||||||
public string? Title { get; set; }
|
public string? Title { get; set; }
|
||||||
public string? Description { get; set; }
|
public string? Description { get; set; }
|
||||||
public Guid ProjectId { get; set; }
|
|
||||||
public Guid StatusId { get; set; }
|
public Guid StatusId { get; set; }
|
||||||
public List<BasicEmployeeDto>? Assignees { get; set; }
|
public List<BasicEmployeeDto>? Assignees { get; set; }
|
||||||
public DateTime StartDate { get; set; }
|
public DateTime StartDate { get; set; }
|
||||||
|
|||||||
@ -17,6 +17,11 @@ namespace Marco.Pms.Model.ServiceProject
|
|||||||
[ValidateNever]
|
[ValidateNever]
|
||||||
[ForeignKey("ProjectId")]
|
[ForeignKey("ProjectId")]
|
||||||
public ServiceProject? Project { get; set; }
|
public ServiceProject? Project { get; set; }
|
||||||
|
public Guid? ProjectBranchId { get; set; }
|
||||||
|
|
||||||
|
[ValidateNever]
|
||||||
|
[ForeignKey("ProjectBranchId")]
|
||||||
|
public ProjectBranch? ProjectBranch { get; set; }
|
||||||
public Guid StatusId { get; set; }
|
public Guid StatusId { get; set; }
|
||||||
|
|
||||||
[ValidateNever]
|
[ValidateNever]
|
||||||
|
|||||||
@ -0,0 +1,9 @@
|
|||||||
|
namespace Marco.Pms.Model.ViewModels.ServiceProject
|
||||||
|
{
|
||||||
|
public class BasicProjectBranchVM
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public string? BranchName { get; set; }
|
||||||
|
public string? BranchType { get; set; } // HQ, ATMs, Bank Branches, Overcounter desk
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,8 +6,5 @@
|
|||||||
public string? Name { get; set; }
|
public string? Name { get; set; }
|
||||||
public string? ShortName { get; set; }
|
public string? ShortName { get; set; }
|
||||||
public DateTime AssignedDate { get; set; }
|
public DateTime AssignedDate { get; set; }
|
||||||
public string? ContactName { get; set; }
|
|
||||||
public string? ContactPhone { get; set; }
|
|
||||||
public string? ContactEmail { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,7 @@ namespace Marco.Pms.Model.ViewModels.ServiceProject
|
|||||||
public string? Description { get; set; }
|
public string? Description { get; set; }
|
||||||
public string? JobTicketUId { get; set; }
|
public string? JobTicketUId { get; set; }
|
||||||
public BasicServiceProjectVM? Project { get; set; }
|
public BasicServiceProjectVM? Project { get; set; }
|
||||||
|
public BasicProjectBranchVM? ProjectBranch { get; set; }
|
||||||
public List<BasicEmployeeVM>? Assignees { get; set; }
|
public List<BasicEmployeeVM>? Assignees { get; set; }
|
||||||
public JobStatus? Status { get; set; }
|
public JobStatus? Status { get; set; }
|
||||||
public DateTime StartDate { get; set; }
|
public DateTime StartDate { get; set; }
|
||||||
|
|||||||
@ -204,6 +204,7 @@ namespace Marco.Pms.Services.MappingProfiles
|
|||||||
CreateMap<ProjectBranchDto, ProjectBranch>();
|
CreateMap<ProjectBranchDto, ProjectBranch>();
|
||||||
CreateMap<ProjectBranch, ProjectBranchVM>();
|
CreateMap<ProjectBranch, ProjectBranchVM>();
|
||||||
CreateMap<ProjectBranch, ProjectBranchDetailsVM>();
|
CreateMap<ProjectBranch, ProjectBranchDetailsVM>();
|
||||||
|
CreateMap<ProjectBranch, BasicProjectBranchVM>();
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
//#region ======================================================= Talking Points =======================================================
|
//#region ======================================================= Talking Points =======================================================
|
||||||
|
|||||||
@ -96,7 +96,8 @@ namespace Marco.Pms.Services.Service
|
|||||||
{
|
{
|
||||||
var normalizedSearch = searchString.Trim().ToLowerInvariant();
|
var normalizedSearch = searchString.Trim().ToLowerInvariant();
|
||||||
serviceProjectQuery = serviceProjectQuery
|
serviceProjectQuery = serviceProjectQuery
|
||||||
.Where(sp => sp.Name.ToLower().Contains(normalizedSearch));
|
.Where(sp => sp.Name.ToLower().Contains(normalizedSearch) ||
|
||||||
|
(!string.IsNullOrWhiteSpace(sp.ShortName) && sp.ShortName.ToLower().Contains(normalizedSearch)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate total count and pages for pagination metadata
|
// Calculate total count and pages for pagination metadata
|
||||||
@ -756,7 +757,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
// Validate existence of related service project for given tenant
|
// Validate existence of related service project for given tenant
|
||||||
var serviceProject = await _context.ServiceProjects
|
var serviceProject = await _context.ServiceProjects
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.FirstOrDefaultAsync(sp => sp.Id == model.ProjectId && sp.TenantId == tenantId);
|
.FirstOrDefaultAsync(sp => sp.Id == model.ProjectId && sp.TenantId == tenantId && sp.IsActive);
|
||||||
|
|
||||||
if (serviceProject == null)
|
if (serviceProject == null)
|
||||||
{
|
{
|
||||||
@ -1533,6 +1534,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
.Include(jt => jt.Status)
|
.Include(jt => jt.Status)
|
||||||
.Include(jt => jt.Project)
|
.Include(jt => jt.Project)
|
||||||
.Include(jt => jt.CreatedBy).ThenInclude(e => e!.JobRole)
|
.Include(jt => jt.CreatedBy).ThenInclude(e => e!.JobRole)
|
||||||
|
.Include(jt => jt.ProjectBranch)
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.FirstOrDefaultAsync(jt =>
|
.FirstOrDefaultAsync(jt =>
|
||||||
jt.Id == id &&
|
jt.Id == id &&
|
||||||
@ -1730,6 +1732,40 @@ namespace Marco.Pms.Services.Service
|
|||||||
return ApiResponse<object>.ErrorResponse("Service project not found", "Service project not found or inactive", 404);
|
return ApiResponse<object>.ErrorResponse("Service project not found", "Service project not found or inactive", 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (model.ProjectBranchId.HasValue)
|
||||||
|
{
|
||||||
|
// Log the attempt to fetch project branch
|
||||||
|
_logger.LogInfo("Attempting to fetch project branch with ID: {ProjectBranchId}, Project ID: {ProjectId}, Tenant ID: {TenantId}",
|
||||||
|
model.ProjectBranchId, serviceProject.Id, tenantId);
|
||||||
|
|
||||||
|
// Query project branch with all necessary filters
|
||||||
|
var projectBranch = await _context.ProjectBranches
|
||||||
|
.AsNoTracking()
|
||||||
|
.FirstOrDefaultAsync(pb =>
|
||||||
|
pb.Id == model.ProjectBranchId.Value &&
|
||||||
|
pb.ProjectId == serviceProject.Id &&
|
||||||
|
pb.TenantId == tenantId &&
|
||||||
|
pb.IsActive);
|
||||||
|
|
||||||
|
// Check if project branch exists
|
||||||
|
if (projectBranch == null)
|
||||||
|
{
|
||||||
|
// Log the failure to find project branch
|
||||||
|
_logger.LogWarning("Project branch not found for ID: {ProjectBranchId}, Project ID: {ProjectId}, Tenant ID: {TenantId}",
|
||||||
|
model.ProjectBranchId, serviceProject.Id, tenantId);
|
||||||
|
|
||||||
|
// Return a structured error response
|
||||||
|
return ApiResponse<object>.ErrorResponse(
|
||||||
|
"Project branch not found",
|
||||||
|
"The specified project branch does not exist or is not active for the given project and tenant.",
|
||||||
|
404);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log successful retrieval
|
||||||
|
_logger.LogInfo("Successfully retrieved project branch with ID: {ProjectBranchId}", model.ProjectBranchId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var hasAssignees = model.Assignees?.Any(a => a.IsActive) ?? false;
|
var hasAssignees = model.Assignees?.Any(a => a.IsActive) ?? false;
|
||||||
|
|
||||||
string uIDPrefix = $"JT/{DateTime.Now:MMyy}";
|
string uIDPrefix = $"JT/{DateTime.Now:MMyy}";
|
||||||
@ -1990,7 +2026,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
var projectTask = Task.Run(async () =>
|
var projectTask = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||||
return await context.ServiceProjects.FirstOrDefaultAsync(sp => sp.Id == model.ProjectId && sp.TenantId == tenantId && sp.IsActive);
|
return await context.ServiceProjects.FirstOrDefaultAsync(sp => sp.Id == jobTicket.ProjectId && sp.TenantId == tenantId && sp.IsActive);
|
||||||
});
|
});
|
||||||
var statusTask = Task.Run(async () =>
|
var statusTask = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
@ -2003,7 +2039,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
// Validate existence of foreign entities
|
// Validate existence of foreign entities
|
||||||
if (projectTask.Result == null)
|
if (projectTask.Result == null)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Service project not found during job ticket update. ProjectId: {ProjectId}, TenantId: {TenantId}", model.ProjectId, tenantId);
|
_logger.LogWarning("Service project not found during job ticket update. ProjectId: {ProjectId}, TenantId: {TenantId}", jobTicket.ProjectId, tenantId);
|
||||||
return ApiResponse<object>.ErrorResponse("Service project not found", "Service project not found", 404);
|
return ApiResponse<object>.ErrorResponse("Service project not found", "Service project not found", 404);
|
||||||
}
|
}
|
||||||
if (statusTask.Result == null)
|
if (statusTask.Result == null)
|
||||||
@ -2197,13 +2233,13 @@ namespace Marco.Pms.Services.Service
|
|||||||
{
|
{
|
||||||
await transaction.RollbackAsync();
|
await transaction.RollbackAsync();
|
||||||
_logger.LogError(dbEx, "Database error while updating job ticket for project {ProjectId} by employee {EmployeeId} in tenant {TenantId}",
|
_logger.LogError(dbEx, "Database error while updating job ticket for project {ProjectId} by employee {EmployeeId} in tenant {TenantId}",
|
||||||
model.ProjectId, loggedInEmployee.Id, tenantId);
|
jobTicket.ProjectId, loggedInEmployee.Id, tenantId);
|
||||||
return ApiResponse<object>.ErrorResponse("Database Error", "An error occurred while saving data to the database.", 500);
|
return ApiResponse<object>.ErrorResponse("Database Error", "An error occurred while saving data to the database.", 500);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "Unhandled exception while updating job ticket for project {ProjectId} by employee {EmployeeId} in tenant {TenantId}",
|
_logger.LogError(ex, "Unhandled exception while updating job ticket for project {ProjectId} by employee {EmployeeId} in tenant {TenantId}",
|
||||||
model.ProjectId, loggedInEmployee.Id, tenantId);
|
jobTicket.ProjectId, loggedInEmployee.Id, tenantId);
|
||||||
return ApiResponse<object>.ErrorResponse("Internal Server Error", "An unexpected error occurred.", 500);
|
return ApiResponse<object>.ErrorResponse("Internal Server Error", "An unexpected error occurred.", 500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user