Compare commits
32 Commits
cb2856b2df
...
2ed0e6e5b6
| Author | SHA1 | Date | |
|---|---|---|---|
| 2ed0e6e5b6 | |||
| 72a92417b5 | |||
| 3dfde6d9a5 | |||
| 4164c7d761 | |||
| 303f326773 | |||
| e2956c0c8c | |||
| 39378f3a88 | |||
| caacb43aa8 | |||
| 29ea1698bc | |||
| 793877b8f8 | |||
| f47586710b | |||
| b21d30c18e | |||
| d78a2fe3b2 | |||
| 6ebc74499f | |||
| 17ae02a0b3 | |||
| 9d5535edf1 | |||
| c689f2dfd8 | |||
| 5c019a2ff6 | |||
| cb185db4f3 | |||
| 1a51860517 | |||
| f275d08215 | |||
| 4ccc690560 | |||
| 82f3fdbc23 | |||
| 790e9f63e1 | |||
| 0636c8aedd | |||
| 8f2c828282 | |||
| 169e7f6601 | |||
| 691a670a28 | |||
| 76b6ac6581 | |||
| abe7870ad5 | |||
| 712c5e2a0a | |||
| 8814dc59d9 |
@ -44,6 +44,7 @@ namespace Marco.Pms.DataAccess.Data
|
|||||||
public DbSet<TaskAllocation> TaskAllocations { get; set; }
|
public DbSet<TaskAllocation> TaskAllocations { get; set; }
|
||||||
public DbSet<TaskComment> TaskComments { get; set; }
|
public DbSet<TaskComment> TaskComments { get; set; }
|
||||||
public DbSet<TaskMembers> TaskMembers { get; set; }
|
public DbSet<TaskMembers> TaskMembers { get; set; }
|
||||||
|
public DbSet<TaskAttachment> TaskAttachments { get; set; }
|
||||||
public DbSet<Attendance> Attendes { get; set; }
|
public DbSet<Attendance> Attendes { get; set; }
|
||||||
public DbSet<AttendanceLog> AttendanceLogs { get; set; }
|
public DbSet<AttendanceLog> AttendanceLogs { get; set; }
|
||||||
public DbSet<Employee> Employees { get; set; }
|
public DbSet<Employee> Employees { get; set; }
|
||||||
@ -160,14 +161,19 @@ namespace Marco.Pms.DataAccess.Data
|
|||||||
},
|
},
|
||||||
new StatusMaster
|
new StatusMaster
|
||||||
{
|
{
|
||||||
Id = new Guid("603e994b-a27f-4e5d-a251-f3d69b0498ba"),
|
Id = new Guid("cdad86aa-8a56-4ff4-b633-9c629057dfef"),
|
||||||
Status = "In Progress",
|
Status = "In Progress",
|
||||||
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
|
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||||
|
}, new StatusMaster
|
||||||
|
{
|
||||||
|
Id = new Guid("603e994b-a27f-4e5d-a251-f3d69b0498ba"),
|
||||||
|
Status = "On Hold",
|
||||||
|
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||||
},
|
},
|
||||||
new StatusMaster
|
new StatusMaster
|
||||||
{
|
{
|
||||||
Id = new Guid("ef1c356e-0fe0-42df-a5d3-8daee355492d"),
|
Id = new Guid("ef1c356e-0fe0-42df-a5d3-8daee355492d"),
|
||||||
Status = "On Hold",
|
Status = "In Active",
|
||||||
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
|
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||||
},
|
},
|
||||||
new StatusMaster
|
new StatusMaster
|
||||||
|
|||||||
3269
Marco.Pms.DataAccess/Migrations/20250612094243_Added_TaskAttachments_Table.Designer.cs
generated
Normal file
3269
Marco.Pms.DataAccess/Migrations/20250612094243_Added_TaskAttachments_Table.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,36 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Marco.Pms.DataAccess.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class Added_TaskAttachments_Table : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "TaskAttachments",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||||
|
ReferenceId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||||
|
DocumentId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci")
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_TaskAttachments", x => x.Id);
|
||||||
|
})
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "TaskAttachments");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3275
Marco.Pms.DataAccess/Migrations/20250619060620_Added_New_Status_Master_In_Progress.Designer.cs
generated
Normal file
3275
Marco.Pms.DataAccess/Migrations/20250619060620_Added_New_Status_Master_In_Progress.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,57 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Marco.Pms.DataAccess.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class Added_New_Status_Master_In_Progress : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "StatusMasters",
|
||||||
|
keyColumn: "Id",
|
||||||
|
keyValue: new Guid("603e994b-a27f-4e5d-a251-f3d69b0498ba"),
|
||||||
|
column: "Status",
|
||||||
|
value: "On Hold");
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "StatusMasters",
|
||||||
|
keyColumn: "Id",
|
||||||
|
keyValue: new Guid("ef1c356e-0fe0-42df-a5d3-8daee355492d"),
|
||||||
|
column: "Status",
|
||||||
|
value: "In Active");
|
||||||
|
|
||||||
|
migrationBuilder.InsertData(
|
||||||
|
table: "StatusMasters",
|
||||||
|
columns: new[] { "Id", "Status", "TenantId" },
|
||||||
|
values: new object[] { new Guid("cdad86aa-8a56-4ff4-b633-9c629057dfef"), "In Progress", new Guid("b3466e83-7e11-464c-b93a-daf047838b26") });
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DeleteData(
|
||||||
|
table: "StatusMasters",
|
||||||
|
keyColumn: "Id",
|
||||||
|
keyValue: new Guid("cdad86aa-8a56-4ff4-b633-9c629057dfef"));
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "StatusMasters",
|
||||||
|
keyColumn: "Id",
|
||||||
|
keyValue: new Guid("603e994b-a27f-4e5d-a251-f3d69b0498ba"),
|
||||||
|
column: "Status",
|
||||||
|
value: "In Progress");
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "StatusMasters",
|
||||||
|
keyColumn: "Id",
|
||||||
|
keyValue: new Guid("ef1c356e-0fe0-42df-a5d3-8daee355492d"),
|
||||||
|
column: "Status",
|
||||||
|
value: "On Hold");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -63,6 +63,23 @@ namespace Marco.Pms.DataAccess.Migrations
|
|||||||
b.ToTable("TaskAllocations");
|
b.ToTable("TaskAllocations");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Marco.Pms.Model.Activities.TaskAttachment", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
|
b.Property<Guid>("DocumentId")
|
||||||
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
|
b.Property<Guid>("ReferenceId")
|
||||||
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("TaskAttachments");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Marco.Pms.Model.Activities.TaskComment", b =>
|
modelBuilder.Entity("Marco.Pms.Model.Activities.TaskComment", b =>
|
||||||
{
|
{
|
||||||
b.Property<Guid>("Id")
|
b.Property<Guid>("Id")
|
||||||
@ -1658,17 +1675,23 @@ namespace Marco.Pms.DataAccess.Migrations
|
|||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("603e994b-a27f-4e5d-a251-f3d69b0498ba"),
|
Id = new Guid("cdad86aa-8a56-4ff4-b633-9c629057dfef"),
|
||||||
Status = "In Progress",
|
Status = "In Progress",
|
||||||
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
|
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||||
},
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("ef1c356e-0fe0-42df-a5d3-8daee355492d"),
|
Id = new Guid("603e994b-a27f-4e5d-a251-f3d69b0498ba"),
|
||||||
Status = "On Hold",
|
Status = "On Hold",
|
||||||
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
|
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||||
},
|
},
|
||||||
new
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("ef1c356e-0fe0-42df-a5d3-8daee355492d"),
|
||||||
|
Status = "In Active",
|
||||||
|
TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||||
|
},
|
||||||
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("33deaef9-9af1-4f2a-b443-681ea0d04f81"),
|
Id = new Guid("33deaef9-9af1-4f2a-b443-681ea0d04f81"),
|
||||||
Status = "Completed",
|
Status = "Completed",
|
||||||
|
|||||||
9
Marco.Pms.Model/Activities/TaskAttachment.cs
Normal file
9
Marco.Pms.Model/Activities/TaskAttachment.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
namespace Marco.Pms.Model.Activities
|
||||||
|
{
|
||||||
|
public class TaskAttachment
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public Guid ReferenceId { get; set; }
|
||||||
|
public Guid DocumentId { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,17 +0,0 @@
|
|||||||
using System.ComponentModel.DataAnnotations.Schema;
|
|
||||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
|
||||||
|
|
||||||
namespace Marco.Pms.Model.Activities
|
|
||||||
{
|
|
||||||
public class TaskImages
|
|
||||||
{
|
|
||||||
public Guid Id { get; set; }
|
|
||||||
|
|
||||||
public Guid TaskAllocationId { get; set; }
|
|
||||||
[ValidateNever]
|
|
||||||
[ForeignKey(nameof(TaskAllocationId))]
|
|
||||||
public TaskAllocation? TaskAllocation { get; set; }
|
|
||||||
|
|
||||||
public string? ImagePath { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,11 +1,12 @@
|
|||||||
namespace Marco.Pms.Model.Dtos.Activities
|
using Marco.Pms.Model.Utilities;
|
||||||
|
|
||||||
|
namespace Marco.Pms.Model.Dtos.Activities
|
||||||
{
|
{
|
||||||
public class CreateCommentDto
|
public class CreateCommentDto
|
||||||
{
|
{
|
||||||
public Guid TaskAllocationId { get; set; }
|
public Guid TaskAllocationId { get; set; }
|
||||||
|
|
||||||
public DateTime CommentDate { get; set; }
|
public DateTime CommentDate { get; set; }
|
||||||
public string? Comment { get; set; }
|
public string? Comment { get; set; }
|
||||||
|
public List<FileUploadModel>? Images { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
namespace Marco.Pms.Model.Dtos.Activities
|
using Marco.Pms.Model.Utilities;
|
||||||
|
|
||||||
|
namespace Marco.Pms.Model.Dtos.Activities
|
||||||
{
|
{
|
||||||
public class ReportTaskDto
|
public class ReportTaskDto
|
||||||
{
|
{
|
||||||
@ -7,5 +9,6 @@
|
|||||||
public DateTime ReportedDate { get; set; }
|
public DateTime ReportedDate { get; set; }
|
||||||
public string? Comment { get; set; }
|
public string? Comment { get; set; }
|
||||||
public List<ReportCheckListDto>? CheckList { get; set; }
|
public List<ReportCheckListDto>? CheckList { get; set; }
|
||||||
|
public List<FileUploadModel>? Images { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
public List<UpdateContactPhoneDto>? ContactPhones { get; set; }
|
public List<UpdateContactPhoneDto>? ContactPhones { get; set; }
|
||||||
public List<UpdateContactEmailDto>? ContactEmails { get; set; }
|
public List<UpdateContactEmailDto>? ContactEmails { get; set; }
|
||||||
public List<Guid>? BucketIds { get; set; }
|
public List<Guid>? BucketIds { get; set; }
|
||||||
public Guid ContactCategoryId { get; set; }
|
public Guid? ContactCategoryId { get; set; }
|
||||||
public string? Description { get; set; }
|
public string? Description { get; set; }
|
||||||
public string? Organization { get; set; }
|
public string? Organization { get; set; }
|
||||||
public string? Address { get; set; }
|
public string? Address { get; set; }
|
||||||
|
|||||||
@ -101,6 +101,7 @@ namespace Marco.Pms.Model.Mapper
|
|||||||
{
|
{
|
||||||
Id = taskAllocation.Id,
|
Id = taskAllocation.Id,
|
||||||
AssignmentDate = taskAllocation.AssignmentDate,
|
AssignmentDate = taskAllocation.AssignmentDate,
|
||||||
|
Description = taskAllocation.Description,
|
||||||
PlannedTask = taskAllocation.PlannedTask,
|
PlannedTask = taskAllocation.PlannedTask,
|
||||||
ReportedDate = taskAllocation.ReportedDate,
|
ReportedDate = taskAllocation.ReportedDate,
|
||||||
CompletedTask = taskAllocation.CompletedTask,
|
CompletedTask = taskAllocation.CompletedTask,
|
||||||
|
|||||||
@ -8,5 +8,6 @@
|
|||||||
public string? Comment { get; set; }
|
public string? Comment { get; set; }
|
||||||
public Guid CommentedBy { get; set; }
|
public Guid CommentedBy { get; set; }
|
||||||
public BasicEmployeeVM? Employee { get; set; }
|
public BasicEmployeeVM? Employee { get; set; }
|
||||||
|
public List<string>? PreSignedUrls { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,9 @@ namespace Marco.Pms.Model.ViewModels.Activities
|
|||||||
public double PlannedTask { get; set; }
|
public double PlannedTask { get; set; }
|
||||||
public double CompletedTask { get; set; }
|
public double CompletedTask { get; set; }
|
||||||
public BasicEmployeeVM? AssignedBy { get; set; }
|
public BasicEmployeeVM? AssignedBy { get; set; }
|
||||||
|
public string? Description { get; set; }
|
||||||
public Guid WorkItemId { get; set; }
|
public Guid WorkItemId { get; set; }
|
||||||
|
public List<string>? ReportedPreSignedUrls { get; set; }
|
||||||
public WorkItem? WorkItem { get; set; }
|
public WorkItem? WorkItem { get; set; }
|
||||||
public List<BasicEmployeeVM>? teamMembers { get; set; }
|
public List<BasicEmployeeVM>? teamMembers { get; set; }
|
||||||
public List<CommentVM>? comments { get; set; }
|
public List<CommentVM>? comments { get; set; }
|
||||||
|
|||||||
@ -10,7 +10,6 @@
|
|||||||
public string? Description { get; set; }
|
public string? Description { get; set; }
|
||||||
public Guid AssignedBy { get; set; }
|
public Guid AssignedBy { get; set; }
|
||||||
public Guid WorkItemId { get; set; }
|
public Guid WorkItemId { get; set; }
|
||||||
|
|
||||||
public List<CommentVM>? Comments { get; set; }
|
public List<CommentVM>? Comments { get; set; }
|
||||||
public List<CheckListVM>? checkList { get; set; }
|
public List<CheckListVM>? checkList { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,6 +13,7 @@ namespace Marco.Pms.Model.ViewModels.Activities
|
|||||||
public string? Description { get; set; }
|
public string? Description { get; set; }
|
||||||
public string? AssignBy { get; set; }
|
public string? AssignBy { get; set; }
|
||||||
public WorkItem? WorkItem { get; set; }
|
public WorkItem? WorkItem { get; set; }
|
||||||
|
public List<string>? PreSignedUrls { get; set; }
|
||||||
public List<CommentVM>? Comments { get; set; }
|
public List<CommentVM>? Comments { get; set; }
|
||||||
public List<EmployeeVM>? TeamMembers { get; set; }
|
public List<EmployeeVM>? TeamMembers { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,11 +7,13 @@ using Marco.Pms.Model.Mapper;
|
|||||||
using Marco.Pms.Model.Projects;
|
using Marco.Pms.Model.Projects;
|
||||||
using Marco.Pms.Model.Utilities;
|
using Marco.Pms.Model.Utilities;
|
||||||
using Marco.Pms.Model.ViewModels.AttendanceVM;
|
using Marco.Pms.Model.ViewModels.AttendanceVM;
|
||||||
|
using Marco.Pms.Services.Hubs;
|
||||||
using Marco.Pms.Services.Service;
|
using Marco.Pms.Services.Service;
|
||||||
using MarcoBMS.Services.Helpers;
|
using MarcoBMS.Services.Helpers;
|
||||||
using MarcoBMS.Services.Service;
|
using MarcoBMS.Services.Service;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.SignalR;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Document = Marco.Pms.Model.DocumentManager.Document;
|
using Document = Marco.Pms.Model.DocumentManager.Document;
|
||||||
@ -30,10 +32,11 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
private readonly S3UploadService _s3Service;
|
private readonly S3UploadService _s3Service;
|
||||||
private readonly PermissionServices _permission;
|
private readonly PermissionServices _permission;
|
||||||
private readonly ILoggingService _logger;
|
private readonly ILoggingService _logger;
|
||||||
|
private readonly IHubContext<MarcoHub> _signalR;
|
||||||
|
|
||||||
|
|
||||||
public AttendanceController(
|
public AttendanceController(
|
||||||
ApplicationDbContext context, EmployeeHelper employeeHelper, ProjectsHelper projectsHelper, UserHelper userHelper, S3UploadService s3Service, ILoggingService logger, PermissionServices permission)
|
ApplicationDbContext context, EmployeeHelper employeeHelper, ProjectsHelper projectsHelper, UserHelper userHelper, S3UploadService s3Service, ILoggingService logger, PermissionServices permission, IHubContext<MarcoHub> signalR)
|
||||||
{
|
{
|
||||||
_context = context;
|
_context = context;
|
||||||
_employeeHelper = employeeHelper;
|
_employeeHelper = employeeHelper;
|
||||||
@ -42,6 +45,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
_s3Service = s3Service;
|
_s3Service = s3Service;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_permission = permission;
|
_permission = permission;
|
||||||
|
_signalR = signalR;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Guid GetTenantId()
|
private Guid GetTenantId()
|
||||||
@ -558,6 +562,13 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
Activity = attendance.Activity,
|
Activity = attendance.Activity,
|
||||||
JobRoleName = employee.JobRole.Name
|
JobRoleName = employee.JobRole.Name
|
||||||
};
|
};
|
||||||
|
var sendActivity = 0;
|
||||||
|
if (recordAttendanceDot.Id == Guid.Empty)
|
||||||
|
{
|
||||||
|
sendActivity = 1;
|
||||||
|
}
|
||||||
|
var notification = new { LoggedInUserId = currentEmployee.Id, Keyword = "Attendance", Activity = sendActivity, ProjectId = attendance.ProjectID, Response = vm };
|
||||||
|
await _signalR.Clients.All.SendAsync("NotificationEventHandler", notification);
|
||||||
_logger.LogInfo("Attendance for employee {FirstName} {LastName} has been marked", employee.FirstName ?? string.Empty, employee.LastName ?? string.Empty);
|
_logger.LogInfo("Attendance for employee {FirstName} {LastName} has been marked", employee.FirstName ?? string.Empty, employee.LastName ?? string.Empty);
|
||||||
return Ok(ApiResponse<object>.SuccessResponse(vm, "Attendance marked successfully.", 200));
|
return Ok(ApiResponse<object>.SuccessResponse(vm, "Attendance marked successfully.", 200));
|
||||||
}
|
}
|
||||||
@ -688,7 +699,6 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
}
|
}
|
||||||
Document? document = null;
|
Document? document = null;
|
||||||
var Image = recordAttendanceDot.Image;
|
var Image = recordAttendanceDot.Image;
|
||||||
var objectKey = string.Empty;
|
|
||||||
var preSignedUrl = string.Empty;
|
var preSignedUrl = string.Empty;
|
||||||
|
|
||||||
if (Image != null && Image.ContentType != null)
|
if (Image != null && Image.ContentType != null)
|
||||||
@ -697,7 +707,16 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
if (string.IsNullOrEmpty(Image.Base64Data))
|
if (string.IsNullOrEmpty(Image.Base64Data))
|
||||||
return BadRequest(ApiResponse<object>.ErrorResponse("Base64 data is missing", "Base64 data is missing", 400));
|
return BadRequest(ApiResponse<object>.ErrorResponse("Base64 data is missing", "Base64 data is missing", 400));
|
||||||
|
|
||||||
objectKey = await _s3Service.UploadFileAsync(Image.Base64Data, TenantId, "attendance");
|
//If base64 has a data URI prefix, strip it
|
||||||
|
var base64 = Image.Base64Data.Contains(",")
|
||||||
|
? Image.Base64Data.Substring(Image.Base64Data.IndexOf(",") + 1)
|
||||||
|
: Image.Base64Data;
|
||||||
|
|
||||||
|
string fileType = _s3Service.GetContentTypeFromBase64(base64);
|
||||||
|
string fileName = _s3Service.GenerateFileName(fileType, TenantId, "attendance");
|
||||||
|
|
||||||
|
string objectKey = $"tenant-{TenantId}/Employee/{recordAttendanceDot.EmployeeID}/Attendance/{fileName}";
|
||||||
|
await _s3Service.UploadFileAsync(base64, fileType, objectKey);
|
||||||
preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(objectKey);
|
preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(objectKey);
|
||||||
|
|
||||||
document = new Document
|
document = new Document
|
||||||
@ -712,6 +731,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
};
|
};
|
||||||
_context.Documents.Add(document);
|
_context.Documents.Add(document);
|
||||||
|
|
||||||
|
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,11 +9,13 @@ using Marco.Pms.Model.Mapper;
|
|||||||
using Marco.Pms.Model.Projects;
|
using Marco.Pms.Model.Projects;
|
||||||
using Marco.Pms.Model.Utilities;
|
using Marco.Pms.Model.Utilities;
|
||||||
using Marco.Pms.Model.ViewModels.Employee;
|
using Marco.Pms.Model.ViewModels.Employee;
|
||||||
|
using Marco.Pms.Services.Hubs;
|
||||||
using MarcoBMS.Services.Helpers;
|
using MarcoBMS.Services.Helpers;
|
||||||
using MarcoBMS.Services.Service;
|
using MarcoBMS.Services.Service;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.SignalR;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace MarcoBMS.Services.Controllers
|
namespace MarcoBMS.Services.Controllers
|
||||||
@ -32,9 +34,11 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
private readonly UserHelper _userHelper;
|
private readonly UserHelper _userHelper;
|
||||||
private readonly IConfiguration _configuration;
|
private readonly IConfiguration _configuration;
|
||||||
private readonly ILoggingService _logger;
|
private readonly ILoggingService _logger;
|
||||||
|
private readonly IHubContext<MarcoHub> _signalR;
|
||||||
|
|
||||||
public EmployeeController(UserManager<ApplicationUser> userManager, IEmailSender emailSender,
|
public EmployeeController(UserManager<ApplicationUser> userManager, IEmailSender emailSender,
|
||||||
ApplicationDbContext context, EmployeeHelper employeeHelper, UserHelper userHelper, IConfiguration configuration, ILoggingService logger)
|
ApplicationDbContext context, EmployeeHelper employeeHelper, UserHelper userHelper, IConfiguration configuration, ILoggingService logger,
|
||||||
|
IHubContext<MarcoHub> signalR)
|
||||||
{
|
{
|
||||||
_context = context;
|
_context = context;
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
@ -43,6 +47,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
_userHelper = userHelper;
|
_userHelper = userHelper;
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
_signalR = signalR;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
@ -154,6 +159,8 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
public async Task<IActionResult> CreateUser([FromBody] CreateUserDto model)
|
public async Task<IActionResult> CreateUser([FromBody] CreateUserDto model)
|
||||||
{
|
{
|
||||||
Guid tenantId = _userHelper.GetTenantId();
|
Guid tenantId = _userHelper.GetTenantId();
|
||||||
|
var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
|
Guid employeeId = Guid.Empty;
|
||||||
if (model == null)
|
if (model == null)
|
||||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid data", "Invaild Data", 400));
|
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid data", "Invaild Data", 400));
|
||||||
|
|
||||||
@ -180,6 +187,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
|
|
||||||
_context.Employees.Update(existingEmployee);
|
_context.Employees.Update(existingEmployee);
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
|
employeeId = existingEmployee.Id;
|
||||||
responsemessage = "User updated successfully.";
|
responsemessage = "User updated successfully.";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -214,7 +222,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
_context.Employees.Add(newEmployee);
|
_context.Employees.Add(newEmployee);
|
||||||
|
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
|
employeeId = newEmployee.Id;
|
||||||
|
|
||||||
/* SEND USER REGISTRATION MAIL*/
|
/* SEND USER REGISTRATION MAIL*/
|
||||||
var token = await _userManager.GeneratePasswordResetTokenAsync(user);
|
var token = await _userManager.GeneratePasswordResetTokenAsync(user);
|
||||||
@ -233,6 +241,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
_context.Employees.Update(existingEmployee);
|
_context.Employees.Update(existingEmployee);
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
|
|
||||||
|
employeeId = existingEmployee.Id;
|
||||||
|
|
||||||
/* SEND USER REGISTRATION MAIL*/
|
/* SEND USER REGISTRATION MAIL*/
|
||||||
var token = await _userManager.GeneratePasswordResetTokenAsync(user);
|
var token = await _userManager.GeneratePasswordResetTokenAsync(user);
|
||||||
@ -256,17 +265,22 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
existingEmployee = GetUpdateEmployeeModel(model, existingEmployee);
|
existingEmployee = GetUpdateEmployeeModel(model, existingEmployee);
|
||||||
_context.Employees.Update(existingEmployee);
|
_context.Employees.Update(existingEmployee);
|
||||||
responsemessage = "User updated successfully.";
|
responsemessage = "User updated successfully.";
|
||||||
|
employeeId = existingEmployee.Id;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Create Employee record if missing
|
// Create Employee record if missing
|
||||||
Employee newEmployee = GetNewEmployeeModel(model, tenantId, string.Empty);
|
Employee newEmployee = GetNewEmployeeModel(model, tenantId, string.Empty);
|
||||||
_context.Employees.Add(newEmployee);
|
_context.Employees.Add(newEmployee);
|
||||||
|
employeeId = newEmployee.Id;
|
||||||
}
|
}
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
responsemessage = "User created successfully.";
|
responsemessage = "User created successfully.";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
var notification = new { LoggedInUserId = LoggedInEmployee.Id, Keyword = "Employee", EmployeeId = employeeId };
|
||||||
|
|
||||||
|
await _signalR.Clients.All.SendAsync("NotificationEventHandler", notification);
|
||||||
return Ok(ApiResponse<object>.SuccessResponse("Success.", responsemessage, 200));
|
return Ok(ApiResponse<object>.SuccessResponse("Success.", responsemessage, 200));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -420,6 +434,9 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
}
|
}
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
_logger.LogInfo("Employee with ID {EmployeId} Deleted successfully", employee.Id);
|
_logger.LogInfo("Employee with ID {EmployeId} Deleted successfully", employee.Id);
|
||||||
|
var notification = new { LoggedInUserId = LoggedEmployee.Id, Keyword = "Employee", EmployeeId = employee.Id };
|
||||||
|
|
||||||
|
await _signalR.Clients.All.SendAsync("NotificationEventHandler", notification);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@ -68,7 +68,16 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
return BadRequest(ApiResponse<object>.ErrorResponse("Base64 data is missing", "Base64 data is missing", 400));
|
return BadRequest(ApiResponse<object>.ErrorResponse("Base64 data is missing", "Base64 data is missing", 400));
|
||||||
}
|
}
|
||||||
|
|
||||||
var objectKey = await _s3Service.UploadFileAsync(Image.Base64Data, tenantId, "forum");
|
//If base64 has a data URI prefix, strip it
|
||||||
|
var base64 = Image.Base64Data.Contains(",")
|
||||||
|
? Image.Base64Data.Substring(Image.Base64Data.IndexOf(",") + 1)
|
||||||
|
: Image.Base64Data;
|
||||||
|
|
||||||
|
string fileType = _s3Service.GetContentTypeFromBase64(base64);
|
||||||
|
string fileName = _s3Service.GenerateFileName(fileType, tenantId, "forum");
|
||||||
|
|
||||||
|
string objectKey = $"tenant-{tenantId}/project-{createTicketDto.LinkedProjectId}/froum/{fileName}";
|
||||||
|
await _s3Service.UploadFileAsync(base64, fileType, objectKey);
|
||||||
|
|
||||||
Document document = attachmentDto.ToDocumentFromForumAttachmentDto(objectKey, objectKey, createTicketDto.CreatedAt, tenantId);
|
Document document = attachmentDto.ToDocumentFromForumAttachmentDto(objectKey, objectKey, createTicketDto.CreatedAt, tenantId);
|
||||||
_context.Documents.Add(document);
|
_context.Documents.Add(document);
|
||||||
@ -182,7 +191,16 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
return BadRequest(ApiResponse<object>.ErrorResponse("Base64 data is missing", "Base64 data is missing", 400));
|
return BadRequest(ApiResponse<object>.ErrorResponse("Base64 data is missing", "Base64 data is missing", 400));
|
||||||
}
|
}
|
||||||
|
|
||||||
var objectKey = await _s3Service.UploadFileAsync(Image.Base64Data, tenantId, "forum");
|
//If base64 has a data URI prefix, strip it
|
||||||
|
var base64 = Image.Base64Data.Contains(",")
|
||||||
|
? Image.Base64Data.Substring(Image.Base64Data.IndexOf(",") + 1)
|
||||||
|
: Image.Base64Data;
|
||||||
|
|
||||||
|
string fileType = _s3Service.GetContentTypeFromBase64(base64);
|
||||||
|
string fileName = _s3Service.GenerateFileName(fileType, tenantId, "forum");
|
||||||
|
|
||||||
|
string objectKey = $"tenant-{tenantId}/project-{updateTicketDto.LinkedProjectId}/froum/{fileName}";
|
||||||
|
await _s3Service.UploadFileAsync(base64, fileType, objectKey);
|
||||||
|
|
||||||
Document document = attachmentDto.ToDocumentFromUpdateAttachmentDto(objectKey, objectKey, updateTicketDto.CreatedAt, tenantId);
|
Document document = attachmentDto.ToDocumentFromUpdateAttachmentDto(objectKey, objectKey, updateTicketDto.CreatedAt, tenantId);
|
||||||
_context.Documents.Add(document);
|
_context.Documents.Add(document);
|
||||||
@ -329,6 +347,14 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
List<TicketAttachment> attachments = new List<TicketAttachment>();
|
List<TicketAttachment> attachments = new List<TicketAttachment>();
|
||||||
List<Document> documents = new List<Document>();
|
List<Document> documents = new List<Document>();
|
||||||
|
|
||||||
|
TicketForum? ticket = await _context.Tickets.FirstOrDefaultAsync(t => t.Id == addCommentDto.TicketId);
|
||||||
|
|
||||||
|
if (ticket == null)
|
||||||
|
{
|
||||||
|
_logger.LogError("Ticket {TicketId} not Found in database", addCommentDto.TicketId);
|
||||||
|
return NotFound(ApiResponse<object>.ErrorResponse("Ticket not Found", "Ticket not Found", 404));
|
||||||
|
}
|
||||||
|
|
||||||
TicketComment comment = addCommentDto.ToTicketCommentFromAddCommentDto(tenantId);
|
TicketComment comment = addCommentDto.ToTicketCommentFromAddCommentDto(tenantId);
|
||||||
_context.TicketComments.Add(comment);
|
_context.TicketComments.Add(comment);
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
@ -344,7 +370,16 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
return BadRequest(ApiResponse<object>.ErrorResponse("Base64 data is missing", "Base64 data is missing", 400));
|
return BadRequest(ApiResponse<object>.ErrorResponse("Base64 data is missing", "Base64 data is missing", 400));
|
||||||
}
|
}
|
||||||
|
|
||||||
var objectKey = await _s3Service.UploadFileAsync(Image.Base64Data, tenantId, "forum");
|
//If base64 has a data URI prefix, strip it
|
||||||
|
var base64 = Image.Base64Data.Contains(",")
|
||||||
|
? Image.Base64Data.Substring(Image.Base64Data.IndexOf(",") + 1)
|
||||||
|
: Image.Base64Data;
|
||||||
|
|
||||||
|
string fileType = _s3Service.GetContentTypeFromBase64(base64);
|
||||||
|
string fileName = _s3Service.GenerateFileName(fileType, tenantId, "forum");
|
||||||
|
|
||||||
|
string objectKey = $"tenant-{tenantId}/project-{ticket.LinkedProjectId}/froum/{fileName}";
|
||||||
|
await _s3Service.UploadFileAsync(base64, fileType, objectKey);
|
||||||
|
|
||||||
Document document = attachmentDto.ToDocumentFromForumAttachmentDto(objectKey, objectKey, addCommentDto.SentAt, tenantId);
|
Document document = attachmentDto.ToDocumentFromForumAttachmentDto(objectKey, objectKey, addCommentDto.SentAt, tenantId);
|
||||||
_context.Documents.Add(document);
|
_context.Documents.Add(document);
|
||||||
@ -396,6 +431,14 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
Guid tenantId = _userHelper.GetTenantId();
|
Guid tenantId = _userHelper.GetTenantId();
|
||||||
List<TicketAttachment> attachments = new List<TicketAttachment>();
|
List<TicketAttachment> attachments = new List<TicketAttachment>();
|
||||||
|
|
||||||
|
TicketForum? ticket = await _context.Tickets.FirstOrDefaultAsync(t => t.Id == updateCommentDto.TicketId);
|
||||||
|
|
||||||
|
if (ticket == null)
|
||||||
|
{
|
||||||
|
_logger.LogError("Ticket {TicketId} not Found in database", updateCommentDto.TicketId);
|
||||||
|
return NotFound(ApiResponse<object>.ErrorResponse("Ticket not Found", "Ticket not Found", 404));
|
||||||
|
}
|
||||||
|
|
||||||
TicketComment existingComment = await _context.TicketComments.AsNoTracking().FirstOrDefaultAsync(c => c.Id == updateCommentDto.Id) ?? new TicketComment();
|
TicketComment existingComment = await _context.TicketComments.AsNoTracking().FirstOrDefaultAsync(c => c.Id == updateCommentDto.Id) ?? new TicketComment();
|
||||||
TicketComment updateComment = updateCommentDto.ToTicketCommentFromUpdateCommentDto(tenantId, existingComment);
|
TicketComment updateComment = updateCommentDto.ToTicketCommentFromUpdateCommentDto(tenantId, existingComment);
|
||||||
_context.TicketComments.Update(updateComment);
|
_context.TicketComments.Update(updateComment);
|
||||||
@ -419,7 +462,16 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
return BadRequest(ApiResponse<object>.ErrorResponse("Base64 data is missing", "Base64 data is missing", 400));
|
return BadRequest(ApiResponse<object>.ErrorResponse("Base64 data is missing", "Base64 data is missing", 400));
|
||||||
}
|
}
|
||||||
|
|
||||||
var objectKey = await _s3Service.UploadFileAsync(Image.Base64Data, tenantId, "forum");
|
//If base64 has a data URI prefix, strip it
|
||||||
|
var base64 = Image.Base64Data.Contains(",")
|
||||||
|
? Image.Base64Data.Substring(Image.Base64Data.IndexOf(",") + 1)
|
||||||
|
: Image.Base64Data;
|
||||||
|
|
||||||
|
string fileType = _s3Service.GetContentTypeFromBase64(base64);
|
||||||
|
string fileName = _s3Service.GenerateFileName(fileType, tenantId, "forum");
|
||||||
|
|
||||||
|
string objectKey = $"tenant-{tenantId}/project-{ticket.LinkedProjectId}/froum/{fileName}";
|
||||||
|
await _s3Service.UploadFileAsync(base64, fileType, objectKey);
|
||||||
|
|
||||||
Document document = attachmentDto.ToDocumentFromUpdateAttachmentDto(objectKey, objectKey, existingComment.SentAt, tenantId);
|
Document document = attachmentDto.ToDocumentFromUpdateAttachmentDto(objectKey, objectKey, existingComment.SentAt, tenantId);
|
||||||
_context.Documents.Add(document);
|
_context.Documents.Add(document);
|
||||||
@ -491,6 +543,16 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
Guid tenantId = _userHelper.GetTenantId();
|
Guid tenantId = _userHelper.GetTenantId();
|
||||||
List<TicketAttachmentVM> ticketAttachmentVMs = new List<TicketAttachmentVM>();
|
List<TicketAttachmentVM> ticketAttachmentVMs = new List<TicketAttachmentVM>();
|
||||||
|
|
||||||
|
List<Guid> ticketIds = forumAttachmentDtos.Select(f => f.TicketId.HasValue ? f.TicketId.Value : Guid.Empty).ToList();
|
||||||
|
|
||||||
|
List<TicketForum> tickets = await _context.Tickets.Where(t => ticketIds.Contains(t.Id)).ToListAsync();
|
||||||
|
|
||||||
|
if (tickets == null || tickets.Count > 0)
|
||||||
|
{
|
||||||
|
_logger.LogError("Tickets not Found in database");
|
||||||
|
return NotFound(ApiResponse<object>.ErrorResponse("Ticket not Found", "Ticket not Found", 404));
|
||||||
|
}
|
||||||
|
|
||||||
TicketAttachment attachment = new TicketAttachment();
|
TicketAttachment attachment = new TicketAttachment();
|
||||||
|
|
||||||
foreach (var forumAttachmentDto in forumAttachmentDtos)
|
foreach (var forumAttachmentDto in forumAttachmentDtos)
|
||||||
@ -505,7 +567,17 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
_logger.LogError("ticket ID is missing");
|
_logger.LogError("ticket ID is missing");
|
||||||
return BadRequest(ApiResponse<object>.ErrorResponse("ticket ID is missing", "ticket ID is missing", 400));
|
return BadRequest(ApiResponse<object>.ErrorResponse("ticket ID is missing", "ticket ID is missing", 400));
|
||||||
}
|
}
|
||||||
var objectKey = await _s3Service.UploadFileAsync(forumAttachmentDto.Base64Data, tenantId, "forum");
|
var ticket = tickets.FirstOrDefault(t => t.Id == forumAttachmentDto.TicketId);
|
||||||
|
//If base64 has a data URI prefix, strip it
|
||||||
|
var base64 = forumAttachmentDto.Base64Data.Contains(",")
|
||||||
|
? forumAttachmentDto.Base64Data.Substring(forumAttachmentDto.Base64Data.IndexOf(",") + 1)
|
||||||
|
: forumAttachmentDto.Base64Data;
|
||||||
|
|
||||||
|
string fileType = _s3Service.GetContentTypeFromBase64(base64);
|
||||||
|
string fileName = _s3Service.GenerateFileName(fileType, tenantId, "forum");
|
||||||
|
|
||||||
|
string objectKey = $"tenant-{tenantId}/project-{ticket?.LinkedProjectId}/froum/{fileName}";
|
||||||
|
await _s3Service.UploadFileAsync(base64, fileType, objectKey);
|
||||||
|
|
||||||
Document document = forumAttachmentDto.ToDocumentFromForumAttachmentDto(objectKey, objectKey, forumAttachmentDto.SentAt, tenantId);
|
Document document = forumAttachmentDto.ToDocumentFromForumAttachmentDto(objectKey, objectKey, forumAttachmentDto.SentAt, tenantId);
|
||||||
_context.Documents.Add(document);
|
_context.Documents.Add(document);
|
||||||
|
|||||||
@ -749,11 +749,11 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
return Ok(response);
|
return Ok(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("contact-tag/{id}")]
|
//[HttpGet("contact-tag/{id}")]
|
||||||
public async Task<IActionResult> GetContactTagMaster(Guid id)
|
//public async Task<IActionResult> GetContactTagMaster(Guid id)
|
||||||
{
|
//{
|
||||||
return Ok();
|
// return Ok();
|
||||||
}
|
//}
|
||||||
|
|
||||||
[HttpPost("contact-tag")]
|
[HttpPost("contact-tag")]
|
||||||
public async Task<IActionResult> CreateContactTagMaster([FromBody] CreateContactTagDto contactTagDto)
|
public async Task<IActionResult> CreateContactTagMaster([FromBody] CreateContactTagDto contactTagDto)
|
||||||
|
|||||||
@ -8,12 +8,13 @@ using Marco.Pms.Model.Projects;
|
|||||||
using Marco.Pms.Model.Utilities;
|
using Marco.Pms.Model.Utilities;
|
||||||
using Marco.Pms.Model.ViewModels.Employee;
|
using Marco.Pms.Model.ViewModels.Employee;
|
||||||
using Marco.Pms.Model.ViewModels.Projects;
|
using Marco.Pms.Model.ViewModels.Projects;
|
||||||
|
using Marco.Pms.Services.Hubs;
|
||||||
using MarcoBMS.Services.Helpers;
|
using MarcoBMS.Services.Helpers;
|
||||||
using MarcoBMS.Services.Service;
|
using MarcoBMS.Services.Service;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.SignalR;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
namespace MarcoBMS.Services.Controllers
|
namespace MarcoBMS.Services.Controllers
|
||||||
{
|
{
|
||||||
@ -27,15 +28,18 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
private readonly ILoggingService _logger;
|
private readonly ILoggingService _logger;
|
||||||
private readonly RolesHelper _rolesHelper;
|
private readonly RolesHelper _rolesHelper;
|
||||||
private readonly ProjectsHelper _projectsHelper;
|
private readonly ProjectsHelper _projectsHelper;
|
||||||
|
private readonly IHubContext<MarcoHub> _signalR;
|
||||||
|
|
||||||
|
|
||||||
public ProjectController(ApplicationDbContext context, UserHelper userHelper, ILoggingService logger, RolesHelper rolesHelper, ProjectsHelper projectHelper)
|
public ProjectController(ApplicationDbContext context, UserHelper userHelper, ILoggingService logger, RolesHelper rolesHelper, ProjectsHelper projectHelper, IHubContext<MarcoHub> signalR)
|
||||||
{
|
{
|
||||||
_context = context;
|
_context = context;
|
||||||
_userHelper = userHelper;
|
_userHelper = userHelper;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_rolesHelper = rolesHelper;
|
_rolesHelper = rolesHelper;
|
||||||
_projectsHelper = projectHelper;
|
_projectsHelper = projectHelper;
|
||||||
|
_signalR = signalR;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("list/basic")]
|
[HttpGet("list/basic")]
|
||||||
@ -60,7 +64,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
List<Project> projects = await _projectsHelper.GetMyProjects(tenantId, LoggedInEmployee);
|
List<Project> projects = await _projectsHelper.GetMyProjects(tenantId, LoggedInEmployee);
|
||||||
|
|
||||||
|
|
||||||
// 4. Project projection to ProjectInfoVM
|
// 4. Project projection to ProjectInfoVM
|
||||||
@ -84,8 +88,6 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
return Ok(ApiResponse<object>.SuccessResponse(response, "Success.", 200));
|
return Ok(ApiResponse<object>.SuccessResponse(response, "Success.", 200));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[HttpGet("list")]
|
[HttpGet("list")]
|
||||||
public async Task<IActionResult> GetAll()
|
public async Task<IActionResult> GetAll()
|
||||||
{
|
{
|
||||||
@ -314,6 +316,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<IActionResult> Create([FromBody] CreateProjectDto projectDto)
|
public async Task<IActionResult> Create([FromBody] CreateProjectDto projectDto)
|
||||||
{
|
{
|
||||||
|
var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
if (!ModelState.IsValid)
|
if (!ModelState.IsValid)
|
||||||
{
|
{
|
||||||
var errors = ModelState.Values
|
var errors = ModelState.Values
|
||||||
@ -330,6 +333,9 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
_context.Projects.Add(project);
|
_context.Projects.Add(project);
|
||||||
|
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
|
var notification = new { LoggedInUserId = LoggedInEmployee.Id, Keyword = "Create_Project", Response = project.ToProjectDto() };
|
||||||
|
|
||||||
|
await _signalR.Clients.All.SendAsync("NotificationEventHandler", notification);
|
||||||
|
|
||||||
return Ok(ApiResponse<object>.SuccessResponse(project.ToProjectDto(), "Success.", 200));
|
return Ok(ApiResponse<object>.SuccessResponse(project.ToProjectDto(), "Success.", 200));
|
||||||
}
|
}
|
||||||
@ -338,6 +344,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
[Route("update/{id}")]
|
[Route("update/{id}")]
|
||||||
public async Task<IActionResult> Update([FromRoute] Guid id, [FromBody] UpdateProjectDto updateProjectDto)
|
public async Task<IActionResult> Update([FromRoute] Guid id, [FromBody] UpdateProjectDto updateProjectDto)
|
||||||
{
|
{
|
||||||
|
var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
if (!ModelState.IsValid)
|
if (!ModelState.IsValid)
|
||||||
{
|
{
|
||||||
var errors = ModelState.Values
|
var errors = ModelState.Values
|
||||||
@ -356,6 +363,10 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
|
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
|
|
||||||
|
var notification = new { LoggedInUserId = LoggedInEmployee.Id, Keyword = "Update_Project", Response = project.ToProjectDto() };
|
||||||
|
|
||||||
|
await _signalR.Clients.All.SendAsync("NotificationEventHandler", notification);
|
||||||
|
|
||||||
return Ok(ApiResponse<object>.SuccessResponse(project.ToProjectDto(), "Success.", 200));
|
return Ok(ApiResponse<object>.SuccessResponse(project.ToProjectDto(), "Success.", 200));
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -365,7 +376,6 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//[HttpPost("assign-employee")]
|
//[HttpPost("assign-employee")]
|
||||||
//public async Task<IActionResult> AssignEmployee(int? allocationid, int employeeId, int projectId)
|
//public async Task<IActionResult> AssignEmployee(int? allocationid, int employeeId, int projectId)
|
||||||
//{
|
//{
|
||||||
@ -506,7 +516,11 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
if (projectAllocationDot != null)
|
if (projectAllocationDot != null)
|
||||||
{
|
{
|
||||||
Guid TenentID = GetTenantId();
|
Guid TenentID = GetTenantId();
|
||||||
|
var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
|
|
||||||
List<object>? result = new List<object>();
|
List<object>? result = new List<object>();
|
||||||
|
List<Guid> employeeIds = new List<Guid>();
|
||||||
|
List<Guid> projectIds = new List<Guid>();
|
||||||
|
|
||||||
foreach (var item in projectAllocationDot)
|
foreach (var item in projectAllocationDot)
|
||||||
{
|
{
|
||||||
@ -535,6 +549,9 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
projectAllocationFromDb.IsActive = false;
|
projectAllocationFromDb.IsActive = false;
|
||||||
_context.Entry(projectAllocationFromDb).Property(e => e.ReAllocationDate).IsModified = true;
|
_context.Entry(projectAllocationFromDb).Property(e => e.ReAllocationDate).IsModified = true;
|
||||||
_context.Entry(projectAllocationFromDb).Property(e => e.IsActive).IsModified = true;
|
_context.Entry(projectAllocationFromDb).Property(e => e.IsActive).IsModified = true;
|
||||||
|
|
||||||
|
employeeIds.Add(projectAllocation.EmployeeId);
|
||||||
|
projectIds.Add(projectAllocation.ProjectId);
|
||||||
}
|
}
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
var result1 = new
|
var result1 = new
|
||||||
@ -556,15 +573,21 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
projectAllocation.IsActive = true;
|
projectAllocation.IsActive = true;
|
||||||
_context.ProjectAllocations.Add(projectAllocation);
|
_context.ProjectAllocations.Add(projectAllocation);
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
|
|
||||||
|
employeeIds.Add(projectAllocation.EmployeeId);
|
||||||
|
projectIds.Add(projectAllocation.ProjectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
return Ok(ApiResponse<object>.ErrorResponse(ex.Message, ex, 400));
|
return Ok(ApiResponse<object>.ErrorResponse(ex.Message, ex, 400));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var notification = new { LoggedInUserId = LoggedInEmployee.Id, Keyword = "Assign_Project", ProjectIds = projectIds, EmployeeList = employeeIds };
|
||||||
|
|
||||||
|
await _signalR.Clients.All.SendAsync("NotificationEventHandler", notification);
|
||||||
return Ok(ApiResponse<object>.SuccessResponse(result, "Data saved successfully", 200));
|
return Ok(ApiResponse<object>.SuccessResponse(result, "Data saved successfully", 200));
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -576,7 +599,10 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
public async Task<IActionResult> CreateProjectTask(List<WorkItemDot> workItemDot)
|
public async Task<IActionResult> CreateProjectTask(List<WorkItemDot> workItemDot)
|
||||||
{
|
{
|
||||||
Guid tenantId = GetTenantId();
|
Guid tenantId = GetTenantId();
|
||||||
|
var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
List<WorkItemVM> workItems = new List<WorkItemVM> { };
|
List<WorkItemVM> workItems = new List<WorkItemVM> { };
|
||||||
|
List<Guid> projectIds = new List<Guid>();
|
||||||
|
string message = "";
|
||||||
string responseMessage = "";
|
string responseMessage = "";
|
||||||
if (workItemDot != null)
|
if (workItemDot != null)
|
||||||
{
|
{
|
||||||
@ -584,19 +610,25 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
{
|
{
|
||||||
WorkItem workItem = item.ToWorkItemFromWorkItemDto(tenantId);
|
WorkItem workItem = item.ToWorkItemFromWorkItemDto(tenantId);
|
||||||
|
|
||||||
|
var workArea = await _context.WorkAreas.Include(a => a.Floor).FirstOrDefaultAsync(a => a.Id == workItem.WorkAreaId) ?? new WorkArea();
|
||||||
|
|
||||||
|
Building building = await _context.Buildings.FirstOrDefaultAsync(b => b.Id == (workArea.Floor != null ? workArea.Floor.BuildingId : Guid.Empty)) ?? new Building();
|
||||||
|
|
||||||
if (item.Id != null)
|
if (item.Id != null)
|
||||||
{
|
{
|
||||||
//update
|
//update
|
||||||
_context.WorkItems.Update(workItem);
|
_context.WorkItems.Update(workItem);
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
responseMessage = "Task Added Successfully";
|
responseMessage = "Task Updated Successfully";
|
||||||
|
message = $"Task Updated in Building: {building.Name}, on Floor: {workArea.Floor?.FloorName}, in Area: {workArea.AreaName} by {LoggedInEmployee.FirstName} {LoggedInEmployee.LastName}";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//create
|
//create
|
||||||
_context.WorkItems.Add(workItem);
|
_context.WorkItems.Add(workItem);
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
responseMessage = "Task Updated Successfully";
|
responseMessage = "Task Added Successfully";
|
||||||
|
message = $"Task Added in Building: {building.Name}, on Floor: {workArea.Floor?.FloorName}, in Area: {workArea.AreaName} by {LoggedInEmployee.FirstName} {LoggedInEmployee.LastName}";
|
||||||
}
|
}
|
||||||
var result = new WorkItemVM
|
var result = new WorkItemVM
|
||||||
{
|
{
|
||||||
@ -604,9 +636,14 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
WorkItem = workItem
|
WorkItem = workItem
|
||||||
};
|
};
|
||||||
workItems.Add(result);
|
workItems.Add(result);
|
||||||
|
projectIds.Add(building.ProjectId);
|
||||||
}
|
}
|
||||||
var activity = await _context.ActivityMasters.ToListAsync();
|
var activity = await _context.ActivityMasters.ToListAsync();
|
||||||
var category = await _context.WorkCategoryMasters.ToListAsync();
|
var category = await _context.WorkCategoryMasters.ToListAsync();
|
||||||
|
|
||||||
|
var notification = new { LoggedInUserId = LoggedInEmployee.Id, Keyword = "Infra", ProjectIds = projectIds, Message = message };
|
||||||
|
|
||||||
|
await _signalR.Clients.All.SendAsync("NotificationEventHandler", notification);
|
||||||
return Ok(ApiResponse<object>.SuccessResponse(workItems, responseMessage, 200));
|
return Ok(ApiResponse<object>.SuccessResponse(workItems, responseMessage, 200));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -618,7 +655,9 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
public async Task<IActionResult> DeleteProjectTask(Guid id)
|
public async Task<IActionResult> DeleteProjectTask(Guid id)
|
||||||
{
|
{
|
||||||
Guid tenantId = _userHelper.GetTenantId();
|
Guid tenantId = _userHelper.GetTenantId();
|
||||||
WorkItem? task = await _context.WorkItems.AsNoTracking().FirstOrDefaultAsync(t => t.Id == id && t.TenantId == tenantId);
|
var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
|
List<Guid> projectIds = new List<Guid>();
|
||||||
|
WorkItem? task = await _context.WorkItems.AsNoTracking().Include(t => t.WorkArea).FirstOrDefaultAsync(t => t.Id == id && t.TenantId == tenantId);
|
||||||
if (task != null)
|
if (task != null)
|
||||||
{
|
{
|
||||||
if (task.CompletedWork == 0)
|
if (task.CompletedWork == 0)
|
||||||
@ -629,6 +668,15 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
_context.WorkItems.Remove(task);
|
_context.WorkItems.Remove(task);
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
_logger.LogInfo("Task with ID {WorkItemId} has been successfully deleted.", task.Id);
|
_logger.LogInfo("Task with ID {WorkItemId} has been successfully deleted.", task.Id);
|
||||||
|
|
||||||
|
var floorId = task.WorkArea?.FloorId;
|
||||||
|
var floor = await _context.Floor.Include(f => f.Building).FirstOrDefaultAsync(f => f.Id == floorId);
|
||||||
|
|
||||||
|
|
||||||
|
projectIds.Add(floor?.Building?.ProjectId ?? Guid.Empty);
|
||||||
|
|
||||||
|
var notification = new { LoggedInUserId = LoggedInEmployee.Id, Keyword = "Infra", ProjectIds = projectIds, Message = $"Task Deleted in Building: {floor?.Building?.Name}, on Floor: {floor?.FloorName}, in Area: {task.WorkArea?.AreaName} by {LoggedInEmployee.FirstName} {LoggedInEmployee.LastName}" };
|
||||||
|
await _signalR.Clients.All.SendAsync("NotificationEventHandler", notification);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -656,8 +704,12 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
public async Task<IActionResult> ManageProjectInfra(List<InfraDot> infraDots)
|
public async Task<IActionResult> ManageProjectInfra(List<InfraDot> infraDots)
|
||||||
{
|
{
|
||||||
Guid tenantId = GetTenantId();
|
Guid tenantId = GetTenantId();
|
||||||
|
var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
|
|
||||||
var responseData = new InfraVM { };
|
var responseData = new InfraVM { };
|
||||||
string responseMessage = "";
|
string responseMessage = "";
|
||||||
|
string message = "";
|
||||||
|
List<Guid> projectIds = new List<Guid>();
|
||||||
if (infraDots != null)
|
if (infraDots != null)
|
||||||
{
|
{
|
||||||
foreach (var item in infraDots)
|
foreach (var item in infraDots)
|
||||||
@ -675,6 +727,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
responseData.building = building;
|
responseData.building = building;
|
||||||
responseMessage = "Buliding Added Successfully";
|
responseMessage = "Buliding Added Successfully";
|
||||||
|
message = "Building Added";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -683,8 +736,10 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
responseData.building = building;
|
responseData.building = building;
|
||||||
responseMessage = "Buliding Updated Successfully";
|
responseMessage = "Buliding Updated Successfully";
|
||||||
|
message = "Building Updated";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
projectIds.Add(building.ProjectId);
|
||||||
}
|
}
|
||||||
if (item.Floor != null)
|
if (item.Floor != null)
|
||||||
{
|
{
|
||||||
@ -698,6 +753,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
responseData.floor = floor;
|
responseData.floor = floor;
|
||||||
responseMessage = "Floor Added Successfully";
|
responseMessage = "Floor Added Successfully";
|
||||||
|
message = "Floor Added";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -706,7 +762,11 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
responseData.floor = floor;
|
responseData.floor = floor;
|
||||||
responseMessage = "Floor Updated Successfully";
|
responseMessage = "Floor Updated Successfully";
|
||||||
|
message = "Floor Updated";
|
||||||
}
|
}
|
||||||
|
Building? building = await _context.Buildings.FirstOrDefaultAsync(b => b.Id == floor.BuildingId);
|
||||||
|
projectIds.Add(building?.ProjectId ?? Guid.Empty);
|
||||||
|
message = $"{message} in Building: {building?.Name}";
|
||||||
}
|
}
|
||||||
if (item.WorkArea != null)
|
if (item.WorkArea != null)
|
||||||
{
|
{
|
||||||
@ -720,6 +780,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
responseData.workArea = workArea;
|
responseData.workArea = workArea;
|
||||||
responseMessage = "Work Area Added Successfully";
|
responseMessage = "Work Area Added Successfully";
|
||||||
|
message = "Work Area Added";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -728,9 +789,17 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
responseData.workArea = workArea;
|
responseData.workArea = workArea;
|
||||||
responseMessage = "Work Area Updated Successfully";
|
responseMessage = "Work Area Updated Successfully";
|
||||||
|
message = "Work Area Updated";
|
||||||
}
|
}
|
||||||
|
Floor? floor = await _context.Floor.Include(f => f.Building).FirstOrDefaultAsync(f => f.Id == workArea.FloorId);
|
||||||
|
projectIds.Add(floor?.Building?.ProjectId ?? Guid.Empty);
|
||||||
|
message = $"{message} in Building: {floor?.Building?.Name}, on Floor: {floor?.FloorName}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
message = $"{message} by {LoggedInEmployee.FirstName} {LoggedInEmployee.LastName}";
|
||||||
|
var notification = new { LoggedInUserId = LoggedInEmployee.Id, Keyword = "Infra", ProjectIds = projectIds, Message = message };
|
||||||
|
|
||||||
|
await _signalR.Clients.All.SendAsync("NotificationEventHandler", notification);
|
||||||
return Ok(ApiResponse<object>.SuccessResponse(responseData, responseMessage, 200));
|
return Ok(ApiResponse<object>.SuccessResponse(responseData, responseMessage, 200));
|
||||||
}
|
}
|
||||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid details.", "Infra Details are not valid.", 400));
|
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid details.", "Infra Details are not valid.", 400));
|
||||||
@ -776,16 +845,15 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
return Ok(ApiResponse<object>.SuccessResponse(projects, "Success.", 200));
|
return Ok(ApiResponse<object>.SuccessResponse(projects, "Success.", 200));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[HttpPost("assign-projects/{employeeId}")]
|
[HttpPost("assign-projects/{employeeId}")]
|
||||||
public async Task<ActionResult> AssigneProjectsToEmployee([FromBody] List<ProjectsAllocationDto> projectAllocationDtos, [FromRoute] Guid employeeId)
|
public async Task<ActionResult> AssigneProjectsToEmployee([FromBody] List<ProjectsAllocationDto> projectAllocationDtos, [FromRoute] Guid employeeId)
|
||||||
{
|
{
|
||||||
if (projectAllocationDtos != null && employeeId != Guid.Empty)
|
if (projectAllocationDtos != null && employeeId != Guid.Empty)
|
||||||
{
|
{
|
||||||
Guid TenentID = GetTenantId();
|
Guid TenentID = GetTenantId();
|
||||||
|
var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
List<object>? result = new List<object>();
|
List<object>? result = new List<object>();
|
||||||
|
List<Guid> projectIds = new List<Guid>();
|
||||||
|
|
||||||
foreach (var projectAllocationDto in projectAllocationDtos)
|
foreach (var projectAllocationDto in projectAllocationDtos)
|
||||||
{
|
{
|
||||||
@ -813,6 +881,8 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
projectAllocationFromDb.IsActive = false;
|
projectAllocationFromDb.IsActive = false;
|
||||||
_context.Entry(projectAllocationFromDb).Property(e => e.ReAllocationDate).IsModified = true;
|
_context.Entry(projectAllocationFromDb).Property(e => e.ReAllocationDate).IsModified = true;
|
||||||
_context.Entry(projectAllocationFromDb).Property(e => e.IsActive).IsModified = true;
|
_context.Entry(projectAllocationFromDb).Property(e => e.IsActive).IsModified = true;
|
||||||
|
|
||||||
|
projectIds.Add(projectAllocation.ProjectId);
|
||||||
}
|
}
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
var result1 = new
|
var result1 = new
|
||||||
@ -835,6 +905,8 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
_context.ProjectAllocations.Add(projectAllocation);
|
_context.ProjectAllocations.Add(projectAllocation);
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
|
|
||||||
|
projectIds.Add(projectAllocation.ProjectId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -845,6 +917,9 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
return Ok(ApiResponse<object>.ErrorResponse(ex.Message, ex, 400));
|
return Ok(ApiResponse<object>.ErrorResponse(ex.Message, ex, 400));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var notification = new { LoggedInUserId = LoggedInEmployee.Id, Keyword = "Assign_Project", ProjectIds = projectIds, EmployeeId = employeeId };
|
||||||
|
|
||||||
|
await _signalR.Clients.All.SendAsync("NotificationEventHandler", notification);
|
||||||
|
|
||||||
return Ok(ApiResponse<object>.SuccessResponse(result, "Data saved successfully", 200));
|
return Ok(ApiResponse<object>.SuccessResponse(result, "Data saved successfully", 200));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,10 +8,13 @@ using Marco.Pms.Model.Projects;
|
|||||||
using Marco.Pms.Model.Utilities;
|
using Marco.Pms.Model.Utilities;
|
||||||
using Marco.Pms.Model.ViewModels.Activities;
|
using Marco.Pms.Model.ViewModels.Activities;
|
||||||
using Marco.Pms.Model.ViewModels.Employee;
|
using Marco.Pms.Model.ViewModels.Employee;
|
||||||
|
using Marco.Pms.Services.Service;
|
||||||
using MarcoBMS.Services.Helpers;
|
using MarcoBMS.Services.Helpers;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.CodeAnalysis;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Document = Marco.Pms.Model.DocumentManager.Document;
|
||||||
|
|
||||||
namespace MarcoBMS.Services.Controllers
|
namespace MarcoBMS.Services.Controllers
|
||||||
{
|
{
|
||||||
@ -23,12 +26,14 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
{
|
{
|
||||||
private readonly ApplicationDbContext _context;
|
private readonly ApplicationDbContext _context;
|
||||||
private readonly UserHelper _userHelper;
|
private readonly UserHelper _userHelper;
|
||||||
|
private readonly S3UploadService _s3Service;
|
||||||
|
|
||||||
|
|
||||||
public TaskController(ApplicationDbContext context, UserHelper userHelper)
|
public TaskController(ApplicationDbContext context, UserHelper userHelper, S3UploadService s3Service)
|
||||||
{
|
{
|
||||||
_context = context;
|
_context = context;
|
||||||
_userHelper = userHelper;
|
_userHelper = userHelper;
|
||||||
|
_s3Service = s3Service;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Guid GetTenantId()
|
private Guid GetTenantId()
|
||||||
@ -84,7 +89,6 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
return Ok(ApiResponse<object>.SuccessResponse(response, "Task assignned successfully", 200));
|
return Ok(ApiResponse<object>.SuccessResponse(response, "Task assignned successfully", 200));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[HttpPost("report")]
|
[HttpPost("report")]
|
||||||
public async Task<IActionResult> ReportTaskProgress([FromBody] ReportTaskDto reportTask)
|
public async Task<IActionResult> ReportTaskProgress([FromBody] ReportTaskDto reportTask)
|
||||||
{
|
{
|
||||||
@ -104,10 +108,13 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
|
|
||||||
var checkListIds = reportTask.CheckList != null ? reportTask.CheckList.Select(c => c.Id).ToList() : new List<Guid>();
|
var checkListIds = reportTask.CheckList != null ? reportTask.CheckList.Select(c => c.Id).ToList() : new List<Guid>();
|
||||||
var checkList = await _context.ActivityCheckLists.Where(c => checkListIds.Contains(c.Id)).ToListAsync();
|
var checkList = await _context.ActivityCheckLists.Where(c => checkListIds.Contains(c.Id)).ToListAsync();
|
||||||
if (taskAllocation == null)
|
if (taskAllocation == null || taskAllocation.WorkItem == null)
|
||||||
{
|
{
|
||||||
return BadRequest(ApiResponse<object>.ErrorResponse("No such task has been allocated.", "No such task has been allocated.", 400));
|
return BadRequest(ApiResponse<object>.ErrorResponse("No such task has been allocated.", "No such task has been allocated.", 400));
|
||||||
}
|
}
|
||||||
|
WorkArea workArea = await _context.WorkAreas.Include(a => a.Floor).FirstOrDefaultAsync(a => a.Id == taskAllocation.WorkItem.WorkAreaId) ?? new WorkArea();
|
||||||
|
|
||||||
|
var bulding = await _context.Buildings.FirstOrDefaultAsync(b => b.Id == (workArea.Floor != null ? workArea.Floor.BuildingId : Guid.Empty));
|
||||||
if (taskAllocation.WorkItem != null)
|
if (taskAllocation.WorkItem != null)
|
||||||
{
|
{
|
||||||
if (taskAllocation.CompletedTask != 0)
|
if (taskAllocation.CompletedTask != 0)
|
||||||
@ -143,6 +150,49 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
_context.CheckListMappings.AddRange(checkListMappings);
|
_context.CheckListMappings.AddRange(checkListMappings);
|
||||||
var comment = reportTask.ToCommentFromReportTaskDto(tenantId, Employee.Id);
|
var comment = reportTask.ToCommentFromReportTaskDto(tenantId, Employee.Id);
|
||||||
|
|
||||||
|
var Images = reportTask.Images;
|
||||||
|
|
||||||
|
if (Images != null && Images.Count > 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
foreach (var Image in Images)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(Image.Base64Data))
|
||||||
|
return BadRequest(ApiResponse<object>.ErrorResponse("Base64 data is missing", "Base64 data is missing", 400));
|
||||||
|
|
||||||
|
//If base64 has a data URI prefix, strip it
|
||||||
|
var base64 = Image.Base64Data.Contains(",")
|
||||||
|
? Image.Base64Data.Substring(Image.Base64Data.IndexOf(",") + 1)
|
||||||
|
: Image.Base64Data;
|
||||||
|
|
||||||
|
string fileType = _s3Service.GetContentTypeFromBase64(base64);
|
||||||
|
string fileName = _s3Service.GenerateFileName(fileType, tenantId, "task_report");
|
||||||
|
|
||||||
|
string objectKey = $"tenant-{tenantId}/project-{bulding?.ProjectId}/Actitvity/{fileName}";
|
||||||
|
await _s3Service.UploadFileAsync(base64, fileType, objectKey);
|
||||||
|
|
||||||
|
Document document = new Document
|
||||||
|
{
|
||||||
|
FileName = Image.FileName ?? "",
|
||||||
|
ContentType = Image.ContentType ?? "",
|
||||||
|
S3Key = objectKey,
|
||||||
|
Base64Data = Image.Base64Data,
|
||||||
|
FileSize = Image.FileSize,
|
||||||
|
UploadedAt = DateTime.UtcNow,
|
||||||
|
TenantId = tenantId
|
||||||
|
};
|
||||||
|
_context.Documents.Add(document);
|
||||||
|
TaskAttachment attachment = new TaskAttachment
|
||||||
|
{
|
||||||
|
DocumentId = document.Id,
|
||||||
|
ReferenceId = reportTask.Id
|
||||||
|
};
|
||||||
|
_context.TaskAttachments.Add(attachment);
|
||||||
|
}
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
_context.TaskComments.Add(comment);
|
_context.TaskComments.Add(comment);
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
|
|
||||||
@ -164,10 +214,62 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
var tenantId = GetTenantId();
|
var tenantId = GetTenantId();
|
||||||
var Employee = await _userHelper.GetCurrentEmployeeAsync();
|
var Employee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
|
|
||||||
|
var taskAllocation = await _context.TaskAllocations.Include(t => t.WorkItem).FirstOrDefaultAsync(t => t.Id == createComment.TaskAllocationId);
|
||||||
|
if (taskAllocation == null || taskAllocation.WorkItem == null)
|
||||||
|
{
|
||||||
|
return BadRequest(ApiResponse<object>.ErrorResponse("No such task has been allocated.", "No such task has been allocated.", 400));
|
||||||
|
}
|
||||||
|
WorkArea workArea = await _context.WorkAreas.Include(a => a.Floor).FirstOrDefaultAsync(a => a.Id == taskAllocation.WorkItem.WorkAreaId) ?? new WorkArea();
|
||||||
|
|
||||||
|
var bulding = await _context.Buildings.FirstOrDefaultAsync(b => b.Id == (workArea.Floor != null ? workArea.Floor.BuildingId : Guid.Empty));
|
||||||
|
|
||||||
var comment = createComment.ToCommentFromCommentDto(tenantId, Employee.Id);
|
var comment = createComment.ToCommentFromCommentDto(tenantId, Employee.Id);
|
||||||
_context.TaskComments.Add(comment);
|
_context.TaskComments.Add(comment);
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
|
|
||||||
|
var Images = createComment.Images;
|
||||||
|
|
||||||
|
if (Images != null && Images.Count > 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
foreach (var Image in Images)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(Image.Base64Data))
|
||||||
|
return BadRequest(ApiResponse<object>.ErrorResponse("Base64 data is missing", "Base64 data is missing", 400));
|
||||||
|
|
||||||
|
//If base64 has a data URI prefix, strip it
|
||||||
|
var base64 = Image.Base64Data.Contains(",")
|
||||||
|
? Image.Base64Data.Substring(Image.Base64Data.IndexOf(",") + 1)
|
||||||
|
: Image.Base64Data;
|
||||||
|
|
||||||
|
string fileType = _s3Service.GetContentTypeFromBase64(base64);
|
||||||
|
string fileName = _s3Service.GenerateFileName(fileType, tenantId, "task_report");
|
||||||
|
|
||||||
|
string objectKey = $"tenant-{tenantId}/project-{bulding?.ProjectId}/Actitvity/{fileName}";
|
||||||
|
await _s3Service.UploadFileAsync(base64, fileType, objectKey);
|
||||||
|
|
||||||
|
Document document = new Document
|
||||||
|
{
|
||||||
|
FileName = Image.FileName ?? "",
|
||||||
|
ContentType = Image.ContentType ?? "",
|
||||||
|
S3Key = objectKey,
|
||||||
|
Base64Data = Image.Base64Data,
|
||||||
|
FileSize = Image.FileSize,
|
||||||
|
UploadedAt = DateTime.UtcNow,
|
||||||
|
TenantId = tenantId
|
||||||
|
};
|
||||||
|
_context.Documents.Add(document);
|
||||||
|
TaskAttachment attachment = new TaskAttachment
|
||||||
|
{
|
||||||
|
DocumentId = document.Id,
|
||||||
|
ReferenceId = comment.Id
|
||||||
|
};
|
||||||
|
_context.TaskAttachments.Add(attachment);
|
||||||
|
}
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
CommentVM response = comment.ToCommentVMFromTaskComment();
|
CommentVM response = comment.ToCommentVMFromTaskComment();
|
||||||
return Ok(ApiResponse<object>.SuccessResponse(response, "Comment saved successfully", 200));
|
return Ok(ApiResponse<object>.SuccessResponse(response, "Comment saved successfully", 200));
|
||||||
}
|
}
|
||||||
@ -215,6 +317,13 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
|
|
||||||
List<Employee> employees = await _context.Employees.Where(e => employeeIdList.Contains(e.Id)).Include(e => e.JobRole).ToListAsync();
|
List<Employee> employees = await _context.Employees.Where(e => employeeIdList.Contains(e.Id)).Include(e => e.JobRole).ToListAsync();
|
||||||
|
|
||||||
|
List<TaskComment> allComments = await _context.TaskComments.Include(c => c.Employee).Where(c => taskIdList.Contains(c.TaskAllocationId)).ToListAsync();
|
||||||
|
var allCommentIds = allComments.Select(c => c.Id).ToList();
|
||||||
|
|
||||||
|
var taskAttachments = await _context.TaskAttachments.Where(t => taskIdList.Contains(t.ReferenceId) || allCommentIds.Contains(t.ReferenceId)).ToListAsync();
|
||||||
|
var documentIds = taskAttachments.Select(t => t.DocumentId).ToList();
|
||||||
|
var documents = await _context.Documents.Where(d => documentIds.Contains(d.Id)).ToListAsync();
|
||||||
|
|
||||||
List<ListTaskVM> tasks = new List<ListTaskVM>();
|
List<ListTaskVM> tasks = new List<ListTaskVM>();
|
||||||
//foreach (var workItem in workItems)
|
//foreach (var workItem in workItems)
|
||||||
//{
|
//{
|
||||||
@ -223,10 +332,21 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
|
|
||||||
var response = taskAllocation.ToListTaskVMFromTaskAllocation();
|
var response = taskAllocation.ToListTaskVMFromTaskAllocation();
|
||||||
|
|
||||||
List<TaskComment> comments = await _context.TaskComments.Where(c => c.TaskAllocationId == taskAllocation.Id).ToListAsync();
|
List<TaskComment> comments = allComments.Where(c => c.TaskAllocationId == taskAllocation.Id).ToList();
|
||||||
List<BasicEmployeeVM> team = new List<BasicEmployeeVM>();
|
List<BasicEmployeeVM> team = new List<BasicEmployeeVM>();
|
||||||
List<TaskMembers> taskMembers = teamMembers.Where(m => m.TaskAllocationId == taskAllocation.Id).ToList();
|
List<TaskMembers> taskMembers = teamMembers.Where(m => m.TaskAllocationId == taskAllocation.Id).ToList();
|
||||||
|
|
||||||
|
var taskDocumentIds = taskAttachments.Where(t => t.ReferenceId == taskAllocation.Id).Select(t => t.DocumentId).ToList();
|
||||||
|
var taskDocuments = documents.Where(d => taskDocumentIds.Contains(d.Id)).ToList();
|
||||||
|
|
||||||
|
List<string> taskPreSignedUrls = new List<string>();
|
||||||
|
foreach (var document in taskDocuments)
|
||||||
|
{
|
||||||
|
string preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(document.S3Key);
|
||||||
|
taskPreSignedUrls.Add(preSignedUrl);
|
||||||
|
}
|
||||||
|
response.ReportedPreSignedUrls = taskPreSignedUrls;
|
||||||
|
|
||||||
foreach (var taskMember in taskMembers)
|
foreach (var taskMember in taskMembers)
|
||||||
{
|
{
|
||||||
var teamMember = employees.Find(e => e.Id == taskMember.EmployeeId);
|
var teamMember = employees.Find(e => e.Id == taskMember.EmployeeId);
|
||||||
@ -238,7 +358,18 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
List<CommentVM> commentVM = new List<CommentVM> { };
|
List<CommentVM> commentVM = new List<CommentVM> { };
|
||||||
foreach (var comment in comments)
|
foreach (var comment in comments)
|
||||||
{
|
{
|
||||||
commentVM.Add(comment.ToCommentVMFromTaskComment());
|
var commentDocumentIds = taskAttachments.Where(t => t.ReferenceId == comment.Id).Select(t => t.DocumentId).ToList();
|
||||||
|
var commentDocuments = documents.Where(d => commentDocumentIds.Contains(d.Id)).ToList();
|
||||||
|
List<string> commentPreSignedUrls = new List<string>();
|
||||||
|
foreach (var document in commentDocuments)
|
||||||
|
{
|
||||||
|
string preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(document.S3Key);
|
||||||
|
commentPreSignedUrls.Add(preSignedUrl);
|
||||||
|
}
|
||||||
|
CommentVM commentVm = comment.ToCommentVMFromTaskComment();
|
||||||
|
commentVm.PreSignedUrls = commentPreSignedUrls;
|
||||||
|
|
||||||
|
commentVM.Add(commentVm);
|
||||||
}
|
}
|
||||||
List<ActivityCheckList> checkLists = await _context.ActivityCheckLists.Where(x => x.ActivityId == (taskAllocation.WorkItem != null ? taskAllocation.WorkItem.ActivityId : Guid.Empty)).ToListAsync();
|
List<ActivityCheckList> checkLists = await _context.ActivityCheckLists.Where(x => x.ActivityId == (taskAllocation.WorkItem != null ? taskAllocation.WorkItem.ActivityId : Guid.Empty)).ToListAsync();
|
||||||
List<CheckListMappings> checkListMappings = await _context.CheckListMappings.Where(c => c.TaskAllocationId == taskAllocation.Id).ToListAsync();
|
List<CheckListMappings> checkListMappings = await _context.CheckListMappings.Where(c => c.TaskAllocationId == taskAllocation.Id).ToListAsync();
|
||||||
@ -280,8 +411,23 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
if (taskAllocation == null) return NotFound(ApiResponse<object>.ErrorResponse("Task Not Found", "Task not found", 404));
|
if (taskAllocation == null) return NotFound(ApiResponse<object>.ErrorResponse("Task Not Found", "Task not found", 404));
|
||||||
var taskVM = taskAllocation.TaskAllocationToTaskVM(employeeName);
|
var taskVM = taskAllocation.TaskAllocationToTaskVM(employeeName);
|
||||||
var comments = await _context.TaskComments.Where(c => c.TaskAllocationId == taskAllocation.Id).ToListAsync();
|
var comments = await _context.TaskComments.Where(c => c.TaskAllocationId == taskAllocation.Id).ToListAsync();
|
||||||
|
var commentIds = comments.Select(c => c.Id).ToList();
|
||||||
|
var taskAttachments = await _context.TaskAttachments.Where(t => t.ReferenceId == taskAllocation.Id || commentIds.Contains(t.ReferenceId)).ToListAsync();
|
||||||
|
var documentIds = taskAttachments.Select(t => t.DocumentId).ToList();
|
||||||
|
var documents = await _context.Documents.Where(d => documentIds.Contains(d.Id)).ToListAsync();
|
||||||
var team = await _context.TaskMembers.Where(m => m.TaskAllocationId == taskAllocation.Id).Include(m => m.Employee).ToListAsync();
|
var team = await _context.TaskMembers.Where(m => m.TaskAllocationId == taskAllocation.Id).Include(m => m.Employee).ToListAsync();
|
||||||
var teamMembers = new List<EmployeeVM> { };
|
var teamMembers = new List<EmployeeVM> { };
|
||||||
|
|
||||||
|
var taskDocumentIds = taskAttachments.Where(t => t.ReferenceId == taskAllocation.Id).Select(t => t.DocumentId).ToList();
|
||||||
|
var taskDocuments = documents.Where(d => taskDocumentIds.Contains(d.Id)).ToList();
|
||||||
|
|
||||||
|
List<string> taskPreSignedUrls = new List<string>();
|
||||||
|
foreach (var document in taskDocuments)
|
||||||
|
{
|
||||||
|
string preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(document.S3Key);
|
||||||
|
taskPreSignedUrls.Add(preSignedUrl);
|
||||||
|
}
|
||||||
|
taskVM.PreSignedUrls = taskPreSignedUrls;
|
||||||
foreach (var member in team)
|
foreach (var member in team)
|
||||||
{
|
{
|
||||||
var result = member.Employee != null ? member.Employee.ToEmployeeVMFromEmployee() : new EmployeeVM();
|
var result = member.Employee != null ? member.Employee.ToEmployeeVMFromEmployee() : new EmployeeVM();
|
||||||
@ -290,7 +436,17 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
List<CommentVM> Comments = new List<CommentVM> { };
|
List<CommentVM> Comments = new List<CommentVM> { };
|
||||||
foreach (var comment in comments)
|
foreach (var comment in comments)
|
||||||
{
|
{
|
||||||
Comments.Add(comment.ToCommentVMFromTaskComment());
|
var commentDocumentIds = taskAttachments.Where(t => t.ReferenceId == comment.Id).Select(t => t.DocumentId).ToList();
|
||||||
|
var commentDocuments = documents.Where(d => commentDocumentIds.Contains(d.Id)).ToList();
|
||||||
|
List<string> commentPreSignedUrls = new List<string>();
|
||||||
|
foreach (var document in commentDocuments)
|
||||||
|
{
|
||||||
|
string preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(document.S3Key);
|
||||||
|
commentPreSignedUrls.Add(preSignedUrl);
|
||||||
|
}
|
||||||
|
CommentVM commentVM = comment.ToCommentVMFromTaskComment();
|
||||||
|
commentVM.PreSignedUrls = commentPreSignedUrls;
|
||||||
|
Comments.Add(commentVM);
|
||||||
}
|
}
|
||||||
taskVM.Comments = Comments;
|
taskVM.Comments = Comments;
|
||||||
taskVM.TeamMembers = teamMembers;
|
taskVM.TeamMembers = teamMembers;
|
||||||
|
|||||||
35
Marco.Pms.Services/Hub/MarcoHub.cs
Normal file
35
Marco.Pms.Services/Hub/MarcoHub.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
using MarcoBMS.Services.Service;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.SignalR;
|
||||||
|
|
||||||
|
namespace Marco.Pms.Services.Hubs
|
||||||
|
{
|
||||||
|
[Authorize]
|
||||||
|
public class MarcoHub : Hub
|
||||||
|
{
|
||||||
|
private readonly ILoggingService _logger;
|
||||||
|
public MarcoHub(ILoggingService logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
public async Task SendMessage(string user, string message)
|
||||||
|
{
|
||||||
|
_logger.LogInfo($"User: {user} Message : {message}");
|
||||||
|
await Clients.All.SendAsync("ReceiveMessage", user, message);
|
||||||
|
}
|
||||||
|
public override async Task OnConnectedAsync()
|
||||||
|
{
|
||||||
|
await base.OnConnectedAsync();
|
||||||
|
_logger.LogInfo($"Connected successfully");
|
||||||
|
await Clients.All.SendAsync("Connected successfully");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optional: override OnDisconnectedAsync
|
||||||
|
public override async Task OnDisconnectedAsync(Exception? exception)
|
||||||
|
{
|
||||||
|
await base.OnDisconnectedAsync(exception);
|
||||||
|
_logger.LogInfo($"DIsonnected successfully");
|
||||||
|
await Clients.All.SendAsync("Disonnected successfully");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -17,6 +17,7 @@
|
|||||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.12" />
|
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.12" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="8.0.12" />
|
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="8.0.12" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.7" />
|
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.7" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.2.0" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.12">
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.12">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
|||||||
@ -4,6 +4,7 @@ using Marco.Pms.Model.Authentication;
|
|||||||
using Marco.Pms.Model.Entitlements;
|
using Marco.Pms.Model.Entitlements;
|
||||||
using Marco.Pms.Model.Utilities;
|
using Marco.Pms.Model.Utilities;
|
||||||
using Marco.Pms.Services.Helpers;
|
using Marco.Pms.Services.Helpers;
|
||||||
|
using Marco.Pms.Services.Hubs;
|
||||||
using Marco.Pms.Services.Service;
|
using Marco.Pms.Services.Service;
|
||||||
using MarcoBMS.Services.Helpers;
|
using MarcoBMS.Services.Helpers;
|
||||||
using MarcoBMS.Services.Middleware;
|
using MarcoBMS.Services.Middleware;
|
||||||
@ -59,7 +60,8 @@ builder.Services.AddCors(options =>
|
|||||||
{
|
{
|
||||||
policy.AllowAnyOrigin()
|
policy.AllowAnyOrigin()
|
||||||
.AllowAnyMethod()
|
.AllowAnyMethod()
|
||||||
.AllowAnyHeader();
|
.AllowAnyHeader()
|
||||||
|
.WithExposedHeaders("Authorization");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -161,10 +163,28 @@ if (jwtSettings != null && jwtSettings.Key != null)
|
|||||||
ValidAudience = jwtSettings.Audience,
|
ValidAudience = jwtSettings.Audience,
|
||||||
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.Key))
|
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.Key))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
options.Events = new JwtBearerEvents
|
||||||
|
{
|
||||||
|
OnMessageReceived = context =>
|
||||||
|
{
|
||||||
|
var accessToken = context.Request.Query["access_token"];
|
||||||
|
var path = context.HttpContext.Request.Path;
|
||||||
|
|
||||||
|
// Match your hub route here
|
||||||
|
if (!string.IsNullOrEmpty(accessToken) && path.StartsWithSegments("/hubs/marco"))
|
||||||
|
{
|
||||||
|
context.Token = accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
};
|
||||||
});
|
});
|
||||||
builder.Services.AddSingleton(jwtSettings);
|
builder.Services.AddSingleton(jwtSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
builder.Services.AddSignalR();
|
||||||
builder.WebHost.ConfigureKestrel(options =>
|
builder.WebHost.ConfigureKestrel(options =>
|
||||||
{
|
{
|
||||||
options.AddServerHeader = false; // Disable the "Server" header
|
options.AddServerHeader = false; // Disable the "Server" header
|
||||||
@ -207,7 +227,7 @@ app.UseHttpsRedirection();
|
|||||||
|
|
||||||
|
|
||||||
app.UseAuthorization();
|
app.UseAuthorization();
|
||||||
|
app.MapHub<MarcoHub>("/hubs/marco");
|
||||||
app.MapControllers();
|
app.MapControllers();
|
||||||
|
|
||||||
app.Run();
|
app.Run();
|
||||||
|
|||||||
@ -28,53 +28,46 @@ namespace Marco.Pms.Services.Service
|
|||||||
_s3Client = new AmazonS3Client(settings.AccessKey, settings.SecretKey, region);
|
_s3Client = new AmazonS3Client(settings.AccessKey, settings.SecretKey, region);
|
||||||
}
|
}
|
||||||
//public async Task<string> UploadFileAsync(string fileName, string contentType)
|
//public async Task<string> UploadFileAsync(string fileName, string contentType)
|
||||||
public async Task<string> UploadFileAsync(string base64Data, Guid tenantId, string tag)
|
public async Task UploadFileAsync(string base64, string fileType, string objectKey)
|
||||||
{
|
{
|
||||||
byte[] fileBytes;
|
byte[] fileBytes;
|
||||||
|
|
||||||
//If base64 has a data URI prefix, strip it
|
|
||||||
var base64 = base64Data.Contains(",")
|
|
||||||
? base64Data.Substring(base64Data.IndexOf(",") + 1)
|
|
||||||
: base64Data;
|
|
||||||
var allowedFilesType = _configuration.GetSection("WhiteList:ContentType")
|
var allowedFilesType = _configuration.GetSection("WhiteList:ContentType")
|
||||||
.GetChildren()
|
.GetChildren()
|
||||||
.Select(x => x.Value)
|
.Select(x => x.Value)
|
||||||
.ToList();
|
.ToList();
|
||||||
string fileType = GetContentTypeFromBase64(base64);
|
|
||||||
if (allowedFilesType != null && allowedFilesType.Contains(fileType))
|
if (allowedFilesType == null || !allowedFilesType.Contains(fileType))
|
||||||
{
|
{
|
||||||
string fileName = GenerateFileName(fileType, tenantId, tag);
|
throw new InvalidOperationException("Unsupported file type.");
|
||||||
|
|
||||||
fileBytes = Convert.FromBase64String(base64);
|
|
||||||
|
|
||||||
|
|
||||||
using var fileStream = new MemoryStream(fileBytes);
|
|
||||||
|
|
||||||
// Generate a unique object key (you can customize this)
|
|
||||||
var objectKey = $"{fileName}";
|
|
||||||
|
|
||||||
var uploadRequest = new TransferUtilityUploadRequest
|
|
||||||
{
|
|
||||||
InputStream = fileStream,
|
|
||||||
Key = objectKey,
|
|
||||||
BucketName = _bucketName,
|
|
||||||
ContentType = fileType,
|
|
||||||
AutoCloseStream = true
|
|
||||||
};
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var transferUtility = new TransferUtility(_s3Client);
|
|
||||||
await transferUtility.UploadAsync(uploadRequest);
|
|
||||||
_logger.LogInfo("File uploaded to Amazon S3");
|
|
||||||
return objectKey;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError("{error} while uploading file to S3", ex.Message);
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
throw new InvalidOperationException("Unsupported file type.");
|
|
||||||
|
fileBytes = Convert.FromBase64String(base64);
|
||||||
|
|
||||||
|
|
||||||
|
using var fileStream = new MemoryStream(fileBytes);
|
||||||
|
|
||||||
|
var uploadRequest = new TransferUtilityUploadRequest
|
||||||
|
{
|
||||||
|
InputStream = fileStream,
|
||||||
|
Key = objectKey,
|
||||||
|
BucketName = _bucketName,
|
||||||
|
ContentType = fileType,
|
||||||
|
AutoCloseStream = true
|
||||||
|
};
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var transferUtility = new TransferUtility(_s3Client);
|
||||||
|
await transferUtility.UploadAsync(uploadRequest);
|
||||||
|
_logger.LogInfo("File uploaded to Amazon S3");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError("{error} while uploading file to S3", ex.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
public string GeneratePreSignedUrlAsync(string objectKey)
|
public string GeneratePreSignedUrlAsync(string objectKey)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
"Title": "Dev"
|
"Title": "Dev"
|
||||||
},
|
},
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"DefaultConnectionString": "Server=147.93.98.152;User ID=devuser;Password=AppUser@123$;Database=MarcoBMSGuid"
|
"DefaultConnectionString": "Server=147.93.98.152;User ID=devuser;Password=AppUser@123$;Database=MarcoBMS1"
|
||||||
},
|
},
|
||||||
"SmtpSettings": {
|
"SmtpSettings": {
|
||||||
"SmtpServer": "smtp.gmail.com",
|
"SmtpServer": "smtp.gmail.com",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user