Merge pull request 'Organization_Management' (#142) from Organization_Management into main
Reviewed-on: #142
This commit is contained in:
commit
d0912cca56
@ -9,6 +9,7 @@ using Marco.Pms.Model.Expenses;
|
||||
using Marco.Pms.Model.Forum;
|
||||
using Marco.Pms.Model.Mail;
|
||||
using Marco.Pms.Model.Master;
|
||||
using Marco.Pms.Model.OrganizationModel;
|
||||
using Marco.Pms.Model.Projects;
|
||||
using Marco.Pms.Model.Roles;
|
||||
using Marco.Pms.Model.TenantModels;
|
||||
@ -39,6 +40,8 @@ namespace Marco.Pms.DataAccess.Data
|
||||
public DbSet<SubscriptionPlanDetails> SubscriptionPlanDetails { get; set; }
|
||||
public DbSet<TenantSubscriptions> TenantSubscriptions { get; set; }
|
||||
public DbSet<ApplicationUser> ApplicationUsers { get; set; }
|
||||
public DbSet<ServiceMaster> ServiceMasters { get; set; }
|
||||
public DbSet<ActivityGroupMaster> ActivityGroupMasters { get; set; }
|
||||
public DbSet<ActivityMaster> ActivityMasters { get; set; }
|
||||
public DbSet<Project> Projects { get; set; }
|
||||
public DbSet<ProjectAllocation> ProjectAllocations { get; set; }
|
||||
@ -119,6 +122,17 @@ namespace Marco.Pms.DataAccess.Data
|
||||
public DbSet<AttachmentVersionMapping> AttachmentVersionMappings { get; set; }
|
||||
public DbSet<AttachmentTagMapping> AttachmentTagMappings { get; set; }
|
||||
|
||||
public DbSet<GlobalServiceMaster> GlobalServiceMasters { get; set; }
|
||||
public DbSet<GlobalActivityGroupMaster> GlobalActivityGroupMasters { get; set; }
|
||||
public DbSet<GlobalActivityMaster> GlobalActivityMasters { get; set; }
|
||||
|
||||
public DbSet<Organization> Organizations { get; set; }
|
||||
public DbSet<OrgTypeMaster> OrgTypeMasters { get; set; }
|
||||
public DbSet<TenantOrgMapping> TenantOrgMappings { get; set; }
|
||||
public DbSet<OrgServiceMapping> OrgServiceMappings { get; set; }
|
||||
public DbSet<ProjectServiceMapping> ProjectServiceMappings { get; set; }
|
||||
public DbSet<ProjectOrgMapping> ProjectOrgMappings { get; set; }
|
||||
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
@ -134,6 +148,7 @@ namespace Marco.Pms.DataAccess.Data
|
||||
.HasForeignKey(e => e.UserId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity<TenantStatus>().HasData(
|
||||
new TenantStatus
|
||||
{
|
||||
@ -152,6 +167,21 @@ namespace Marco.Pms.DataAccess.Data
|
||||
}
|
||||
);
|
||||
|
||||
modelBuilder.Entity<Organization>().HasData(
|
||||
new Organization
|
||||
{
|
||||
Id = Guid.Parse("4e3a6d31-c640-40f7-8d67-6c109fcdb9ea"),
|
||||
Name = "MarcoBMS",
|
||||
ContactPerson = "Admin",
|
||||
Email = "admin@marcoaiot.com",
|
||||
ContactNumber = "123456789",
|
||||
Address = "2nd Floor, Fullora Building, Tejas CHS, behind Kothrud Stand, Tejas Society, Dahanukar Colony, Kothrud, Pune, Maharashtra 411038",
|
||||
CreatedAt = DateTime.MinValue,
|
||||
SPRID = 5400,
|
||||
IsActive = true
|
||||
}
|
||||
);
|
||||
|
||||
modelBuilder.Entity<Tenant>().HasData(
|
||||
new Tenant
|
||||
{
|
||||
@ -165,6 +195,7 @@ namespace Marco.Pms.DataAccess.Data
|
||||
DomainName = "www.marcobms.org",
|
||||
TenantStatusId = Guid.Parse("62b05792-5115-4f99-8ff5-e8374859b191"),
|
||||
IndustryId = Guid.Parse("15436ee3-a650-469e-bfc2-59993f7514bb"),
|
||||
OrganizationId = Guid.Parse("4e3a6d31-c640-40f7-8d67-6c109fcdb9ea"),
|
||||
BillingAddress = "2nd Floor, Fullora Building, Tejas CHS, behind Kothrud Stand, Tejas Society, Dahanukar Colony, Kothrud, Pune, Maharashtra 411038",
|
||||
OnBoardingDate = DateTime.MinValue,
|
||||
IsSuperTenant = true,
|
||||
@ -199,6 +230,7 @@ namespace Marco.Pms.DataAccess.Data
|
||||
Status = "Completed"
|
||||
}
|
||||
);
|
||||
|
||||
modelBuilder.Entity<Project>().HasData(
|
||||
new Project
|
||||
{
|
||||
@ -228,6 +260,7 @@ namespace Marco.Pms.DataAccess.Data
|
||||
new Industry { Id = Guid.Parse("8a0d6134-2dbe-4e0a-b250-ff34cb7b9df0"), Name = "Education & Training" }
|
||||
|
||||
);
|
||||
|
||||
modelBuilder.Entity<TicketStatusMaster>().HasData(
|
||||
new TicketStatusMaster
|
||||
{
|
||||
@ -275,6 +308,7 @@ namespace Marco.Pms.DataAccess.Data
|
||||
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
}
|
||||
);
|
||||
|
||||
modelBuilder.Entity<TicketTypeMaster>().HasData(
|
||||
new TicketTypeMaster
|
||||
{
|
||||
@ -293,6 +327,7 @@ namespace Marco.Pms.DataAccess.Data
|
||||
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
}
|
||||
);
|
||||
|
||||
modelBuilder.Entity<TicketPriorityMaster>().HasData(
|
||||
new TicketPriorityMaster
|
||||
{
|
||||
@ -340,6 +375,7 @@ namespace Marco.Pms.DataAccess.Data
|
||||
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
}
|
||||
);
|
||||
|
||||
modelBuilder.Entity<TicketTagMaster>().HasData(
|
||||
new TicketTagMaster
|
||||
{
|
||||
@ -385,6 +421,7 @@ namespace Marco.Pms.DataAccess.Data
|
||||
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
}
|
||||
);
|
||||
|
||||
modelBuilder.Entity<WorkStatusMaster>().HasData(
|
||||
new WorkStatusMaster
|
||||
{
|
||||
@ -760,7 +797,7 @@ namespace Marco.Pms.DataAccess.Data
|
||||
Name = "Project Documents",
|
||||
Description = "Project documents are formal records that outline the plans, progress, and details necessary to execute and manage a project effectively.",
|
||||
EntityTypeId = Guid.Parse("c8fe7115-aa27-43bc-99f4-7b05fabe436e"),
|
||||
CreatedAt = DateTime.UtcNow,
|
||||
CreatedAt = new DateTime(2025, 9, 15, 12, 42, 3, 202, DateTimeKind.Utc),
|
||||
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
},
|
||||
new DocumentCategoryMaster
|
||||
@ -769,7 +806,7 @@ namespace Marco.Pms.DataAccess.Data
|
||||
Name = "Employee Documents",
|
||||
Description = "Employment details along with legal IDs like passports or driver’s licenses to verify identity and work authorization.",
|
||||
EntityTypeId = Guid.Parse("dbb9555a-7a0c-40f2-a9ed-f0463f1ceed7"),
|
||||
CreatedAt = DateTime.UtcNow,
|
||||
CreatedAt = new DateTime(2025, 9, 15, 12, 42, 3, 202, DateTimeKind.Utc),
|
||||
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
|
||||
}
|
||||
);
|
||||
@ -955,6 +992,19 @@ namespace Marco.Pms.DataAccess.Data
|
||||
}
|
||||
);
|
||||
|
||||
modelBuilder.Entity<OrgTypeMaster>().HasData(
|
||||
new OrgTypeMaster
|
||||
{
|
||||
Id = Guid.Parse("5ee49bcd-b6d3-482f-9aaf-484afe04abec"),
|
||||
Name = "Service Provider"
|
||||
},
|
||||
new OrgTypeMaster
|
||||
{
|
||||
Id = Guid.Parse("a283356a-9b02-4029-afb7-e65c703efdd4"),
|
||||
Name = "Sub-Contractor"
|
||||
}
|
||||
);
|
||||
|
||||
modelBuilder.Entity<Module>().HasData(
|
||||
new Module
|
||||
{
|
||||
@ -996,9 +1046,12 @@ namespace Marco.Pms.DataAccess.Data
|
||||
new Feature { Id = new Guid("52c9cf54-1eb2-44d2-81bb-524cf29c0a94"), Description = "Attendance", Name = "Attendance Management", ModuleId = new Guid("2a231490-bcb1-4bdd-91f1-f25fb7f25b23"), IsActive = true },
|
||||
new Feature { Id = new Guid("a8cf4331-8f04-4961-8360-a3f7c3cc7462"), Description = "Manage Document", Name = "Document Management", ModuleId = new Guid("2a231490-bcb1-4bdd-91f1-f25fb7f25b23"), IsActive = true },
|
||||
|
||||
// Master Module
|
||||
new Feature { Id = new Guid("be3b3afc-6ccf-4566-b9b6-aafcb65546be"), Description = "Global Masters", Name = "Masters", ModuleId = new Guid("c43db8c7-ab73-47f4-9d3b-f83e81357924"), IsActive = true },
|
||||
new Feature { Id = new Guid("39e66f81-efc6-446c-95bd-46bff6cfb606"), Description = "Managing all directory related rights", Name = "Directory Management", ModuleId = new Guid("c43db8c7-ab73-47f4-9d3b-f83e81357924"), IsActive = true },
|
||||
new Feature { Id = new Guid("6d4c82d6-dbce-48ab-b8b8-f785f4d8c914"), Description = "Managing all organization related rights", Name = "Organization Management", ModuleId = new Guid("c43db8c7-ab73-47f4-9d3b-f83e81357924"), IsActive = true },
|
||||
|
||||
// Tenant Module
|
||||
new Feature { Id = new Guid("2f3509b7-160d-410a-b9b6-daadd96c986d"), Description = "Managing all tenant related rights", Name = "Tenant Management", ModuleId = new Guid("f482a079-4dec-4f2d-9867-6baf2a4f23d9"), IsActive = true }
|
||||
);
|
||||
|
||||
@ -1055,7 +1108,12 @@ namespace Marco.Pms.DataAccess.Data
|
||||
new FeaturePermission { Id = new Guid("1f4bda08-1873-449a-bb66-3e8222bd871b"), FeatureId = new Guid("a4e25142-449b-4334-a6e5-22f70e4732d7"), IsEnabled = true, Name = "Review", Description = "Allows a user to examine submitted expenses for accuracy, completeness, and policy compliance before they are approved or rejected." },
|
||||
new FeaturePermission { Id = new Guid("eaafdd76-8aac-45f9-a530-315589c6deca"), FeatureId = new Guid("a4e25142-449b-4334-a6e5-22f70e4732d7"), IsEnabled = true, Name = "Approve", Description = "Allows a user to authorize or reject submitted expenses, making them officially accepted or declined within the system." },
|
||||
new FeaturePermission { Id = new Guid("ea5a1529-4ee8-4828-80ea-0e23c9d4dd11"), FeatureId = new Guid("a4e25142-449b-4334-a6e5-22f70e4732d7"), IsEnabled = true, Name = "Process", Description = "Allows a user to handle post-approval actions such as recording payments, updating financial records, or marking expenses as reimbursed or settled." },
|
||||
new FeaturePermission { Id = new Guid("bdee29a2-b73b-402d-8dd1-c4b1f81ccbc3"), FeatureId = new Guid("a4e25142-449b-4334-a6e5-22f70e4732d7"), IsEnabled = true, Name = "Manage", Description = "Allows a user to configure and control system settings, such as managing expense types, payment modes, permissions, and overall workflow rules." }
|
||||
new FeaturePermission { Id = new Guid("bdee29a2-b73b-402d-8dd1-c4b1f81ccbc3"), FeatureId = new Guid("a4e25142-449b-4334-a6e5-22f70e4732d7"), IsEnabled = true, Name = "Manage", Description = "Allows a user to configure and control system settings, such as managing expense types, payment modes, permissions, and overall workflow rules." },
|
||||
|
||||
// Organization Management Feature
|
||||
new FeaturePermission { Id = new Guid("068cb3c1-49c5-4746-9f29-1fce16e820ac"), FeatureId = new Guid("6d4c82d6-dbce-48ab-b8b8-f785f4d8c914"), IsEnabled = true, Name = "Add Organization", Description = "Allow user to create new organization" },
|
||||
new FeaturePermission { Id = new Guid("c1ae1363-ab8a-4bd9-a9d1-8c2c6083873a"), FeatureId = new Guid("6d4c82d6-dbce-48ab-b8b8-f785f4d8c914"), IsEnabled = true, Name = "Edit Organization", Description = "Allow the user to update the basic information of the organization" },
|
||||
new FeaturePermission { Id = new Guid("7a6cf830-0008-4e03-b31d-0d050cb634f4"), FeatureId = new Guid("6d4c82d6-dbce-48ab-b8b8-f785f4d8c914"), IsEnabled = true, Name = "View Organization", Description = "Allow the user to view information of the organization" }
|
||||
|
||||
);
|
||||
|
||||
|
@ -62,7 +62,6 @@ namespace Marco.Pms.DataAccess.Initializer
|
||||
// State = "State",
|
||||
// Postalcode = "1234567890",
|
||||
// City = "City",
|
||||
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26"),
|
||||
IsRootUser = true,
|
||||
|
||||
}, "User@123").GetAwaiter().GetResult();
|
||||
@ -78,13 +77,10 @@ namespace Marco.Pms.DataAccess.Initializer
|
||||
Gender = "",
|
||||
EmergencyPhoneNumber = "1234567890",
|
||||
CurrentAddress = "",
|
||||
AadharNumber = "1234567890",
|
||||
ApplicationUserId = user.Id,
|
||||
BirthDate = DateTime.MinValue,
|
||||
PanNumber = "",
|
||||
PermanentAddress = "",
|
||||
PhoneNumber = "",
|
||||
TenantId = user.TenantId
|
||||
PhoneNumber = ""
|
||||
};
|
||||
_db.Employees.Add(emp);
|
||||
|
||||
|
6079
Marco.Pms.DataAccess/Migrations/20250916051642_Added_Tables_Related_To_Organizations.Designer.cs
generated
Normal file
6079
Marco.Pms.DataAccess/Migrations/20250916051642_Added_Tables_Related_To_Organizations.Designer.cs
generated
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,757 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional
|
||||
|
||||
namespace Marco.Pms.DataAccess.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Added_Tables_Related_To_Organizations : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.UpdateData(
|
||||
table: "ActivityMasters",
|
||||
keyColumn: "UnitOfMeasurement",
|
||||
keyValue: null,
|
||||
column: "UnitOfMeasurement",
|
||||
value: "");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "UnitOfMeasurement",
|
||||
table: "ActivityMasters",
|
||||
type: "longtext",
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "ActivityMasters",
|
||||
keyColumn: "ActivityName",
|
||||
keyValue: null,
|
||||
column: "ActivityName",
|
||||
value: "");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "ActivityName",
|
||||
table: "ActivityMasters",
|
||||
type: "longtext",
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "ActivityGroupId",
|
||||
table: "ActivityMasters",
|
||||
type: "char(36)",
|
||||
nullable: true,
|
||||
collation: "ascii_general_ci");
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "IsSystem",
|
||||
table: "ActivityMasters",
|
||||
type: "tinyint(1)",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "GlobalServiceMasters",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
Name = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Description = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_GlobalServiceMasters", x => x.Id);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Organizations",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
Name = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Email = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
ContactPerson = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Address = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
ContactNumber = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
SPRID = table.Column<double>(type: "double", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
CreatedById = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
|
||||
UpdatedById = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
|
||||
UpdatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: true),
|
||||
IsActive = table.Column<bool>(type: "tinyint(1)", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Organizations", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Organizations_Employees_CreatedById",
|
||||
column: x => x.CreatedById,
|
||||
principalTable: "Employees",
|
||||
principalColumn: "Id");
|
||||
table.ForeignKey(
|
||||
name: "FK_Organizations_Employees_UpdatedById",
|
||||
column: x => x.UpdatedById,
|
||||
principalTable: "Employees",
|
||||
principalColumn: "Id");
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "OrgTypeMasters",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
Name = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_OrgTypeMasters", x => x.Id);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ServiceMasters",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
Name = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Description = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
IsSystem = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
TenantId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ServiceMasters", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ServiceMasters_Tenants_TenantId",
|
||||
column: x => x.TenantId,
|
||||
principalTable: "Tenants",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "GlobalActivityGroupMasters",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
Name = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Description = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
ServiceId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_GlobalActivityGroupMasters", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_GlobalActivityGroupMasters_GlobalServiceMasters_ServiceId",
|
||||
column: x => x.ServiceId,
|
||||
principalTable: "GlobalServiceMasters",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "OrgServiceMappings",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
OrganizationId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
ServiceId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_OrgServiceMappings", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_OrgServiceMappings_GlobalServiceMasters_ServiceId",
|
||||
column: x => x.ServiceId,
|
||||
principalTable: "GlobalServiceMasters",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_OrgServiceMappings_Organizations_OrganizationId",
|
||||
column: x => x.OrganizationId,
|
||||
principalTable: "Organizations",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "TenantOrgMappings",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
OrganizationId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
SPRID = table.Column<double>(type: "double", nullable: false),
|
||||
IsActive = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
AssignedDate = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
ReassignedDate = table.Column<DateTime>(type: "datetime(6)", nullable: true),
|
||||
TenantId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_TenantOrgMappings", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_TenantOrgMappings_Organizations_OrganizationId",
|
||||
column: x => x.OrganizationId,
|
||||
principalTable: "Organizations",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_TenantOrgMappings_Tenants_TenantId",
|
||||
column: x => x.TenantId,
|
||||
principalTable: "Tenants",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ActivityGroupMasters",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
Name = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Description = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
ServiceId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
IsSystem = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
TenantId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ActivityGroupMasters", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ActivityGroupMasters_ServiceMasters_ServiceId",
|
||||
column: x => x.ServiceId,
|
||||
principalTable: "ServiceMasters",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_ActivityGroupMasters_Tenants_TenantId",
|
||||
column: x => x.TenantId,
|
||||
principalTable: "Tenants",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ProjectServiceMappings",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
ServiceId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
ProjectId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
PlannedStartDate = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
PlannedEndDate = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
ActualStartDate = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
ActualEndDate = table.Column<DateTime>(type: "datetime(6)", nullable: true),
|
||||
TenantId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ProjectServiceMappings", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ProjectServiceMappings_Projects_ProjectId",
|
||||
column: x => x.ProjectId,
|
||||
principalTable: "Projects",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_ProjectServiceMappings_ServiceMasters_ServiceId",
|
||||
column: x => x.ServiceId,
|
||||
principalTable: "ServiceMasters",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_ProjectServiceMappings_Tenants_TenantId",
|
||||
column: x => x.TenantId,
|
||||
principalTable: "Tenants",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "GlobalActivityMasters",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
ActivityName = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
UnitOfMeasurement = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
ActivityGroupId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
IsActive = table.Column<bool>(type: "tinyint(1)", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_GlobalActivityMasters", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_GlobalActivityMasters_GlobalActivityGroupMasters_ActivityGro~",
|
||||
column: x => x.ActivityGroupId,
|
||||
principalTable: "GlobalActivityGroupMasters",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ProjectOrgMappings",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
OrganizationId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
ParentOrganizationId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
ProjectServiceId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
OrganizationTypeId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
AssignedDate = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
CompletionDate = table.Column<DateTime>(type: "datetime(6)", nullable: true),
|
||||
TenantId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ProjectOrgMappings", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ProjectOrgMappings_OrgTypeMasters_OrganizationTypeId",
|
||||
column: x => x.OrganizationTypeId,
|
||||
principalTable: "OrgTypeMasters",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_ProjectOrgMappings_Organizations_OrganizationId",
|
||||
column: x => x.OrganizationId,
|
||||
principalTable: "Organizations",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_ProjectOrgMappings_Organizations_ParentOrganizationId",
|
||||
column: x => x.ParentOrganizationId,
|
||||
principalTable: "Organizations",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_ProjectOrgMappings_ProjectServiceMappings_ProjectServiceId",
|
||||
column: x => x.ProjectServiceId,
|
||||
principalTable: "ProjectServiceMappings",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_ProjectOrgMappings_Tenants_TenantId",
|
||||
column: x => x.TenantId,
|
||||
principalTable: "Tenants",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "DocumentCategoryMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("2d9fb9cf-db53-476b-a452-492e88e2b51f"),
|
||||
column: "CreatedAt",
|
||||
value: new DateTime(2025, 9, 15, 12, 42, 3, 202, DateTimeKind.Utc));
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "DocumentCategoryMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("cfbff269-072b-477a-b48b-72cdc57dd1d3"),
|
||||
column: "CreatedAt",
|
||||
value: new DateTime(2025, 9, 15, 12, 42, 3, 202, DateTimeKind.Utc));
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "DocumentTypeMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("07ca7182-9ac0-4407-b988-59901170cb86"),
|
||||
column: "CreatedAt",
|
||||
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc));
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "DocumentTypeMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("16c40b80-c207-4a0c-a4d3-381414afe35a"),
|
||||
column: "CreatedAt",
|
||||
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc));
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "DocumentTypeMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("260abd7e-c96d-4ae4-a29b-9b5bb5d24ebd"),
|
||||
column: "CreatedAt",
|
||||
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc));
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "DocumentTypeMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("2d1d7441-46a8-425e-9395-94d0956f8e91"),
|
||||
column: "CreatedAt",
|
||||
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc));
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "DocumentTypeMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("336225ac-67f3-4e14-ba7a-8fad03cf2832"),
|
||||
column: "CreatedAt",
|
||||
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc));
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "DocumentTypeMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("5668de00-5d84-47f7-b9b5-7fefd1219f05"),
|
||||
column: "CreatedAt",
|
||||
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc));
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "DocumentTypeMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("6344393b-9bb1-45f8-b620-9f6e279d012c"),
|
||||
column: "CreatedAt",
|
||||
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc));
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "DocumentTypeMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("7cc41c91-23cb-442b-badd-f932138d149f"),
|
||||
column: "CreatedAt",
|
||||
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc));
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "DocumentTypeMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("846e89a9-5735-45ec-a21d-c97f85a94ada"),
|
||||
column: "CreatedAt",
|
||||
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc));
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "DocumentTypeMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("a1a190ba-c4a8-432f-b26d-1231ca1d44bc"),
|
||||
column: "CreatedAt",
|
||||
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc));
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "DocumentTypeMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("f76d8215-d399-4f0e-b414-12e427f50be3"),
|
||||
column: "CreatedAt",
|
||||
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc));
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "OrgTypeMasters",
|
||||
columns: new[] { "Id", "Name" },
|
||||
values: new object[,]
|
||||
{
|
||||
{ new Guid("5ee49bcd-b6d3-482f-9aaf-484afe04abec"), "Service Provider" },
|
||||
{ new Guid("743806fe-d991-4079-b223-e4e2da44f435"), "Tenant" },
|
||||
{ new Guid("a283356a-9b02-4029-afb7-e65c703efdd4"), "Sub-Contractor" },
|
||||
{ new Guid("b1877a3b-8832-47b1-bbe3-dc7e98672f49"), "PMC" }
|
||||
});
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "Organizations",
|
||||
columns: new[] { "Id", "Address", "ContactNumber", "ContactPerson", "CreatedAt", "CreatedById", "Email", "IsActive", "Name", "SPRID", "UpdatedAt", "UpdatedById" },
|
||||
values: new object[] { new Guid("4e3a6d31-c640-40f7-8d67-6c109fcdb9ea"), "2nd Floor, Fullora Building, Tejas CHS, behind Kothrud Stand, Tejas Society, Dahanukar Colony, Kothrud, Pune, Maharashtra 411038", "123456789", "Admin", new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), null, "admin@marcoaiot.com", true, "MarcoBMS", 5400.0, null, null });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ActivityMasters_ActivityGroupId",
|
||||
table: "ActivityMasters",
|
||||
column: "ActivityGroupId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ActivityGroupMasters_ServiceId",
|
||||
table: "ActivityGroupMasters",
|
||||
column: "ServiceId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ActivityGroupMasters_TenantId",
|
||||
table: "ActivityGroupMasters",
|
||||
column: "TenantId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_GlobalActivityGroupMasters_ServiceId",
|
||||
table: "GlobalActivityGroupMasters",
|
||||
column: "ServiceId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_GlobalActivityMasters_ActivityGroupId",
|
||||
table: "GlobalActivityMasters",
|
||||
column: "ActivityGroupId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Organizations_CreatedById",
|
||||
table: "Organizations",
|
||||
column: "CreatedById");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Organizations_UpdatedById",
|
||||
table: "Organizations",
|
||||
column: "UpdatedById");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_OrgServiceMappings_OrganizationId",
|
||||
table: "OrgServiceMappings",
|
||||
column: "OrganizationId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_OrgServiceMappings_ServiceId",
|
||||
table: "OrgServiceMappings",
|
||||
column: "ServiceId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ProjectOrgMappings_OrganizationId",
|
||||
table: "ProjectOrgMappings",
|
||||
column: "OrganizationId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ProjectOrgMappings_OrganizationTypeId",
|
||||
table: "ProjectOrgMappings",
|
||||
column: "OrganizationTypeId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ProjectOrgMappings_ParentOrganizationId",
|
||||
table: "ProjectOrgMappings",
|
||||
column: "ParentOrganizationId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ProjectOrgMappings_ProjectServiceId",
|
||||
table: "ProjectOrgMappings",
|
||||
column: "ProjectServiceId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ProjectOrgMappings_TenantId",
|
||||
table: "ProjectOrgMappings",
|
||||
column: "TenantId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ProjectServiceMappings_ProjectId",
|
||||
table: "ProjectServiceMappings",
|
||||
column: "ProjectId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ProjectServiceMappings_ServiceId",
|
||||
table: "ProjectServiceMappings",
|
||||
column: "ServiceId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ProjectServiceMappings_TenantId",
|
||||
table: "ProjectServiceMappings",
|
||||
column: "TenantId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ServiceMasters_TenantId",
|
||||
table: "ServiceMasters",
|
||||
column: "TenantId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TenantOrgMappings_OrganizationId",
|
||||
table: "TenantOrgMappings",
|
||||
column: "OrganizationId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TenantOrgMappings_TenantId",
|
||||
table: "TenantOrgMappings",
|
||||
column: "TenantId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_ActivityMasters_ActivityGroupMasters_ActivityGroupId",
|
||||
table: "ActivityMasters",
|
||||
column: "ActivityGroupId",
|
||||
principalTable: "ActivityGroupMasters",
|
||||
principalColumn: "Id");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_ActivityMasters_ActivityGroupMasters_ActivityGroupId",
|
||||
table: "ActivityMasters");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ActivityGroupMasters");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "GlobalActivityMasters");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "OrgServiceMappings");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ProjectOrgMappings");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "TenantOrgMappings");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "GlobalActivityGroupMasters");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "OrgTypeMasters");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ProjectServiceMappings");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Organizations");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "GlobalServiceMasters");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ServiceMasters");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_ActivityMasters_ActivityGroupId",
|
||||
table: "ActivityMasters");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "ActivityGroupId",
|
||||
table: "ActivityMasters");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "IsSystem",
|
||||
table: "ActivityMasters");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "UnitOfMeasurement",
|
||||
table: "ActivityMasters",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "ActivityName",
|
||||
table: "ActivityMasters",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "DocumentCategoryMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("2d9fb9cf-db53-476b-a452-492e88e2b51f"),
|
||||
column: "CreatedAt",
|
||||
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6233));
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "DocumentCategoryMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("cfbff269-072b-477a-b48b-72cdc57dd1d3"),
|
||||
column: "CreatedAt",
|
||||
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6226));
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "DocumentTypeMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("07ca7182-9ac0-4407-b988-59901170cb86"),
|
||||
column: "CreatedAt",
|
||||
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6307));
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "DocumentTypeMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("16c40b80-c207-4a0c-a4d3-381414afe35a"),
|
||||
column: "CreatedAt",
|
||||
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6290));
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "DocumentTypeMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("260abd7e-c96d-4ae4-a29b-9b5bb5d24ebd"),
|
||||
column: "CreatedAt",
|
||||
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6298));
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "DocumentTypeMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("2d1d7441-46a8-425e-9395-94d0956f8e91"),
|
||||
column: "CreatedAt",
|
||||
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6286));
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "DocumentTypeMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("336225ac-67f3-4e14-ba7a-8fad03cf2832"),
|
||||
column: "CreatedAt",
|
||||
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6275));
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "DocumentTypeMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("5668de00-5d84-47f7-b9b5-7fefd1219f05"),
|
||||
column: "CreatedAt",
|
||||
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6319));
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "DocumentTypeMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("6344393b-9bb1-45f8-b620-9f6e279d012c"),
|
||||
column: "CreatedAt",
|
||||
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6282));
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "DocumentTypeMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("7cc41c91-23cb-442b-badd-f932138d149f"),
|
||||
column: "CreatedAt",
|
||||
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6314));
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "DocumentTypeMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("846e89a9-5735-45ec-a21d-c97f85a94ada"),
|
||||
column: "CreatedAt",
|
||||
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6311));
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "DocumentTypeMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("a1a190ba-c4a8-432f-b26d-1231ca1d44bc"),
|
||||
column: "CreatedAt",
|
||||
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6302));
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "DocumentTypeMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("f76d8215-d399-4f0e-b414-12e427f50be3"),
|
||||
column: "CreatedAt",
|
||||
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6295));
|
||||
}
|
||||
}
|
||||
}
|
6117
Marco.Pms.DataAccess/Migrations/20250917055522_Added_IsActive_In_ServiceMaster.Designer.cs
generated
Normal file
6117
Marco.Pms.DataAccess/Migrations/20250917055522_Added_IsActive_In_ServiceMaster.Designer.cs
generated
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,77 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional
|
||||
|
||||
namespace Marco.Pms.DataAccess.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Added_IsActive_In_ServiceMaster : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "IsActive",
|
||||
table: "ServiceMasters",
|
||||
type: "tinyint(1)",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "IsActive",
|
||||
table: "ActivityGroupMasters",
|
||||
type: "tinyint(1)",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "Features",
|
||||
columns: new[] { "Id", "Description", "IsActive", "ModuleId", "Name" },
|
||||
values: new object[] { new Guid("6d4c82d6-dbce-48ab-b8b8-f785f4d8c914"), "Managing all organization related rights", true, new Guid("c43db8c7-ab73-47f4-9d3b-f83e81357924"), "Organization Management" });
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "FeaturePermissions",
|
||||
columns: new[] { "Id", "Description", "FeatureId", "IsEnabled", "Name" },
|
||||
values: new object[,]
|
||||
{
|
||||
{ new Guid("068cb3c1-49c5-4746-9f29-1fce16e820ac"), "Allow user to create new organization", new Guid("6d4c82d6-dbce-48ab-b8b8-f785f4d8c914"), true, "Add Organization" },
|
||||
{ new Guid("7a6cf830-0008-4e03-b31d-0d050cb634f4"), "Allow the user to view information of the organization", new Guid("6d4c82d6-dbce-48ab-b8b8-f785f4d8c914"), true, "View Organization" },
|
||||
{ new Guid("c1ae1363-ab8a-4bd9-a9d1-8c2c6083873a"), "Allow the user to update the basic information of the organization", new Guid("6d4c82d6-dbce-48ab-b8b8-f785f4d8c914"), true, "Edit Organization" }
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DeleteData(
|
||||
table: "FeaturePermissions",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("068cb3c1-49c5-4746-9f29-1fce16e820ac"));
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "FeaturePermissions",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("7a6cf830-0008-4e03-b31d-0d050cb634f4"));
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "FeaturePermissions",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("c1ae1363-ab8a-4bd9-a9d1-8c2c6083873a"));
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "Features",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("6d4c82d6-dbce-48ab-b8b8-f785f4d8c914"));
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "IsActive",
|
||||
table: "ServiceMasters");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "IsActive",
|
||||
table: "ActivityGroupMasters");
|
||||
}
|
||||
}
|
||||
}
|
6114
Marco.Pms.DataAccess/Migrations/20250917063934_Updated_EMployee_Table.Designer.cs
generated
Normal file
6114
Marco.Pms.DataAccess/Migrations/20250917063934_Updated_EMployee_Table.Designer.cs
generated
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,136 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Marco.Pms.DataAccess.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Updated_EMployee_Table : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Employees_JobRoles_JobRoleId",
|
||||
table: "Employees");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AadharNumber",
|
||||
table: "Employees");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "PanNumber",
|
||||
table: "Employees");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "RoleId",
|
||||
table: "Employees");
|
||||
|
||||
migrationBuilder.AlterColumn<Guid>(
|
||||
name: "JobRoleId",
|
||||
table: "Employees",
|
||||
type: "char(36)",
|
||||
nullable: false,
|
||||
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"),
|
||||
collation: "ascii_general_ci",
|
||||
oldClrType: typeof(Guid),
|
||||
oldType: "char(36)",
|
||||
oldNullable: true)
|
||||
.OldAnnotation("Relational:Collation", "ascii_general_ci");
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "Employees",
|
||||
keyColumn: "FirstName",
|
||||
keyValue: null,
|
||||
column: "FirstName",
|
||||
value: "");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "FirstName",
|
||||
table: "Employees",
|
||||
type: "longtext",
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "HasApplicationAccess",
|
||||
table: "Employees",
|
||||
type: "tinyint(1)",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Employees_JobRoles_JobRoleId",
|
||||
table: "Employees",
|
||||
column: "JobRoleId",
|
||||
principalTable: "JobRoles",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Employees_JobRoles_JobRoleId",
|
||||
table: "Employees");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "HasApplicationAccess",
|
||||
table: "Employees");
|
||||
|
||||
migrationBuilder.AlterColumn<Guid>(
|
||||
name: "JobRoleId",
|
||||
table: "Employees",
|
||||
type: "char(36)",
|
||||
nullable: true,
|
||||
collation: "ascii_general_ci",
|
||||
oldClrType: typeof(Guid),
|
||||
oldType: "char(36)")
|
||||
.OldAnnotation("Relational:Collation", "ascii_general_ci");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "FirstName",
|
||||
table: "Employees",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "AadharNumber",
|
||||
table: "Employees",
|
||||
type: "longtext",
|
||||
nullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "PanNumber",
|
||||
table: "Employees",
|
||||
type: "longtext",
|
||||
nullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "RoleId",
|
||||
table: "Employees",
|
||||
type: "char(36)",
|
||||
nullable: false,
|
||||
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"),
|
||||
collation: "ascii_general_ci");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Employees_JobRoles_JobRoleId",
|
||||
table: "Employees",
|
||||
column: "JobRoleId",
|
||||
principalTable: "JobRoles",
|
||||
principalColumn: "Id");
|
||||
}
|
||||
}
|
||||
}
|
6098
Marco.Pms.DataAccess/Migrations/20250917072710_Added_Organization_In_Employee_Table.Designer.cs
generated
Normal file
6098
Marco.Pms.DataAccess/Migrations/20250917072710_Added_Organization_In_Employee_Table.Designer.cs
generated
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,70 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Marco.Pms.DataAccess.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Added_Organization_In_Employee_Table : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Organizations_Employees_CreatedById",
|
||||
table: "Organizations");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Organizations_Employees_UpdatedById",
|
||||
table: "Organizations");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Organizations_CreatedById",
|
||||
table: "Organizations");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Organizations_UpdatedById",
|
||||
table: "Organizations");
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "OrganizationId",
|
||||
table: "Employees",
|
||||
type: "char(36)",
|
||||
nullable: false,
|
||||
defaultValue: new Guid("4e3a6d31-c640-40f7-8d67-6c109fcdb9ea"),
|
||||
collation: "ascii_general_ci");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "OrganizationId",
|
||||
table: "Employees");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Organizations_CreatedById",
|
||||
table: "Organizations",
|
||||
column: "CreatedById");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Organizations_UpdatedById",
|
||||
table: "Organizations",
|
||||
column: "UpdatedById");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Organizations_Employees_CreatedById",
|
||||
table: "Organizations",
|
||||
column: "CreatedById",
|
||||
principalTable: "Employees",
|
||||
principalColumn: "Id");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Organizations_Employees_UpdatedById",
|
||||
table: "Organizations",
|
||||
column: "UpdatedById",
|
||||
principalTable: "Employees",
|
||||
principalColumn: "Id");
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,39 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Marco.Pms.DataAccess.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Added_Organization_In_Employee_Table_As_Forgin_Key : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Employees_OrganizationId",
|
||||
table: "Employees",
|
||||
column: "OrganizationId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Employees_Organizations_OrganizationId",
|
||||
table: "Employees",
|
||||
column: "OrganizationId",
|
||||
principalTable: "Organizations",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Employees_Organizations_OrganizationId",
|
||||
table: "Employees");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Employees_OrganizationId",
|
||||
table: "Employees");
|
||||
}
|
||||
}
|
||||
}
|
6111
Marco.Pms.DataAccess/Migrations/20250917090050_Added_IsPrimary_Parameter_In_Employee_Table.Designer.cs
generated
Normal file
6111
Marco.Pms.DataAccess/Migrations/20250917090050_Added_IsPrimary_Parameter_In_Employee_Table.Designer.cs
generated
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,29 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Marco.Pms.DataAccess.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Added_IsPrimary_Parameter_In_Employee_Table : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "IsPrimary",
|
||||
table: "Employees",
|
||||
type: "tinyint(1)",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "IsPrimary",
|
||||
table: "Employees");
|
||||
}
|
||||
}
|
||||
}
|
6122
Marco.Pms.DataAccess/Migrations/20250917092024_Added_Organization_In_Tenant_Table_As_Forgin_Key.Designer.cs
generated
Normal file
6122
Marco.Pms.DataAccess/Migrations/20250917092024_Added_Organization_In_Tenant_Table_As_Forgin_Key.Designer.cs
generated
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,69 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Marco.Pms.DataAccess.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Added_Organization_In_Tenant_Table_As_Forgin_Key : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "TenantId",
|
||||
table: "AspNetUsers");
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "OrganizationId",
|
||||
table: "Tenants",
|
||||
type: "char(36)",
|
||||
nullable: false,
|
||||
defaultValue: new Guid("4e3a6d31-c640-40f7-8d67-6c109fcdb9ea"),
|
||||
collation: "ascii_general_ci");
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "Tenants",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("b3466e83-7e11-464c-b93a-daf047838b26"),
|
||||
column: "OrganizationId",
|
||||
value: new Guid("4e3a6d31-c640-40f7-8d67-6c109fcdb9ea"));
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Tenants_OrganizationId",
|
||||
table: "Tenants",
|
||||
column: "OrganizationId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Tenants_Organizations_OrganizationId",
|
||||
table: "Tenants",
|
||||
column: "OrganizationId",
|
||||
principalTable: "Organizations",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Tenants_Organizations_OrganizationId",
|
||||
table: "Tenants");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Tenants_OrganizationId",
|
||||
table: "Tenants");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "OrganizationId",
|
||||
table: "Tenants");
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "TenantId",
|
||||
table: "AspNetUsers",
|
||||
type: "char(36)",
|
||||
nullable: true,
|
||||
collation: "ascii_general_ci");
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,136 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Marco.Pms.DataAccess.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Added_Promoter_And_PMC_In_Project_Table_As_Forgin_Key : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Employees_Tenants_TenantId",
|
||||
table: "Employees");
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "PMCId",
|
||||
table: "Projects",
|
||||
type: "char(36)",
|
||||
nullable: false,
|
||||
defaultValue: new Guid("4e3a6d31-c640-40f7-8d67-6c109fcdb9ea"),
|
||||
collation: "ascii_general_ci");
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "PromoterId",
|
||||
table: "Projects",
|
||||
type: "char(36)",
|
||||
nullable: false,
|
||||
defaultValue: new Guid("4e3a6d31-c640-40f7-8d67-6c109fcdb9ea"),
|
||||
collation: "ascii_general_ci");
|
||||
|
||||
migrationBuilder.AlterColumn<Guid>(
|
||||
name: "TenantId",
|
||||
table: "Employees",
|
||||
type: "char(36)",
|
||||
nullable: true,
|
||||
collation: "ascii_general_ci",
|
||||
oldClrType: typeof(Guid),
|
||||
oldType: "char(36)")
|
||||
.OldAnnotation("Relational:Collation", "ascii_general_ci");
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "Projects",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("85bf587b-7ca9-4685-b77c-d817f5847e85"),
|
||||
columns: new[] { "PMCId", "PromoterId" },
|
||||
values: new object[] { new Guid("4e3a6d31-c640-40f7-8d67-6c109fcdb9ea"), new Guid("4e3a6d31-c640-40f7-8d67-6c109fcdb9ea") });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Projects_PMCId",
|
||||
table: "Projects",
|
||||
column: "PMCId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Projects_PromoterId",
|
||||
table: "Projects",
|
||||
column: "PromoterId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Employees_Tenants_TenantId",
|
||||
table: "Employees",
|
||||
column: "TenantId",
|
||||
principalTable: "Tenants",
|
||||
principalColumn: "Id");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Projects_Organizations_PMCId",
|
||||
table: "Projects",
|
||||
column: "PMCId",
|
||||
principalTable: "Organizations",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Projects_Organizations_PromoterId",
|
||||
table: "Projects",
|
||||
column: "PromoterId",
|
||||
principalTable: "Organizations",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Employees_Tenants_TenantId",
|
||||
table: "Employees");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Projects_Organizations_PMCId",
|
||||
table: "Projects");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Projects_Organizations_PromoterId",
|
||||
table: "Projects");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Projects_PMCId",
|
||||
table: "Projects");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Projects_PromoterId",
|
||||
table: "Projects");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "PMCId",
|
||||
table: "Projects");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "PromoterId",
|
||||
table: "Projects");
|
||||
|
||||
migrationBuilder.AlterColumn<Guid>(
|
||||
name: "TenantId",
|
||||
table: "Employees",
|
||||
type: "char(36)",
|
||||
nullable: false,
|
||||
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"),
|
||||
collation: "ascii_general_ci",
|
||||
oldClrType: typeof(Guid),
|
||||
oldType: "char(36)",
|
||||
oldNullable: true)
|
||||
.OldAnnotation("Relational:Collation", "ascii_general_ci");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Employees_Tenants_TenantId",
|
||||
table: "Employees",
|
||||
column: "TenantId",
|
||||
principalTable: "Tenants",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
}
|
||||
}
|
6151
Marco.Pms.DataAccess/Migrations/20250918112243_Added_IsActive_In_ProjectServiceMapping_Table.Designer.cs
generated
Normal file
6151
Marco.Pms.DataAccess/Migrations/20250918112243_Added_IsActive_In_ProjectServiceMapping_Table.Designer.cs
generated
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,29 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Marco.Pms.DataAccess.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Added_IsActive_In_ProjectServiceMapping_Table : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "IsActive",
|
||||
table: "ProjectServiceMappings",
|
||||
type: "tinyint(1)",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "IsActive",
|
||||
table: "ProjectServiceMappings");
|
||||
}
|
||||
}
|
||||
}
|
6119
Marco.Pms.DataAccess/Migrations/20250920041347_Removed_TenantId_From_MPIN_And_OTP.Designer.cs
generated
Normal file
6119
Marco.Pms.DataAccess/Migrations/20250920041347_Removed_TenantId_From_MPIN_And_OTP.Designer.cs
generated
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Marco.Pms.DataAccess.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Removed_TenantId_From_MPIN_And_OTP : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_MPINDetails_Tenants_TenantId",
|
||||
table: "MPINDetails");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_OTPDetails_Tenants_TenantId",
|
||||
table: "OTPDetails");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_OTPDetails_TenantId",
|
||||
table: "OTPDetails");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_MPINDetails_TenantId",
|
||||
table: "MPINDetails");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "TenantId",
|
||||
table: "OTPDetails");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "TenantId",
|
||||
table: "MPINDetails");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "TenantId",
|
||||
table: "OTPDetails",
|
||||
type: "char(36)",
|
||||
nullable: false,
|
||||
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"),
|
||||
collation: "ascii_general_ci");
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "TenantId",
|
||||
table: "MPINDetails",
|
||||
type: "char(36)",
|
||||
nullable: false,
|
||||
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"),
|
||||
collation: "ascii_general_ci");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_OTPDetails_TenantId",
|
||||
table: "OTPDetails",
|
||||
column: "TenantId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_MPINDetails_TenantId",
|
||||
table: "MPINDetails",
|
||||
column: "TenantId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_MPINDetails_Tenants_TenantId",
|
||||
table: "MPINDetails",
|
||||
column: "TenantId",
|
||||
principalTable: "Tenants",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_OTPDetails_Tenants_TenantId",
|
||||
table: "OTPDetails",
|
||||
column: "TenantId",
|
||||
principalTable: "Tenants",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
}
|
||||
}
|
6133
Marco.Pms.DataAccess/Migrations/20250920105816_Added_Service_FK_In_ProjectAllocation.Designer.cs
generated
Normal file
6133
Marco.Pms.DataAccess/Migrations/20250920105816_Added_Service_FK_In_ProjectAllocation.Designer.cs
generated
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Marco.Pms.DataAccess.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Added_Service_FK_In_ProjectAllocation : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "ServiceId",
|
||||
table: "ProjectAllocations",
|
||||
type: "char(36)",
|
||||
nullable: true,
|
||||
collation: "ascii_general_ci");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "logoImage",
|
||||
table: "Organizations",
|
||||
type: "longtext",
|
||||
nullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "Organizations",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("4e3a6d31-c640-40f7-8d67-6c109fcdb9ea"),
|
||||
column: "logoImage",
|
||||
value: null);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ProjectAllocations_ServiceId",
|
||||
table: "ProjectAllocations",
|
||||
column: "ServiceId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_ProjectAllocations_ServiceMasters_ServiceId",
|
||||
table: "ProjectAllocations",
|
||||
column: "ServiceId",
|
||||
principalTable: "ServiceMasters",
|
||||
principalColumn: "Id");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_ProjectAllocations_ServiceMasters_ServiceId",
|
||||
table: "ProjectAllocations");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_ProjectAllocations_ServiceId",
|
||||
table: "ProjectAllocations");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "ServiceId",
|
||||
table: "ProjectAllocations");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "logoImage",
|
||||
table: "Organizations");
|
||||
}
|
||||
}
|
||||
}
|
6207
Marco.Pms.DataAccess/Migrations/20250924103942_Added_Assigned_By_In_Mapping_Tables.Designer.cs
generated
Normal file
6207
Marco.Pms.DataAccess/Migrations/20250924103942_Added_Assigned_By_In_Mapping_Tables.Designer.cs
generated
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,84 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Marco.Pms.DataAccess.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Added_Assigned_By_In_Mapping_Tables : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "AssignedById",
|
||||
table: "TenantOrgMappings",
|
||||
type: "char(36)",
|
||||
nullable: false,
|
||||
defaultValue: new Guid("08dd8b35-d98b-44f1-896d-12aec3f035aa"),
|
||||
collation: "ascii_general_ci");
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "AssignedById",
|
||||
table: "ProjectOrgMappings",
|
||||
type: "char(36)",
|
||||
nullable: false,
|
||||
defaultValue: new Guid("08dd8b35-d98b-44f1-896d-12aec3f035aa"),
|
||||
collation: "ascii_general_ci");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TenantOrgMappings_AssignedById",
|
||||
table: "TenantOrgMappings",
|
||||
column: "AssignedById");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ProjectOrgMappings_AssignedById",
|
||||
table: "ProjectOrgMappings",
|
||||
column: "AssignedById");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_ProjectOrgMappings_Employees_AssignedById",
|
||||
table: "ProjectOrgMappings",
|
||||
column: "AssignedById",
|
||||
principalTable: "Employees",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_TenantOrgMappings_Employees_AssignedById",
|
||||
table: "TenantOrgMappings",
|
||||
column: "AssignedById",
|
||||
principalTable: "Employees",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_ProjectOrgMappings_Employees_AssignedById",
|
||||
table: "ProjectOrgMappings");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_TenantOrgMappings_Employees_AssignedById",
|
||||
table: "TenantOrgMappings");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_TenantOrgMappings_AssignedById",
|
||||
table: "TenantOrgMappings");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_ProjectOrgMappings_AssignedById",
|
||||
table: "ProjectOrgMappings");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AssignedById",
|
||||
table: "TenantOrgMappings");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AssignedById",
|
||||
table: "ProjectOrgMappings");
|
||||
}
|
||||
}
|
||||
}
|
6197
Marco.Pms.DataAccess/Migrations/20250924113835_Deleted_Organization_Types.Designer.cs
generated
Normal file
6197
Marco.Pms.DataAccess/Migrations/20250924113835_Deleted_Organization_Types.Designer.cs
generated
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional
|
||||
|
||||
namespace Marco.Pms.DataAccess.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Deleted_Organization_Types : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DeleteData(
|
||||
table: "OrgTypeMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("743806fe-d991-4079-b223-e4e2da44f435"));
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "OrgTypeMasters",
|
||||
keyColumn: "Id",
|
||||
keyValue: new Guid("b1877a3b-8832-47b1-bbe3-dc7e98672f49"));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.InsertData(
|
||||
table: "OrgTypeMasters",
|
||||
columns: new[] { "Id", "Name" },
|
||||
values: new object[,]
|
||||
{
|
||||
{ new Guid("743806fe-d991-4079-b223-e4e2da44f435"), "Tenant" },
|
||||
{ new Guid("b1877a3b-8832-47b1-bbe3-dc7e98672f49"), "PMC" }
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
6205
Marco.Pms.DataAccess/Migrations/20250927091428_Added_Forgin_Key_For_Approver.Designer.cs
generated
Normal file
6205
Marco.Pms.DataAccess/Migrations/20250927091428_Added_Forgin_Key_For_Approver.Designer.cs
generated
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,92 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Marco.Pms.DataAccess.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Added_Forgin_Key_For_Approver : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Attendes_Employees_EmployeeID",
|
||||
table: "Attendes");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "EmployeeID",
|
||||
table: "Attendes",
|
||||
newName: "EmployeeId");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "ApprovedBy",
|
||||
table: "Attendes",
|
||||
newName: "ApprovedById");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_Attendes_EmployeeID",
|
||||
table: "Attendes",
|
||||
newName: "IX_Attendes_EmployeeId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Attendes_ApprovedById",
|
||||
table: "Attendes",
|
||||
column: "ApprovedById");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Attendes_Employees_ApprovedById",
|
||||
table: "Attendes",
|
||||
column: "ApprovedById",
|
||||
principalTable: "Employees",
|
||||
principalColumn: "Id");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Attendes_Employees_EmployeeId",
|
||||
table: "Attendes",
|
||||
column: "EmployeeId",
|
||||
principalTable: "Employees",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Attendes_Employees_ApprovedById",
|
||||
table: "Attendes");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Attendes_Employees_EmployeeId",
|
||||
table: "Attendes");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Attendes_ApprovedById",
|
||||
table: "Attendes");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "EmployeeId",
|
||||
table: "Attendes",
|
||||
newName: "EmployeeID");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "ApprovedById",
|
||||
table: "Attendes",
|
||||
newName: "ApprovedBy");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_Attendes_EmployeeId",
|
||||
table: "Attendes",
|
||||
newName: "IX_Attendes_EmployeeID");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Attendes_Employees_EmployeeID",
|
||||
table: "Attendes",
|
||||
column: "EmployeeID",
|
||||
principalTable: "Employees",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -20,18 +20,21 @@ namespace Marco.Pms.Helpers.CacheHelper
|
||||
var mongoDB = client.GetDatabase(mongoUrl.DatabaseName); // Your MongoDB Database name
|
||||
_collection = mongoDB.GetCollection<EmployeePermissionMongoDB>("EmployeeProfile");
|
||||
}
|
||||
public async Task<bool> AddApplicationRoleToCache(Guid employeeId, List<string> newRoleIds, List<string> newPermissionIds)
|
||||
public async Task<bool> AddApplicationRoleToCache(Guid employeeId, List<string> newRoleIds, List<string> newPermissionIds, Guid tenantId)
|
||||
{
|
||||
|
||||
// 2. Perform database queries concurrently for better performance.
|
||||
var employeeIdString = employeeId.ToString();
|
||||
var tenantIdString = tenantId.ToString();
|
||||
|
||||
// 5. Build a single, efficient update operation.
|
||||
var filter = Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.Id, employeeIdString);
|
||||
filter &= Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.TenantId, tenantIdString);
|
||||
|
||||
var update = Builders<EmployeePermissionMongoDB>.Update
|
||||
.AddToSetEach(e => e.ApplicationRoleIds, newRoleIds)
|
||||
.Set(r => r.ExpireAt, DateTime.UtcNow.Date.AddDays(1))
|
||||
.Set(r => r.TenantId, tenantIdString)
|
||||
.AddToSetEach(e => e.PermissionIds, newPermissionIds);
|
||||
|
||||
var options = new UpdateOptions { IsUpsert = true };
|
||||
@ -44,14 +47,17 @@ namespace Marco.Pms.Helpers.CacheHelper
|
||||
// The operation is successful if an existing document was modified OR a new one was created.
|
||||
return result.IsAcknowledged && (result.ModifiedCount > 0 || result.UpsertedId != null);
|
||||
}
|
||||
public async Task<bool> AddProjectsToCache(Guid employeeId, List<Guid> projectIds)
|
||||
public async Task<bool> AddProjectsToCache(Guid employeeId, List<Guid> projectIds, Guid tenantId)
|
||||
{
|
||||
var newprojectIds = projectIds.Select(p => p.ToString()).ToList();
|
||||
var tenantIdString = tenantId.ToString();
|
||||
|
||||
var filter = Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.Id, employeeId.ToString());
|
||||
filter &= Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.TenantId, tenantIdString);
|
||||
|
||||
var update = Builders<EmployeePermissionMongoDB>.Update
|
||||
.Set(r => r.ExpireAt, DateTime.UtcNow.Date.AddDays(1))
|
||||
.Set(r => r.TenantId, tenantIdString)
|
||||
.AddToSetEach(e => e.ProjectIds, newprojectIds);
|
||||
|
||||
var result = await _collection.UpdateOneAsync(filter, update, new UpdateOptions { IsUpsert = true });
|
||||
@ -62,10 +68,12 @@ namespace Marco.Pms.Helpers.CacheHelper
|
||||
await InitializeCollectionAsync();
|
||||
return true;
|
||||
}
|
||||
public async Task<List<Guid>> GetProjectsFromCache(Guid employeeId)
|
||||
public async Task<List<Guid>> GetProjectsFromCache(Guid employeeId, Guid tenantId)
|
||||
{
|
||||
var filter = Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.Id, employeeId.ToString());
|
||||
var tenantIdString = tenantId.ToString();
|
||||
|
||||
var filter = Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.Id, employeeId.ToString());
|
||||
filter &= Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.TenantId, tenantIdString);
|
||||
|
||||
var result = await _collection
|
||||
.Find(filter)
|
||||
@ -79,10 +87,12 @@ namespace Marco.Pms.Helpers.CacheHelper
|
||||
|
||||
return projectIds;
|
||||
}
|
||||
public async Task<List<Guid>> GetPermissionsFromCache(Guid employeeId)
|
||||
public async Task<List<Guid>> GetPermissionsFromCache(Guid employeeId, Guid tenantId)
|
||||
{
|
||||
var filter = Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.Id, employeeId.ToString());
|
||||
var tenantIdString = tenantId.ToString();
|
||||
|
||||
var filter = Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.Id, employeeId.ToString());
|
||||
filter &= Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.TenantId, tenantIdString);
|
||||
|
||||
var result = await _collection
|
||||
.Find(filter)
|
||||
@ -96,10 +106,13 @@ namespace Marco.Pms.Helpers.CacheHelper
|
||||
|
||||
return permissionIds;
|
||||
}
|
||||
public async Task<bool> ClearAllProjectIdsFromCache(Guid employeeId)
|
||||
public async Task<bool> ClearAllProjectIdsFromCache(Guid employeeId, Guid tenantId)
|
||||
{
|
||||
var tenantIdString = tenantId.ToString();
|
||||
|
||||
var filter = Builders<EmployeePermissionMongoDB>.Filter
|
||||
.Eq(e => e.Id, employeeId.ToString());
|
||||
filter &= Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.TenantId, tenantIdString);
|
||||
|
||||
var update = Builders<EmployeePermissionMongoDB>.Update
|
||||
.Set(e => e.ProjectIds, new List<string>());
|
||||
@ -125,18 +138,25 @@ namespace Marco.Pms.Helpers.CacheHelper
|
||||
|
||||
return true;
|
||||
}
|
||||
public async Task<bool> ClearAllProjectIdsByPermissionIdFromCache(Guid permissionId)
|
||||
public async Task<bool> ClearAllProjectIdsByPermissionIdFromCache(Guid permissionId, Guid tenantId)
|
||||
{
|
||||
var tenantIdString = tenantId.ToString();
|
||||
|
||||
var filter = Builders<EmployeePermissionMongoDB>.Filter.AnyEq(e => e.PermissionIds, permissionId.ToString());
|
||||
filter &= Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.TenantId, tenantIdString);
|
||||
|
||||
var update = Builders<EmployeePermissionMongoDB>.Update.Set(e => e.ProjectIds, new List<string>());
|
||||
|
||||
var result = await _collection.UpdateManyAsync(filter, update).ConfigureAwait(false);
|
||||
return result.IsAcknowledged && result.ModifiedCount > 0;
|
||||
}
|
||||
public async Task<bool> RemoveRoleIdFromCache(Guid employeeId, Guid roleId)
|
||||
public async Task<bool> RemoveRoleIdFromCache(Guid employeeId, Guid roleId, Guid tenantId)
|
||||
{
|
||||
var tenantIdString = tenantId.ToString();
|
||||
|
||||
var filter = Builders<EmployeePermissionMongoDB>.Filter
|
||||
.Eq(e => e.Id, employeeId.ToString());
|
||||
filter &= Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.TenantId, tenantIdString);
|
||||
|
||||
var update = Builders<EmployeePermissionMongoDB>.Update
|
||||
.Pull(e => e.ApplicationRoleIds, roleId.ToString());
|
||||
@ -151,10 +171,13 @@ namespace Marco.Pms.Helpers.CacheHelper
|
||||
|
||||
return true;
|
||||
}
|
||||
public async Task<bool> ClearAllPermissionIdsByEmployeeIDFromCache(Guid employeeId)
|
||||
public async Task<bool> ClearAllPermissionIdsByEmployeeIDFromCache(Guid employeeId, Guid tenantId)
|
||||
{
|
||||
var tenantIdString = tenantId.ToString();
|
||||
|
||||
var filter = Builders<EmployeePermissionMongoDB>.Filter
|
||||
.Eq(e => e.Id, employeeId.ToString());
|
||||
filter &= Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.TenantId, tenantIdString);
|
||||
|
||||
var update = Builders<EmployeePermissionMongoDB>.Update
|
||||
.Set(e => e.PermissionIds, new List<string>());
|
||||
@ -189,11 +212,14 @@ namespace Marco.Pms.Helpers.CacheHelper
|
||||
|
||||
return true;
|
||||
}
|
||||
public async Task<bool> ClearAllEmployeesFromCacheByEmployeeIds(List<string> employeeIds)
|
||||
public async Task<bool> ClearAllEmployeesFromCacheByEmployeeIds(List<string> employeeIds, Guid tenantId)
|
||||
{
|
||||
var tenantIdString = tenantId.ToString();
|
||||
|
||||
try
|
||||
{
|
||||
var filter = Builders<EmployeePermissionMongoDB>.Filter.In(x => x.Id, employeeIds);
|
||||
filter &= Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.TenantId, tenantIdString);
|
||||
|
||||
var result = await _collection.DeleteManyAsync(filter);
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
using Marco.Pms.DataAccess.Data;
|
||||
using Marco.Pms.Model.Master;
|
||||
using Marco.Pms.Model.MongoDBModels;
|
||||
using Marco.Pms.Model.MongoDBModels.Masters;
|
||||
using Marco.Pms.Model.MongoDBModels.Project;
|
||||
using Marco.Pms.Model.OrganizationModel;
|
||||
using Marco.Pms.Model.Projects;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
@ -55,7 +57,7 @@ namespace Marco.Pms.Helpers
|
||||
var indexModel = new CreateIndexModel<ProjectMongoDB>(indexKeys, indexOptions);
|
||||
await _projectCollection.Indexes.CreateOneAsync(indexModel);
|
||||
}
|
||||
public async Task<bool> UpdateProjectDetailsOnlyToCache(Project project, StatusMaster projectStatus)
|
||||
public async Task<bool> UpdateProjectDetailsOnlyToCache(Project project, StatusMaster projectStatus, Organization promotor, Organization pmc)
|
||||
{
|
||||
// Build the update definition
|
||||
var updates = Builders<ProjectMongoDB>.Update.Combine(
|
||||
@ -67,6 +69,26 @@ namespace Marco.Pms.Helpers
|
||||
Id = projectStatus.Id.ToString(),
|
||||
Status = projectStatus.Status
|
||||
}),
|
||||
Builders<ProjectMongoDB>.Update.Set(r => r.Promoter, new OrganizationMongoDB
|
||||
{
|
||||
Id = promotor.Id.ToString(),
|
||||
Name = promotor.Name,
|
||||
ContactPerson = promotor.ContactPerson,
|
||||
Email = promotor.Email,
|
||||
Address = promotor.Address,
|
||||
ContactNumber = promotor.ContactNumber,
|
||||
SPRID = promotor.SPRID
|
||||
}),
|
||||
Builders<ProjectMongoDB>.Update.Set(r => r.PMC, new OrganizationMongoDB
|
||||
{
|
||||
Id = pmc.Id.ToString(),
|
||||
Name = pmc.Name,
|
||||
ContactPerson = pmc.ContactPerson,
|
||||
Email = pmc.Email,
|
||||
Address = promotor.Address,
|
||||
ContactNumber = promotor.ContactNumber,
|
||||
SPRID = promotor.SPRID
|
||||
}),
|
||||
Builders<ProjectMongoDB>.Update.Set(r => r.StartDate, project.StartDate),
|
||||
Builders<ProjectMongoDB>.Update.Set(r => r.EndDate, project.EndDate),
|
||||
Builders<ProjectMongoDB>.Update.Set(r => r.ContactPerson, project.ContactPerson)
|
||||
@ -407,10 +429,19 @@ namespace Marco.Pms.Helpers
|
||||
|
||||
#region=================================================================== WorkItem Cache Helper ===================================================================
|
||||
|
||||
public async Task<List<WorkItemMongoDB>> GetWorkItemsByWorkAreaIdsFromCache(List<Guid> workAreaIds)
|
||||
public async Task<List<WorkItemMongoDB>> GetWorkItemsByWorkAreaIdsFromCache(List<Guid> workAreaIds, List<Guid> serviceIds)
|
||||
{
|
||||
var stringWorkAreaIds = workAreaIds.Select(wa => wa.ToString()).ToList();
|
||||
var filter = Builders<WorkItemMongoDB>.Filter.In(w => w.WorkAreaId, stringWorkAreaIds);
|
||||
|
||||
var filterBuilder = Builders<WorkItemMongoDB>.Filter;
|
||||
var filter = filterBuilder.Empty;
|
||||
|
||||
filter &= filterBuilder.In(w => w.WorkAreaId, stringWorkAreaIds);
|
||||
if (serviceIds.Any())
|
||||
{
|
||||
var stringServiceIds = serviceIds.Select(s => s.ToString()).ToList();
|
||||
filter &= filterBuilder.In(w => w.ActivityMaster!.ActivityGroupMaster!.Service!.Id, stringServiceIds);
|
||||
}
|
||||
|
||||
var workItems = await _taskCollection // replace with your actual collection name
|
||||
.Find(filter)
|
||||
@ -449,9 +480,17 @@ namespace Marco.Pms.Helpers
|
||||
}
|
||||
}
|
||||
}
|
||||
public async Task<List<WorkItemMongoDB>> GetWorkItemDetailsByWorkAreaFromCache(Guid workAreaId)
|
||||
public async Task<List<WorkItemMongoDB>> GetWorkItemDetailsByWorkAreaFromCache(Guid workAreaId, List<Guid> serviceIds)
|
||||
{
|
||||
var filter = Builders<WorkItemMongoDB>.Filter.Eq(p => p.WorkAreaId, workAreaId.ToString());
|
||||
var filterBuilder = Builders<WorkItemMongoDB>.Filter;
|
||||
var filter = filterBuilder.Empty;
|
||||
|
||||
filter &= filterBuilder.Eq(p => p.WorkAreaId, workAreaId.ToString());
|
||||
if (serviceIds.Any())
|
||||
{
|
||||
var stringServiceIds = serviceIds.Select(s => s.ToString()).ToList();
|
||||
filter &= filterBuilder.In(w => w.ActivityMaster!.ActivityGroupMaster!.Service!.Id, stringServiceIds);
|
||||
}
|
||||
|
||||
var options = new UpdateOptions { IsUpsert = true };
|
||||
var workItems = await _taskCollection
|
||||
|
@ -1,8 +1,8 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Marco.Pms.Model.Dtos.Attendance;
|
||||
using Marco.Pms.Model.Dtos.Attendance;
|
||||
using Marco.Pms.Model.Employees;
|
||||
using Marco.Pms.Model.Utilities;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Marco.Pms.Model.AttendanceModule
|
||||
{
|
||||
@ -10,9 +10,11 @@ namespace Marco.Pms.Model.AttendanceModule
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string Comment { get; set; } = string.Empty;
|
||||
public Guid EmployeeID { get; set; }
|
||||
|
||||
public Guid EmployeeId { get; set; }
|
||||
|
||||
[ForeignKey("EmployeeId")]
|
||||
[ValidateNever]
|
||||
public Employee? Employee { get; set; }
|
||||
public DateTime Date { get; set; }
|
||||
public Guid ProjectID { get; set; }
|
||||
|
||||
@ -22,8 +24,9 @@ namespace Marco.Pms.Model.AttendanceModule
|
||||
public bool IsApproved { get; set; }
|
||||
public ATTENDANCE_MARK_TYPE Activity { get; set; }
|
||||
|
||||
public Guid? ApprovedBy { get; set; }
|
||||
[ForeignKey("EmployeeID")]
|
||||
public Guid? ApprovedById { get; set; }
|
||||
|
||||
[ForeignKey("ApprovedById")]
|
||||
[ValidateNever]
|
||||
public Employee? Approver { get; set; }
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
using Marco.Pms.Model.Utilities;
|
||||
|
||||
namespace Marco.Pms.Model.Authentication
|
||||
namespace Marco.Pms.Model.Authentication
|
||||
{
|
||||
public class MPINDetails : TenantRelation
|
||||
public class MPINDetails
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid UserId { get; set; }
|
||||
|
@ -1,8 +1,6 @@
|
||||
using Marco.Pms.Model.Utilities;
|
||||
|
||||
namespace Marco.Pms.Model.Authentication
|
||||
namespace Marco.Pms.Model.Authentication
|
||||
{
|
||||
public class OTPDetails : TenantRelation
|
||||
public class OTPDetails
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid UserId { get; set; }
|
||||
|
@ -2,8 +2,9 @@
|
||||
{
|
||||
public class CreateActivityMasterDto
|
||||
{
|
||||
public string? ActivityName { get; set; }
|
||||
public string? UnitOfMeasurement { get; set; }
|
||||
public required Guid ActivityGroupId { get; set; }
|
||||
public required string ActivityName { get; set; }
|
||||
public required string UnitOfMeasurement { get; set; }
|
||||
public List<CreateCheckListDto>? CheckList { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
public class CreateCheckListDto
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public bool IsMandatory { get; set; }
|
||||
public required string Description { get; set; }
|
||||
public required bool IsMandatory { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -9,8 +9,8 @@
|
||||
public string? Email { get; set; }
|
||||
|
||||
public required string Gender { get; set; }
|
||||
public required string BirthDate { get; set; }
|
||||
public required string JoiningDate { get; set; }
|
||||
public required DateTime BirthDate { get; set; }
|
||||
public required DateTime JoiningDate { get; set; }
|
||||
|
||||
public required string PermanentAddress { get; set; }
|
||||
public required string CurrentAddress { get; set; }
|
||||
@ -18,17 +18,9 @@
|
||||
|
||||
public string? EmergencyPhoneNumber { get; set; }
|
||||
public string? EmergencyContactPerson { get; set; }
|
||||
|
||||
public string? AadharNumber { get; set; }
|
||||
|
||||
public string? PanNumber { get; set; }
|
||||
|
||||
//public IFormFile? Photo { get; set; } // To store the captured photo
|
||||
//public List<IFormFile>? Documents { get; set; }
|
||||
|
||||
public Guid? JobRoleId { get; set; }
|
||||
|
||||
// public int TenantId { get; set; }
|
||||
public Guid JobRoleId { get; set; }
|
||||
public required Guid OrganizationId { get; set; }
|
||||
public required bool HasApplicationAccess { get; set; }
|
||||
}
|
||||
public class MobileUserManageDto
|
||||
{
|
||||
@ -36,10 +28,13 @@
|
||||
public required string FirstName { get; set; }
|
||||
public required string LastName { get; set; }
|
||||
public required string PhoneNumber { get; set; }
|
||||
public string? Email { get; set; }
|
||||
public required DateTime JoiningDate { get; set; }
|
||||
public required string Gender { get; set; }
|
||||
public Guid JobRoleId { get; set; }
|
||||
public string? ProfileImage { get; set; }
|
||||
public required Guid OrganizationId { get; set; }
|
||||
public required bool HasApplicationAccess { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
|
10
Marco.Pms.Model/Dtos/Master/ActivityGroupDto.cs
Normal file
10
Marco.Pms.Model/Dtos/Master/ActivityGroupDto.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace Marco.Pms.Model.Dtos.Master
|
||||
{
|
||||
public class ActivityGroupDto
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
public required string Name { get; set; }
|
||||
public required string Description { get; set; }
|
||||
public required Guid ServiceId { get; set; }
|
||||
}
|
||||
}
|
9
Marco.Pms.Model/Dtos/Master/ServiceMasterDto.cs
Normal file
9
Marco.Pms.Model/Dtos/Master/ServiceMasterDto.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace Marco.Pms.Model.Dtos.Master
|
||||
{
|
||||
public class ServiceMasterDto
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
public required string Name { get; set; }
|
||||
public required string Description { get; set; }
|
||||
}
|
||||
}
|
11
Marco.Pms.Model/Dtos/Organization/AssignOrganizationDto.cs
Normal file
11
Marco.Pms.Model/Dtos/Organization/AssignOrganizationDto.cs
Normal file
@ -0,0 +1,11 @@
|
||||
namespace Marco.Pms.Model.Dtos.Organization
|
||||
{
|
||||
public class AssignOrganizationDto
|
||||
{
|
||||
public required Guid ProjectId { get; set; }
|
||||
public required Guid OrganizationId { get; set; }
|
||||
public Guid? ParentOrganizationId { get; set; }
|
||||
public required List<Guid> ServiceIds { get; set; }
|
||||
public required Guid OrganizationTypeId { get; set; }
|
||||
}
|
||||
}
|
13
Marco.Pms.Model/Dtos/Organization/CreateOrganizationDto.cs
Normal file
13
Marco.Pms.Model/Dtos/Organization/CreateOrganizationDto.cs
Normal file
@ -0,0 +1,13 @@
|
||||
namespace Marco.Pms.Model.Dtos.Organization
|
||||
{
|
||||
public class CreateOrganizationDto
|
||||
{
|
||||
public required string Name { get; set; }
|
||||
public required string Email { get; set; }
|
||||
public required string ContactPerson { get; set; }
|
||||
public required string Address { get; set; }
|
||||
public required string ContactNumber { get; set; }
|
||||
public string? logoImage { get; set; }
|
||||
public List<Guid>? ServiceIds { get; set; }
|
||||
}
|
||||
}
|
12
Marco.Pms.Model/Dtos/Organization/UpdateOrganizationDto.cs
Normal file
12
Marco.Pms.Model/Dtos/Organization/UpdateOrganizationDto.cs
Normal file
@ -0,0 +1,12 @@
|
||||
namespace Marco.Pms.Model.Dtos.Organization
|
||||
{
|
||||
public class UpdateOrganizationDto
|
||||
{
|
||||
public required Guid Id { get; set; }
|
||||
public required string Name { get; set; }
|
||||
public required string ContactPerson { get; set; }
|
||||
public required string Address { get; set; }
|
||||
public required string ContactNumber { get; set; }
|
||||
public List<Guid>? ServiceIds { get; set; }
|
||||
}
|
||||
}
|
10
Marco.Pms.Model/Dtos/Projects/AssignServiceDto.cs
Normal file
10
Marco.Pms.Model/Dtos/Projects/AssignServiceDto.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace Marco.Pms.Model.Dtos.Projects
|
||||
{
|
||||
public class AssignServiceDto
|
||||
{
|
||||
public required Guid ProjectId { get; set; }
|
||||
public required List<Guid> ServiceIds { get; set; }
|
||||
public DateTime PlannedStartDate { get; set; }
|
||||
public DateTime PlannedEndDate { get; set; }
|
||||
}
|
||||
}
|
@ -7,17 +7,18 @@ namespace Marco.Pms.Model.Dtos.Project
|
||||
{
|
||||
[Required(ErrorMessage = "Project Name is required!")]
|
||||
[DisplayName("Project Name")]
|
||||
public string? Name { get; set; }
|
||||
public required string Name { get; set; }
|
||||
|
||||
[DisplayName("Short Name")]
|
||||
public string? ShortName { get; set; }
|
||||
|
||||
[DisplayName("Project Address")]
|
||||
[Required(ErrorMessage = "Project Address is required!")]
|
||||
public string? ProjectAddress { get; set; }
|
||||
public required string ProjectAddress { get; set; }
|
||||
|
||||
|
||||
[DisplayName("Contact Person")]
|
||||
public string? ContactPerson { get; set; }
|
||||
public required string ContactPerson { get; set; }
|
||||
|
||||
|
||||
public DateTime? StartDate { get; set; }
|
||||
@ -25,6 +26,8 @@ namespace Marco.Pms.Model.Dtos.Project
|
||||
|
||||
[DisplayName("Project Status")]
|
||||
[Required(ErrorMessage = "Project Status is required!")]
|
||||
public Guid ProjectStatusId { get; set; }
|
||||
public required Guid ProjectStatusId { get; set; }
|
||||
public required Guid PromoterId { get; set; }
|
||||
public required Guid PMCId { get; set; }
|
||||
}
|
||||
}
|
||||
|
8
Marco.Pms.Model/Dtos/Projects/DeassignServiceDto.cs
Normal file
8
Marco.Pms.Model/Dtos/Projects/DeassignServiceDto.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace Marco.Pms.Model.Dtos.Projects
|
||||
{
|
||||
public class DeassignServiceDto
|
||||
{
|
||||
public required Guid ProjectId { get; set; }
|
||||
public required List<Guid> ServiceIds { get; set; }
|
||||
}
|
||||
}
|
@ -2,9 +2,10 @@
|
||||
{
|
||||
public class ProjectAllocationDot
|
||||
{
|
||||
public Guid EmpID { get; set; }
|
||||
public Guid EmployeeId { get; set; }
|
||||
public Guid JobRoleId { get; set; }
|
||||
public Guid ProjectId { get; set; }
|
||||
public Guid ServiceId { get; set; }
|
||||
public bool Status { get; set; }
|
||||
}
|
||||
|
||||
@ -13,6 +14,7 @@
|
||||
{
|
||||
public Guid ProjectId { get; set; }
|
||||
public Guid JobRoleId { get; set; }
|
||||
public Guid ServiceId { get; set; }
|
||||
public bool Status { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -5,20 +5,20 @@ namespace Marco.Pms.Model.Dtos.Project
|
||||
{
|
||||
public class UpdateProjectDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public required Guid Id { get; set; }
|
||||
[Required(ErrorMessage = "Project Name is required!")]
|
||||
[DisplayName("Project Name")]
|
||||
public string? Name { get; set; }
|
||||
public required string Name { get; set; }
|
||||
[DisplayName("Short Name")]
|
||||
public string? ShortName { get; set; }
|
||||
|
||||
[DisplayName("Project Address")]
|
||||
[Required(ErrorMessage = "Project Address is required!")]
|
||||
public string? ProjectAddress { get; set; }
|
||||
public required string ProjectAddress { get; set; }
|
||||
|
||||
|
||||
[DisplayName("Contact Person")]
|
||||
public string? ContactPerson { get; set; }
|
||||
public required string ContactPerson { get; set; }
|
||||
|
||||
|
||||
public DateTime? StartDate { get; set; }
|
||||
@ -26,6 +26,8 @@ namespace Marco.Pms.Model.Dtos.Project
|
||||
|
||||
[DisplayName("Project Status")]
|
||||
[Required(ErrorMessage = "Project Status is required!")]
|
||||
public Guid ProjectStatusId { get; set; }
|
||||
public required Guid ProjectStatusId { get; set; }
|
||||
public required Guid PromoterId { get; set; }
|
||||
public required Guid PMCId { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -17,5 +17,6 @@
|
||||
public required string OrganizationSize { get; set; }
|
||||
public required Guid IndustryId { get; set; }
|
||||
public required string Reference { get; set; }
|
||||
public List<Guid>? ServiceIds { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,56 +1,53 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Marco.Pms.Model.Entitlements;
|
||||
using Marco.Pms.Model.Entitlements;
|
||||
using Marco.Pms.Model.OrganizationModel;
|
||||
using Marco.Pms.Model.Roles;
|
||||
using Marco.Pms.Model.Utilities;
|
||||
using Marco.Pms.Model.TenantModels;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Marco.Pms.Model.Employees
|
||||
{
|
||||
public class Employee : TenantRelation
|
||||
public class Employee
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string? FirstName { get; set; }
|
||||
public string FirstName { get; set; } = string.Empty;
|
||||
public string? LastName { get; set; }
|
||||
public string? MiddleName { get; set; }
|
||||
public string? Email { get; set; }
|
||||
|
||||
public string? Gender { get; set; }
|
||||
public DateTime? BirthDate { get; set; }
|
||||
public DateTime? JoiningDate { get; set; }
|
||||
|
||||
public string? PermanentAddress { get; set; }
|
||||
public string? CurrentAddress { get; set; }
|
||||
public string? PhoneNumber { get; set; }
|
||||
|
||||
public string? EmergencyPhoneNumber { get; set; }
|
||||
public string? EmergencyContactPerson { get; set; }
|
||||
|
||||
|
||||
public string? AadharNumber { get; set; }
|
||||
|
||||
public string? PanNumber { get; set; }
|
||||
|
||||
public byte[]? Photo { get; set; } // To store the captured photo
|
||||
|
||||
public string? ApplicationUserId { get; set; }
|
||||
[ForeignKey("ApplicationUserId")]
|
||||
[ValidateNever]
|
||||
public ApplicationUser? ApplicationUser { get; set; }
|
||||
|
||||
|
||||
public bool IsActive { get; set; } = true;
|
||||
|
||||
public bool HasApplicationAccess { get; set; } = false;
|
||||
public bool IsPrimary { get; set; } = false;
|
||||
public bool IsSystem { get; set; } = false;
|
||||
|
||||
public Guid RoleId { get; set; }
|
||||
//[ForeignKey(nameof(RoleId))]
|
||||
//public EmployeeRole EmployeeRole { get; set; }
|
||||
|
||||
public Guid? JobRoleId { get; set; }
|
||||
public Guid JobRoleId { get; set; }
|
||||
[ForeignKey("JobRoleId")]
|
||||
[ValidateNever]
|
||||
public JobRole? JobRole { get; set; }
|
||||
|
||||
public Guid OrganizationId { get; set; } = Guid.Parse("4e3a6d31-c640-40f7-8d67-6c109fcdb9ea");
|
||||
|
||||
[ValidateNever]
|
||||
[ForeignKey("OrganizationId")]
|
||||
public Organization? Organization { get; set; }
|
||||
|
||||
public Guid? TenantId { get; set; }
|
||||
|
||||
[ValidateNever]
|
||||
[ForeignKey("TenantId")]
|
||||
public Tenant? Tenant { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +1,10 @@
|
||||
using System.ComponentModel;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
|
||||
namespace Marco.Pms.Model.Entitlements
|
||||
{
|
||||
public class ApplicationUser : IdentityUser
|
||||
{
|
||||
//[Required]
|
||||
// public string Role { get; set; } // e.g. Admin, SiteManager, SkilledWorker, etc.
|
||||
|
||||
|
||||
[DisplayName("TenantId")]
|
||||
public Guid TenantId { get; set; }
|
||||
|
||||
public bool? IsRootUser { get; set; } = false;
|
||||
|
||||
public bool IsActive { get; set; } = true;
|
||||
|
||||
//[ValidateNever]
|
||||
//[ForeignKey(nameof(TenantId))]
|
||||
//public Tenant Tenant { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -87,6 +87,18 @@ namespace Marco.Pms.Model.Entitlements
|
||||
PermissionIds = new List<string>()
|
||||
},
|
||||
new SubMenuItem
|
||||
{
|
||||
Text = "Organizations",
|
||||
Available = true,
|
||||
Link = "/organizations",
|
||||
PermissionIds = new List<string>
|
||||
{
|
||||
"068cb3c1-49c5-4746-9f29-1fce16e820ac",
|
||||
"c1ae1363-ab8a-4bd9-a9d1-8c2c6083873a",
|
||||
"7a6cf830-0008-4e03-b31d-0d050cb634f4"
|
||||
}
|
||||
},
|
||||
new SubMenuItem
|
||||
{
|
||||
Text = "Project Report",
|
||||
Available = true,
|
||||
|
@ -46,6 +46,10 @@
|
||||
public static readonly Guid DeleteDocument = Guid.Parse("40863a13-5a66-469d-9b48-135bc5dbf486");
|
||||
public static readonly Guid DownloadDocument = Guid.Parse("404373d0-860f-490e-a575-1c086ffbce1d");
|
||||
public static readonly Guid VerifyDocument = Guid.Parse("13a1f30f-38d1-41bf-8e7a-b75189aab8e0");
|
||||
|
||||
public static readonly Guid AddOrganization = Guid.Parse("068cb3c1-49c5-4746-9f29-1fce16e820ac");
|
||||
public static readonly Guid EditOrganization = Guid.Parse("c1ae1363-ab8a-4bd9-a9d1-8c2c6083873a");
|
||||
public static readonly Guid ViewOrganization = Guid.Parse("7a6cf830-0008-4e03-b31d-0d050cb634f4");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
public List<Guid>? WorkCategoryIds { get; set; }
|
||||
public List<Guid>? ActivityIds { get; set; }
|
||||
public List<Guid>? UploadedByIds { get; set; }
|
||||
public List<Guid>? ServiceIds { get; set; }
|
||||
public DateTime? StartDate { get; set; }
|
||||
public DateTime? EndDate { get; set; }
|
||||
}
|
||||
|
11
Marco.Pms.Model/Filters/TaskFilter.cs
Normal file
11
Marco.Pms.Model/Filters/TaskFilter.cs
Normal file
@ -0,0 +1,11 @@
|
||||
namespace Marco.Pms.Model.Filters
|
||||
{
|
||||
public class TaskFilter
|
||||
{
|
||||
public List<Guid>? BuildingIds { get; set; }
|
||||
public List<Guid>? FloorIds { get; set; }
|
||||
public List<Guid>? ActivityIds { get; set; }
|
||||
public DateTime? dateFrom { get; set; }
|
||||
public DateTime? dateTo { get; set; }
|
||||
}
|
||||
}
|
@ -23,14 +23,12 @@ namespace Marco.Pms.Model.Mapper
|
||||
Email = model.Email,
|
||||
CurrentAddress = model.CurrentAddress,
|
||||
BirthDate = model.BirthDate,
|
||||
AadharNumber = model.AadharNumber,
|
||||
ApplicationUserId = model.ApplicationUserId,
|
||||
EmergencyPhoneNumber = model.EmergencyPhoneNumber,
|
||||
EmergencyContactPerson = model.EmergencyContactPerson,
|
||||
Gender = model.Gender,
|
||||
JobRole = (model.JobRole != null ? model.JobRole.Name : null),
|
||||
JobRoleId = model.JobRoleId,
|
||||
PanNumber = model.PanNumber,
|
||||
PermanentAddress = model.PermanentAddress,
|
||||
PhoneNumber = model.PhoneNumber,
|
||||
Photo = base64String,
|
||||
@ -38,7 +36,9 @@ namespace Marco.Pms.Model.Mapper
|
||||
IsRootUser = model.ApplicationUser?.IsRootUser ?? false,
|
||||
IsSystem = model.IsSystem,
|
||||
JoiningDate = model.JoiningDate,
|
||||
TenantId = model.TenantId
|
||||
TenantId = model.TenantId ?? Guid.Empty,
|
||||
HasApplicationAccess = model.HasApplicationAccess,
|
||||
OrganizationId = model.OrganizationId
|
||||
};
|
||||
}
|
||||
public static BasicEmployeeVM ToBasicEmployeeVMFromEmployee(this Employee employee)
|
||||
@ -66,10 +66,8 @@ namespace Marco.Pms.Model.Mapper
|
||||
BirthDate = null,
|
||||
EmergencyPhoneNumber = string.Empty,
|
||||
EmergencyContactPerson = string.Empty,
|
||||
AadharNumber = string.Empty,
|
||||
Gender = model.Gender,
|
||||
MiddleName = string.Empty,
|
||||
PanNumber = string.Empty,
|
||||
PermanentAddress = string.Empty,
|
||||
PhoneNumber = model.PhoneNumber,
|
||||
Photo = image,
|
||||
|
@ -57,7 +57,7 @@ namespace Marco.Pms.Model.Mapper
|
||||
return new ProjectAllocation
|
||||
{
|
||||
AllocationDate = DateTime.Now,
|
||||
EmployeeId = model.EmpID,
|
||||
EmployeeId = model.EmployeeId,
|
||||
JobRoleId = model.JobRoleId,
|
||||
TenantId = TenantId,
|
||||
ProjectId = model.ProjectId
|
||||
@ -65,7 +65,7 @@ namespace Marco.Pms.Model.Mapper
|
||||
}
|
||||
|
||||
|
||||
public static ProjectAllocation ToProjectAllocationFromProjectsAllocationDto(this ProjectsAllocationDto model, Guid TenantId,Guid employeeId)
|
||||
public static ProjectAllocation ToProjectAllocationFromProjectsAllocationDto(this ProjectsAllocationDto model, Guid TenantId, Guid employeeId)
|
||||
{
|
||||
return new ProjectAllocation
|
||||
{
|
||||
|
20
Marco.Pms.Model/Master/ActivityGroupMaster.cs
Normal file
20
Marco.Pms.Model/Master/ActivityGroupMaster.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using Marco.Pms.Model.Utilities;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Marco.Pms.Model.Master
|
||||
{
|
||||
public class ActivityGroupMaster : TenantRelation
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public Guid ServiceId { get; set; }
|
||||
|
||||
[ValidateNever]
|
||||
[ForeignKey("ServiceId")]
|
||||
public ServiceMaster? Service { get; set; }
|
||||
public bool IsActive { get; set; } = true;
|
||||
public bool IsSystem { get; set; } = false;
|
||||
}
|
||||
}
|
@ -1,14 +1,20 @@
|
||||
using Marco.Pms.Model.Utilities;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Marco.Pms.Model.Master
|
||||
{
|
||||
public class ActivityMaster : TenantRelation
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string? ActivityName { get; set; }
|
||||
|
||||
public string? UnitOfMeasurement { get; set; }
|
||||
public string ActivityName { get; set; } = string.Empty;
|
||||
public string UnitOfMeasurement { get; set; } = string.Empty;
|
||||
public Guid? ActivityGroupId { get; set; }
|
||||
|
||||
[ValidateNever]
|
||||
[ForeignKey("ActivityGroupId")]
|
||||
public ActivityGroupMaster? ActivityGroup { get; set; }
|
||||
public bool IsActive { get; set; } = true;
|
||||
public bool IsSystem { get; set; } = false;
|
||||
}
|
||||
}
|
||||
|
17
Marco.Pms.Model/Master/GlobalActivityGroupMaster.cs
Normal file
17
Marco.Pms.Model/Master/GlobalActivityGroupMaster.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Marco.Pms.Model.Master
|
||||
{
|
||||
public class GlobalActivityGroupMaster
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public Guid ServiceId { get; set; }
|
||||
|
||||
[ValidateNever]
|
||||
[ForeignKey("ServiceId")]
|
||||
public GlobalServiceMaster? Service { get; set; }
|
||||
}
|
||||
}
|
18
Marco.Pms.Model/Master/GlobalActivityMaster.cs
Normal file
18
Marco.Pms.Model/Master/GlobalActivityMaster.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Marco.Pms.Model.Master
|
||||
{
|
||||
public class GlobalActivityMaster
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string ActivityName { get; set; } = string.Empty;
|
||||
public string UnitOfMeasurement { get; set; } = string.Empty;
|
||||
public Guid ActivityGroupId { get; set; }
|
||||
|
||||
[ValidateNever]
|
||||
[ForeignKey("ActivityGroupId")]
|
||||
public GlobalActivityGroupMaster? ActivityGroup { get; set; }
|
||||
public bool IsActive { get; set; } = true;
|
||||
}
|
||||
}
|
9
Marco.Pms.Model/Master/GlobalServiceMaster.cs
Normal file
9
Marco.Pms.Model/Master/GlobalServiceMaster.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace Marco.Pms.Model.Master
|
||||
{
|
||||
public class GlobalServiceMaster
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Description { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
13
Marco.Pms.Model/Master/ServiceMaster.cs
Normal file
13
Marco.Pms.Model/Master/ServiceMaster.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using Marco.Pms.Model.Utilities;
|
||||
|
||||
namespace Marco.Pms.Model.Master
|
||||
{
|
||||
public class ServiceMaster : TenantRelation
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public bool IsActive { get; set; } = true;
|
||||
public bool IsSystem { get; set; } = false;
|
||||
}
|
||||
}
|
@ -10,5 +10,6 @@ namespace Marco.Pms.Model.MongoDBModels.Employees
|
||||
public List<string> PermissionIds { get; set; } = new List<string>();
|
||||
public List<string> ProjectIds { get; set; } = new List<string>();
|
||||
public DateTime ExpireAt { get; set; } = DateTime.UtcNow.Date.AddDays(1);
|
||||
public string TenantId { get; set; } = string.Empty; // Tenant ID
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,10 @@
|
||||
namespace Marco.Pms.Model.MongoDBModels.Masters
|
||||
{
|
||||
public class ActivityGroupMasterMongoDB
|
||||
{
|
||||
public string Id { get; set; } = string.Empty;
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public ServiceMasterMongoDB? Service { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
namespace Marco.Pms.Model.MongoDBModels.Masters
|
||||
{
|
||||
public class ServiceMasterMongoDB
|
||||
{
|
||||
public string Id { get; set; } = string.Empty;
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Description { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
13
Marco.Pms.Model/MongoDBModels/OrganizationMongoDB.cs
Normal file
13
Marco.Pms.Model/MongoDBModels/OrganizationMongoDB.cs
Normal file
@ -0,0 +1,13 @@
|
||||
namespace Marco.Pms.Model.MongoDBModels
|
||||
{
|
||||
public class OrganizationMongoDB
|
||||
{
|
||||
public string Id { get; set; } = string.Empty;
|
||||
public string? Name { get; set; }
|
||||
public string? Email { get; set; }
|
||||
public string? ContactPerson { get; set; }
|
||||
public string? Address { get; set; }
|
||||
public string? ContactNumber { get; set; }
|
||||
public double SPRID { get; set; }
|
||||
}
|
||||
}
|
@ -1,9 +1,12 @@
|
||||
namespace Marco.Pms.Model.MongoDBModels.Project
|
||||
using Marco.Pms.Model.MongoDBModels.Masters;
|
||||
|
||||
namespace Marco.Pms.Model.MongoDBModels.Project
|
||||
{
|
||||
public class ActivityMasterMongoDB
|
||||
{
|
||||
public string Id { get; set; } = string.Empty;
|
||||
public string? ActivityName { get; set; }
|
||||
public string? UnitOfMeasurement { get; set; }
|
||||
public ActivityGroupMasterMongoDB? ActivityGroupMaster { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,8 @@ namespace Marco.Pms.Model.MongoDBModels.Project
|
||||
public DateTime? StartDate { get; set; }
|
||||
public DateTime? EndDate { get; set; }
|
||||
public StatusMasterMongoDB? ProjectStatus { get; set; }
|
||||
public OrganizationMongoDB? Promoter { get; set; }
|
||||
public OrganizationMongoDB? PMC { get; set; }
|
||||
public int TeamSize { get; set; }
|
||||
public double CompletedWork { get; set; }
|
||||
public double PlannedWork { get; set; }
|
||||
|
21
Marco.Pms.Model/OrganizationModel/OrgServiceMapping.cs
Normal file
21
Marco.Pms.Model/OrganizationModel/OrgServiceMapping.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using Marco.Pms.Model.Master;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Marco.Pms.Model.OrganizationModel
|
||||
{
|
||||
public class OrgServiceMapping
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid OrganizationId { get; set; }
|
||||
|
||||
[ValidateNever]
|
||||
[ForeignKey("OrganizationId")]
|
||||
public Organization? Organization { get; set; }
|
||||
public Guid ServiceId { get; set; }
|
||||
|
||||
[ValidateNever]
|
||||
[ForeignKey("ServiceId")]
|
||||
public GlobalServiceMaster? Service { get; set; }
|
||||
}
|
||||
}
|
8
Marco.Pms.Model/OrganizationModel/OrgTypeMaster.cs
Normal file
8
Marco.Pms.Model/OrganizationModel/OrgTypeMaster.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace Marco.Pms.Model.OrganizationModel
|
||||
{
|
||||
public class OrgTypeMaster
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
27
Marco.Pms.Model/OrganizationModel/Organization.cs
Normal file
27
Marco.Pms.Model/OrganizationModel/Organization.cs
Normal file
@ -0,0 +1,27 @@
|
||||
namespace Marco.Pms.Model.OrganizationModel
|
||||
{
|
||||
public class Organization
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Email { get; set; } = string.Empty;
|
||||
public string ContactPerson { get; set; } = string.Empty;
|
||||
public string Address { get; set; } = string.Empty;
|
||||
public string ContactNumber { get; set; } = string.Empty;
|
||||
public double SPRID { get; set; }
|
||||
public string? logoImage { get; set; }
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
public Guid? CreatedById { get; set; }
|
||||
|
||||
//[ValidateNever]
|
||||
//[ForeignKey("CreatedById")]
|
||||
//public Employee? CreatedBy { get; set; }
|
||||
public Guid? UpdatedById { get; set; }
|
||||
|
||||
//[ValidateNever]
|
||||
//[ForeignKey("UpdatedById")]
|
||||
//public Employee? UpdatedBy { get; set; }
|
||||
public DateTime? UpdatedAt { get; set; }
|
||||
public bool IsActive { get; set; } = true;
|
||||
}
|
||||
}
|
40
Marco.Pms.Model/OrganizationModel/ProjectOrgMapping.cs
Normal file
40
Marco.Pms.Model/OrganizationModel/ProjectOrgMapping.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using Marco.Pms.Model.Employees;
|
||||
using Marco.Pms.Model.Utilities;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Marco.Pms.Model.OrganizationModel
|
||||
{
|
||||
public class ProjectOrgMapping : TenantRelation
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid OrganizationId { get; set; }
|
||||
|
||||
[ValidateNever]
|
||||
[ForeignKey("OrganizationId")]
|
||||
public Organization? Organization { get; set; }
|
||||
public Guid ParentOrganizationId { get; set; }
|
||||
|
||||
[ValidateNever]
|
||||
[ForeignKey("ParentOrganizationId")]
|
||||
public Organization? ParentOrganization { get; set; }
|
||||
public Guid ProjectServiceId { get; set; }
|
||||
|
||||
[ValidateNever]
|
||||
[ForeignKey("ProjectServiceId")]
|
||||
public ProjectServiceMapping? ProjectService { get; set; }
|
||||
public Guid OrganizationTypeId { get; set; }
|
||||
|
||||
[ValidateNever]
|
||||
[ForeignKey("OrganizationTypeId")]
|
||||
public OrgTypeMaster? OrganizationType { get; set; }
|
||||
|
||||
public Guid AssignedById { get; set; }
|
||||
|
||||
[ValidateNever]
|
||||
[ForeignKey("AssignedById")]
|
||||
public Employee? AssignedBy { get; set; }
|
||||
public DateTime AssignedDate { get; set; }
|
||||
public DateTime? CompletionDate { get; set; }
|
||||
}
|
||||
}
|
28
Marco.Pms.Model/OrganizationModel/ProjectServiceMapping.cs
Normal file
28
Marco.Pms.Model/OrganizationModel/ProjectServiceMapping.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using Marco.Pms.Model.Master;
|
||||
using Marco.Pms.Model.Projects;
|
||||
using Marco.Pms.Model.Utilities;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Marco.Pms.Model.OrganizationModel
|
||||
{
|
||||
public class ProjectServiceMapping : TenantRelation
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid ServiceId { get; set; }
|
||||
|
||||
[ValidateNever]
|
||||
[ForeignKey("ServiceId")]
|
||||
public ServiceMaster? Service { get; set; }
|
||||
public Guid ProjectId { get; set; }
|
||||
|
||||
[ValidateNever]
|
||||
[ForeignKey("ProjectId")]
|
||||
public Project? Project { get; set; }
|
||||
public DateTime PlannedStartDate { get; set; }
|
||||
public DateTime PlannedEndDate { get; set; }
|
||||
public DateTime ActualStartDate { get; set; }
|
||||
public DateTime? ActualEndDate { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
}
|
||||
}
|
26
Marco.Pms.Model/OrganizationModel/TenantOrgMapping.cs
Normal file
26
Marco.Pms.Model/OrganizationModel/TenantOrgMapping.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using Marco.Pms.Model.Employees;
|
||||
using Marco.Pms.Model.Utilities;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Marco.Pms.Model.OrganizationModel
|
||||
{
|
||||
public class TenantOrgMapping : TenantRelation
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid OrganizationId { get; set; }
|
||||
|
||||
[ValidateNever]
|
||||
[ForeignKey("OrganizationId")]
|
||||
public Organization? Organization { get; set; }
|
||||
public double SPRID { get; set; }
|
||||
public bool IsActive { get; set; } = true;
|
||||
public Guid AssignedById { get; set; }
|
||||
|
||||
[ValidateNever]
|
||||
[ForeignKey("AssignedById")]
|
||||
public Employee? AssignedBy { get; set; }
|
||||
public DateTime AssignedDate { get; set; }
|
||||
public DateTime? ReassignedDate { get; set; }
|
||||
}
|
||||
}
|
@ -1,9 +1,10 @@
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Marco.Pms.Model.Master;
|
||||
using Marco.Pms.Model.Master;
|
||||
using Marco.Pms.Model.OrganizationModel;
|
||||
using Marco.Pms.Model.Utilities;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Marco.Pms.Model.Projects
|
||||
{
|
||||
@ -32,5 +33,16 @@ namespace Marco.Pms.Model.Projects
|
||||
[ValidateNever]
|
||||
[ForeignKey(nameof(ProjectStatusId))]
|
||||
public StatusMaster? ProjectStatus { get; set; }
|
||||
|
||||
public Guid PromoterId { get; set; } = Guid.Parse("4e3a6d31-c640-40f7-8d67-6c109fcdb9ea");
|
||||
|
||||
[ValidateNever]
|
||||
[ForeignKey("PromoterId")]
|
||||
public Organization? Promoter { get; set; }
|
||||
public Guid PMCId { get; set; } = Guid.Parse("4e3a6d31-c640-40f7-8d67-6c109fcdb9ea");
|
||||
|
||||
[ValidateNever]
|
||||
[ForeignKey("PMCId")]
|
||||
public Organization? PMC { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Marco.Pms.Model.Employees;
|
||||
using Marco.Pms.Model.Employees;
|
||||
using Marco.Pms.Model.Master;
|
||||
using Marco.Pms.Model.Utilities;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Marco.Pms.Model.Projects
|
||||
{
|
||||
@ -21,9 +22,15 @@ namespace Marco.Pms.Model.Projects
|
||||
public bool IsActive { get; set; } = true;
|
||||
|
||||
public Guid ProjectId { get; set; }
|
||||
|
||||
[ForeignKey("ProjectId")]
|
||||
[ValidateNever]
|
||||
public Project? Project { get; set; }
|
||||
public Guid? ServiceId { get; set; }
|
||||
|
||||
[ForeignKey("ServiceId")]
|
||||
[ValidateNever]
|
||||
public ServiceMaster? Service { get; set; }
|
||||
|
||||
|
||||
public DateTime AllocationDate { get; set; }
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Marco.Pms.Model.Master;
|
||||
using Marco.Pms.Model.OrganizationModel;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
@ -34,5 +35,10 @@ namespace Marco.Pms.Model.TenantModels
|
||||
|
||||
public bool IsActive { get; set; } = true;
|
||||
public bool IsSuperTenant { get; set; } = false;
|
||||
public Guid OrganizationId { get; set; } = Guid.Parse("4e3a6d31-c640-40f7-8d67-6c109fcdb9ea");
|
||||
|
||||
[ValidateNever]
|
||||
[ForeignKey("OrganizationId")]
|
||||
public Organization? Organization { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,9 @@
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string? ActivityName { get; set; }
|
||||
|
||||
public string? UnitOfMeasurement { get; set; }
|
||||
public List<CheckListVM>? CheckLists { get; set; }
|
||||
public bool IsActive { get; set; } = true;
|
||||
public bool IsSystem { get; set; } = false;
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ namespace Marco.Pms.Model.ViewModels.AttendanceVM
|
||||
public string? FirstName { get; set; }
|
||||
public string? LastName { get; set; }
|
||||
public string? EmployeeAvatar { get; set; }
|
||||
public string? OrganizationName { get; set; }
|
||||
public DateTime? CheckInTime { get; set; }
|
||||
public DateTime? CheckOutTime { get; set; }
|
||||
public string? JobRoleName { get; set; }
|
||||
|
@ -17,21 +17,16 @@
|
||||
|
||||
public string? EmergencyPhoneNumber { get; set; }
|
||||
public string? EmergencyContactPerson { get; set; }
|
||||
|
||||
public string? AadharNumber { get; set; }
|
||||
|
||||
public bool IsActive { get; set; } = true;
|
||||
public bool IsRootUser { get; set; }
|
||||
public string? PanNumber { get; set; }
|
||||
|
||||
public string? Photo { get; set; } // To store the captured photo
|
||||
|
||||
public string? ApplicationUserId { get; set; }
|
||||
|
||||
public Guid? JobRoleId { get; set; }
|
||||
public Guid JobRoleId { get; set; }
|
||||
public Guid TenantId { get; set; }
|
||||
public bool IsSystem { get; set; }
|
||||
public string? JobRole { get; set; }
|
||||
public bool HasApplicationAccess { get; set; }
|
||||
public Guid OrganizationId { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
using Marco.Pms.Model.ViewModels.Activities;
|
||||
|
||||
namespace Marco.Pms.Model.ViewModels.Master
|
||||
{
|
||||
public class ActivityGroupDetailsListVM
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public bool IsSystem { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public List<ActivityVM>? Activities { get; set; }
|
||||
}
|
||||
}
|
11
Marco.Pms.Model/ViewModels/Master/ActivityGroupMasterVM.cs
Normal file
11
Marco.Pms.Model/ViewModels/Master/ActivityGroupMasterVM.cs
Normal file
@ -0,0 +1,11 @@
|
||||
namespace Marco.Pms.Model.ViewModels.Master
|
||||
{
|
||||
public class ActivityGroupMasterVM
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public bool IsSystem { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
}
|
||||
}
|
12
Marco.Pms.Model/ViewModels/Master/ServiceDetailsListVM.cs
Normal file
12
Marco.Pms.Model/ViewModels/Master/ServiceDetailsListVM.cs
Normal file
@ -0,0 +1,12 @@
|
||||
namespace Marco.Pms.Model.ViewModels.Master
|
||||
{
|
||||
public class ServiceDetailsListVM
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public bool IsSystem { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public List<ActivityGroupDetailsListVM>? ActivityGroups { get; set; }
|
||||
}
|
||||
}
|
11
Marco.Pms.Model/ViewModels/Master/ServiceMasterVM.cs
Normal file
11
Marco.Pms.Model/ViewModels/Master/ServiceMasterVM.cs
Normal file
@ -0,0 +1,11 @@
|
||||
namespace Marco.Pms.Model.ViewModels.Master
|
||||
{
|
||||
public class ServiceMasterVM
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public bool IsSystem { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
using Marco.Pms.Model.OrganizationModel;
|
||||
using Marco.Pms.Model.ViewModels.Master;
|
||||
using Marco.Pms.Model.ViewModels.Projects;
|
||||
|
||||
namespace Marco.Pms.Model.ViewModels.Organization
|
||||
{
|
||||
public class AssignOrganizationVm
|
||||
{
|
||||
public BasicProjectVM? Project { get; set; }
|
||||
public BasicOrganizationVm? Organization { get; set; }
|
||||
public BasicOrganizationVm? ParentOrganization { get; set; }
|
||||
public ServiceMasterVM? Service { get; set; }
|
||||
public OrgTypeMaster? OrganizationType { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
namespace Marco.Pms.Model.ViewModels.Organization
|
||||
{
|
||||
public class BasicOrganizationVm
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? Email { get; set; }
|
||||
public string? ContactPerson { get; set; }
|
||||
public string? Address { get; set; }
|
||||
public string? ContactNumber { get; set; }
|
||||
public double SPRID { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
using Marco.Pms.Model.Master;
|
||||
using Marco.Pms.Model.ViewModels.Activities;
|
||||
|
||||
namespace Marco.Pms.Model.ViewModels.Organization
|
||||
{
|
||||
public class OrganizationDetailsVM
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? Email { get; set; }
|
||||
public string? ContactPerson { get; set; }
|
||||
public string? Address { get; set; }
|
||||
public string? ContactNumber { get; set; }
|
||||
public double SPRID { get; set; }
|
||||
public int ActiveEmployeeCount { get; set; }
|
||||
public int ActiveApplicationUserCount { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public BasicEmployeeVM? CreatedBy { get; set; }
|
||||
public BasicEmployeeVM? UpdatedBy { get; set; }
|
||||
public DateTime? UpdatedAt { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public List<ProjectServiceMappingVM>? Projects { get; set; }
|
||||
public List<GlobalServiceMaster>? Services { get; set; }
|
||||
public string? logoImage { get; set; }
|
||||
}
|
||||
}
|
21
Marco.Pms.Model/ViewModels/Organization/OrganizationVM.cs
Normal file
21
Marco.Pms.Model/ViewModels/Organization/OrganizationVM.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using Marco.Pms.Model.ViewModels.Activities;
|
||||
|
||||
namespace Marco.Pms.Model.ViewModels.Organization
|
||||
{
|
||||
public class OrganizationVM
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? Email { get; set; }
|
||||
public string? ContactPerson { get; set; }
|
||||
public string? Address { get; set; }
|
||||
public string? ContactNumber { get; set; }
|
||||
public double SPRID { get; set; }
|
||||
public string? logoImage { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public BasicEmployeeVM? CreatedBy { get; set; }
|
||||
public BasicEmployeeVM? UpdatedBy { get; set; }
|
||||
public DateTime? UpdatedAt { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
using Marco.Pms.Model.ViewModels.Activities;
|
||||
using Marco.Pms.Model.ViewModels.Master;
|
||||
|
||||
namespace Marco.Pms.Model.ViewModels.Organization
|
||||
{
|
||||
public class ProjectOrganizationVM
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? Email { get; set; }
|
||||
public string? ContactPerson { get; set; }
|
||||
public double SPRID { get; set; }
|
||||
public string? logoImage { get; set; }
|
||||
public DateTime AssignedDate { get; set; }
|
||||
public BasicEmployeeVM? AssignedBy { get; set; }
|
||||
public ServiceMasterVM? Service { get; set; }
|
||||
public DateTime? CompletionDate { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
using Marco.Pms.Model.ViewModels.Master;
|
||||
using Marco.Pms.Model.ViewModels.Projects;
|
||||
|
||||
namespace Marco.Pms.Model.ViewModels.Organization
|
||||
{
|
||||
public class ProjectServiceMappingVM
|
||||
{
|
||||
public BasicProjectVM? Project { get; set; }
|
||||
public ServiceMasterVM? Service { get; set; }
|
||||
public DateTime PlannedStartDate { get; set; }
|
||||
public DateTime PlannedEndDate { get; set; }
|
||||
public DateTime ActualStartDate { get; set; }
|
||||
public DateTime? ActualEndDate { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
}
|
||||
}
|
14
Marco.Pms.Model/ViewModels/Projects/ProjectServiceVM.cs
Normal file
14
Marco.Pms.Model/ViewModels/Projects/ProjectServiceVM.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using Marco.Pms.Model.ViewModels.Master;
|
||||
|
||||
namespace Marco.Pms.Model.ViewModels.Projects
|
||||
{
|
||||
public class ProjectServiceVM
|
||||
{
|
||||
public BasicProjectVM? Project { get; set; }
|
||||
public ServiceMasterVM? Service { get; set; }
|
||||
public DateTime PlannedStartDate { get; set; }
|
||||
public DateTime PlannedEndDate { get; set; }
|
||||
public DateTime ActualStartDate { get; set; }
|
||||
public DateTime? ActualEndDate { get; set; }
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using Marco.Pms.Model.Master;
|
||||
using Marco.Pms.Model.ViewModels.Organization;
|
||||
|
||||
namespace Marco.Pms.Model.ViewModels.Projects
|
||||
{
|
||||
@ -12,6 +13,8 @@ namespace Marco.Pms.Model.ViewModels.Projects
|
||||
public DateTime? StartDate { get; set; }
|
||||
public DateTime? EndDate { get; set; }
|
||||
public StatusMaster? ProjectStatus { get; set; }
|
||||
public BasicOrganizationVm? Promoter { get; set; }
|
||||
public BasicOrganizationVm? PMC { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ namespace Marco.Pms.Model.ViewModels.Tenant
|
||||
public string ContactNumber { get; set; } = string.Empty;
|
||||
public string? logoImage { get; set; } // Base64
|
||||
public string? OrganizationSize { get; set; }
|
||||
public Guid OrganizationId { get; set; }
|
||||
public Industry? Industry { get; set; }
|
||||
public TenantStatus? TenantStatus { get; set; }
|
||||
}
|
||||
|
@ -575,22 +575,23 @@ namespace Marco.Pms.Services.Controllers
|
||||
{
|
||||
ProjectManagement, new List<MasterMenuVM>
|
||||
{
|
||||
new MasterMenuVM { Id = 3, Name = "Activity" },
|
||||
new MasterMenuVM { Id = 4, Name = "Work Category" }
|
||||
new MasterMenuVM { Id = 3, Name = "Work Category" },
|
||||
new MasterMenuVM { Id = 8, Name = "Services" }
|
||||
//new MasterMenuVM { Id = 10, Name = "Payment Mode" }
|
||||
}
|
||||
},
|
||||
{
|
||||
DirectoryManagement, new List<MasterMenuVM>
|
||||
{
|
||||
new MasterMenuVM { Id = 5, Name = "Contact Category" },
|
||||
new MasterMenuVM { Id = 6, Name = "Contact Tag" }
|
||||
new MasterMenuVM { Id = 4, Name = "Contact Category" },
|
||||
new MasterMenuVM { Id = 5, Name = "Contact Tag" }
|
||||
}
|
||||
},
|
||||
{
|
||||
ExpenseManagement, new List<MasterMenuVM>
|
||||
{
|
||||
new MasterMenuVM { Id = 7, Name = "Expense Type" },
|
||||
new MasterMenuVM { Id = 8, Name = "Payment Mode" }
|
||||
new MasterMenuVM { Id = 6, Name = "Expense Type" },
|
||||
new MasterMenuVM { Id = 7, Name = "Payment Mode" }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -107,7 +107,7 @@ namespace MarcoBMS.Services.Controllers
|
||||
_logger.LogWarning("The employee Id sent by user is empty");
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Employee ID is required and must not be Empty.", "Employee ID is required and must not be empty.", 400));
|
||||
}
|
||||
List<Attendance> attendances = await _context.Attendes.Where(c => c.EmployeeID == employeeId && c.TenantId == TenantId && c.AttendanceDate.Date >= fromDate && c.AttendanceDate.Date <= toDate).ToListAsync();
|
||||
List<Attendance> attendances = await _context.Attendes.Where(c => c.EmployeeId == employeeId && c.TenantId == TenantId && c.AttendanceDate.Date >= fromDate && c.AttendanceDate.Date <= toDate).ToListAsync();
|
||||
Employee? employee = await _context.Employees.Include(e => e.JobRole).FirstOrDefaultAsync(e => e.Id == employeeId && e.TenantId == TenantId && e.IsActive);
|
||||
List<EmployeeAttendanceVM> results = new List<EmployeeAttendanceVM>();
|
||||
|
||||
@ -143,12 +143,21 @@ namespace MarcoBMS.Services.Controllers
|
||||
/// <param name="projectId">ProjectID</param>
|
||||
/// <param name="date">YYYY-MM-dd</param>
|
||||
/// <returns></returns>
|
||||
|
||||
[HttpGet("project/log")]
|
||||
|
||||
public async Task<IActionResult> EmployeeAttendanceByDateRange([FromQuery] Guid projectId, [FromQuery] string? dateFrom = null, [FromQuery] string? dateTo = null)
|
||||
public async Task<IActionResult> EmployeeAttendanceByDateRange([FromQuery] Guid projectId, [FromQuery] Guid? organizationId, [FromQuery] string? dateFrom = null, [FromQuery] string? dateTo = null)
|
||||
{
|
||||
Guid TenantId = GetTenantId();
|
||||
Guid tenantId = GetTenantId();
|
||||
var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||
|
||||
var project = await _context.Projects.AsNoTracking().FirstOrDefaultAsync(p => p.Id == projectId && p.TenantId == tenantId);
|
||||
if (project == null)
|
||||
{
|
||||
_logger.LogWarning("Project {ProjectId} not found in database", projectId);
|
||||
return NotFound(ApiResponse<object>.ErrorResponse("Project not found."));
|
||||
}
|
||||
|
||||
var hasTeamAttendancePermission = await _permission.HasPermission(PermissionsMaster.TeamAttendance, LoggedInEmployee.Id);
|
||||
var hasSelfAttendancePermission = await _permission.HasPermission(PermissionsMaster.SelfAttendance, LoggedInEmployee.Id);
|
||||
var hasProjectPermission = await _permission.HasProjectPermission(LoggedInEmployee, projectId);
|
||||
@ -188,10 +197,10 @@ namespace MarcoBMS.Services.Controllers
|
||||
|
||||
if (hasTeamAttendancePermission)
|
||||
{
|
||||
List<Attendance> lstAttendance = await _context.Attendes.Where(c => c.ProjectID == projectId && c.AttendanceDate.Date >= fromDate.Date && c.AttendanceDate.Date <= toDate.Date && c.TenantId == TenantId).ToListAsync();
|
||||
List<Attendance> lstAttendance = await _context.Attendes.Where(c => c.ProjectID == projectId && c.AttendanceDate.Date >= fromDate.Date && c.AttendanceDate.Date <= toDate.Date && c.TenantId == tenantId).ToListAsync();
|
||||
|
||||
|
||||
List<ProjectAllocation> projectteam = await _projectServices.GetTeamByProject(TenantId, projectId, true);
|
||||
List<ProjectAllocation> projectteam = await _projectServices.GetTeamByProject(tenantId, projectId, organizationId, true);
|
||||
var jobRole = await _context.JobRoles.ToListAsync();
|
||||
foreach (Attendance? attendance in lstAttendance)
|
||||
{
|
||||
@ -202,7 +211,7 @@ namespace MarcoBMS.Services.Controllers
|
||||
CheckOutTime = attendance.OutTime,
|
||||
Activity = attendance.Activity
|
||||
};
|
||||
teamMember = projectteam.Find(x => x.EmployeeId == attendance.EmployeeID);
|
||||
teamMember = projectteam.Find(x => x.EmployeeId == attendance.EmployeeId);
|
||||
if (teamMember != null)
|
||||
{
|
||||
result1.EmployeeAvatar = null;
|
||||
@ -212,12 +221,14 @@ namespace MarcoBMS.Services.Controllers
|
||||
result1.FirstName = teamMember.Employee.FirstName;
|
||||
result1.LastName = teamMember.Employee.LastName;
|
||||
result1.JobRoleName = teamMember.Employee.JobRole != null ? teamMember.Employee.JobRole.Name : null;
|
||||
result1.OrganizationName = teamMember.Employee.Organization?.Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
result1.FirstName = null;
|
||||
result1.LastName = null;
|
||||
result1.JobRoleName = null;
|
||||
result1.OrganizationName = null;
|
||||
}
|
||||
|
||||
result.Add(result1);
|
||||
@ -227,8 +238,22 @@ namespace MarcoBMS.Services.Controllers
|
||||
}
|
||||
else if (hasSelfAttendancePermission)
|
||||
{
|
||||
List<Attendance> lstAttendances = await _context.Attendes.Where(c => c.ProjectID == projectId && c.EmployeeID == LoggedInEmployee.Id && c.AttendanceDate.Date >= fromDate.Date && c.AttendanceDate.Date <= toDate.Date && c.TenantId == TenantId).ToListAsync();
|
||||
ProjectAllocation? projectAllocation = await _context.ProjectAllocations.Include(pa => pa.Employee).FirstOrDefaultAsync(pa => pa.ProjectId == projectId && pa.EmployeeId == LoggedInEmployee.Id && pa.TenantId == TenantId && pa.IsActive);
|
||||
List<Attendance> lstAttendances = await _context.Attendes
|
||||
.Where(c => c.ProjectID == projectId && c.EmployeeId == LoggedInEmployee.Id && c.AttendanceDate.Date >= fromDate.Date && c.AttendanceDate.Date <= toDate.Date && c.TenantId == tenantId)
|
||||
.ToListAsync();
|
||||
|
||||
var projectAllocationQuery = _context.ProjectAllocations
|
||||
.Include(pa => pa.Employee)
|
||||
.ThenInclude(e => e!.Organization)
|
||||
.Where(pa => pa.ProjectId == projectId && pa.EmployeeId == LoggedInEmployee.Id && pa.TenantId == tenantId && pa.IsActive);
|
||||
|
||||
if (organizationId.HasValue)
|
||||
{
|
||||
projectAllocationQuery = projectAllocationQuery.Where(pa => pa.Employee != null && pa.Employee.OrganizationId == organizationId);
|
||||
}
|
||||
|
||||
var projectAllocation = await projectAllocationQuery.FirstOrDefaultAsync();
|
||||
|
||||
foreach (var attendance in lstAttendances)
|
||||
{
|
||||
if (projectAllocation != null)
|
||||
@ -241,6 +266,7 @@ namespace MarcoBMS.Services.Controllers
|
||||
FirstName = projectAllocation.Employee?.FirstName,
|
||||
LastName = projectAllocation.Employee?.LastName,
|
||||
JobRoleName = projectAllocation.Employee?.JobRole?.Name,
|
||||
OrganizationName = projectAllocation.Employee?.Organization?.Name,
|
||||
CheckInTime = attendance.InTime,
|
||||
CheckOutTime = attendance.OutTime,
|
||||
Activity = attendance.Activity
|
||||
@ -253,118 +279,79 @@ namespace MarcoBMS.Services.Controllers
|
||||
return Ok(ApiResponse<object>.SuccessResponse(result, System.String.Format("{0} Attendance records fetched successfully", result.Count), 200));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="projectId">ProjectID</param>
|
||||
/// <param name="date">YYYY-MM-dd</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("project/team")]
|
||||
public async Task<IActionResult> EmployeeAttendanceByProject([FromQuery] Guid projectId, [FromQuery] bool IncludeInActive, [FromQuery] string? date = null)
|
||||
/// <summary>
|
||||
/// Retrieves employee attendance records for a specified project and date.
|
||||
/// The result is filtered based on the logged-in employee's permissions (Team or Self).
|
||||
/// </summary>
|
||||
/// <param name="projectId">The ID of the project.</param>
|
||||
/// <param name="organizationId">Optional. Filters attendance for employees of a specific organization.</param>
|
||||
/// <param name="includeInactive">Optional. Includes inactive employees in the team list if true.</param>
|
||||
/// <param name="date">Optional. The date for which to fetch attendance, in "yyyy-MM-dd" format. Defaults to the current UTC date.</param>
|
||||
/// <returns>An IActionResult containing a list of employee attendance records or an error response.</returns>
|
||||
public async Task<IActionResult> EmployeeAttendanceByProjectAsync([FromQuery] Guid projectId, [FromQuery] Guid? organizationId, [FromQuery] bool includeInactive, [FromQuery] string? date = null)
|
||||
{
|
||||
Guid TenantId = GetTenantId();
|
||||
var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||
var hasTeamAttendancePermission = await _permission.HasPermission(PermissionsMaster.TeamAttendance, LoggedInEmployee.Id);
|
||||
var hasSelfAttendancePermission = await _permission.HasPermission(PermissionsMaster.SelfAttendance, LoggedInEmployee.Id);
|
||||
var hasProjectPermission = await _permission.HasProjectPermission(LoggedInEmployee, projectId);
|
||||
var tenantId = GetTenantId();
|
||||
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||
|
||||
if (!hasProjectPermission)
|
||||
// --- 1. Initial Validation and Permission Checks ---
|
||||
_logger.LogInfo("Fetching attendance for ProjectId: {ProjectId}, TenantId: {TenantId}", projectId, tenantId);
|
||||
|
||||
// Validate date format
|
||||
if (!DateTime.TryParse(date, out var forDate))
|
||||
{
|
||||
_logger.LogWarning("Employee {EmployeeId} tries to access attendance of project {ProjectId}, but don't have access", LoggedInEmployee.Id, projectId);
|
||||
return Unauthorized(ApiResponse<object>.ErrorResponse("Unauthorized access", "Unauthorized access", 404));
|
||||
forDate = DateTime.UtcNow.Date; // Default to today's date
|
||||
}
|
||||
|
||||
DateTime forDate = new DateTime();
|
||||
|
||||
if (date != null && DateTime.TryParse(date, out forDate) == false)
|
||||
// Check if the project exists and if the employee has access
|
||||
var project = await _context.Projects.AsNoTracking().FirstOrDefaultAsync(p => p.Id == projectId && p.TenantId == tenantId);
|
||||
if (project == null)
|
||||
{
|
||||
_logger.LogWarning("User sent Invalid Date while featching attendance logs");
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid Date", "Invalid Date", 400));
|
||||
|
||||
}
|
||||
if (projectId == Guid.Empty)
|
||||
{
|
||||
_logger.LogWarning("The project Id sent by user is less than or equal to zero");
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Project ID is required and must be greater than zero.", "Project ID is required and must be greater than zero.", 400));
|
||||
_logger.LogWarning("Project {ProjectId} not found in database", projectId);
|
||||
return NotFound(ApiResponse<object>.ErrorResponse("Project not found."));
|
||||
}
|
||||
|
||||
var result = new List<EmployeeAttendanceVM>();
|
||||
Attendance? attendance = null;
|
||||
if (!await _permission.HasProjectPermission(loggedInEmployee, projectId))
|
||||
{
|
||||
_logger.LogWarning("Unauthorized access attempt by EmployeeId: {EmployeeId} for ProjectId: {ProjectId}", loggedInEmployee.Id, projectId);
|
||||
return Unauthorized(ApiResponse<object>.ErrorResponse("You do not have permission to access this project."));
|
||||
}
|
||||
|
||||
// --- 2. Delegate to Specific Logic Based on Permissions ---
|
||||
try
|
||||
{
|
||||
var hasTeamAttendancePermission = await _permission.HasPermission(PermissionsMaster.TeamAttendance, loggedInEmployee.Id);
|
||||
List<EmployeeAttendanceVM> result;
|
||||
|
||||
if (date == null) forDate = DateTime.UtcNow.Date;
|
||||
if (hasTeamAttendancePermission)
|
||||
{
|
||||
List<Attendance> lstAttendance = await _context.Attendes.Where(c => c.ProjectID == projectId && c.AttendanceDate.Date == forDate && c.TenantId == TenantId).ToListAsync();
|
||||
|
||||
|
||||
List<ProjectAllocation> projectteam = await _projectServices.GetTeamByProject(TenantId, projectId, IncludeInActive);
|
||||
var idList = projectteam.Select(p => p.EmployeeId).ToList();
|
||||
//var emp = await _context.Employees.Where(e => idList.Contains(e.Id)).Include(e => e.JobRole).ToListAsync();
|
||||
var jobRole = await _context.JobRoles.ToListAsync();
|
||||
|
||||
foreach (ProjectAllocation teamMember in projectteam)
|
||||
_logger.LogInfo("EmployeeId: {EmployeeId} has Team Attendance permission. Fetching team attendance.", loggedInEmployee.Id);
|
||||
result = await GetTeamAttendanceAsync(tenantId, projectId, organizationId, forDate, includeInactive);
|
||||
}
|
||||
else if (await _permission.HasPermission(PermissionsMaster.SelfAttendance, loggedInEmployee.Id))
|
||||
{
|
||||
if (teamMember.Employee != null && teamMember.Employee.JobRole != null)
|
||||
_logger.LogInfo("EmployeeId: {EmployeeId} has Self Attendance permission. Fetching self attendance.", loggedInEmployee.Id);
|
||||
result = await GetSelfAttendanceAsync(tenantId, projectId, loggedInEmployee.Id, organizationId, forDate);
|
||||
}
|
||||
else
|
||||
{
|
||||
var result1 = new EmployeeAttendanceVM()
|
||||
{
|
||||
EmployeeAvatar = null,
|
||||
EmployeeId = teamMember.EmployeeId,
|
||||
FirstName = teamMember.Employee.FirstName,
|
||||
LastName = teamMember.Employee.LastName,
|
||||
JobRoleName = teamMember.Employee.JobRole.Name,
|
||||
};
|
||||
|
||||
//var member = emp.Where(e => e.Id == teamMember.EmployeeId);
|
||||
|
||||
|
||||
attendance = lstAttendance.Find(x => x.EmployeeID == teamMember.EmployeeId) ?? new Attendance();
|
||||
if (attendance != null)
|
||||
{
|
||||
result1.Id = attendance.Id;
|
||||
result1.CheckInTime = attendance.InTime;
|
||||
result1.CheckOutTime = attendance.OutTime;
|
||||
result1.Activity = attendance.Activity;
|
||||
_logger.LogWarning("Access denied for EmployeeId: {EmployeeId}. No valid attendance permission found.", loggedInEmployee.Id);
|
||||
return StatusCode(403, ApiResponse<object>.ErrorResponse("You do not have permission to view attendance.", new { }, 403));
|
||||
}
|
||||
|
||||
result.Add(result1);
|
||||
_logger.LogInfo("Successfully fetched {Count} attendance records for ProjectId: {ProjectId}", result.Count, projectId);
|
||||
return Ok(ApiResponse<object>.SuccessResponse(result, $"{result.Count} attendance records fetched successfully."));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "An error occurred while fetching attendance for ProjectId: {ProjectId}", projectId);
|
||||
return StatusCode(500, ApiResponse<object>.ErrorResponse("An internal server error occurred."));
|
||||
}
|
||||
}
|
||||
|
||||
result.Sort(delegate (EmployeeAttendanceVM x, EmployeeAttendanceVM y)
|
||||
{
|
||||
//return x.FirstName.CompareTo(y.FirstName);
|
||||
return string.Compare(x.FirstName, y.FirstName, StringComparison.Ordinal);
|
||||
});
|
||||
}
|
||||
else if (hasSelfAttendancePermission)
|
||||
{
|
||||
Attendance lstAttendance = await _context.Attendes.FirstOrDefaultAsync(c => c.ProjectID == projectId && c.EmployeeID == LoggedInEmployee.Id && c.AttendanceDate.Date == forDate && c.TenantId == TenantId) ?? new Attendance();
|
||||
ProjectAllocation? projectAllocation = await _context.ProjectAllocations.Include(pa => pa.Employee).FirstOrDefaultAsync(pa => pa.ProjectId == projectId && pa.EmployeeId == LoggedInEmployee.Id && pa.TenantId == TenantId && pa.IsActive);
|
||||
if (projectAllocation != null)
|
||||
{
|
||||
EmployeeAttendanceVM result1 = new EmployeeAttendanceVM
|
||||
{
|
||||
Id = lstAttendance.Id,
|
||||
EmployeeAvatar = null,
|
||||
EmployeeId = projectAllocation.EmployeeId,
|
||||
FirstName = projectAllocation.Employee?.FirstName,
|
||||
LastName = projectAllocation.Employee?.LastName,
|
||||
JobRoleName = projectAllocation.Employee?.JobRole?.Name,
|
||||
CheckInTime = lstAttendance.InTime,
|
||||
CheckOutTime = lstAttendance.OutTime,
|
||||
Activity = lstAttendance.Activity
|
||||
};
|
||||
result.Add(result1);
|
||||
}
|
||||
}
|
||||
_logger.LogInfo("{count} Attendance records fetched successfully", result.Count);
|
||||
|
||||
return Ok(ApiResponse<object>.SuccessResponse(result, System.String.Format("{0} Attendance records fetched successfully", result.Count), 200));
|
||||
}
|
||||
|
||||
[HttpGet("regularize")]
|
||||
public async Task<IActionResult> GetRequestRegularizeAttendance([FromQuery] Guid projectId, [FromQuery] bool IncludeInActive)
|
||||
public async Task<IActionResult> GetRequestRegularizeAttendance([FromQuery] Guid projectId, [FromQuery] Guid? organizationId, [FromQuery] bool IncludeInActive)
|
||||
{
|
||||
Guid TenantId = GetTenantId();
|
||||
Employee LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||
@ -379,11 +366,14 @@ namespace MarcoBMS.Services.Controllers
|
||||
|
||||
List<Attendance> lstAttendance = await _context.Attendes.Where(c => c.ProjectID == projectId && c.Activity == ATTENDANCE_MARK_TYPE.REQUEST_REGULARIZE && c.TenantId == TenantId).ToListAsync();
|
||||
|
||||
List<ProjectAllocation> projectteam = await _projectServices.GetTeamByProject(TenantId, projectId, true);
|
||||
List<ProjectAllocation> projectteam = await _projectServices.GetTeamByProject(TenantId, projectId, organizationId, true);
|
||||
var idList = projectteam.Select(p => p.EmployeeId).ToList();
|
||||
var jobRole = await _context.JobRoles.ToListAsync();
|
||||
|
||||
foreach (Attendance attende in lstAttendance)
|
||||
{
|
||||
var teamMember = projectteam.Find(m => m.EmployeeId == attende.EmployeeId);
|
||||
if (teamMember != null && teamMember.Employee != null && teamMember.Employee.JobRole != null)
|
||||
{
|
||||
var result1 = new EmployeeAttendanceVM()
|
||||
{
|
||||
@ -392,19 +382,16 @@ namespace MarcoBMS.Services.Controllers
|
||||
CheckOutTime = attende.OutTime,
|
||||
Activity = attende.Activity,
|
||||
EmployeeAvatar = null,
|
||||
EmployeeId = attende.EmployeeID,
|
||||
|
||||
EmployeeId = attende.EmployeeId,
|
||||
FirstName = teamMember.Employee.FirstName,
|
||||
LastName = teamMember.Employee.LastName,
|
||||
JobRoleName = teamMember.Employee.JobRole.Name,
|
||||
OrganizationName = teamMember.Employee.Organization?.Name
|
||||
};
|
||||
|
||||
var teamMember = projectteam.Find(m => m.EmployeeId == attende.EmployeeID);
|
||||
if (teamMember != null && teamMember.Employee != null && teamMember.Employee.JobRole != null)
|
||||
{
|
||||
result1.FirstName = teamMember.Employee.FirstName;
|
||||
result1.LastName = teamMember.Employee.LastName;
|
||||
result1.JobRoleName = teamMember.Employee.JobRole.Name;
|
||||
result.Add(result1);
|
||||
}
|
||||
|
||||
result.Add(result1);
|
||||
|
||||
}
|
||||
|
||||
result.Sort(delegate (EmployeeAttendanceVM x, EmployeeAttendanceVM y)
|
||||
@ -415,7 +402,6 @@ namespace MarcoBMS.Services.Controllers
|
||||
return Ok(ApiResponse<object>.SuccessResponse(result, System.String.Format("{0} Attendance records fetched successfully", result.Count), 200));
|
||||
}
|
||||
|
||||
|
||||
[HttpPost]
|
||||
[Route("record")]
|
||||
public async Task<IActionResult> RecordAttendance([FromBody] RecordAttendanceDot recordAttendanceDot)
|
||||
@ -490,7 +476,7 @@ namespace MarcoBMS.Services.Controllers
|
||||
{
|
||||
attendance.IsApproved = true;
|
||||
attendance.Activity = ATTENDANCE_MARK_TYPE.REGULARIZE;
|
||||
attendance.ApprovedBy = currentEmployee.Id;
|
||||
attendance.ApprovedById = currentEmployee.Id;
|
||||
// do nothing
|
||||
}
|
||||
else if (recordAttendanceDot.Action == ATTENDANCE_MARK_TYPE.REGULARIZE_REJECT)
|
||||
@ -511,7 +497,7 @@ namespace MarcoBMS.Services.Controllers
|
||||
attendance.AttendanceDate = recordAttendanceDot.Date;
|
||||
// attendance.Activity = recordAttendanceDot.Action;
|
||||
attendance.Comment = recordAttendanceDot.Comment;
|
||||
attendance.EmployeeID = recordAttendanceDot.EmployeeID;
|
||||
attendance.EmployeeId = recordAttendanceDot.EmployeeID;
|
||||
attendance.ProjectID = recordAttendanceDot.ProjectID;
|
||||
attendance.Date = DateTime.UtcNow;
|
||||
|
||||
@ -586,7 +572,7 @@ namespace MarcoBMS.Services.Controllers
|
||||
|
||||
var name = $"{vm.FirstName} {vm.LastName}";
|
||||
|
||||
await _firebase.SendAttendanceMessageAsync(attendance.ProjectID, name, recordAttendanceDot.Action, attendance.EmployeeID, TenantId);
|
||||
await _firebase.SendAttendanceMessageAsync(attendance.ProjectID, name, recordAttendanceDot.Action, attendance.EmployeeId, TenantId);
|
||||
|
||||
});
|
||||
|
||||
@ -654,7 +640,7 @@ namespace MarcoBMS.Services.Controllers
|
||||
TenantId = tenantId,
|
||||
AttendanceDate = recordAttendanceDot.Date,
|
||||
Comment = recordAttendanceDot.Comment,
|
||||
EmployeeID = recordAttendanceDot.EmployeeID,
|
||||
EmployeeId = recordAttendanceDot.EmployeeID,
|
||||
ProjectID = recordAttendanceDot.ProjectID,
|
||||
Date = DateTime.UtcNow,
|
||||
InTime = finalDateTime,
|
||||
@ -795,7 +781,7 @@ namespace MarcoBMS.Services.Controllers
|
||||
|
||||
var name = $"{vm.FirstName} {vm.LastName}";
|
||||
|
||||
await _firebase.SendAttendanceMessageAsync(attendance.ProjectID, name, recordAttendanceDot.Action, attendance.EmployeeID, tenantId);
|
||||
await _firebase.SendAttendanceMessageAsync(attendance.ProjectID, name, recordAttendanceDot.Action, attendance.EmployeeId, tenantId);
|
||||
|
||||
});
|
||||
|
||||
@ -823,5 +809,112 @@ namespace MarcoBMS.Services.Controllers
|
||||
DateTime finalDateTime = new DateTime(date.Year, date.Month, date.Day, parsedTime.Hour, parsedTime.Minute, 0);
|
||||
return finalDateTime;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches attendance for an entire project team using a single, optimized database query.
|
||||
/// </summary>
|
||||
private async Task<List<EmployeeAttendanceVM>> GetTeamAttendanceAsync(Guid tenantId, Guid projectId, Guid? organizationId, DateTime forDate, bool includeInactive)
|
||||
{
|
||||
// This single query joins ProjectAllocations with Employees and performs a LEFT JOIN with Attendances.
|
||||
// This is far more efficient than fetching collections and joining them in memory.
|
||||
var query = _context.ProjectAllocations
|
||||
.Include(pa => pa.Employee)
|
||||
.ThenInclude(e => e!.Organization)
|
||||
.Include(pa => pa.Employee)
|
||||
.ThenInclude(e => e!.JobRole)
|
||||
.Where(pa => pa.TenantId == tenantId && pa.ProjectId == projectId);
|
||||
|
||||
// Apply filters based on optional parameters
|
||||
if (!includeInactive)
|
||||
{
|
||||
query = query.Where(pa => pa.IsActive);
|
||||
}
|
||||
if (organizationId.HasValue)
|
||||
{
|
||||
query = query.Where(pa => pa.Employee != null && pa.Employee.OrganizationId == organizationId);
|
||||
}
|
||||
|
||||
List<Attendance> lstAttendance = await _context.Attendes.Where(c => c.ProjectID == projectId && c.AttendanceDate.Date == forDate && c.TenantId == tenantId).ToListAsync();
|
||||
|
||||
var teamAttendance = await query
|
||||
.AsNoTracking()
|
||||
.ToListAsync();
|
||||
|
||||
var response = teamAttendance
|
||||
.Select(teamMember =>
|
||||
{
|
||||
var result1 = new EmployeeAttendanceVM()
|
||||
{
|
||||
EmployeeAvatar = null,
|
||||
EmployeeId = teamMember.EmployeeId,
|
||||
FirstName = teamMember.Employee?.FirstName,
|
||||
LastName = teamMember.Employee?.LastName,
|
||||
OrganizationName = teamMember.Employee?.Organization?.Name,
|
||||
JobRoleName = teamMember.Employee?.JobRole?.Name,
|
||||
};
|
||||
|
||||
//var member = emp.Where(e => e.Id == teamMember.EmployeeId);
|
||||
|
||||
|
||||
var attendance = lstAttendance.Find(x => x.EmployeeId == teamMember.EmployeeId) ?? new Attendance();
|
||||
if (attendance != null)
|
||||
{
|
||||
result1.Id = attendance.Id;
|
||||
result1.CheckInTime = attendance.InTime;
|
||||
result1.CheckOutTime = attendance.OutTime;
|
||||
result1.Activity = attendance.Activity;
|
||||
}
|
||||
return result1;
|
||||
})
|
||||
.OrderBy(vm => vm.FirstName) // Let the database handle sorting.
|
||||
.ThenBy(vm => vm.LastName).ToList();
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches a single attendance record for the logged-in employee.
|
||||
/// </summary>
|
||||
private async Task<List<EmployeeAttendanceVM>> GetSelfAttendanceAsync(Guid tenantId, Guid projectId, Guid employeeId, Guid? organizationId, DateTime forDate)
|
||||
{
|
||||
List<EmployeeAttendanceVM> result = new List<EmployeeAttendanceVM>();
|
||||
|
||||
// This query fetches the employee's project allocation and their attendance in a single trip.
|
||||
Attendance lstAttendance = await _context.Attendes
|
||||
.FirstOrDefaultAsync(c => c.ProjectID == projectId && c.EmployeeId == employeeId && c.AttendanceDate.Date == forDate && c.TenantId == tenantId) ?? new Attendance();
|
||||
|
||||
var projectAllocationQuery = _context.ProjectAllocations
|
||||
.Include(pa => pa.Employee)
|
||||
.ThenInclude(e => e!.Organization)
|
||||
.Where(pa => pa.ProjectId == projectId && pa.EmployeeId == employeeId && pa.TenantId == tenantId && pa.IsActive);
|
||||
|
||||
if (organizationId.HasValue)
|
||||
{
|
||||
projectAllocationQuery = projectAllocationQuery.Where(pa => pa.Employee != null && pa.Employee.OrganizationId == organizationId);
|
||||
}
|
||||
|
||||
var projectAllocation = await projectAllocationQuery.FirstOrDefaultAsync();
|
||||
|
||||
if (projectAllocation != null)
|
||||
{
|
||||
EmployeeAttendanceVM result1 = new EmployeeAttendanceVM
|
||||
{
|
||||
Id = lstAttendance.Id,
|
||||
EmployeeAvatar = null,
|
||||
EmployeeId = projectAllocation.EmployeeId,
|
||||
FirstName = projectAllocation.Employee?.FirstName,
|
||||
OrganizationName = projectAllocation.Employee?.Organization?.Name,
|
||||
LastName = projectAllocation.Employee?.LastName,
|
||||
JobRoleName = projectAllocation.Employee?.JobRole?.Name,
|
||||
CheckInTime = lstAttendance.InTime,
|
||||
CheckOutTime = lstAttendance.OutTime,
|
||||
Activity = lstAttendance.Activity
|
||||
};
|
||||
result.Add(result1);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
using Marco.Pms.DataAccess.Data;
|
||||
using AutoMapper;
|
||||
using Marco.Pms.DataAccess.Data;
|
||||
using Marco.Pms.Model.Authentication;
|
||||
using Marco.Pms.Model.Dtos.Authentication;
|
||||
using Marco.Pms.Model.Dtos.Util;
|
||||
using Marco.Pms.Model.Employees;
|
||||
using Marco.Pms.Model.Entitlements;
|
||||
using Marco.Pms.Model.Utilities;
|
||||
using Marco.Pms.Services.Service.ServiceInterfaces;
|
||||
using Marco.Pms.Model.ViewModels.Tenant;
|
||||
using MarcoBMS.Services.Helpers;
|
||||
using MarcoBMS.Services.Service;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
@ -23,36 +24,37 @@ namespace MarcoBMS.Services.Controllers
|
||||
[Route("api/[controller]")]
|
||||
public class AuthController : ControllerBase
|
||||
{
|
||||
private readonly IDbContextFactory<ApplicationDbContext> _dbContextFactory;
|
||||
private readonly IServiceScopeFactory _serviceScopeFactory;
|
||||
private readonly UserManager<ApplicationUser> _userManager;
|
||||
private readonly UserHelper _userHelper;
|
||||
private readonly ApplicationDbContext _context;
|
||||
private readonly JwtSettings _jwtSettings;
|
||||
private readonly RefreshTokenService _refreshTokenService;
|
||||
private readonly IEmailSender _emailSender;
|
||||
private readonly IConfiguration _configuration;
|
||||
private readonly EmployeeHelper _employeeHelper;
|
||||
private readonly ILoggingService _logger;
|
||||
private readonly IFirebaseService _firebase;
|
||||
private readonly Guid tenantId;
|
||||
public AuthController(UserManager<ApplicationUser> userManager, ApplicationDbContext context, JwtSettings jwtSettings, RefreshTokenService refreshTokenService,
|
||||
IEmailSender emailSender, IConfiguration configuration, EmployeeHelper employeeHelper, UserHelper userHelper, ILoggingService logger, IFirebaseService firebase)
|
||||
|
||||
public AuthController(IDbContextFactory<ApplicationDbContext> dbContextFactory,
|
||||
IServiceScopeFactory serviceScopeFactory,
|
||||
UserManager<ApplicationUser> userManager,
|
||||
JwtSettings jwtSettings,
|
||||
IConfiguration configuration,
|
||||
ILoggingService logger)
|
||||
{
|
||||
_userManager = userManager;
|
||||
_jwtSettings = jwtSettings;
|
||||
_refreshTokenService = refreshTokenService;
|
||||
_emailSender = emailSender;
|
||||
_configuration = configuration;
|
||||
_employeeHelper = employeeHelper;
|
||||
_context = context;
|
||||
_userHelper = userHelper;
|
||||
_logger = logger;
|
||||
_firebase = firebase;
|
||||
tenantId = userHelper.GetTenantId();
|
||||
_dbContextFactory = dbContextFactory ?? throw new ArgumentNullException(nameof(dbContextFactory));
|
||||
_serviceScopeFactory = serviceScopeFactory ?? throw new ArgumentNullException(nameof(serviceScopeFactory));
|
||||
_userManager = userManager ?? throw new ArgumentNullException(nameof(userManager));
|
||||
_jwtSettings = jwtSettings ?? throw new ArgumentNullException(nameof(jwtSettings));
|
||||
_configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
|
||||
[HttpPost("login")]
|
||||
// old login APIs
|
||||
|
||||
[HttpPost("login/v1")]
|
||||
public async Task<IActionResult> Login([FromBody] LoginDto loginDto)
|
||||
{
|
||||
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var _refreshTokenService = scope.ServiceProvider.GetRequiredService<RefreshTokenService>();
|
||||
var _employeeHelper = scope.ServiceProvider.GetRequiredService<EmployeeHelper>();
|
||||
try
|
||||
{
|
||||
|
||||
@ -102,8 +104,8 @@ namespace MarcoBMS.Services.Controllers
|
||||
}
|
||||
|
||||
// Generate tokens
|
||||
var token = _refreshTokenService.GenerateJwtToken(user.UserName, emp.TenantId, _jwtSettings);
|
||||
var refreshToken = await _refreshTokenService.CreateRefreshToken(user.Id, emp.TenantId.ToString(), _jwtSettings);
|
||||
var token = _refreshTokenService.GenerateJwtToken(user.UserName, emp.TenantId ?? Guid.Empty, emp.OrganizationId, _jwtSettings);
|
||||
var refreshToken = await _refreshTokenService.CreateRefreshToken(user.Id, emp.TenantId.ToString(), emp.OrganizationId, _jwtSettings);
|
||||
|
||||
_logger.LogInfo("User login successful - UserId: {UserId}", user.Id);
|
||||
return Ok(ApiResponse<object>.SuccessResponse(new
|
||||
@ -129,16 +131,15 @@ namespace MarcoBMS.Services.Controllers
|
||||
[HttpPost("login-mobile")]
|
||||
public async Task<IActionResult> LoginMobile([FromBody] LoginDto loginDto)
|
||||
{
|
||||
// Log the start of the login attempt for traceability.
|
||||
_logger.LogInfo("Login attempt initiated for user: {Username}", loginDto.Username ?? "N/A");
|
||||
|
||||
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var _refreshTokenService = scope.ServiceProvider.GetRequiredService<RefreshTokenService>();
|
||||
var _employeeHelper = scope.ServiceProvider.GetRequiredService<EmployeeHelper>();
|
||||
try
|
||||
{
|
||||
// --- Input Validation ---
|
||||
// Ensure that the request body and essential fields are not null or empty.
|
||||
// Validate input DTO
|
||||
if (loginDto == null || string.IsNullOrWhiteSpace(loginDto.Username) || string.IsNullOrWhiteSpace(loginDto.Password))
|
||||
{
|
||||
_logger.LogWarning("Login failed due to missing username or password.");
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Username or password is missing.", "Invalid request", 400));
|
||||
}
|
||||
|
||||
@ -198,20 +199,17 @@ namespace MarcoBMS.Services.Controllers
|
||||
_logger.LogWarning("Login failed: Could not find associated employee record for user ID {UserId}", user.Id);
|
||||
return NotFound(ApiResponse<object>.ErrorResponse("Employee not found", "Employee details missing", 404));
|
||||
}
|
||||
_logger.LogInfo("Successfully found employee details for tenant ID: {TenantId}", emp.TenantId);
|
||||
_logger.LogInfo("Successfully found employee details for tenant ID: {TenantId}", emp.TenantId ?? Guid.Empty);
|
||||
|
||||
// --- Token Generation ---
|
||||
// Generate the primary JWT access token.
|
||||
_logger.LogInfo("Generating JWT for user: {Username}", user.UserName);
|
||||
var token = _refreshTokenService.GenerateJwtToken(user.UserName, emp.TenantId, _jwtSettings);
|
||||
// Generate JWT token
|
||||
var token = _refreshTokenService.GenerateJwtToken(user.UserName, emp.TenantId ?? Guid.Empty, emp.OrganizationId, _jwtSettings);
|
||||
|
||||
// Generate a new refresh token and store it in the database.
|
||||
_logger.LogInfo("Generating and storing Refresh Token for user: {Username}", user.UserName);
|
||||
var refreshToken = await _refreshTokenService.CreateRefreshToken(user.Id, emp.TenantId.ToString(), _jwtSettings);
|
||||
var refreshToken = await _refreshTokenService.CreateRefreshToken(user.Id, emp.TenantId.ToString(), emp.OrganizationId, _jwtSettings);
|
||||
|
||||
// Fetch the user's MPIN token if it exists.
|
||||
_logger.LogInfo("Fetching MPIN token for user: {Username}", user.UserName);
|
||||
var mpinToken = await _context.MPINDetails.FirstOrDefaultAsync(p => p.UserId == Guid.Parse(user.Id) && p.TenantId == emp.TenantId);
|
||||
// Fetch MPIN Token
|
||||
var mpinToken = await _context.MPINDetails.FirstOrDefaultAsync(p => p.UserId == Guid.Parse(user.Id));
|
||||
|
||||
// --- Response Assembly ---
|
||||
// Combine all tokens into a single response object.
|
||||
@ -235,15 +233,6 @@ namespace MarcoBMS.Services.Controllers
|
||||
return StatusCode(500, ApiResponse<object>.ErrorResponse("Internal Error", ex.Message, 500));
|
||||
}
|
||||
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
// --- Push Notification Section ---
|
||||
// This section attempts to send a test push notification to the user's device.
|
||||
// It's designed to fail gracefully and handle invalid Firebase Cloud Messaging (FCM) tokens.
|
||||
var name = $"{emp.FirstName} {emp.LastName}";
|
||||
await _firebase.SendLoginMessageAsync(name, tenantId);
|
||||
|
||||
});
|
||||
return Ok(ApiResponse<object>.SuccessResponse(responseData, "User logged in successfully.", 200));
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -257,10 +246,13 @@ namespace MarcoBMS.Services.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[HttpPost("login-mpin")]
|
||||
[HttpPost("login-mpin/v1")]
|
||||
public async Task<IActionResult> VerifyMPIN([FromBody] VerifyMPINDto verifyMPIN)
|
||||
{
|
||||
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var _refreshTokenService = scope.ServiceProvider.GetRequiredService<RefreshTokenService>();
|
||||
|
||||
try
|
||||
{
|
||||
// Validate the MPIN token and extract claims
|
||||
@ -311,7 +303,7 @@ namespace MarcoBMS.Services.Controllers
|
||||
|
||||
// Retrieve MPIN details
|
||||
var mpinDetails = await _context.MPINDetails
|
||||
.FirstOrDefaultAsync(p => p.UserId == Guid.Parse(requestEmployee.ApplicationUserId) && p.TenantId == tenantId);
|
||||
.FirstOrDefaultAsync(p => p.UserId == Guid.Parse(requestEmployee.ApplicationUserId));
|
||||
|
||||
if (mpinDetails == null)
|
||||
{
|
||||
@ -355,19 +347,263 @@ namespace MarcoBMS.Services.Controllers
|
||||
return StatusCode(500, ApiResponse<object>.ErrorResponse("Internal Error", ex.Message, 500));
|
||||
}
|
||||
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
// --- Push Notification Section ---
|
||||
// This section attempts to send a test push notification to the user's device.
|
||||
// It's designed to fail gracefully and handle invalid Firebase Cloud Messaging (FCM) tokens.
|
||||
await _firebase.SendLoginOnAnotherDeviceMessageAsync(requestEmployee.Id, verifyMPIN.FcmToken, tenantId);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
// Generate new tokens
|
||||
var jwtToken = _refreshTokenService.GenerateJwtToken(requestEmployee.Email, tenantId, _jwtSettings);
|
||||
var refreshToken = await _refreshTokenService.CreateRefreshToken(requestEmployee.ApplicationUserId, tenantId.ToString(), _jwtSettings);
|
||||
var jwtToken = _refreshTokenService.GenerateJwtToken(requestEmployee.Email, tenantId, requestEmployee.OrganizationId, _jwtSettings);
|
||||
var refreshToken = await _refreshTokenService.CreateRefreshToken(requestEmployee.ApplicationUserId, tenantId.ToString(), requestEmployee.OrganizationId, _jwtSettings);
|
||||
|
||||
_logger.LogInfo("MPIN verification successful - EmployeeId: {EmployeeId}", requestEmployee.Id);
|
||||
|
||||
return Ok(ApiResponse<object>.SuccessResponse(new
|
||||
{
|
||||
token = jwtToken,
|
||||
refreshToken
|
||||
}, "User logged in successfully.", 200));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Unexpected error occurred while verifying MPIN");
|
||||
return StatusCode(500, ApiResponse<object>.ErrorResponse("Unexpected error", ex.Message, 500));
|
||||
}
|
||||
}
|
||||
|
||||
// new login APIs
|
||||
|
||||
[HttpPost("login")]
|
||||
public async Task<IActionResult> LoginAsync([FromBody] LoginDto loginDto)
|
||||
{
|
||||
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var _refreshTokenService = scope.ServiceProvider.GetRequiredService<RefreshTokenService>();
|
||||
try
|
||||
{
|
||||
// Retrieve employee details
|
||||
var emp = await _context.Employees.FirstOrDefaultAsync(e => e.Email == loginDto.Username && e.IsActive && e.HasApplicationAccess);
|
||||
if (emp == null)
|
||||
{
|
||||
_logger.LogWarning("Login failed: No employee record found for Email: {Email}", loginDto.Username ?? string.Empty);
|
||||
return Unauthorized(ApiResponse<object>.ErrorResponse("Invalid username or password.", "Invalid username or password.", 404));
|
||||
}
|
||||
|
||||
// Find user by email
|
||||
var user = await _context.ApplicationUsers
|
||||
.FirstOrDefaultAsync(u => u.Email == loginDto.Username || u.PhoneNumber == loginDto.Username);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
_logger.LogWarning("Login failed: User not found for input {Username}", loginDto.Username ?? string.Empty);
|
||||
return Unauthorized(ApiResponse<object>.ErrorResponse("Invalid username or password.", "Invalid username or password.", 401));
|
||||
}
|
||||
|
||||
// Check if the user is active
|
||||
if (!user.IsActive)
|
||||
{
|
||||
_logger.LogWarning("Login failed: Inactive user attempted login - UserId: {UserId}", user.Id);
|
||||
return Unauthorized(ApiResponse<object>.ErrorResponse("Invalid username or password.", "Invalid username or password.", 400));
|
||||
}
|
||||
|
||||
// Ensure the user's email is confirmed
|
||||
if (!user.EmailConfirmed)
|
||||
{
|
||||
_logger.LogWarning("Login failed: Email not confirmed for UserId: {UserId}", user.Id);
|
||||
return Unauthorized(ApiResponse<object>.ErrorResponse("Invalid username or password.", "Invalid username or password.", 400));
|
||||
}
|
||||
|
||||
// Validate the password
|
||||
if (!await _userManager.CheckPasswordAsync(user, loginDto.Password ?? string.Empty))
|
||||
{
|
||||
_logger.LogWarning("Login failed: Incorrect password for UserId: {UserId}", user.Id);
|
||||
return Unauthorized(ApiResponse<object>.ErrorResponse("Invalid username or password.", "Invalid username or password.", 401));
|
||||
}
|
||||
|
||||
// Ensure UserName exists for JWT
|
||||
if (string.IsNullOrWhiteSpace(user.UserName))
|
||||
{
|
||||
_logger.LogWarning("Login failed: Username not found for UserId: {UserId}", user.Id);
|
||||
return Unauthorized(ApiResponse<object>.ErrorResponse("Invalid username or password.", "Invalid username or password.", 404));
|
||||
}
|
||||
|
||||
// Generate tokens
|
||||
var token = _refreshTokenService.GenerateJwtTokenWithOrganization(user.UserName, emp.OrganizationId, _jwtSettings);
|
||||
var refreshToken = await _refreshTokenService.CreateRefreshTokenWithOrganization(user.Id, emp.OrganizationId, _jwtSettings);
|
||||
|
||||
//var token = _refreshTokenService.GenerateJwtToken(user.UserName, emp.TenantId ?? Guid.Empty, _jwtSettings);
|
||||
//var refreshToken = await _refreshTokenService.CreateRefreshToken(user.Id, emp.TenantId.ToString(), _jwtSettings);
|
||||
|
||||
_logger.LogInfo("User login successful - UserId: {UserId}", user.Id);
|
||||
return Ok(ApiResponse<object>.SuccessResponse(new
|
||||
{
|
||||
token,
|
||||
refreshToken
|
||||
}, "User logged in successfully.", 200));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Unexpected error during login");
|
||||
return StatusCode(500, ApiResponse<object>.ErrorResponse("Unexpected error", ex.Message, 500));
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("app/login")]
|
||||
public async Task<IActionResult> LoginMobileAsync([FromBody] LoginDto loginDto)
|
||||
{
|
||||
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var _refreshTokenService = scope.ServiceProvider.GetRequiredService<RefreshTokenService>();
|
||||
var _employeeHelper = scope.ServiceProvider.GetRequiredService<EmployeeHelper>();
|
||||
|
||||
// Validate input DTO
|
||||
if (loginDto == null || string.IsNullOrWhiteSpace(loginDto.Username) || string.IsNullOrWhiteSpace(loginDto.Password))
|
||||
{
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Username or password is missing.", "Invalid request", 400));
|
||||
}
|
||||
|
||||
// Find user by email or phone number
|
||||
var user = await _context.ApplicationUsers
|
||||
.FirstOrDefaultAsync(u => u.Email == loginDto.Username || u.PhoneNumber == loginDto.Username);
|
||||
|
||||
// If user not found, return unauthorized
|
||||
if (user == null)
|
||||
{
|
||||
return Unauthorized(ApiResponse<object>.ErrorResponse("Invalid username or password.", "Invalid username or password.", 401));
|
||||
}
|
||||
|
||||
// Check if user is inactive
|
||||
if (!user.IsActive)
|
||||
{
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("User is inactive", "User is inactive", 400));
|
||||
}
|
||||
|
||||
// Check if user email is not confirmed
|
||||
if (!user.EmailConfirmed)
|
||||
{
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Your email is not verified. Please verify your email.", "Email not verified", 400));
|
||||
}
|
||||
|
||||
// Validate password using ASP.NET Identity
|
||||
var isPasswordValid = await _userManager.CheckPasswordAsync(user, loginDto.Password);
|
||||
if (!isPasswordValid)
|
||||
{
|
||||
return Unauthorized(ApiResponse<object>.ErrorResponse("Invalid username or password.", "Invalid credentials", 401));
|
||||
}
|
||||
|
||||
// Check if username is missing
|
||||
if (string.IsNullOrWhiteSpace(user.UserName))
|
||||
{
|
||||
return NotFound(ApiResponse<object>.ErrorResponse("UserName not found", "Username is missing", 404));
|
||||
}
|
||||
|
||||
// Get employee information for tenant context
|
||||
var emp = await _employeeHelper.GetEmployeeByApplicationUserID(user.Id);
|
||||
if (emp == null)
|
||||
{
|
||||
return NotFound(ApiResponse<object>.ErrorResponse("Employee not found", "Employee details missing", 404));
|
||||
}
|
||||
|
||||
// Generate JWT token
|
||||
var token = _refreshTokenService.GenerateJwtTokenWithOrganization(user.UserName, emp.OrganizationId, _jwtSettings);
|
||||
|
||||
// Generate Refresh Token and store in DB
|
||||
var refreshToken = await _refreshTokenService.CreateRefreshTokenWithOrganization(user.Id, emp.OrganizationId, _jwtSettings);
|
||||
|
||||
//// Generate JWT token
|
||||
//var token = _refreshTokenService.GenerateJwtToken(user.UserName, emp.TenantId ?? Guid.Empty, _jwtSettings);
|
||||
|
||||
//// Generate Refresh Token and store in DB
|
||||
//var refreshToken = await _refreshTokenService.CreateRefreshToken(user.Id, emp.TenantId.ToString(), _jwtSettings);
|
||||
|
||||
// Fetch MPIN Token
|
||||
var mpinToken = await _context.MPINDetails.FirstOrDefaultAsync(p => p.UserId == Guid.Parse(user.Id));
|
||||
|
||||
// Combine all tokens in response
|
||||
var responseData = new
|
||||
{
|
||||
token,
|
||||
refreshToken,
|
||||
mpinToken = mpinToken?.MPINToken
|
||||
};
|
||||
|
||||
// Return success response
|
||||
return Ok(ApiResponse<object>.SuccessResponse(responseData, "User logged in successfully.", 200));
|
||||
}
|
||||
|
||||
[HttpPost("login-mpin")]
|
||||
public async Task<IActionResult> VerifyMPINAsync([FromBody] VerifyMPINDto verifyMPIN)
|
||||
{
|
||||
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var _refreshTokenService = scope.ServiceProvider.GetRequiredService<RefreshTokenService>();
|
||||
|
||||
try
|
||||
{
|
||||
// Validate the MPIN token and extract claims
|
||||
var claimsPrincipal = _refreshTokenService.ValidateToken(verifyMPIN.MPINToken, _jwtSettings);
|
||||
if (claimsPrincipal?.Identity == null || !claimsPrincipal.Identity.IsAuthenticated)
|
||||
{
|
||||
_logger.LogWarning("Invalid or unauthenticated MPIN token");
|
||||
return Unauthorized(ApiResponse<object>.ErrorResponse("Invalid MPIN token", "Unauthorized", 401));
|
||||
}
|
||||
|
||||
string? tokenType = claimsPrincipal.FindFirst("token_type")?.Value;
|
||||
string? tokenUserId = claimsPrincipal.FindFirst(ClaimTypes.NameIdentifier)?.Value;
|
||||
|
||||
// Validate essential claims
|
||||
if (string.IsNullOrWhiteSpace(tokenType) || string.IsNullOrWhiteSpace(tokenUserId))
|
||||
{
|
||||
_logger.LogWarning("MPIN token claims are incomplete");
|
||||
return Unauthorized(ApiResponse<object>.ErrorResponse("Invalid token claims", "MPIN token does not match your identity", 401));
|
||||
}
|
||||
|
||||
// Fetch employee by ID and tenant
|
||||
var requestEmployee = await _context.Employees
|
||||
.Include(e => e.ApplicationUser)
|
||||
.FirstOrDefaultAsync(e => e.Id == verifyMPIN.EmployeeId && e.HasApplicationAccess && e.ApplicationUserId == tokenUserId && e.IsActive);
|
||||
|
||||
if (requestEmployee == null || string.IsNullOrWhiteSpace(requestEmployee.ApplicationUserId))
|
||||
{
|
||||
_logger.LogWarning("Employee not found or invalid for verification - EmployeeId: {EmployeeId}", verifyMPIN.EmployeeId);
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid request", "Provided invalid employee information", 400));
|
||||
}
|
||||
|
||||
// Validate that the token belongs to the same employee making the request
|
||||
if (requestEmployee.ApplicationUserId != tokenUserId || tokenType != "mpin")
|
||||
{
|
||||
_logger.LogWarning("Token identity does not match employee info - EmployeeId: {EmployeeId}", requestEmployee.Id);
|
||||
return Unauthorized(ApiResponse<object>.ErrorResponse("Unauthorized", "MPIN token does not match your identity", 401));
|
||||
}
|
||||
|
||||
// Ensure MPIN input is valid
|
||||
if (string.IsNullOrWhiteSpace(verifyMPIN.MPIN))
|
||||
{
|
||||
_logger.LogWarning("MPIN not provided for EmployeeId: {EmployeeId}", requestEmployee.Id);
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid request", "MPIN not provided", 400));
|
||||
}
|
||||
|
||||
// Retrieve MPIN details
|
||||
var mpinDetails = await _context.MPINDetails
|
||||
.FirstOrDefaultAsync(p => p.UserId == Guid.Parse(requestEmployee.ApplicationUserId));
|
||||
|
||||
if (mpinDetails == null)
|
||||
{
|
||||
_logger.LogWarning("MPIN not set for EmployeeId: {EmployeeId}", requestEmployee.Id);
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("MPIN not set", "You have not set an MPIN", 400));
|
||||
}
|
||||
|
||||
// Compare hashed MPIN
|
||||
var providedMPINHash = ComputeSha256Hash(verifyMPIN.MPIN);
|
||||
if (providedMPINHash != mpinDetails.MPIN)
|
||||
{
|
||||
_logger.LogWarning("MPIN mismatch for EmployeeId: {EmployeeId}", requestEmployee.Id);
|
||||
return Unauthorized(ApiResponse<object>.ErrorResponse("MPIN mismatch", "MPIN did not match", 401));
|
||||
}
|
||||
|
||||
// Generate new tokens
|
||||
var jwtToken = _refreshTokenService.GenerateJwtTokenWithOrganization(requestEmployee.ApplicationUser?.UserName, requestEmployee.OrganizationId, _jwtSettings);
|
||||
var refreshToken = await _refreshTokenService.CreateRefreshTokenWithOrganization(requestEmployee.ApplicationUserId, requestEmployee.OrganizationId, _jwtSettings);
|
||||
|
||||
//var jwtToken = _refreshTokenService.GenerateJwtToken(requestEmployee.Email, tenantId, _jwtSettings);
|
||||
//var refreshToken = await _refreshTokenService.CreateRefreshToken(requestEmployee.ApplicationUserId, tenantId.ToString(), _jwtSettings);
|
||||
|
||||
_logger.LogInfo("MPIN verification successful - EmployeeId: {EmployeeId}", requestEmployee.Id);
|
||||
|
||||
@ -387,7 +623,15 @@ namespace MarcoBMS.Services.Controllers
|
||||
[HttpPost("logout")]
|
||||
public async Task<IActionResult> Logout([FromBody] LogoutDto logoutDto)
|
||||
{
|
||||
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var _refreshTokenService = scope.ServiceProvider.GetRequiredService<RefreshTokenService>();
|
||||
var _userHelper = scope.ServiceProvider.GetRequiredService<UserHelper>();
|
||||
|
||||
var tenantId = _userHelper.GetTenantId();
|
||||
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||
|
||||
|
||||
if (string.IsNullOrWhiteSpace(logoutDto.RefreshToken))
|
||||
{
|
||||
_logger.LogWarning("Logout failed: Refresh token is missing");
|
||||
@ -433,6 +677,11 @@ namespace MarcoBMS.Services.Controllers
|
||||
[HttpPost("refresh-token")]
|
||||
public async Task<IActionResult> RefreshToken([FromBody] RefreshTokenDto refreshTokenDto)
|
||||
{
|
||||
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var _refreshTokenService = scope.ServiceProvider.GetRequiredService<RefreshTokenService>();
|
||||
var _employeeHelper = scope.ServiceProvider.GetRequiredService<EmployeeHelper>();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(refreshTokenDto.RefreshToken))
|
||||
{
|
||||
_logger.LogWarning("Refresh token is missing from the request body.");
|
||||
@ -441,6 +690,18 @@ namespace MarcoBMS.Services.Controllers
|
||||
|
||||
try
|
||||
{
|
||||
// Validate the MPIN token and extract claims
|
||||
var claimsPrincipal = _refreshTokenService.ValidateToken(refreshTokenDto.RefreshToken, _jwtSettings);
|
||||
if (claimsPrincipal?.Identity == null || !claimsPrincipal.Identity.IsAuthenticated)
|
||||
{
|
||||
_logger.LogWarning("Invalid or unauthenticated MPIN token");
|
||||
return Unauthorized(ApiResponse<object>.ErrorResponse("Invalid MPIN token", "Unauthorized", 401));
|
||||
}
|
||||
|
||||
string? tokenTenantId = claimsPrincipal.FindFirst("TenantId")?.Value ?? string.Empty;
|
||||
|
||||
var tenantId = Guid.Parse(tokenTenantId);
|
||||
|
||||
// Step 1: Fetch and validate the refresh token
|
||||
var refreshToken = await _refreshTokenService.GetRefreshToken(refreshTokenDto.RefreshToken);
|
||||
if (refreshToken == null)
|
||||
@ -476,8 +737,8 @@ namespace MarcoBMS.Services.Controllers
|
||||
// Step 4: Fetch employee and generate new tokens
|
||||
var emp = await _employeeHelper.GetEmployeeByApplicationUserID(user.Id);
|
||||
|
||||
var newJwtToken = _refreshTokenService.GenerateJwtToken(user.UserName, emp.TenantId, _jwtSettings);
|
||||
var newRefreshToken = await _refreshTokenService.CreateRefreshToken(user.Id, emp.TenantId.ToString(), _jwtSettings);
|
||||
var newJwtToken = _refreshTokenService.GenerateJwtToken(user.UserName, tenantId, emp.OrganizationId, _jwtSettings);
|
||||
var newRefreshToken = await _refreshTokenService.CreateRefreshToken(user.Id, tenantId.ToString(), emp.OrganizationId, _jwtSettings);
|
||||
|
||||
_logger.LogInfo("New access and refresh token issued for user: {UserId}", user.Id);
|
||||
|
||||
@ -496,6 +757,10 @@ namespace MarcoBMS.Services.Controllers
|
||||
[HttpPost("forgot-password")]
|
||||
public async Task<IActionResult> ForgotPassword([FromBody] ForgotPasswordDto forgotPasswordDto)
|
||||
{
|
||||
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var _emailSender = scope.ServiceProvider.GetRequiredService<IEmailSender>();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(forgotPasswordDto.Email))
|
||||
{
|
||||
_logger.LogWarning("ForgotPassword request received without email.");
|
||||
@ -532,6 +797,11 @@ namespace MarcoBMS.Services.Controllers
|
||||
[HttpPost("reset-password")]
|
||||
public async Task<IActionResult> ResetPassword([FromBody] ResetPasswordDto model)
|
||||
{
|
||||
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var _emailSender = scope.ServiceProvider.GetRequiredService<IEmailSender>();
|
||||
var _employeeHelper = scope.ServiceProvider.GetRequiredService<EmployeeHelper>();
|
||||
|
||||
_logger.LogInfo("Password reset request received for email: {Email}", model.Email ?? string.Empty);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(model.Email) || string.IsNullOrWhiteSpace(model.Token) || string.IsNullOrWhiteSpace(model.NewPassword))
|
||||
@ -609,6 +879,10 @@ namespace MarcoBMS.Services.Controllers
|
||||
[HttpPost("send-otp")]
|
||||
public async Task<IActionResult> SendOtpEmail([FromBody] GenerateOTPDto generateOTP)
|
||||
{
|
||||
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var _emailSender = scope.ServiceProvider.GetRequiredService<IEmailSender>();
|
||||
|
||||
try
|
||||
{
|
||||
// Validate input email
|
||||
@ -629,16 +903,15 @@ namespace MarcoBMS.Services.Controllers
|
||||
.FirstOrDefaultAsync(e => e.ApplicationUserId == requestedUser.Id);
|
||||
|
||||
// Generate a random 4-digit OTP
|
||||
string otp = new Random().Next(1000, 9999).ToString();
|
||||
string otp = GenerateSecureOtp();
|
||||
|
||||
// Store OTP in database
|
||||
var otpDetails = new OTPDetails
|
||||
{
|
||||
UserId = Guid.Parse(requestedUser.Id),
|
||||
OTP = otp,
|
||||
ExpriesInSec = 300, // 10 minutes
|
||||
TimeStamp = DateTime.UtcNow,
|
||||
TenantId = requestedUser.TenantId
|
||||
ExpriesInSec = 300, // 5 minutes
|
||||
TimeStamp = DateTime.UtcNow
|
||||
};
|
||||
|
||||
_context.OTPDetails.Add(otpDetails);
|
||||
@ -673,6 +946,10 @@ namespace MarcoBMS.Services.Controllers
|
||||
[HttpPost("login-otp")]
|
||||
public async Task<IActionResult> LoginWithOTP([FromBody] VerifyOTPDto verifyOTP)
|
||||
{
|
||||
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var _refreshTokenService = scope.ServiceProvider.GetRequiredService<RefreshTokenService>();
|
||||
|
||||
try
|
||||
{
|
||||
// Validate input
|
||||
@ -700,7 +977,7 @@ namespace MarcoBMS.Services.Controllers
|
||||
|
||||
// Fetch most recent OTP
|
||||
var otpDetails = await _context.OTPDetails
|
||||
.Where(o => o.UserId == userId && o.TenantId == requestEmployee.TenantId)
|
||||
.Where(o => o.UserId == userId)
|
||||
.OrderByDescending(o => o.TimeStamp)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
@ -726,21 +1003,24 @@ namespace MarcoBMS.Services.Controllers
|
||||
}
|
||||
|
||||
// Generate access and refresh tokens
|
||||
var accessToken = _refreshTokenService.GenerateJwtToken(
|
||||
requestEmployee.ApplicationUser?.UserName,
|
||||
requestEmployee.TenantId,
|
||||
_jwtSettings
|
||||
);
|
||||
var accessToken = _refreshTokenService.GenerateJwtTokenWithOrganization(requestEmployee.ApplicationUser?.UserName, requestEmployee.OrganizationId, _jwtSettings);
|
||||
var refreshToken = await _refreshTokenService.CreateRefreshTokenWithOrganization(requestEmployee.ApplicationUserId, requestEmployee.OrganizationId, _jwtSettings);
|
||||
|
||||
var refreshToken = await _refreshTokenService.CreateRefreshToken(
|
||||
requestEmployee.ApplicationUserId,
|
||||
requestEmployee.TenantId.ToString(),
|
||||
_jwtSettings
|
||||
);
|
||||
//var accessToken = _refreshTokenService.GenerateJwtToken(
|
||||
// requestEmployee.ApplicationUser?.UserName,
|
||||
// requestEmployee.TenantId ?? Guid.Empty,
|
||||
// _jwtSettings
|
||||
//);
|
||||
|
||||
//var refreshToken = await _refreshTokenService.CreateRefreshToken(
|
||||
// requestEmployee.ApplicationUserId,
|
||||
// requestEmployee.TenantId.ToString(),
|
||||
// _jwtSettings
|
||||
//);
|
||||
|
||||
// Fetch MPIN token if exists
|
||||
var mpinDetails = await _context.MPINDetails
|
||||
.FirstOrDefaultAsync(p => p.UserId == userId && p.TenantId == requestEmployee.TenantId);
|
||||
.FirstOrDefaultAsync(p => p.UserId == userId);
|
||||
|
||||
// Build and return response
|
||||
var response = new
|
||||
@ -764,8 +1044,9 @@ namespace MarcoBMS.Services.Controllers
|
||||
[HttpPost("sendmail")]
|
||||
public async Task<IActionResult> SendEmail([FromBody] EmailDot emailDot)
|
||||
{
|
||||
|
||||
|
||||
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var _emailSender = scope.ServiceProvider.GetRequiredService<IEmailSender>();
|
||||
|
||||
var user = await _userManager.FindByEmailAsync(emailDot.ToEmail ?? string.Empty);
|
||||
if (user == null)
|
||||
@ -800,8 +1081,15 @@ namespace MarcoBMS.Services.Controllers
|
||||
[HttpPost("change-password")]
|
||||
public async Task<IActionResult> ChangePassword([FromBody] ChangePasswordDto changePassword)
|
||||
{
|
||||
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
|
||||
try
|
||||
{
|
||||
var _userHelper = scope.ServiceProvider.GetRequiredService<UserHelper>();
|
||||
var _emailSender = scope.ServiceProvider.GetRequiredService<IEmailSender>();
|
||||
var _employeeHelper = scope.ServiceProvider.GetRequiredService<EmployeeHelper>();
|
||||
|
||||
// Get the currently logged-in user
|
||||
var loggedUser = await _userHelper.GetCurrentUserAsync();
|
||||
|
||||
@ -859,13 +1147,18 @@ namespace MarcoBMS.Services.Controllers
|
||||
[HttpPost("generate-mpin")]
|
||||
public async Task<IActionResult> GenerateMPIN([FromBody] GenerateMPINDto generateMPINDto)
|
||||
{
|
||||
Guid tenantId = _userHelper.GetTenantId();
|
||||
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
|
||||
var _userHelper = scope.ServiceProvider.GetRequiredService<UserHelper>();
|
||||
var _refreshTokenService = scope.ServiceProvider.GetRequiredService<RefreshTokenService>();
|
||||
|
||||
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||
|
||||
// Get the employee for whom MPIN is being generated
|
||||
var requestEmployee = await _context.Employees
|
||||
.Include(e => e.ApplicationUser)
|
||||
.FirstOrDefaultAsync(e => e.Id == generateMPINDto.EmployeeId && e.TenantId == tenantId);
|
||||
.FirstOrDefaultAsync(e => e.Id == generateMPINDto.EmployeeId);
|
||||
|
||||
// Validate employee and MPIN input
|
||||
if (requestEmployee == null || string.IsNullOrWhiteSpace(generateMPINDto.MPIN) || generateMPINDto.MPIN.Length != 4 || !generateMPINDto.MPIN.All(char.IsDigit))
|
||||
@ -885,13 +1178,13 @@ namespace MarcoBMS.Services.Controllers
|
||||
string mpinHash = ComputeSha256Hash(generateMPINDto.MPIN);
|
||||
string mpinToken = _refreshTokenService.CreateMPINToken(
|
||||
requestEmployee.ApplicationUserId,
|
||||
requestEmployee.TenantId.ToString(),
|
||||
requestEmployee.OrganizationId.ToString(),
|
||||
_jwtSettings
|
||||
);
|
||||
|
||||
// Prepare MPIN entity
|
||||
Guid userId = Guid.Parse(requestEmployee.ApplicationUserId ?? string.Empty);
|
||||
var existingMPIN = await _context.MPINDetails.FirstOrDefaultAsync(p => p.UserId == userId && p.TenantId == tenantId);
|
||||
var existingMPIN = await _context.MPINDetails.FirstOrDefaultAsync(p => p.UserId == userId);
|
||||
|
||||
if (existingMPIN == null)
|
||||
{
|
||||
@ -901,8 +1194,7 @@ namespace MarcoBMS.Services.Controllers
|
||||
UserId = userId,
|
||||
MPIN = mpinHash,
|
||||
MPINToken = mpinToken,
|
||||
TimeStamp = DateTime.UtcNow,
|
||||
TenantId = tenantId
|
||||
TimeStamp = DateTime.UtcNow
|
||||
};
|
||||
|
||||
_context.MPINDetails.Add(mPINDetails);
|
||||
@ -929,6 +1221,15 @@ namespace MarcoBMS.Services.Controllers
|
||||
[HttpPost("set/device-token")]
|
||||
public async Task<IActionResult> StoreDeviceToken([FromBody] FCMTokenDto model)
|
||||
{
|
||||
// Create DbContext asynchronously for fresh connection
|
||||
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
||||
|
||||
// Create a scope to get scoped services
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var _httpContextAccessor = scope.ServiceProvider.GetRequiredService<IHttpContextAccessor>();
|
||||
var _userHelper = scope.ServiceProvider.GetRequiredService<UserHelper>();
|
||||
|
||||
var tenantId = _userHelper.GetTenantId();
|
||||
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||
|
||||
var existingFCMTokenMapping = await _context.FCMTokenMappings.Where(ft => ft.FcmToken == model.FcmToken).ToListAsync();
|
||||
@ -958,6 +1259,158 @@ namespace MarcoBMS.Services.Controllers
|
||||
}
|
||||
return Ok(ApiResponse<object>.SuccessResponse(new { }, "FCM Token registered Successfuly", 200));
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
[HttpGet("get/user/tenants")]
|
||||
public async Task<IActionResult> GetTenantListByEmployeeAsync()
|
||||
{
|
||||
// Create DbContext asynchronously to ensure DB connection is established fresh
|
||||
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
||||
|
||||
// Create a service scope to resolve scoped services like IHttpContextAccessor, IMapper, ILogger
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var _httpContextAccessor = scope.ServiceProvider.GetRequiredService<IHttpContextAccessor>();
|
||||
var _mapper = scope.ServiceProvider.GetRequiredService<IMapper>();
|
||||
var _userHelper = scope.ServiceProvider.GetRequiredService<UserHelper>();
|
||||
|
||||
_logger.LogDebug("Starting GetTenantAsync method.");
|
||||
|
||||
// Extract OrganizationId from current user's claims
|
||||
string stringOrganizationId = _httpContextAccessor.HttpContext?.User.FindFirst("OrganizationId")?.Value ?? string.Empty;
|
||||
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||
|
||||
if (string.IsNullOrEmpty(stringOrganizationId))
|
||||
{
|
||||
_logger.LogWarning("OrganizationId claim missing in user token.");
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("OrganizationId claim is missing", 400));
|
||||
}
|
||||
|
||||
if (!Guid.TryParse(stringOrganizationId, out var organizationId))
|
||||
{
|
||||
_logger.LogWarning("Invalid OrganizationId format: {OrganizationId}", stringOrganizationId);
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid OrganizationId format", 400));
|
||||
}
|
||||
|
||||
_logger.LogInfo("Fetching TenantOrgMappings for OrganizationId: {OrganizationId}", organizationId);
|
||||
|
||||
// Retrieve all TenantOrgMappings that match the organizationId and have a related Tenant
|
||||
var tenantOrgMappingTask = Task.Run(async () =>
|
||||
{
|
||||
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await context.TenantOrgMappings.Where(to => to.OrganizationId == organizationId && to.Tenant != null).Select(to => to.TenantId).ToListAsync();
|
||||
});
|
||||
var projectTask = Task.Run(async () =>
|
||||
{
|
||||
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await context.Projects.Where(to => to.PromoterId == organizationId || to.PMCId == organizationId).Select(to => to.TenantId).ToListAsync();
|
||||
});
|
||||
|
||||
await Task.WhenAll(tenantOrgMappingTask, projectTask);
|
||||
|
||||
var tenantIds = tenantOrgMappingTask.Result;
|
||||
|
||||
tenantIds.AddRange(projectTask.Result);
|
||||
|
||||
tenantIds = tenantIds.Distinct().ToList();
|
||||
|
||||
// Additionally fetch the Tenant record associated directly with this OrganizationId if any
|
||||
var tenants = await _context.Tenants
|
||||
.Include(t => t.Industry)
|
||||
.Include(t => t.TenantStatus)
|
||||
.Where(t => t.OrganizationId == organizationId || tenantIds.Contains(t.Id)).ToListAsync();
|
||||
|
||||
tenants = tenants.Distinct().ToList();
|
||||
|
||||
// Map the tenant entities to TenantListVM view models
|
||||
var response = _mapper.Map<List<TenantListVM>>(tenants);
|
||||
|
||||
_logger.LogInfo("Fetched {Count} tenants for OrganizationId: {OrganizationId}", tenants.Count, organizationId);
|
||||
_logger.LogDebug("GetTenantAsync method completed successfully.");
|
||||
|
||||
return Ok(ApiResponse<object>.SuccessResponse(response, "Successfully fetched the list of tenant", 200));
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
[HttpPost("select-tenant/{tenantId}")]
|
||||
public async Task<IActionResult> SelectTenantAsync(Guid tenantId)
|
||||
{
|
||||
// Create DbContext asynchronously for fresh connection
|
||||
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
||||
|
||||
// Create a scope to get scoped services
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
var _httpContextAccessor = scope.ServiceProvider.GetRequiredService<IHttpContextAccessor>();
|
||||
var _userHelper = scope.ServiceProvider.GetRequiredService<UserHelper>();
|
||||
var _refreshTokenService = scope.ServiceProvider.GetRequiredService<RefreshTokenService>();
|
||||
|
||||
_logger.LogDebug("Starting SelectTenantAsync for tenantId: {TenantId}", tenantId);
|
||||
|
||||
// Get the current logged-in employee
|
||||
Employee loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||
|
||||
// Extract OrganizationId from user claims
|
||||
string stringOrganizationId = _httpContextAccessor.HttpContext?.User.FindFirst("OrganizationId")?.Value ?? string.Empty;
|
||||
|
||||
if (string.IsNullOrEmpty(stringOrganizationId))
|
||||
{
|
||||
_logger.LogWarning("OrganizationId claim is missing.");
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("OrganizationId claim is missing", 400));
|
||||
}
|
||||
|
||||
if (!Guid.TryParse(stringOrganizationId, out var organizationId))
|
||||
{
|
||||
_logger.LogWarning("Invalid OrganizationId format: {OrganizationId}", stringOrganizationId);
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid OrganizationId format", 400));
|
||||
}
|
||||
|
||||
// Find TenantOrgMapping for given tenantId and organizationId to validate access
|
||||
var tenantOrganizationTask = Task.Run(async () =>
|
||||
{
|
||||
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await context.TenantOrgMappings
|
||||
.FirstOrDefaultAsync(to => to.TenantId == tenantId && to.OrganizationId == organizationId);
|
||||
|
||||
});
|
||||
|
||||
var primaryOrganizationTask = Task.Run(async () =>
|
||||
{
|
||||
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await context.Tenants
|
||||
.Where(t => t.Id == tenantId && t.OrganizationId == organizationId).ToListAsync();
|
||||
|
||||
});
|
||||
|
||||
await Task.WhenAll(tenantOrganizationTask, primaryOrganizationTask);
|
||||
|
||||
var tenantOrganization = tenantOrganizationTask.Result;
|
||||
var primaryOrganization = primaryOrganizationTask.Result;
|
||||
|
||||
if (tenantOrganization == null && !primaryOrganization.Any())
|
||||
{
|
||||
_logger.LogWarning("Tenant Organization Mapping not found for TenantId: {TenantId} and OrganizationId: {OrganizationId}", tenantId, organizationId);
|
||||
return NotFound(ApiResponse<object>.ErrorResponse("Tenant Organization Mapping not found", "Tenant Organization Mapping not found in database", 404));
|
||||
}
|
||||
|
||||
// Optional: Blacklist the JWT access token
|
||||
string jwtToken = HttpContext.Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
|
||||
if (!string.IsNullOrWhiteSpace(jwtToken))
|
||||
{
|
||||
await _refreshTokenService.BlacklistJwtTokenAsync(jwtToken);
|
||||
_logger.LogInfo("JWT access token blacklisted successfully");
|
||||
}
|
||||
|
||||
// Generate JWT token scoped to selected tenant and logged-in employee
|
||||
var token = _refreshTokenService.GenerateJwtToken(loggedInEmployee.Email, tenantId, loggedInEmployee.OrganizationId, _jwtSettings);
|
||||
|
||||
// Generate and store refresh token
|
||||
var refreshToken = await _refreshTokenService.CreateRefreshToken(loggedInEmployee.ApplicationUserId, tenantId.ToString(), loggedInEmployee.OrganizationId, _jwtSettings);
|
||||
|
||||
_logger.LogInfo("Tenant selected and tokens generated for TenantId: {TenantId} and Employee: {EmployeeEmail}", tenantId, loggedInEmployee.Email ?? string.Empty);
|
||||
|
||||
// Return success response including tokens
|
||||
return Ok(ApiResponse<object>.SuccessResponse(new { Token = token, RefreshToken = refreshToken }, "Tenant is selected", 200));
|
||||
}
|
||||
|
||||
private static string ComputeSha256Hash(string rawData)
|
||||
{
|
||||
using (SHA256 sha256 = SHA256.Create())
|
||||
@ -974,5 +1427,20 @@ namespace MarcoBMS.Services.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
private static string GenerateSecureOtp()
|
||||
{
|
||||
var randomNumber = new byte[2]; // 2 bytes can store values up to 65535
|
||||
using (var rng = RandomNumberGenerator.Create())
|
||||
{
|
||||
rng.GetBytes(randomNumber);
|
||||
}
|
||||
|
||||
// Convert to int and restrict to 4 digit range (0-9999)
|
||||
int randomValue = BitConverter.ToUInt16(randomNumber, 0) % 10000;
|
||||
|
||||
// Format with leading zeros if necessary to ensure 4 digits
|
||||
return randomValue.ToString("D4");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -235,7 +235,7 @@ namespace Marco.Pms.Services.Controllers
|
||||
int inTodays = await _context.Attendes
|
||||
.Where(a => a.InTime >= today && a.InTime < tomorrow &&
|
||||
finalProjectIds.Contains(a.ProjectID))
|
||||
.Select(a => a.EmployeeID)
|
||||
.Select(a => a.EmployeeId)
|
||||
.Distinct()
|
||||
.CountAsync();
|
||||
|
||||
@ -354,7 +354,7 @@ namespace Marco.Pms.Services.Controllers
|
||||
Guid tenantId = _userHelper.GetTenantId();
|
||||
var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||
|
||||
var attendance = await _context.Attendes.Where(a => a.EmployeeID == LoggedInEmployee.Id && a.TenantId == tenantId).ToListAsync();
|
||||
var attendance = await _context.Attendes.Where(a => a.EmployeeId == LoggedInEmployee.Id && a.TenantId == tenantId).ToListAsync();
|
||||
if (attendance.Any())
|
||||
{
|
||||
var pendingRegularization = attendance.Where(a => a.Activity == ATTENDANCE_MARK_TYPE.REQUEST_REGULARIZE).ToList().Count;
|
||||
@ -395,12 +395,12 @@ namespace Marco.Pms.Services.Controllers
|
||||
var employeeIds = projectAllocation.Select(p => p.EmployeeId).Distinct().ToList();
|
||||
List<Employee>? employees = await _context.Employees.Where(e => employeeIds.Contains(e.Id)).ToListAsync();
|
||||
|
||||
var attendances = await _context.Attendes.Where(a => employeeIds.Contains(a.EmployeeID) && a.ProjectID == projectId && a.InTime.HasValue && a.InTime.Value.Date == currentDate.Date).ToListAsync();
|
||||
var attendances = await _context.Attendes.Where(a => employeeIds.Contains(a.EmployeeId) && a.ProjectID == projectId && a.InTime.HasValue && a.InTime.Value.Date == currentDate.Date).ToListAsync();
|
||||
List<EmployeeAttendanceVM> employeeAttendanceVMs = new List<EmployeeAttendanceVM>();
|
||||
foreach (var attendance in attendances)
|
||||
{
|
||||
|
||||
Employee? employee = employees.FirstOrDefault(e => e.Id == attendance.EmployeeID);
|
||||
Employee? employee = employees.FirstOrDefault(e => e.Id == attendance.EmployeeId);
|
||||
if (employee != null)
|
||||
{
|
||||
EmployeeAttendanceVM employeeAttendanceVM = new EmployeeAttendanceVM
|
||||
@ -579,7 +579,7 @@ namespace Marco.Pms.Services.Controllers
|
||||
.ToList();
|
||||
|
||||
int presentCount = attendances
|
||||
.Count(a => employeeIds.Contains(a.EmployeeID) && a.InTime!.Value.Date == date);
|
||||
.Count(a => employeeIds.Contains(a.EmployeeId) && a.InTime!.Value.Date == date);
|
||||
|
||||
overviewList.Add(new AttendanceOverviewVM
|
||||
{
|
||||
|
@ -894,7 +894,6 @@ namespace Marco.Pms.Services.Controllers
|
||||
{
|
||||
// Get current logged-in employee for authentication/auditing
|
||||
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||
var tenantId = loggedInEmployee.TenantId;
|
||||
|
||||
_logger.LogInfo("Attempting to verify document. EmployeeId: {EmployeeId}, DocumentId: {DocumentId}, IsVerify: {IsVerify}",
|
||||
loggedInEmployee.Id, id, isVerify);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user