From 0ea14ff1120f258be51b4125156c0b9af7623e06 Mon Sep 17 00:00:00 2001 From: Vikas Nale Date: Tue, 25 Mar 2025 13:01:56 +0530 Subject: [PATCH] Push user rights branh --- .../Data/ApplicationDbContext.cs | 8 +- .../Initializer/DBInitializer.cs | 13 +- .../Marco.Pms.DataAccess.csproj | 26 +- ...cyContactPersonInEmployeeModel.Designer.cs | 1943 ++++++++++++++++ ...ddEmergencyContactPersonInEmployeeModel.cs | 40 + ...ddJobRoleIdInProjectAllocation.Designer.cs | 1943 ++++++++++++++++ ...8053416_addJobRoleIdInProjectAllocation.cs | 40 + ...10050_addJoiningDateToEmployee.Designer.cs | 1946 +++++++++++++++++ ...20250321010050_addJoiningDateToEmployee.cs | 29 + .../ApplicationDbContextModelSnapshot.cs | 16 +- .../Repository/ActivityMasterRepository.cs | 47 - .../Repository/ApplicationRolesRepository.cs | 23 - .../Repository/ApplicationUserRepository.cs | 21 - .../Repository/AttendenceRepository.cs | 22 - .../Repository/BuildingRepository.cs | 22 - .../Repository/EmployeeRepository.cs | 47 - .../Repository/FeaturesRepository.cs | 119 - .../Repository/FloorRepository.cs | 22 - .../IRepository/IActivityMasterRepository.cs | 12 - .../IApplicationRolesRepository.cs | 10 - .../IRepository/IApplicationUserRepository.cs | 9 - .../IRepository/IAttendenceRepository.cs | 11 - .../IRepository/IBuildingRepository.cs | 10 - .../IRepository/IEmployeeRepository.cs | 13 - .../IRepository/IFeatureRepository.cs | 18 - .../IRepository/IFloorRepository.cs | 10 - .../IProjectAllocationRepository.cs | 20 - .../IRepository/IProjectRepository.cs | 18 - .../Repository/IRepository/IRepository.cs | 16 - .../IRepository/IStatusRepository.cs | 11 - .../IRepository/ITaskAllocationRepository.cs | 11 - .../Repository/IRepository/IUnitOfWork.cs | 28 - .../IRepository/IWorkAreaRepository.cs | 10 - .../IRepository/IWorkItemMappingReposiotry.cs | 9 - .../IRepository/IWorkItemRepository.cs | 11 - .../Repository/ProjectAllocationRepository.cs | 84 - .../Repository/ProjectRepository.cs | 146 -- Marco.Pms.DataAccess/Repository/Repository.cs | 102 - .../Repository/StatusRepository.cs | 23 - .../Repository/TaskAllocationRepository.cs | 21 - Marco.Pms.DataAccess/Repository/UnitOfWork.cs | 64 - .../Repository/WorkAreaRepository.cs | 22 - .../Repository/WorkItemMappingReporitury.cs | 22 - .../Repository/WorkItemRepository.cs | 22 - Marco.Pms.Model/Activities/TaskAllocation.cs | 2 +- .../Dtos/Employees/CreateUserDto.cs | 4 +- .../Dtos/Project/ProjectAllocationDot.cs | 2 +- Marco.Pms.Model/Dtos/ResetPasswordDto.cs | 3 - Marco.Pms.Model/Dtos/Util/EmailDot.cs | 11 + Marco.Pms.Model/Employees/Employee.cs | 6 + .../Mapper/ApplicationRoleMapper.cs | 1 - Marco.Pms.Model/Mapper/EmployeeMapper.cs | 35 + Marco.Pms.Model/Mapper/ProjectMapper.cs | 15 +- Marco.Pms.Model/Projects/ProjectAllocation.cs | 2 +- .../ViewModels/Employee/EmployeeProfile.cs | 15 + .../ViewModels/Employee/EmployeeVM.cs | 40 + .../Controllers/ActivityController.cs | 12 +- .../Controllers/AttendanceController.cs | 122 +- .../Controllers/AuthController.cs | 109 +- .../Controllers/EmployeeController.cs | 300 ++- .../Controllers/FileController.cs | 16 +- .../Controllers/ProjectController.cs | 266 ++- .../Controllers/RolesController.cs | 40 +- .../Controllers/TaskController.cs | 23 +- .../Controllers/UserController.cs | 68 + .../EmailTemplates/forgot-password.html | 565 +++++ .../EmailTemplates/full-template.html | 565 +++++ .../EmailTemplates/new-user-email.html | 564 +++++ Marco.Pms.Services/Helpers/EmployeeHelper.cs | 89 +- Marco.Pms.Services/Helpers/ProjectHelper.cs | 2 +- Marco.Pms.Services/Helpers/ProjectsHelper.cs | 48 + Marco.Pms.Services/Helpers/RolesHelper.cs | 53 + Marco.Pms.Services/Helpers/UserHelper.cs | 63 + Marco.Pms.Services/Marco.Pms.Services.csproj | 3 + .../Middleware/LoggingMiddleware.cs | 64 + Marco.Pms.Services/Program.cs | 41 +- Marco.Pms.Services/Service/EmailSender.cs | 52 +- Marco.Pms.Services/Service/IEmailSender.cs | 3 + Marco.Pms.Services/Service/ILoggingService.cs | 15 + Marco.Pms.Services/Service/LoggingServices.cs | 35 + Marco.Pms.Services/appsettings.json | 73 +- .../wwwroot/logos/marco-aiot-tech-logo.jpg | Bin 0 -> 22241 bytes Marco.Pms.Utility/DataConversionUtil.cs | 2 +- Marco.Pms.Utility/EmailSender.cs | 2 +- Marco.Pms.Utility/SessionUtil.cs | 2 +- Marco.Pms.Utility/enum.cs | 2 +- 86 files changed, 8871 insertions(+), 1524 deletions(-) create mode 100644 Marco.Pms.DataAccess/Migrations/20250315082651_addEmergencyContactPersonInEmployeeModel.Designer.cs create mode 100644 Marco.Pms.DataAccess/Migrations/20250315082651_addEmergencyContactPersonInEmployeeModel.cs create mode 100644 Marco.Pms.DataAccess/Migrations/20250318053416_addJobRoleIdInProjectAllocation.Designer.cs create mode 100644 Marco.Pms.DataAccess/Migrations/20250318053416_addJobRoleIdInProjectAllocation.cs create mode 100644 Marco.Pms.DataAccess/Migrations/20250321010050_addJoiningDateToEmployee.Designer.cs create mode 100644 Marco.Pms.DataAccess/Migrations/20250321010050_addJoiningDateToEmployee.cs delete mode 100644 Marco.Pms.DataAccess/Repository/ActivityMasterRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/ApplicationRolesRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/ApplicationUserRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/AttendenceRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/BuildingRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/EmployeeRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/FeaturesRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/FloorRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/IRepository/IActivityMasterRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/IRepository/IApplicationRolesRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/IRepository/IApplicationUserRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/IRepository/IAttendenceRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/IRepository/IBuildingRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/IRepository/IEmployeeRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/IRepository/IFeatureRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/IRepository/IFloorRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/IRepository/IProjectAllocationRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/IRepository/IProjectRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/IRepository/IRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/IRepository/IStatusRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/IRepository/ITaskAllocationRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/IRepository/IUnitOfWork.cs delete mode 100644 Marco.Pms.DataAccess/Repository/IRepository/IWorkAreaRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/IRepository/IWorkItemMappingReposiotry.cs delete mode 100644 Marco.Pms.DataAccess/Repository/IRepository/IWorkItemRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/ProjectAllocationRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/ProjectRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/Repository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/StatusRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/TaskAllocationRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/UnitOfWork.cs delete mode 100644 Marco.Pms.DataAccess/Repository/WorkAreaRepository.cs delete mode 100644 Marco.Pms.DataAccess/Repository/WorkItemMappingReporitury.cs delete mode 100644 Marco.Pms.DataAccess/Repository/WorkItemRepository.cs create mode 100644 Marco.Pms.Model/Dtos/Util/EmailDot.cs create mode 100644 Marco.Pms.Model/Mapper/EmployeeMapper.cs create mode 100644 Marco.Pms.Model/ViewModels/Employee/EmployeeProfile.cs create mode 100644 Marco.Pms.Model/ViewModels/Employee/EmployeeVM.cs create mode 100644 Marco.Pms.Services/Controllers/UserController.cs create mode 100644 Marco.Pms.Services/EmailTemplates/forgot-password.html create mode 100644 Marco.Pms.Services/EmailTemplates/full-template.html create mode 100644 Marco.Pms.Services/EmailTemplates/new-user-email.html create mode 100644 Marco.Pms.Services/Helpers/ProjectsHelper.cs create mode 100644 Marco.Pms.Services/Helpers/RolesHelper.cs create mode 100644 Marco.Pms.Services/Helpers/UserHelper.cs create mode 100644 Marco.Pms.Services/Middleware/LoggingMiddleware.cs create mode 100644 Marco.Pms.Services/Service/ILoggingService.cs create mode 100644 Marco.Pms.Services/Service/LoggingServices.cs create mode 100644 Marco.Pms.Services/wwwroot/logos/marco-aiot-tech-logo.jpg diff --git a/Marco.Pms.DataAccess/Data/ApplicationDbContext.cs b/Marco.Pms.DataAccess/Data/ApplicationDbContext.cs index 4cd2dc6..8526de3 100644 --- a/Marco.Pms.DataAccess/Data/ApplicationDbContext.cs +++ b/Marco.Pms.DataAccess/Data/ApplicationDbContext.cs @@ -4,7 +4,7 @@ using Marco.Pms.Model.Authentication; using Marco.Pms.Model.Employees; using Marco.Pms.Model.Entitlements; using Marco.Pms.Model.Projects; -using MarcoBMS.Utility; +using Marco.Pms.Utility; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; @@ -300,19 +300,19 @@ namespace Marco.Pms.DataAccess.Data Id = 1, Name = "Project", Description = "Project Module", - Key = Guid.NewGuid().ToString() + Key = "b04da7e9-0406-409c-ac7f-b97256e6ea02" }, new Module { Id = 2, Name = "Employee", Description = "Employee Module", - Key = Guid.NewGuid().ToString() + Key = "0971c7fb-6ce1-458a-ae3f-8d3205893637" }, new Module { Id = 3, Name = "Masters", Description = "Masters Module", - Key = Guid.NewGuid().ToString() + Key = "504ec132-e6a9-422f-8f85-050602cfce05" }); diff --git a/Marco.Pms.DataAccess/Initializer/DBInitializer.cs b/Marco.Pms.DataAccess/Initializer/DBInitializer.cs index b3662dc..889e3d7 100644 --- a/Marco.Pms.DataAccess/Initializer/DBInitializer.cs +++ b/Marco.Pms.DataAccess/Initializer/DBInitializer.cs @@ -1,15 +1,10 @@ using Marco.Pms.DataAccess.Data; -using Marco.Pms.DataAccess.Repository; -using Marco.Pms.DataAccess.Repository.IRepository; -using Marco.Pms.Model.Activities; using Marco.Pms.Model.Employees; using Marco.Pms.Model.Entitlements; -using Marco.Pms.Model.Projects; using Marco.Pms.Model.ViewModels; -using MarcoBMS.Utility; +using Marco.Pms.Utility; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; -using System.Text.Json; namespace Marco.Pms.DataAccess.Initializer { @@ -19,14 +14,14 @@ namespace Marco.Pms.DataAccess.Initializer private readonly ApplicationDbContext _db; private readonly UserManager _userManager; private readonly RoleManager _roleManager; - private readonly IUnitOfWork _unitOfWork; + //private readonly IUnitOfWork _unitOfWork; - public DBInitializer(UserManager userManager, RoleManager roleManager, ApplicationDbContext db, IUnitOfWork unitOfWork) + public DBInitializer(UserManager userManager, RoleManager roleManager, ApplicationDbContext db) { _userManager = userManager; _roleManager = roleManager; _db = db; - _unitOfWork = unitOfWork; + //_unitOfWork = unitOfWork; } public void Initialize() diff --git a/Marco.Pms.DataAccess/Marco.Pms.DataAccess.csproj b/Marco.Pms.DataAccess/Marco.Pms.DataAccess.csproj index cb22f94..a6bfd37 100644 --- a/Marco.Pms.DataAccess/Marco.Pms.DataAccess.csproj +++ b/Marco.Pms.DataAccess/Marco.Pms.DataAccess.csproj @@ -7,9 +7,9 @@ - - - + + + @@ -19,26 +19,6 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/Marco.Pms.DataAccess/Migrations/20250315082651_addEmergencyContactPersonInEmployeeModel.Designer.cs b/Marco.Pms.DataAccess/Migrations/20250315082651_addEmergencyContactPersonInEmployeeModel.Designer.cs new file mode 100644 index 0000000..21b5489 --- /dev/null +++ b/Marco.Pms.DataAccess/Migrations/20250315082651_addEmergencyContactPersonInEmployeeModel.Designer.cs @@ -0,0 +1,1943 @@ +// +using System; +using Marco.Pms.DataAccess.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Marco.Pms.DataAccess.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20250315082651_addEmergencyContactPersonInEmployeeModel")] + partial class addEmergencyContactPersonInEmployeeModel + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.12") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + // MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); + + modelBuilder.Entity("Marco.Pms.Model.Activities.TaskAllocation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AllocationDate") + .HasColumnType("datetime(6)"); + + b.Property("BuildingId") + .HasColumnType("int"); + + b.Property("EmployeeId") + .HasColumnType("int"); + + b.Property("EmployeeRole") + .HasColumnType("int"); + + b.Property("ProjectId") + .HasColumnType("int"); + + b.Property("ReAllocationDate") + .HasColumnType("datetime(6)"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.Property("WorkAreaId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BuildingId"); + + b.HasIndex("EmployeeId"); + + b.HasIndex("ProjectId"); + + b.HasIndex("TenantId"); + + b.HasIndex("WorkAreaId"); + + b.ToTable("TaskAllocations"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Activities.WorkItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ActivityId") + .HasColumnType("int"); + + b.Property("CompletedWork") + .HasColumnType("int"); + + b.Property("PlannedWork") + .HasColumnType("int"); + + b.Property("TaskDate") + .HasColumnType("datetime(6)"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.Property("WorkAreaId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ActivityId"); + + b.HasIndex("TenantId"); + + b.HasIndex("WorkAreaId"); + + b.ToTable("WorkItems"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Activities.WorkItemMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("TenantId") + .HasColumnType("int"); + + b.Property("WorkAreaId") + .HasColumnType("int"); + + b.Property("WorkItemId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.HasIndex("WorkAreaId"); + + b.HasIndex("WorkItemId"); + + b.ToTable("WorkItemMapping"); + }); + + modelBuilder.Entity("Marco.Pms.Model.AttendanceModule.Attendance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Activity") + .HasColumnType("int"); + + b.Property("ApprovedBy") + .HasColumnType("int"); + + b.Property("AttendanceDate") + .HasColumnType("datetime(6)"); + + b.Property("Comment") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Date") + .HasColumnType("datetime(6)"); + + b.Property("EmployeeID") + .HasColumnType("int"); + + b.Property("InTime") + .HasColumnType("datetime(6)"); + + b.Property("IsApproved") + .HasColumnType("tinyint(1)"); + + b.Property("OutTime") + .HasColumnType("datetime(6)"); + + b.Property("ProjectID") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeID"); + + b.HasIndex("TenantId"); + + b.ToTable("Attendes"); + }); + + modelBuilder.Entity("Marco.Pms.Model.AttendanceModule.AttendanceLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Activity") + .HasColumnType("int"); + + b.Property("ActivityTime") + .HasColumnType("datetime(6)"); + + b.Property("AttendanceId") + .HasColumnType("int"); + + b.Property("Comment") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("EmployeeID") + .HasColumnType("int"); + + b.Property("Latitude") + .HasColumnType("longtext"); + + b.Property("Longitude") + .HasColumnType("longtext"); + + b.Property("Photo") + .HasColumnType("longblob"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("UpdatedOn") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.HasIndex("AttendanceId"); + + b.HasIndex("EmployeeID"); + + b.HasIndex("TenantId"); + + b.HasIndex("UpdatedBy"); + + b.ToTable("AttendanceLogs"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Authentication.RefreshToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("ExpiryDate") + .HasColumnType("datetime(6)"); + + b.Property("IsRevoked") + .HasColumnType("tinyint(1)"); + + b.Property("IsUsed") + .HasColumnType("tinyint(1)"); + + b.Property("RevokedAt") + .HasColumnType("datetime(6)"); + + b.Property("Token") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RefreshTokens"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Employees.Employee", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AadharNumber") + .HasColumnType("longtext"); + + b.Property("ApplicationUserId") + .HasColumnType("varchar(255)"); + + b.Property("BirthDate") + .HasColumnType("datetime(6)"); + + b.Property("CurrentAddress") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Email") + .HasColumnType("longtext"); + + b.Property("EmergencyContactPerson") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("EmergencyPhoneNumber") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Gender") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("JobRoleId") + .HasColumnType("int"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("MiddleName") + .HasColumnType("longtext"); + + b.Property("PanNumber") + .HasColumnType("longtext"); + + b.Property("PeramnentAddress") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("PhoneNumber") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Photo") + .HasColumnType("longblob"); + + b.Property("RoleId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationUserId"); + + b.HasIndex("JobRoleId"); + + b.HasIndex("TenantId"); + + b.ToTable("Employees"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Employees.WorkShift", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("EndTime") + .HasColumnType("time(6)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("StartTime") + .HasColumnType("time(6)"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("WorkShifts"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.ActivityMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ActivityName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TaskAllocationId") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.Property("UnitOfMeasurement") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("TaskAllocationId"); + + b.HasIndex("TenantId"); + + b.ToTable("ActivityMasters"); + + b.HasData( + new + { + Id = 1, + ActivityName = "Core Cutting", + TenantId = 1, + UnitOfMeasurement = "Number" + }, + new + { + Id = 2, + ActivityName = "Fabrication", + TenantId = 1, + UnitOfMeasurement = "Meter" + }, + new + { + Id = 3, + ActivityName = "Lifting", + TenantId = 1, + UnitOfMeasurement = "Meter" + }, + new + { + Id = 4, + ActivityName = "Hanging", + TenantId = 1, + UnitOfMeasurement = "Meter" + }, + new + { + Id = 5, + ActivityName = "Tapping", + TenantId = 1, + UnitOfMeasurement = "Meter" + }, + new + { + Id = 6, + ActivityName = "Welding", + TenantId = 1, + UnitOfMeasurement = "Meter" + }, + new + { + Id = 7, + ActivityName = "Testing", + TenantId = 1, + UnitOfMeasurement = "Area" + }, + new + { + Id = 8, + ActivityName = "Painting", + TenantId = 1, + UnitOfMeasurement = "Meter" + }, + new + { + Id = 9, + ActivityName = "Marking Area", + TenantId = 1, + UnitOfMeasurement = "Meter" + }, + new + { + Id = 10, + ActivityName = "Drilling", + TenantId = 1, + UnitOfMeasurement = "Number" + }, + new + { + Id = 11, + ActivityName = "MS Support Fabrication", + TenantId = 1, + UnitOfMeasurement = "Number" + }, + new + { + Id = 12, + ActivityName = "MS Support Hanging", + TenantId = 1, + UnitOfMeasurement = "Number" + }, + new + { + Id = 13, + ActivityName = "Hydrant Volve", + TenantId = 1, + UnitOfMeasurement = "Number" + }, + new + { + Id = 14, + ActivityName = "Sprinkler Installation", + TenantId = 1, + UnitOfMeasurement = "Number" + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.ApplicationRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Role") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("ApplicationRoles"); + + b.HasData( + new + { + Id = new Guid("2c8d0808-c421-11ef-9b93-0242ac110002"), + Description = "", + Role = "Admin", + TenantId = 1 + }, + new + { + Id = new Guid("62e0918d-c421-11ef-9b93-0242ac110002"), + Description = "", + Role = "Welder", + TenantId = 1 + }, + new + { + Id = new Guid("68823f1f-c421-11ef-9b93-0242ac110002"), + Description = "", + Role = "Helper", + TenantId = 1 + }, + new + { + Id = new Guid("6d3a7c72-c421-11ef-9b93-0242ac110002"), + Description = "", + Role = "Site Engineer", + TenantId = 1 + }, + new + { + Id = new Guid("6d3aad72-c421-11ef-9b93-0242ac110002"), + Description = "", + Role = "Project Manager", + TenantId = 1 + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.EmployeeRoleMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("EmployeeId") + .HasColumnType("int"); + + b.Property("IsEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("RoleId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeId"); + + b.HasIndex("RoleId"); + + b.HasIndex("TenantId"); + + b.ToTable("EmployeeRoleMappings"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.Feature", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("ModuleId") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ModuleId"); + + b.ToTable("Features"); + + b.HasData( + new + { + Id = new Guid("53176ebf-c75d-42e5-839f-4508ffac3def"), + Description = "Manage Project", + IsActive = true, + ModuleId = 1, + Name = "Manage Project" + }, + new + { + Id = new Guid("9666de86-d7c7-4d3d-acaa-fcd6d6b81f3c"), + Description = "Manage Infra", + IsActive = true, + ModuleId = 1, + Name = "Manage Infra" + }, + new + { + Id = new Guid("9d4b5489-2079-40b9-bd77-6e1bf90bc19f"), + Description = "Manage Tasks", + IsActive = true, + ModuleId = 1, + Name = "Manage Tasks" + }, + new + { + Id = new Guid("39e66f81-efc6-446c-95bd-46bff6cfb606"), + Description = "Assign and Update Tasks Progress", + IsActive = true, + ModuleId = 1, + Name = "Assign and Update Tasks Progress" + }, + new + { + Id = new Guid("81ab8a87-8ccd-4015-a917-0627cee6a100"), + Description = "Manage Employee", + IsActive = true, + ModuleId = 2, + Name = "Manage Employee" + }, + new + { + Id = new Guid("52c9cf54-1eb2-44d2-81bb-524cf29c0a94"), + Description = "Attendance", + IsActive = true, + ModuleId = 2, + Name = "Attendance" + }, + new + { + Id = new Guid("be3b3afc-6ccf-4566-b9b6-aafcb65546be"), + Description = "Global Masters", + IsActive = true, + ModuleId = 3, + Name = "Global Masters" + }, + new + { + Id = new Guid("660131a4-788c-4739-a082-cbbf7879cbf2"), + Description = "Tenant Masters", + IsActive = true, + ModuleId = 3, + Name = "Tenant Masters" + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.FeaturePermission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FeatureId") + .HasColumnType("char(36)"); + + b.Property("IsEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("FeatureId"); + + b.ToTable("FeaturePermissions"); + + b.HasData( + new + { + Id = new Guid("6ea44136-987e-44ba-9e5d-1cf8f5837ebc"), + Description = "", + FeatureId = new Guid("53176ebf-c75d-42e5-839f-4508ffac3def"), + IsEnabled = true, + Name = "View Project" + }, + new + { + Id = new Guid("172fc9b6-755b-4f62-ab26-55c34a330614"), + Description = "", + FeatureId = new Guid("53176ebf-c75d-42e5-839f-4508ffac3def"), + IsEnabled = true, + Name = "Manage Project" + }, + new + { + Id = new Guid("b94802ce-0689-4643-9e1d-11c86950c35b"), + Description = "", + FeatureId = new Guid("53176ebf-c75d-42e5-839f-4508ffac3def"), + IsEnabled = true, + Name = "Manage Team" + }, + new + { + Id = new Guid("c7b68e33-72f0-474f-bd96-77636427ecc8"), + Description = "", + FeatureId = new Guid("9666de86-d7c7-4d3d-acaa-fcd6d6b81f3c"), + IsEnabled = true, + Name = "View Project Infra" + }, + new + { + Id = new Guid("f2aee20a-b754-4537-8166-f9507b44585b"), + Description = "", + FeatureId = new Guid("9666de86-d7c7-4d3d-acaa-fcd6d6b81f3c"), + IsEnabled = true, + Name = "Manage Project Infra" + }, + new + { + Id = new Guid("9fcc5f87-25e3-4846-90ac-67a71ab92e3c"), + Description = "", + FeatureId = new Guid("9d4b5489-2079-40b9-bd77-6e1bf90bc19f"), + IsEnabled = true, + Name = "View Task" + }, + new + { + Id = new Guid("08752f33-3b29-4816-b76b-ea8a968ed3c5"), + Description = "", + FeatureId = new Guid("9d4b5489-2079-40b9-bd77-6e1bf90bc19f"), + IsEnabled = true, + Name = "Manage Task" + }, + new + { + Id = new Guid("d135a4b0-4f9a-4903-ab9c-4843839ebdee"), + Description = "", + FeatureId = new Guid("39e66f81-efc6-446c-95bd-46bff6cfb606"), + IsEnabled = true, + Name = "Assign Task and Report Progress" + }, + new + { + Id = new Guid("ed99ecd4-1bed-42e1-b7b3-d64c04493823"), + Description = "", + FeatureId = new Guid("39e66f81-efc6-446c-95bd-46bff6cfb606"), + IsEnabled = true, + Name = "Approve Task" + }, + new + { + Id = new Guid("b82d2b7e-0d52-45f3-997b-c008ea460e7f"), + Description = "", + FeatureId = new Guid("81ab8a87-8ccd-4015-a917-0627cee6a100"), + IsEnabled = true, + Name = "View Employee" + }, + new + { + Id = new Guid("a97d366a-c2bb-448d-be93-402bd2324566"), + Description = "", + FeatureId = new Guid("81ab8a87-8ccd-4015-a917-0627cee6a100"), + IsEnabled = true, + Name = "Manage Employee" + }, + new + { + Id = new Guid("fbd213e0-0250-46f1-9f5f-4b2a1e6e76a3"), + Description = "", + FeatureId = new Guid("81ab8a87-8ccd-4015-a917-0627cee6a100"), + IsEnabled = true, + Name = "Assign To Project" + }, + new + { + Id = new Guid("915e6bff-65f6-4e3f-aea8-3fd217d3ea9e"), + Description = "", + FeatureId = new Guid("52c9cf54-1eb2-44d2-81bb-524cf29c0a94"), + IsEnabled = true, + Name = "Perform Attendance " + }, + new + { + Id = new Guid("57802c4a-00aa-4a1f-a048-fd2f70dd44b6"), + Description = "", + FeatureId = new Guid("52c9cf54-1eb2-44d2-81bb-524cf29c0a94"), + IsEnabled = true, + Name = "Regularize Attendance" + }, + new + { + Id = new Guid("5ffbafe0-7ab0-48b1-bb50-c1bf76b65f9d"), + Description = "", + FeatureId = new Guid("be3b3afc-6ccf-4566-b9b6-aafcb65546be"), + IsEnabled = true, + Name = "View Masters" + }, + new + { + Id = new Guid("588a8824-f924-4955-82d8-fc51956cf323"), + Description = "", + FeatureId = new Guid("be3b3afc-6ccf-4566-b9b6-aafcb65546be"), + IsEnabled = true, + Name = "Manage Masters" + }, + new + { + Id = new Guid("cb8ec407-46d4-4467-930c-69127cda6dec"), + Description = "", + FeatureId = new Guid("660131a4-788c-4739-a082-cbbf7879cbf2"), + IsEnabled = true, + Name = "View Masters" + }, + new + { + Id = new Guid("6b1a6d97-a951-4de5-9b19-709bac7c4f18"), + Description = "", + FeatureId = new Guid("660131a4-788c-4739-a082-cbbf7879cbf2"), + IsEnabled = true, + Name = "Manage Masters" + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.JobRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("JobRoles"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.Module", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Key") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Modules"); + + b.HasData( + new + { + Id = 1, + Description = "Project Module", + Key = "b04da7e9-0406-409c-ac7f-b97256e6ea02", + Name = "Project" + }, + new + { + Id = 2, + Description = "Employee Module", + Key = "0971c7fb-6ce1-458a-ae3f-8d3205893637", + Name = "Employee" + }, + new + { + Id = 3, + Description = "Masters Module", + Key = "504ec132-e6a9-422f-8f85-050602cfce05", + Name = "Masters" + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.RolePermissionMappings", b => + { + b.Property("ApplicationRoleId") + .HasColumnType("char(36)"); + + b.Property("FeaturePermissionId") + .HasColumnType("char(36)"); + + b.HasKey("ApplicationRoleId", "FeaturePermissionId"); + + b.HasIndex("FeaturePermissionId"); + + b.ToTable("RolePermissionMappings"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.StatusMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Status") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("StatusMasters"); + + b.HasData( + new + { + Id = 1, + Status = "Active", + TenantId = 1 + }, + new + { + Id = 2, + Status = "In Progress", + TenantId = 1 + }, + new + { + Id = 3, + Status = "On Hold", + TenantId = 1 + }, + new + { + Id = 4, + Status = "Completed", + TenantId = 1 + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.Tenant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ContactName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ContactNumber") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("DomainName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("OnBoardingDate") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.ToTable("Tenants"); + + b.HasData( + new + { + Id = 1, + ContactName = "Admin", + ContactNumber = "123456789", + Description = "", + DomainName = "www.marcobms.org", + Name = "MarcoBMS", + OnBoardingDate = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified) + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.Building", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ProjectId") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("Buildings"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.Floor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("BuildingId") + .HasColumnType("int"); + + b.Property("FloorName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BuildingId"); + + b.HasIndex("TenantId"); + + b.ToTable("Floor"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.Project", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ContactPerson") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("EndDate") + .HasColumnType("datetime(6)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ProjectAddress") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ProjectStatusId") + .HasColumnType("int"); + + b.Property("StartDate") + .HasColumnType("datetime(6)"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ProjectStatusId"); + + b.HasIndex("TenantId"); + + b.ToTable("Projects"); + + b.HasData( + new + { + Id = 1, + ContactPerson = "Project 1 Contact Person", + Name = "Project 1", + ProjectAddress = "Project 1 Address", + ProjectStatusId = 1, + TenantId = 1 + }, + new + { + Id = 2, + ContactPerson = "Project 2 Contact Person", + Name = "Project 2", + ProjectAddress = "Project 2 Address", + ProjectStatusId = 2, + TenantId = 1 + }, + new + { + Id = 3, + ContactPerson = "Project 3 Contact Person", + Name = "Project 3", + ProjectAddress = "Project 3 Address", + ProjectStatusId = 3, + TenantId = 1 + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.ProjectAllocation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AllocationDate") + .HasColumnType("datetime(6)"); + + b.Property("EmployeeId") + .HasColumnType("int"); + + b.Property("EmployeeRoleId") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("ProjectId") + .HasColumnType("int"); + + b.Property("ReAllocationDate") + .HasColumnType("datetime(6)"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeId"); + + b.HasIndex("ProjectId"); + + b.HasIndex("TenantId"); + + b.ToTable("ProjectAllocations"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.WorkArea", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AreaName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FloorId") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("FloorId"); + + b.HasIndex("TenantId"); + + b.ToTable("WorkAreas"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("varchar(255)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("varchar(255)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("Discriminator") + .IsRequired() + .HasMaxLength(21) + .HasColumnType("varchar(21)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnd") + .HasColumnType("datetime(6)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("longtext"); + + b.Property("PhoneNumber") + .HasColumnType("longtext"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("SecurityStamp") + .HasColumnType("longtext"); + + b.Property("TwoFactorEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + + b.HasDiscriminator().HasValue("IdentityUser"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("ProviderKey") + .HasColumnType("varchar(255)"); + + b.Property("ProviderDisplayName") + .HasColumnType("longtext"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("RoleId") + .HasColumnType("varchar(255)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.ApplicationUser", b => + { + b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityUser"); + + b.Property("IsRootUser") + .HasColumnType("tinyint(1)"); + + b.Property("Role") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasDiscriminator().HasValue("ApplicationUser"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Activities.TaskAllocation", b => + { + b.HasOne("Marco.Pms.Model.Projects.Building", "Building") + .WithMany() + .HasForeignKey("BuildingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Projects.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Projects.WorkArea", "WorkArea") + .WithMany() + .HasForeignKey("WorkAreaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Building"); + + b.Navigation("Employee"); + + b.Navigation("Project"); + + b.Navigation("Tenant"); + + b.Navigation("WorkArea"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Activities.WorkItem", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.ActivityMaster", "ActivityMaster") + .WithMany() + .HasForeignKey("ActivityId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Projects.WorkArea", "WorkArea") + .WithMany() + .HasForeignKey("WorkAreaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ActivityMaster"); + + b.Navigation("Tenant"); + + b.Navigation("WorkArea"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Activities.WorkItemMapping", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Projects.WorkArea", "WorkArea") + .WithMany() + .HasForeignKey("WorkAreaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Activities.WorkItem", "WorkItem") + .WithMany() + .HasForeignKey("WorkItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + + b.Navigation("WorkArea"); + + b.Navigation("WorkItem"); + }); + + modelBuilder.Entity("Marco.Pms.Model.AttendanceModule.Attendance", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "Approver") + .WithMany() + .HasForeignKey("EmployeeID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Approver"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.AttendanceModule.AttendanceLog", b => + { + b.HasOne("Marco.Pms.Model.AttendanceModule.Attendance", "Attendance") + .WithMany() + .HasForeignKey("AttendanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "UpdatedByEmployee") + .WithMany() + .HasForeignKey("UpdatedBy"); + + b.Navigation("Attendance"); + + b.Navigation("Employee"); + + b.Navigation("Tenant"); + + b.Navigation("UpdatedByEmployee"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Authentication.RefreshToken", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Employees.Employee", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.ApplicationUser", "ApplicationUser") + .WithMany() + .HasForeignKey("ApplicationUserId"); + + b.HasOne("Marco.Pms.Model.Entitlements.JobRole", "JobRole") + .WithMany() + .HasForeignKey("JobRoleId"); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ApplicationUser"); + + b.Navigation("JobRole"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Employees.WorkShift", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.ActivityMaster", b => + { + b.HasOne("Marco.Pms.Model.Activities.TaskAllocation", null) + .WithMany("AllotedTask") + .HasForeignKey("TaskAllocationId"); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.ApplicationRole", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", null) + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.EmployeeRoleMapping", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.ApplicationRole", "Role") + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Employee"); + + b.Navigation("Role"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.Feature", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.Module", "Module") + .WithMany() + .HasForeignKey("ModuleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Module"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.FeaturePermission", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.Feature", "Feature") + .WithMany("FeaturePermissions") + .HasForeignKey("FeatureId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Feature"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.JobRole", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.RolePermissionMappings", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.ApplicationRole", null) + .WithMany() + .HasForeignKey("ApplicationRoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.FeaturePermission", null) + .WithMany() + .HasForeignKey("FeaturePermissionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.StatusMaster", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.Building", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.Floor", b => + { + b.HasOne("Marco.Pms.Model.Projects.Building", "Building") + .WithMany() + .HasForeignKey("BuildingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Building"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.Project", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.StatusMaster", "ProjectStatus") + .WithMany() + .HasForeignKey("ProjectStatusId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ProjectStatus"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.ProjectAllocation", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Projects.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Employee"); + + b.Navigation("Project"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.WorkArea", b => + { + b.HasOne("Marco.Pms.Model.Projects.Floor", "Floor") + .WithMany() + .HasForeignKey("FloorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Floor"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Marco.Pms.Model.Activities.TaskAllocation", b => + { + b.Navigation("AllotedTask"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.Feature", b => + { + b.Navigation("FeaturePermissions"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Marco.Pms.DataAccess/Migrations/20250315082651_addEmergencyContactPersonInEmployeeModel.cs b/Marco.Pms.DataAccess/Migrations/20250315082651_addEmergencyContactPersonInEmployeeModel.cs new file mode 100644 index 0000000..ca20fe3 --- /dev/null +++ b/Marco.Pms.DataAccess/Migrations/20250315082651_addEmergencyContactPersonInEmployeeModel.cs @@ -0,0 +1,40 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Marco.Pms.DataAccess.Migrations +{ + /// + public partial class addEmergencyContactPersonInEmployeeModel : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "EmergencyContactPerson", + table: "Employees", + type: "longtext", + nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AddColumn( + name: "IsActive", + table: "Employees", + type: "tinyint(1)", + nullable: false, + defaultValue: false); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "EmergencyContactPerson", + table: "Employees"); + + migrationBuilder.DropColumn( + name: "IsActive", + table: "Employees"); + } + } +} diff --git a/Marco.Pms.DataAccess/Migrations/20250318053416_addJobRoleIdInProjectAllocation.Designer.cs b/Marco.Pms.DataAccess/Migrations/20250318053416_addJobRoleIdInProjectAllocation.Designer.cs new file mode 100644 index 0000000..dfc1d17 --- /dev/null +++ b/Marco.Pms.DataAccess/Migrations/20250318053416_addJobRoleIdInProjectAllocation.Designer.cs @@ -0,0 +1,1943 @@ +// +using System; +using Marco.Pms.DataAccess.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Marco.Pms.DataAccess.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20250318053416_addJobRoleIdInProjectAllocation")] + partial class addJobRoleIdInProjectAllocation + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.12") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + //MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); + + modelBuilder.Entity("Marco.Pms.Model.Activities.TaskAllocation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AllocationDate") + .HasColumnType("datetime(6)"); + + b.Property("BuildingId") + .HasColumnType("int"); + + b.Property("EmployeeId") + .HasColumnType("int"); + + b.Property("EmployeeRole") + .HasColumnType("int"); + + b.Property("ProjectId") + .HasColumnType("int"); + + b.Property("ReAllocationDate") + .HasColumnType("datetime(6)"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.Property("WorkAreaId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BuildingId"); + + b.HasIndex("EmployeeId"); + + b.HasIndex("ProjectId"); + + b.HasIndex("TenantId"); + + b.HasIndex("WorkAreaId"); + + b.ToTable("TaskAllocations"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Activities.WorkItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ActivityId") + .HasColumnType("int"); + + b.Property("CompletedWork") + .HasColumnType("int"); + + b.Property("PlannedWork") + .HasColumnType("int"); + + b.Property("TaskDate") + .HasColumnType("datetime(6)"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.Property("WorkAreaId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ActivityId"); + + b.HasIndex("TenantId"); + + b.HasIndex("WorkAreaId"); + + b.ToTable("WorkItems"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Activities.WorkItemMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("TenantId") + .HasColumnType("int"); + + b.Property("WorkAreaId") + .HasColumnType("int"); + + b.Property("WorkItemId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.HasIndex("WorkAreaId"); + + b.HasIndex("WorkItemId"); + + b.ToTable("WorkItemMapping"); + }); + + modelBuilder.Entity("Marco.Pms.Model.AttendanceModule.Attendance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Activity") + .HasColumnType("int"); + + b.Property("ApprovedBy") + .HasColumnType("int"); + + b.Property("AttendanceDate") + .HasColumnType("datetime(6)"); + + b.Property("Comment") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Date") + .HasColumnType("datetime(6)"); + + b.Property("EmployeeID") + .HasColumnType("int"); + + b.Property("InTime") + .HasColumnType("datetime(6)"); + + b.Property("IsApproved") + .HasColumnType("tinyint(1)"); + + b.Property("OutTime") + .HasColumnType("datetime(6)"); + + b.Property("ProjectID") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeID"); + + b.HasIndex("TenantId"); + + b.ToTable("Attendes"); + }); + + modelBuilder.Entity("Marco.Pms.Model.AttendanceModule.AttendanceLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Activity") + .HasColumnType("int"); + + b.Property("ActivityTime") + .HasColumnType("datetime(6)"); + + b.Property("AttendanceId") + .HasColumnType("int"); + + b.Property("Comment") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("EmployeeID") + .HasColumnType("int"); + + b.Property("Latitude") + .HasColumnType("longtext"); + + b.Property("Longitude") + .HasColumnType("longtext"); + + b.Property("Photo") + .HasColumnType("longblob"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("UpdatedOn") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.HasIndex("AttendanceId"); + + b.HasIndex("EmployeeID"); + + b.HasIndex("TenantId"); + + b.HasIndex("UpdatedBy"); + + b.ToTable("AttendanceLogs"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Authentication.RefreshToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("ExpiryDate") + .HasColumnType("datetime(6)"); + + b.Property("IsRevoked") + .HasColumnType("tinyint(1)"); + + b.Property("IsUsed") + .HasColumnType("tinyint(1)"); + + b.Property("RevokedAt") + .HasColumnType("datetime(6)"); + + b.Property("Token") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RefreshTokens"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Employees.Employee", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AadharNumber") + .HasColumnType("longtext"); + + b.Property("ApplicationUserId") + .HasColumnType("varchar(255)"); + + b.Property("BirthDate") + .HasColumnType("datetime(6)"); + + b.Property("CurrentAddress") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Email") + .HasColumnType("longtext"); + + b.Property("EmergencyContactPerson") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("EmergencyPhoneNumber") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Gender") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("JobRoleId") + .HasColumnType("int"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("MiddleName") + .HasColumnType("longtext"); + + b.Property("PanNumber") + .HasColumnType("longtext"); + + b.Property("PeramnentAddress") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("PhoneNumber") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Photo") + .HasColumnType("longblob"); + + b.Property("RoleId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationUserId"); + + b.HasIndex("JobRoleId"); + + b.HasIndex("TenantId"); + + b.ToTable("Employees"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Employees.WorkShift", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("EndTime") + .HasColumnType("time(6)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("StartTime") + .HasColumnType("time(6)"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("WorkShifts"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.ActivityMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ActivityName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TaskAllocationId") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.Property("UnitOfMeasurement") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("TaskAllocationId"); + + b.HasIndex("TenantId"); + + b.ToTable("ActivityMasters"); + + b.HasData( + new + { + Id = 1, + ActivityName = "Core Cutting", + TenantId = 1, + UnitOfMeasurement = "Number" + }, + new + { + Id = 2, + ActivityName = "Fabrication", + TenantId = 1, + UnitOfMeasurement = "Meter" + }, + new + { + Id = 3, + ActivityName = "Lifting", + TenantId = 1, + UnitOfMeasurement = "Meter" + }, + new + { + Id = 4, + ActivityName = "Hanging", + TenantId = 1, + UnitOfMeasurement = "Meter" + }, + new + { + Id = 5, + ActivityName = "Tapping", + TenantId = 1, + UnitOfMeasurement = "Meter" + }, + new + { + Id = 6, + ActivityName = "Welding", + TenantId = 1, + UnitOfMeasurement = "Meter" + }, + new + { + Id = 7, + ActivityName = "Testing", + TenantId = 1, + UnitOfMeasurement = "Area" + }, + new + { + Id = 8, + ActivityName = "Painting", + TenantId = 1, + UnitOfMeasurement = "Meter" + }, + new + { + Id = 9, + ActivityName = "Marking Area", + TenantId = 1, + UnitOfMeasurement = "Meter" + }, + new + { + Id = 10, + ActivityName = "Drilling", + TenantId = 1, + UnitOfMeasurement = "Number" + }, + new + { + Id = 11, + ActivityName = "MS Support Fabrication", + TenantId = 1, + UnitOfMeasurement = "Number" + }, + new + { + Id = 12, + ActivityName = "MS Support Hanging", + TenantId = 1, + UnitOfMeasurement = "Number" + }, + new + { + Id = 13, + ActivityName = "Hydrant Volve", + TenantId = 1, + UnitOfMeasurement = "Number" + }, + new + { + Id = 14, + ActivityName = "Sprinkler Installation", + TenantId = 1, + UnitOfMeasurement = "Number" + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.ApplicationRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Role") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("ApplicationRoles"); + + b.HasData( + new + { + Id = new Guid("2c8d0808-c421-11ef-9b93-0242ac110002"), + Description = "", + Role = "Admin", + TenantId = 1 + }, + new + { + Id = new Guid("62e0918d-c421-11ef-9b93-0242ac110002"), + Description = "", + Role = "Welder", + TenantId = 1 + }, + new + { + Id = new Guid("68823f1f-c421-11ef-9b93-0242ac110002"), + Description = "", + Role = "Helper", + TenantId = 1 + }, + new + { + Id = new Guid("6d3a7c72-c421-11ef-9b93-0242ac110002"), + Description = "", + Role = "Site Engineer", + TenantId = 1 + }, + new + { + Id = new Guid("6d3aad72-c421-11ef-9b93-0242ac110002"), + Description = "", + Role = "Project Manager", + TenantId = 1 + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.EmployeeRoleMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("EmployeeId") + .HasColumnType("int"); + + b.Property("IsEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("RoleId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeId"); + + b.HasIndex("RoleId"); + + b.HasIndex("TenantId"); + + b.ToTable("EmployeeRoleMappings"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.Feature", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("ModuleId") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ModuleId"); + + b.ToTable("Features"); + + b.HasData( + new + { + Id = new Guid("53176ebf-c75d-42e5-839f-4508ffac3def"), + Description = "Manage Project", + IsActive = true, + ModuleId = 1, + Name = "Manage Project" + }, + new + { + Id = new Guid("9666de86-d7c7-4d3d-acaa-fcd6d6b81f3c"), + Description = "Manage Infra", + IsActive = true, + ModuleId = 1, + Name = "Manage Infra" + }, + new + { + Id = new Guid("9d4b5489-2079-40b9-bd77-6e1bf90bc19f"), + Description = "Manage Tasks", + IsActive = true, + ModuleId = 1, + Name = "Manage Tasks" + }, + new + { + Id = new Guid("39e66f81-efc6-446c-95bd-46bff6cfb606"), + Description = "Assign and Update Tasks Progress", + IsActive = true, + ModuleId = 1, + Name = "Assign and Update Tasks Progress" + }, + new + { + Id = new Guid("81ab8a87-8ccd-4015-a917-0627cee6a100"), + Description = "Manage Employee", + IsActive = true, + ModuleId = 2, + Name = "Manage Employee" + }, + new + { + Id = new Guid("52c9cf54-1eb2-44d2-81bb-524cf29c0a94"), + Description = "Attendance", + IsActive = true, + ModuleId = 2, + Name = "Attendance" + }, + new + { + Id = new Guid("be3b3afc-6ccf-4566-b9b6-aafcb65546be"), + Description = "Global Masters", + IsActive = true, + ModuleId = 3, + Name = "Global Masters" + }, + new + { + Id = new Guid("660131a4-788c-4739-a082-cbbf7879cbf2"), + Description = "Tenant Masters", + IsActive = true, + ModuleId = 3, + Name = "Tenant Masters" + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.FeaturePermission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FeatureId") + .HasColumnType("char(36)"); + + b.Property("IsEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("FeatureId"); + + b.ToTable("FeaturePermissions"); + + b.HasData( + new + { + Id = new Guid("6ea44136-987e-44ba-9e5d-1cf8f5837ebc"), + Description = "", + FeatureId = new Guid("53176ebf-c75d-42e5-839f-4508ffac3def"), + IsEnabled = true, + Name = "View Project" + }, + new + { + Id = new Guid("172fc9b6-755b-4f62-ab26-55c34a330614"), + Description = "", + FeatureId = new Guid("53176ebf-c75d-42e5-839f-4508ffac3def"), + IsEnabled = true, + Name = "Manage Project" + }, + new + { + Id = new Guid("b94802ce-0689-4643-9e1d-11c86950c35b"), + Description = "", + FeatureId = new Guid("53176ebf-c75d-42e5-839f-4508ffac3def"), + IsEnabled = true, + Name = "Manage Team" + }, + new + { + Id = new Guid("c7b68e33-72f0-474f-bd96-77636427ecc8"), + Description = "", + FeatureId = new Guid("9666de86-d7c7-4d3d-acaa-fcd6d6b81f3c"), + IsEnabled = true, + Name = "View Project Infra" + }, + new + { + Id = new Guid("f2aee20a-b754-4537-8166-f9507b44585b"), + Description = "", + FeatureId = new Guid("9666de86-d7c7-4d3d-acaa-fcd6d6b81f3c"), + IsEnabled = true, + Name = "Manage Project Infra" + }, + new + { + Id = new Guid("9fcc5f87-25e3-4846-90ac-67a71ab92e3c"), + Description = "", + FeatureId = new Guid("9d4b5489-2079-40b9-bd77-6e1bf90bc19f"), + IsEnabled = true, + Name = "View Task" + }, + new + { + Id = new Guid("08752f33-3b29-4816-b76b-ea8a968ed3c5"), + Description = "", + FeatureId = new Guid("9d4b5489-2079-40b9-bd77-6e1bf90bc19f"), + IsEnabled = true, + Name = "Manage Task" + }, + new + { + Id = new Guid("d135a4b0-4f9a-4903-ab9c-4843839ebdee"), + Description = "", + FeatureId = new Guid("39e66f81-efc6-446c-95bd-46bff6cfb606"), + IsEnabled = true, + Name = "Assign Task and Report Progress" + }, + new + { + Id = new Guid("ed99ecd4-1bed-42e1-b7b3-d64c04493823"), + Description = "", + FeatureId = new Guid("39e66f81-efc6-446c-95bd-46bff6cfb606"), + IsEnabled = true, + Name = "Approve Task" + }, + new + { + Id = new Guid("b82d2b7e-0d52-45f3-997b-c008ea460e7f"), + Description = "", + FeatureId = new Guid("81ab8a87-8ccd-4015-a917-0627cee6a100"), + IsEnabled = true, + Name = "View Employee" + }, + new + { + Id = new Guid("a97d366a-c2bb-448d-be93-402bd2324566"), + Description = "", + FeatureId = new Guid("81ab8a87-8ccd-4015-a917-0627cee6a100"), + IsEnabled = true, + Name = "Manage Employee" + }, + new + { + Id = new Guid("fbd213e0-0250-46f1-9f5f-4b2a1e6e76a3"), + Description = "", + FeatureId = new Guid("81ab8a87-8ccd-4015-a917-0627cee6a100"), + IsEnabled = true, + Name = "Assign To Project" + }, + new + { + Id = new Guid("915e6bff-65f6-4e3f-aea8-3fd217d3ea9e"), + Description = "", + FeatureId = new Guid("52c9cf54-1eb2-44d2-81bb-524cf29c0a94"), + IsEnabled = true, + Name = "Perform Attendance " + }, + new + { + Id = new Guid("57802c4a-00aa-4a1f-a048-fd2f70dd44b6"), + Description = "", + FeatureId = new Guid("52c9cf54-1eb2-44d2-81bb-524cf29c0a94"), + IsEnabled = true, + Name = "Regularize Attendance" + }, + new + { + Id = new Guid("5ffbafe0-7ab0-48b1-bb50-c1bf76b65f9d"), + Description = "", + FeatureId = new Guid("be3b3afc-6ccf-4566-b9b6-aafcb65546be"), + IsEnabled = true, + Name = "View Masters" + }, + new + { + Id = new Guid("588a8824-f924-4955-82d8-fc51956cf323"), + Description = "", + FeatureId = new Guid("be3b3afc-6ccf-4566-b9b6-aafcb65546be"), + IsEnabled = true, + Name = "Manage Masters" + }, + new + { + Id = new Guid("cb8ec407-46d4-4467-930c-69127cda6dec"), + Description = "", + FeatureId = new Guid("660131a4-788c-4739-a082-cbbf7879cbf2"), + IsEnabled = true, + Name = "View Masters" + }, + new + { + Id = new Guid("6b1a6d97-a951-4de5-9b19-709bac7c4f18"), + Description = "", + FeatureId = new Guid("660131a4-788c-4739-a082-cbbf7879cbf2"), + IsEnabled = true, + Name = "Manage Masters" + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.JobRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("JobRoles"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.Module", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Key") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Modules"); + + b.HasData( + new + { + Id = 1, + Description = "Project Module", + Key = "b04da7e9-0406-409c-ac7f-b97256e6ea02", + Name = "Project" + }, + new + { + Id = 2, + Description = "Employee Module", + Key = "0971c7fb-6ce1-458a-ae3f-8d3205893637", + Name = "Employee" + }, + new + { + Id = 3, + Description = "Masters Module", + Key = "504ec132-e6a9-422f-8f85-050602cfce05", + Name = "Masters" + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.RolePermissionMappings", b => + { + b.Property("ApplicationRoleId") + .HasColumnType("char(36)"); + + b.Property("FeaturePermissionId") + .HasColumnType("char(36)"); + + b.HasKey("ApplicationRoleId", "FeaturePermissionId"); + + b.HasIndex("FeaturePermissionId"); + + b.ToTable("RolePermissionMappings"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.StatusMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Status") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("StatusMasters"); + + b.HasData( + new + { + Id = 1, + Status = "Active", + TenantId = 1 + }, + new + { + Id = 2, + Status = "In Progress", + TenantId = 1 + }, + new + { + Id = 3, + Status = "On Hold", + TenantId = 1 + }, + new + { + Id = 4, + Status = "Completed", + TenantId = 1 + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.Tenant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ContactName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ContactNumber") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("DomainName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("OnBoardingDate") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.ToTable("Tenants"); + + b.HasData( + new + { + Id = 1, + ContactName = "Admin", + ContactNumber = "123456789", + Description = "", + DomainName = "www.marcobms.org", + Name = "MarcoBMS", + OnBoardingDate = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified) + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.Building", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ProjectId") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("Buildings"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.Floor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("BuildingId") + .HasColumnType("int"); + + b.Property("FloorName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BuildingId"); + + b.HasIndex("TenantId"); + + b.ToTable("Floor"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.Project", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ContactPerson") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("EndDate") + .HasColumnType("datetime(6)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ProjectAddress") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ProjectStatusId") + .HasColumnType("int"); + + b.Property("StartDate") + .HasColumnType("datetime(6)"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ProjectStatusId"); + + b.HasIndex("TenantId"); + + b.ToTable("Projects"); + + b.HasData( + new + { + Id = 1, + ContactPerson = "Project 1 Contact Person", + Name = "Project 1", + ProjectAddress = "Project 1 Address", + ProjectStatusId = 1, + TenantId = 1 + }, + new + { + Id = 2, + ContactPerson = "Project 2 Contact Person", + Name = "Project 2", + ProjectAddress = "Project 2 Address", + ProjectStatusId = 2, + TenantId = 1 + }, + new + { + Id = 3, + ContactPerson = "Project 3 Contact Person", + Name = "Project 3", + ProjectAddress = "Project 3 Address", + ProjectStatusId = 3, + TenantId = 1 + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.ProjectAllocation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AllocationDate") + .HasColumnType("datetime(6)"); + + b.Property("EmployeeId") + .HasColumnType("int"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("JobRoleId") + .HasColumnType("int"); + + b.Property("ProjectId") + .HasColumnType("int"); + + b.Property("ReAllocationDate") + .HasColumnType("datetime(6)"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeId"); + + b.HasIndex("ProjectId"); + + b.HasIndex("TenantId"); + + b.ToTable("ProjectAllocations"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.WorkArea", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AreaName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FloorId") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("FloorId"); + + b.HasIndex("TenantId"); + + b.ToTable("WorkAreas"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("varchar(255)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("varchar(255)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("Discriminator") + .IsRequired() + .HasMaxLength(21) + .HasColumnType("varchar(21)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnd") + .HasColumnType("datetime(6)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("longtext"); + + b.Property("PhoneNumber") + .HasColumnType("longtext"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("SecurityStamp") + .HasColumnType("longtext"); + + b.Property("TwoFactorEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + + b.HasDiscriminator().HasValue("IdentityUser"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("ProviderKey") + .HasColumnType("varchar(255)"); + + b.Property("ProviderDisplayName") + .HasColumnType("longtext"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("RoleId") + .HasColumnType("varchar(255)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.ApplicationUser", b => + { + b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityUser"); + + b.Property("IsRootUser") + .HasColumnType("tinyint(1)"); + + b.Property("Role") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasDiscriminator().HasValue("ApplicationUser"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Activities.TaskAllocation", b => + { + b.HasOne("Marco.Pms.Model.Projects.Building", "Building") + .WithMany() + .HasForeignKey("BuildingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Projects.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Projects.WorkArea", "WorkArea") + .WithMany() + .HasForeignKey("WorkAreaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Building"); + + b.Navigation("Employee"); + + b.Navigation("Project"); + + b.Navigation("Tenant"); + + b.Navigation("WorkArea"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Activities.WorkItem", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.ActivityMaster", "ActivityMaster") + .WithMany() + .HasForeignKey("ActivityId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Projects.WorkArea", "WorkArea") + .WithMany() + .HasForeignKey("WorkAreaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ActivityMaster"); + + b.Navigation("Tenant"); + + b.Navigation("WorkArea"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Activities.WorkItemMapping", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Projects.WorkArea", "WorkArea") + .WithMany() + .HasForeignKey("WorkAreaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Activities.WorkItem", "WorkItem") + .WithMany() + .HasForeignKey("WorkItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + + b.Navigation("WorkArea"); + + b.Navigation("WorkItem"); + }); + + modelBuilder.Entity("Marco.Pms.Model.AttendanceModule.Attendance", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "Approver") + .WithMany() + .HasForeignKey("EmployeeID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Approver"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.AttendanceModule.AttendanceLog", b => + { + b.HasOne("Marco.Pms.Model.AttendanceModule.Attendance", "Attendance") + .WithMany() + .HasForeignKey("AttendanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "UpdatedByEmployee") + .WithMany() + .HasForeignKey("UpdatedBy"); + + b.Navigation("Attendance"); + + b.Navigation("Employee"); + + b.Navigation("Tenant"); + + b.Navigation("UpdatedByEmployee"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Authentication.RefreshToken", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Employees.Employee", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.ApplicationUser", "ApplicationUser") + .WithMany() + .HasForeignKey("ApplicationUserId"); + + b.HasOne("Marco.Pms.Model.Entitlements.JobRole", "JobRole") + .WithMany() + .HasForeignKey("JobRoleId"); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ApplicationUser"); + + b.Navigation("JobRole"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Employees.WorkShift", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.ActivityMaster", b => + { + b.HasOne("Marco.Pms.Model.Activities.TaskAllocation", null) + .WithMany("AllotedTask") + .HasForeignKey("TaskAllocationId"); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.ApplicationRole", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", null) + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.EmployeeRoleMapping", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.ApplicationRole", "Role") + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Employee"); + + b.Navigation("Role"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.Feature", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.Module", "Module") + .WithMany() + .HasForeignKey("ModuleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Module"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.FeaturePermission", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.Feature", "Feature") + .WithMany("FeaturePermissions") + .HasForeignKey("FeatureId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Feature"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.JobRole", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.RolePermissionMappings", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.ApplicationRole", null) + .WithMany() + .HasForeignKey("ApplicationRoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.FeaturePermission", null) + .WithMany() + .HasForeignKey("FeaturePermissionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.StatusMaster", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.Building", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.Floor", b => + { + b.HasOne("Marco.Pms.Model.Projects.Building", "Building") + .WithMany() + .HasForeignKey("BuildingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Building"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.Project", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.StatusMaster", "ProjectStatus") + .WithMany() + .HasForeignKey("ProjectStatusId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ProjectStatus"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.ProjectAllocation", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Projects.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Employee"); + + b.Navigation("Project"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.WorkArea", b => + { + b.HasOne("Marco.Pms.Model.Projects.Floor", "Floor") + .WithMany() + .HasForeignKey("FloorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Floor"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Marco.Pms.Model.Activities.TaskAllocation", b => + { + b.Navigation("AllotedTask"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.Feature", b => + { + b.Navigation("FeaturePermissions"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Marco.Pms.DataAccess/Migrations/20250318053416_addJobRoleIdInProjectAllocation.cs b/Marco.Pms.DataAccess/Migrations/20250318053416_addJobRoleIdInProjectAllocation.cs new file mode 100644 index 0000000..60ecfbf --- /dev/null +++ b/Marco.Pms.DataAccess/Migrations/20250318053416_addJobRoleIdInProjectAllocation.cs @@ -0,0 +1,40 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Marco.Pms.DataAccess.Migrations +{ + /// + public partial class addJobRoleIdInProjectAllocation : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "EmployeeRoleId", + table: "ProjectAllocations"); + + migrationBuilder.AddColumn( + name: "JobRoleId", + table: "ProjectAllocations", + type: "int", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "JobRoleId", + table: "ProjectAllocations"); + + migrationBuilder.AddColumn( + name: "EmployeeRoleId", + table: "ProjectAllocations", + type: "char(36)", + nullable: true, + collation: "ascii_general_ci"); + } + } +} diff --git a/Marco.Pms.DataAccess/Migrations/20250321010050_addJoiningDateToEmployee.Designer.cs b/Marco.Pms.DataAccess/Migrations/20250321010050_addJoiningDateToEmployee.Designer.cs new file mode 100644 index 0000000..f8f45ac --- /dev/null +++ b/Marco.Pms.DataAccess/Migrations/20250321010050_addJoiningDateToEmployee.Designer.cs @@ -0,0 +1,1946 @@ +// +using System; +using Marco.Pms.DataAccess.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Marco.Pms.DataAccess.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20250321010050_addJoiningDateToEmployee")] + partial class addJoiningDateToEmployee + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.12") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + //MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); + + modelBuilder.Entity("Marco.Pms.Model.Activities.TaskAllocation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AllocationDate") + .HasColumnType("datetime(6)"); + + b.Property("BuildingId") + .HasColumnType("int"); + + b.Property("EmployeeId") + .HasColumnType("int"); + + b.Property("EmployeeRole") + .HasColumnType("int"); + + b.Property("ProjectId") + .HasColumnType("int"); + + b.Property("ReAllocationDate") + .HasColumnType("datetime(6)"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.Property("WorkAreaId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BuildingId"); + + b.HasIndex("EmployeeId"); + + b.HasIndex("ProjectId"); + + b.HasIndex("TenantId"); + + b.HasIndex("WorkAreaId"); + + b.ToTable("TaskAllocations"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Activities.WorkItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ActivityId") + .HasColumnType("int"); + + b.Property("CompletedWork") + .HasColumnType("int"); + + b.Property("PlannedWork") + .HasColumnType("int"); + + b.Property("TaskDate") + .HasColumnType("datetime(6)"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.Property("WorkAreaId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ActivityId"); + + b.HasIndex("TenantId"); + + b.HasIndex("WorkAreaId"); + + b.ToTable("WorkItems"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Activities.WorkItemMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("TenantId") + .HasColumnType("int"); + + b.Property("WorkAreaId") + .HasColumnType("int"); + + b.Property("WorkItemId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.HasIndex("WorkAreaId"); + + b.HasIndex("WorkItemId"); + + b.ToTable("WorkItemMapping"); + }); + + modelBuilder.Entity("Marco.Pms.Model.AttendanceModule.Attendance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Activity") + .HasColumnType("int"); + + b.Property("ApprovedBy") + .HasColumnType("int"); + + b.Property("AttendanceDate") + .HasColumnType("datetime(6)"); + + b.Property("Comment") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Date") + .HasColumnType("datetime(6)"); + + b.Property("EmployeeID") + .HasColumnType("int"); + + b.Property("InTime") + .HasColumnType("datetime(6)"); + + b.Property("IsApproved") + .HasColumnType("tinyint(1)"); + + b.Property("OutTime") + .HasColumnType("datetime(6)"); + + b.Property("ProjectID") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeID"); + + b.HasIndex("TenantId"); + + b.ToTable("Attendes"); + }); + + modelBuilder.Entity("Marco.Pms.Model.AttendanceModule.AttendanceLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Activity") + .HasColumnType("int"); + + b.Property("ActivityTime") + .HasColumnType("datetime(6)"); + + b.Property("AttendanceId") + .HasColumnType("int"); + + b.Property("Comment") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("EmployeeID") + .HasColumnType("int"); + + b.Property("Latitude") + .HasColumnType("longtext"); + + b.Property("Longitude") + .HasColumnType("longtext"); + + b.Property("Photo") + .HasColumnType("longblob"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("UpdatedOn") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.HasIndex("AttendanceId"); + + b.HasIndex("EmployeeID"); + + b.HasIndex("TenantId"); + + b.HasIndex("UpdatedBy"); + + b.ToTable("AttendanceLogs"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Authentication.RefreshToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("ExpiryDate") + .HasColumnType("datetime(6)"); + + b.Property("IsRevoked") + .HasColumnType("tinyint(1)"); + + b.Property("IsUsed") + .HasColumnType("tinyint(1)"); + + b.Property("RevokedAt") + .HasColumnType("datetime(6)"); + + b.Property("Token") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RefreshTokens"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Employees.Employee", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AadharNumber") + .HasColumnType("longtext"); + + b.Property("ApplicationUserId") + .HasColumnType("varchar(255)"); + + b.Property("BirthDate") + .HasColumnType("datetime(6)"); + + b.Property("CurrentAddress") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Email") + .HasColumnType("longtext"); + + b.Property("EmergencyContactPerson") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("EmergencyPhoneNumber") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Gender") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("JobRoleId") + .HasColumnType("int"); + + b.Property("JoiningDate") + .HasColumnType("datetime(6)"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("MiddleName") + .HasColumnType("longtext"); + + b.Property("PanNumber") + .HasColumnType("longtext"); + + b.Property("PeramnentAddress") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("PhoneNumber") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Photo") + .HasColumnType("longblob"); + + b.Property("RoleId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationUserId"); + + b.HasIndex("JobRoleId"); + + b.HasIndex("TenantId"); + + b.ToTable("Employees"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Employees.WorkShift", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("EndTime") + .HasColumnType("time(6)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("StartTime") + .HasColumnType("time(6)"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("WorkShifts"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.ActivityMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ActivityName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TaskAllocationId") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.Property("UnitOfMeasurement") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("TaskAllocationId"); + + b.HasIndex("TenantId"); + + b.ToTable("ActivityMasters"); + + b.HasData( + new + { + Id = 1, + ActivityName = "Core Cutting", + TenantId = 1, + UnitOfMeasurement = "Number" + }, + new + { + Id = 2, + ActivityName = "Fabrication", + TenantId = 1, + UnitOfMeasurement = "Meter" + }, + new + { + Id = 3, + ActivityName = "Lifting", + TenantId = 1, + UnitOfMeasurement = "Meter" + }, + new + { + Id = 4, + ActivityName = "Hanging", + TenantId = 1, + UnitOfMeasurement = "Meter" + }, + new + { + Id = 5, + ActivityName = "Tapping", + TenantId = 1, + UnitOfMeasurement = "Meter" + }, + new + { + Id = 6, + ActivityName = "Welding", + TenantId = 1, + UnitOfMeasurement = "Meter" + }, + new + { + Id = 7, + ActivityName = "Testing", + TenantId = 1, + UnitOfMeasurement = "Area" + }, + new + { + Id = 8, + ActivityName = "Painting", + TenantId = 1, + UnitOfMeasurement = "Meter" + }, + new + { + Id = 9, + ActivityName = "Marking Area", + TenantId = 1, + UnitOfMeasurement = "Meter" + }, + new + { + Id = 10, + ActivityName = "Drilling", + TenantId = 1, + UnitOfMeasurement = "Number" + }, + new + { + Id = 11, + ActivityName = "MS Support Fabrication", + TenantId = 1, + UnitOfMeasurement = "Number" + }, + new + { + Id = 12, + ActivityName = "MS Support Hanging", + TenantId = 1, + UnitOfMeasurement = "Number" + }, + new + { + Id = 13, + ActivityName = "Hydrant Volve", + TenantId = 1, + UnitOfMeasurement = "Number" + }, + new + { + Id = 14, + ActivityName = "Sprinkler Installation", + TenantId = 1, + UnitOfMeasurement = "Number" + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.ApplicationRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Role") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("ApplicationRoles"); + + b.HasData( + new + { + Id = new Guid("2c8d0808-c421-11ef-9b93-0242ac110002"), + Description = "", + Role = "Admin", + TenantId = 1 + }, + new + { + Id = new Guid("62e0918d-c421-11ef-9b93-0242ac110002"), + Description = "", + Role = "Welder", + TenantId = 1 + }, + new + { + Id = new Guid("68823f1f-c421-11ef-9b93-0242ac110002"), + Description = "", + Role = "Helper", + TenantId = 1 + }, + new + { + Id = new Guid("6d3a7c72-c421-11ef-9b93-0242ac110002"), + Description = "", + Role = "Site Engineer", + TenantId = 1 + }, + new + { + Id = new Guid("6d3aad72-c421-11ef-9b93-0242ac110002"), + Description = "", + Role = "Project Manager", + TenantId = 1 + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.EmployeeRoleMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("EmployeeId") + .HasColumnType("int"); + + b.Property("IsEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("RoleId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeId"); + + b.HasIndex("RoleId"); + + b.HasIndex("TenantId"); + + b.ToTable("EmployeeRoleMappings"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.Feature", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("ModuleId") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ModuleId"); + + b.ToTable("Features"); + + b.HasData( + new + { + Id = new Guid("53176ebf-c75d-42e5-839f-4508ffac3def"), + Description = "Manage Project", + IsActive = true, + ModuleId = 1, + Name = "Manage Project" + }, + new + { + Id = new Guid("9666de86-d7c7-4d3d-acaa-fcd6d6b81f3c"), + Description = "Manage Infra", + IsActive = true, + ModuleId = 1, + Name = "Manage Infra" + }, + new + { + Id = new Guid("9d4b5489-2079-40b9-bd77-6e1bf90bc19f"), + Description = "Manage Tasks", + IsActive = true, + ModuleId = 1, + Name = "Manage Tasks" + }, + new + { + Id = new Guid("39e66f81-efc6-446c-95bd-46bff6cfb606"), + Description = "Assign and Update Tasks Progress", + IsActive = true, + ModuleId = 1, + Name = "Assign and Update Tasks Progress" + }, + new + { + Id = new Guid("81ab8a87-8ccd-4015-a917-0627cee6a100"), + Description = "Manage Employee", + IsActive = true, + ModuleId = 2, + Name = "Manage Employee" + }, + new + { + Id = new Guid("52c9cf54-1eb2-44d2-81bb-524cf29c0a94"), + Description = "Attendance", + IsActive = true, + ModuleId = 2, + Name = "Attendance" + }, + new + { + Id = new Guid("be3b3afc-6ccf-4566-b9b6-aafcb65546be"), + Description = "Global Masters", + IsActive = true, + ModuleId = 3, + Name = "Global Masters" + }, + new + { + Id = new Guid("660131a4-788c-4739-a082-cbbf7879cbf2"), + Description = "Tenant Masters", + IsActive = true, + ModuleId = 3, + Name = "Tenant Masters" + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.FeaturePermission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FeatureId") + .HasColumnType("char(36)"); + + b.Property("IsEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("FeatureId"); + + b.ToTable("FeaturePermissions"); + + b.HasData( + new + { + Id = new Guid("6ea44136-987e-44ba-9e5d-1cf8f5837ebc"), + Description = "", + FeatureId = new Guid("53176ebf-c75d-42e5-839f-4508ffac3def"), + IsEnabled = true, + Name = "View Project" + }, + new + { + Id = new Guid("172fc9b6-755b-4f62-ab26-55c34a330614"), + Description = "", + FeatureId = new Guid("53176ebf-c75d-42e5-839f-4508ffac3def"), + IsEnabled = true, + Name = "Manage Project" + }, + new + { + Id = new Guid("b94802ce-0689-4643-9e1d-11c86950c35b"), + Description = "", + FeatureId = new Guid("53176ebf-c75d-42e5-839f-4508ffac3def"), + IsEnabled = true, + Name = "Manage Team" + }, + new + { + Id = new Guid("c7b68e33-72f0-474f-bd96-77636427ecc8"), + Description = "", + FeatureId = new Guid("9666de86-d7c7-4d3d-acaa-fcd6d6b81f3c"), + IsEnabled = true, + Name = "View Project Infra" + }, + new + { + Id = new Guid("f2aee20a-b754-4537-8166-f9507b44585b"), + Description = "", + FeatureId = new Guid("9666de86-d7c7-4d3d-acaa-fcd6d6b81f3c"), + IsEnabled = true, + Name = "Manage Project Infra" + }, + new + { + Id = new Guid("9fcc5f87-25e3-4846-90ac-67a71ab92e3c"), + Description = "", + FeatureId = new Guid("9d4b5489-2079-40b9-bd77-6e1bf90bc19f"), + IsEnabled = true, + Name = "View Task" + }, + new + { + Id = new Guid("08752f33-3b29-4816-b76b-ea8a968ed3c5"), + Description = "", + FeatureId = new Guid("9d4b5489-2079-40b9-bd77-6e1bf90bc19f"), + IsEnabled = true, + Name = "Manage Task" + }, + new + { + Id = new Guid("d135a4b0-4f9a-4903-ab9c-4843839ebdee"), + Description = "", + FeatureId = new Guid("39e66f81-efc6-446c-95bd-46bff6cfb606"), + IsEnabled = true, + Name = "Assign Task and Report Progress" + }, + new + { + Id = new Guid("ed99ecd4-1bed-42e1-b7b3-d64c04493823"), + Description = "", + FeatureId = new Guid("39e66f81-efc6-446c-95bd-46bff6cfb606"), + IsEnabled = true, + Name = "Approve Task" + }, + new + { + Id = new Guid("b82d2b7e-0d52-45f3-997b-c008ea460e7f"), + Description = "", + FeatureId = new Guid("81ab8a87-8ccd-4015-a917-0627cee6a100"), + IsEnabled = true, + Name = "View Employee" + }, + new + { + Id = new Guid("a97d366a-c2bb-448d-be93-402bd2324566"), + Description = "", + FeatureId = new Guid("81ab8a87-8ccd-4015-a917-0627cee6a100"), + IsEnabled = true, + Name = "Manage Employee" + }, + new + { + Id = new Guid("fbd213e0-0250-46f1-9f5f-4b2a1e6e76a3"), + Description = "", + FeatureId = new Guid("81ab8a87-8ccd-4015-a917-0627cee6a100"), + IsEnabled = true, + Name = "Assign To Project" + }, + new + { + Id = new Guid("915e6bff-65f6-4e3f-aea8-3fd217d3ea9e"), + Description = "", + FeatureId = new Guid("52c9cf54-1eb2-44d2-81bb-524cf29c0a94"), + IsEnabled = true, + Name = "Perform Attendance " + }, + new + { + Id = new Guid("57802c4a-00aa-4a1f-a048-fd2f70dd44b6"), + Description = "", + FeatureId = new Guid("52c9cf54-1eb2-44d2-81bb-524cf29c0a94"), + IsEnabled = true, + Name = "Regularize Attendance" + }, + new + { + Id = new Guid("5ffbafe0-7ab0-48b1-bb50-c1bf76b65f9d"), + Description = "", + FeatureId = new Guid("be3b3afc-6ccf-4566-b9b6-aafcb65546be"), + IsEnabled = true, + Name = "View Masters" + }, + new + { + Id = new Guid("588a8824-f924-4955-82d8-fc51956cf323"), + Description = "", + FeatureId = new Guid("be3b3afc-6ccf-4566-b9b6-aafcb65546be"), + IsEnabled = true, + Name = "Manage Masters" + }, + new + { + Id = new Guid("cb8ec407-46d4-4467-930c-69127cda6dec"), + Description = "", + FeatureId = new Guid("660131a4-788c-4739-a082-cbbf7879cbf2"), + IsEnabled = true, + Name = "View Masters" + }, + new + { + Id = new Guid("6b1a6d97-a951-4de5-9b19-709bac7c4f18"), + Description = "", + FeatureId = new Guid("660131a4-788c-4739-a082-cbbf7879cbf2"), + IsEnabled = true, + Name = "Manage Masters" + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.JobRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("JobRoles"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.Module", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Key") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Modules"); + + b.HasData( + new + { + Id = 1, + Description = "Project Module", + Key = "b04da7e9-0406-409c-ac7f-b97256e6ea02", + Name = "Project" + }, + new + { + Id = 2, + Description = "Employee Module", + Key = "0971c7fb-6ce1-458a-ae3f-8d3205893637", + Name = "Employee" + }, + new + { + Id = 3, + Description = "Masters Module", + Key = "504ec132-e6a9-422f-8f85-050602cfce05", + Name = "Masters" + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.RolePermissionMappings", b => + { + b.Property("ApplicationRoleId") + .HasColumnType("char(36)"); + + b.Property("FeaturePermissionId") + .HasColumnType("char(36)"); + + b.HasKey("ApplicationRoleId", "FeaturePermissionId"); + + b.HasIndex("FeaturePermissionId"); + + b.ToTable("RolePermissionMappings"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.StatusMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Status") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("StatusMasters"); + + b.HasData( + new + { + Id = 1, + Status = "Active", + TenantId = 1 + }, + new + { + Id = 2, + Status = "In Progress", + TenantId = 1 + }, + new + { + Id = 3, + Status = "On Hold", + TenantId = 1 + }, + new + { + Id = 4, + Status = "Completed", + TenantId = 1 + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.Tenant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ContactName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ContactNumber") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("DomainName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("OnBoardingDate") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.ToTable("Tenants"); + + b.HasData( + new + { + Id = 1, + ContactName = "Admin", + ContactNumber = "123456789", + Description = "", + DomainName = "www.marcobms.org", + Name = "MarcoBMS", + OnBoardingDate = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified) + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.Building", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ProjectId") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("Buildings"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.Floor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("BuildingId") + .HasColumnType("int"); + + b.Property("FloorName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BuildingId"); + + b.HasIndex("TenantId"); + + b.ToTable("Floor"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.Project", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ContactPerson") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("EndDate") + .HasColumnType("datetime(6)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ProjectAddress") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ProjectStatusId") + .HasColumnType("int"); + + b.Property("StartDate") + .HasColumnType("datetime(6)"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ProjectStatusId"); + + b.HasIndex("TenantId"); + + b.ToTable("Projects"); + + b.HasData( + new + { + Id = 1, + ContactPerson = "Project 1 Contact Person", + Name = "Project 1", + ProjectAddress = "Project 1 Address", + ProjectStatusId = 1, + TenantId = 1 + }, + new + { + Id = 2, + ContactPerson = "Project 2 Contact Person", + Name = "Project 2", + ProjectAddress = "Project 2 Address", + ProjectStatusId = 2, + TenantId = 1 + }, + new + { + Id = 3, + ContactPerson = "Project 3 Contact Person", + Name = "Project 3", + ProjectAddress = "Project 3 Address", + ProjectStatusId = 3, + TenantId = 1 + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.ProjectAllocation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AllocationDate") + .HasColumnType("datetime(6)"); + + b.Property("EmployeeId") + .HasColumnType("int"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("JobRoleId") + .HasColumnType("int"); + + b.Property("ProjectId") + .HasColumnType("int"); + + b.Property("ReAllocationDate") + .HasColumnType("datetime(6)"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeId"); + + b.HasIndex("ProjectId"); + + b.HasIndex("TenantId"); + + b.ToTable("ProjectAllocations"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.WorkArea", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AreaName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FloorId") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("FloorId"); + + b.HasIndex("TenantId"); + + b.ToTable("WorkAreas"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("varchar(255)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("varchar(255)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("Discriminator") + .IsRequired() + .HasMaxLength(21) + .HasColumnType("varchar(21)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnd") + .HasColumnType("datetime(6)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("longtext"); + + b.Property("PhoneNumber") + .HasColumnType("longtext"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("SecurityStamp") + .HasColumnType("longtext"); + + b.Property("TwoFactorEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + + b.HasDiscriminator().HasValue("IdentityUser"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("ProviderKey") + .HasColumnType("varchar(255)"); + + b.Property("ProviderDisplayName") + .HasColumnType("longtext"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("RoleId") + .HasColumnType("varchar(255)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.ApplicationUser", b => + { + b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityUser"); + + b.Property("IsRootUser") + .HasColumnType("tinyint(1)"); + + b.Property("Role") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("int"); + + b.HasDiscriminator().HasValue("ApplicationUser"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Activities.TaskAllocation", b => + { + b.HasOne("Marco.Pms.Model.Projects.Building", "Building") + .WithMany() + .HasForeignKey("BuildingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Projects.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Projects.WorkArea", "WorkArea") + .WithMany() + .HasForeignKey("WorkAreaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Building"); + + b.Navigation("Employee"); + + b.Navigation("Project"); + + b.Navigation("Tenant"); + + b.Navigation("WorkArea"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Activities.WorkItem", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.ActivityMaster", "ActivityMaster") + .WithMany() + .HasForeignKey("ActivityId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Projects.WorkArea", "WorkArea") + .WithMany() + .HasForeignKey("WorkAreaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ActivityMaster"); + + b.Navigation("Tenant"); + + b.Navigation("WorkArea"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Activities.WorkItemMapping", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Projects.WorkArea", "WorkArea") + .WithMany() + .HasForeignKey("WorkAreaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Activities.WorkItem", "WorkItem") + .WithMany() + .HasForeignKey("WorkItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + + b.Navigation("WorkArea"); + + b.Navigation("WorkItem"); + }); + + modelBuilder.Entity("Marco.Pms.Model.AttendanceModule.Attendance", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "Approver") + .WithMany() + .HasForeignKey("EmployeeID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Approver"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.AttendanceModule.AttendanceLog", b => + { + b.HasOne("Marco.Pms.Model.AttendanceModule.Attendance", "Attendance") + .WithMany() + .HasForeignKey("AttendanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "UpdatedByEmployee") + .WithMany() + .HasForeignKey("UpdatedBy"); + + b.Navigation("Attendance"); + + b.Navigation("Employee"); + + b.Navigation("Tenant"); + + b.Navigation("UpdatedByEmployee"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Authentication.RefreshToken", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Employees.Employee", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.ApplicationUser", "ApplicationUser") + .WithMany() + .HasForeignKey("ApplicationUserId"); + + b.HasOne("Marco.Pms.Model.Entitlements.JobRole", "JobRole") + .WithMany() + .HasForeignKey("JobRoleId"); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ApplicationUser"); + + b.Navigation("JobRole"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Employees.WorkShift", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.ActivityMaster", b => + { + b.HasOne("Marco.Pms.Model.Activities.TaskAllocation", null) + .WithMany("AllotedTask") + .HasForeignKey("TaskAllocationId"); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.ApplicationRole", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", null) + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.EmployeeRoleMapping", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.ApplicationRole", "Role") + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Employee"); + + b.Navigation("Role"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.Feature", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.Module", "Module") + .WithMany() + .HasForeignKey("ModuleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Module"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.FeaturePermission", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.Feature", "Feature") + .WithMany("FeaturePermissions") + .HasForeignKey("FeatureId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Feature"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.JobRole", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.RolePermissionMappings", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.ApplicationRole", null) + .WithMany() + .HasForeignKey("ApplicationRoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.FeaturePermission", null) + .WithMany() + .HasForeignKey("FeaturePermissionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.StatusMaster", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.Building", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.Floor", b => + { + b.HasOne("Marco.Pms.Model.Projects.Building", "Building") + .WithMany() + .HasForeignKey("BuildingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Building"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.Project", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.StatusMaster", "ProjectStatus") + .WithMany() + .HasForeignKey("ProjectStatusId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ProjectStatus"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.ProjectAllocation", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Projects.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Employee"); + + b.Navigation("Project"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.WorkArea", b => + { + b.HasOne("Marco.Pms.Model.Projects.Floor", "Floor") + .WithMany() + .HasForeignKey("FloorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Floor"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Marco.Pms.Model.Activities.TaskAllocation", b => + { + b.Navigation("AllotedTask"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.Feature", b => + { + b.Navigation("FeaturePermissions"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Marco.Pms.DataAccess/Migrations/20250321010050_addJoiningDateToEmployee.cs b/Marco.Pms.DataAccess/Migrations/20250321010050_addJoiningDateToEmployee.cs new file mode 100644 index 0000000..1bc5bee --- /dev/null +++ b/Marco.Pms.DataAccess/Migrations/20250321010050_addJoiningDateToEmployee.cs @@ -0,0 +1,29 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Marco.Pms.DataAccess.Migrations +{ + /// + public partial class addJoiningDateToEmployee : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "JoiningDate", + table: "Employees", + type: "datetime(6)", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "JoiningDate", + table: "Employees"); + } + } +} diff --git a/Marco.Pms.DataAccess/Migrations/ApplicationDbContextModelSnapshot.cs b/Marco.Pms.DataAccess/Migrations/ApplicationDbContextModelSnapshot.cs index 3d0eafd..0306055 100644 --- a/Marco.Pms.DataAccess/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/Marco.Pms.DataAccess/Migrations/ApplicationDbContextModelSnapshot.cs @@ -302,6 +302,10 @@ namespace Marco.Pms.DataAccess.Migrations b.Property("Email") .HasColumnType("longtext"); + b.Property("EmergencyContactPerson") + .IsRequired() + .HasColumnType("longtext"); + b.Property("EmergencyPhoneNumber") .IsRequired() .HasColumnType("longtext"); @@ -314,9 +318,15 @@ namespace Marco.Pms.DataAccess.Migrations .IsRequired() .HasColumnType("longtext"); + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + b.Property("JobRoleId") .HasColumnType("int"); + b.Property("JoiningDate") + .HasColumnType("datetime(6)"); + b.Property("LastName") .IsRequired() .HasColumnType("longtext"); @@ -1193,12 +1203,12 @@ namespace Marco.Pms.DataAccess.Migrations b.Property("EmployeeId") .HasColumnType("int"); - b.Property("EmployeeRoleId") - .HasColumnType("char(36)"); - b.Property("IsActive") .HasColumnType("tinyint(1)"); + b.Property("JobRoleId") + .HasColumnType("int"); + b.Property("ProjectId") .HasColumnType("int"); diff --git a/Marco.Pms.DataAccess/Repository/ActivityMasterRepository.cs b/Marco.Pms.DataAccess/Repository/ActivityMasterRepository.cs deleted file mode 100644 index f78b06b..0000000 --- a/Marco.Pms.DataAccess/Repository/ActivityMasterRepository.cs +++ /dev/null @@ -1,47 +0,0 @@ -using Marco.Pms.DataAccess.Data; -using Marco.Pms.DataAccess.Repository; -using Marco.Pms.DataAccess.Repository.IRepository; -using Marco.Pms.Model.Entitlements; -using Marco.Pms.Model.Projects; -using Microsoft.EntityFrameworkCore; -using System.Linq.Expressions; -using System.Linq; - -namespace BulkyBook.DataAccess.Repository -{ - public class ActivityMasterRepository : Repository, IActivityMasterRepository - { - private readonly ApplicationDbContext _context; - public ActivityMasterRepository(ApplicationDbContext context) : base(context) - { - _context = context; - } - - - public void Update(ActivityMaster status) - { - _context.ActivityMasters.Update(status); - } - - public Task> GetAllAsync(Expression>? filter = null, string? includeProperties = null) - { - - IQueryable query = _context.ActivityMasters; - if (filter != null) - { - query.Where(filter); - } - if (!string.IsNullOrEmpty(includeProperties)) - { - foreach (var includeProp in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) - { - query = query.Include(includeProp); - } - } - return query.ToListAsync(); - - - // return await _context.Projects.ToListAsync(); ; - } - } -} diff --git a/Marco.Pms.DataAccess/Repository/ApplicationRolesRepository.cs b/Marco.Pms.DataAccess/Repository/ApplicationRolesRepository.cs deleted file mode 100644 index cb13bc5..0000000 --- a/Marco.Pms.DataAccess/Repository/ApplicationRolesRepository.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Marco.Pms.DataAccess.Data; -using Marco.Pms.DataAccess.Repository; -using Marco.Pms.DataAccess.Repository.IRepository; -using Marco.Pms.Model.Entitlements; -using Marco.Pms.Model.Projects; - -namespace BulkyBook.DataAccess.Repository -{ - public class ApplicationRolesRepository : Repository, IApplicationRolesRepository - { - private readonly ApplicationDbContext _db; - public ApplicationRolesRepository(ApplicationDbContext db) : base(db) - { - _db = db; - } - - - public void Update(ApplicationRole status) - { - _db.ApplicationRoles.Update(status); - } - } -} diff --git a/Marco.Pms.DataAccess/Repository/ApplicationUserRepository.cs b/Marco.Pms.DataAccess/Repository/ApplicationUserRepository.cs deleted file mode 100644 index 25b7f3b..0000000 --- a/Marco.Pms.DataAccess/Repository/ApplicationUserRepository.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Marco.Pms.DataAccess.Data; -using Marco.Pms.DataAccess.Repository.IRepository; -using Marco.Pms.Model.Entitlements; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Marco.Pms.DataAccess.Repository -{ - public class ApplicationUserRepository : Repository, IApplicationUserRepository - { - private readonly ApplicationDbContext _db; - public ApplicationUserRepository(ApplicationDbContext db) : base(db) - { - _db = db; - } - - } -} diff --git a/Marco.Pms.DataAccess/Repository/AttendenceRepository.cs b/Marco.Pms.DataAccess/Repository/AttendenceRepository.cs deleted file mode 100644 index 2191975..0000000 --- a/Marco.Pms.DataAccess/Repository/AttendenceRepository.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Marco.Pms.DataAccess.Data; -using Marco.Pms.DataAccess.Repository; -using Marco.Pms.DataAccess.Repository.IRepository; -using Marco.Pms.Model.AttendanceModule; - -namespace BulkyBook.DataAccess.Repository -{ - public class AttendenceRepository : Repository, IAttendenceRepository - { - private readonly ApplicationDbContext _db; - public AttendenceRepository(ApplicationDbContext db) : base(db) - { - _db = db; - } - - - public void Update(Attendance attendance) - { - _db.Attendes.Update(attendance); - } - } -} diff --git a/Marco.Pms.DataAccess/Repository/BuildingRepository.cs b/Marco.Pms.DataAccess/Repository/BuildingRepository.cs deleted file mode 100644 index 9d73d93..0000000 --- a/Marco.Pms.DataAccess/Repository/BuildingRepository.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Marco.Pms.DataAccess.Data; -using Marco.Pms.DataAccess.Repository; -using Marco.Pms.DataAccess.Repository.IRepository; -using Marco.Pms.Model.Projects; - -namespace BulkyBook.DataAccess.Repository -{ - public class BuildingRepository : Repository, IBuildingRepository - { - private readonly ApplicationDbContext _db; - public BuildingRepository(ApplicationDbContext db) : base(db) - { - _db = db; - } - - - public void Update(Building building) - { - _db.Buildings.Update(building); - } - } -} diff --git a/Marco.Pms.DataAccess/Repository/EmployeeRepository.cs b/Marco.Pms.DataAccess/Repository/EmployeeRepository.cs deleted file mode 100644 index 6c4942e..0000000 --- a/Marco.Pms.DataAccess/Repository/EmployeeRepository.cs +++ /dev/null @@ -1,47 +0,0 @@ -using Marco.Pms.DataAccess.Data; -using Marco.Pms.DataAccess.Repository; -using Marco.Pms.DataAccess.Repository.IRepository; -using Marco.Pms.Model.Employees; -using Marco.Pms.Model.Projects; -using Microsoft.EntityFrameworkCore; -using System.Linq.Expressions; -using System.Linq; - -namespace BulkyBook.DataAccess.Repository -{ - public class EmployeeRepository : Repository, IEmployeeRepository - { - private readonly ApplicationDbContext _context; - public EmployeeRepository(ApplicationDbContext db) : base(db) - { - _context = db; - } - - - public void Update(Employee employee) - { - _context.Employees.Update(employee); - } - - public Task> GetAsync(Expression>? filter = null, string? includeProperties = null) - { - - IQueryable query = _context.Employees; - if (filter != null) - { - query.Where(filter); - } - if (!string.IsNullOrEmpty(includeProperties)) - { - foreach (var includeProp in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) - { - query = query.Include(includeProp); - } - } - return query.ToListAsync(); - - - // return await _context.Projects.ToListAsync(); ; - } - } -} diff --git a/Marco.Pms.DataAccess/Repository/FeaturesRepository.cs b/Marco.Pms.DataAccess/Repository/FeaturesRepository.cs deleted file mode 100644 index 689a880..0000000 --- a/Marco.Pms.DataAccess/Repository/FeaturesRepository.cs +++ /dev/null @@ -1,119 +0,0 @@ -using Marco.Pms.DataAccess.Data; -using Marco.Pms.DataAccess.Repository; -using Marco.Pms.DataAccess.Repository.IRepository; -using Marco.Pms.Model.Entitlements; -using Marco.Pms.Model.Projects; -using Microsoft.EntityFrameworkCore; -using System.Linq.Expressions; - -namespace BulkyBook.DataAccess.Repository -{ - public class FeaturesRepository : Repository, IFeatureRepository - { - private readonly ApplicationDbContext _context; - internal DbSet dbSet; - - public FeaturesRepository(ApplicationDbContext db): base(db) - { - _context = db; - this.dbSet = _context.Set(); - - } - - - public void Update(Feature project) - { - _context.Features.Update(project); - } - - - public Task> GetAllAsync(Expression>? filter = null, string? includeProperties = null) - { - - IQueryable query = _context.Features; - if (filter != null) - { - query.Where(filter); - } - if (!string.IsNullOrEmpty(includeProperties)) - { - foreach (var includeProp in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) - { - query = query.Include(includeProp); - } - } - return query.ToListAsync(); - - - // return await _context.Projects.ToListAsync(); ; - } - public Task> GetAsync(Expression>? filter = null, string? includeProperties = null) - { - - IQueryable query = _context.Features; - - if (filter != null) - { - query.Where(filter); - //var projects1= query2.Where(filter).ToListAsync(); - } - if (!string.IsNullOrEmpty(includeProperties)) - { - foreach (var includeProp in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) - { - query = query.Include(includeProp); - } - } - - return query.ToListAsync(); - - - // return await _context.Projects.ToListAsync(); ; - } - - public async Task CreateAsync(Feature projectModel) - { - try - { - await _context.Features.AddAsync(projectModel); - await _context.SaveChangesAsync(); - return projectModel; - } - catch (Exception ex) { throw ex; } - - } - - - - //public async Task UpdateAsync(int id, UpdateFeatureDto projectDto) - //{ - - // var projectModel = await _context.Features.FirstOrDefaultAsync(item => item.Id == id); - - // if (projectModel == null) - // { - // return null; - // } - - // projectModel.ContactPerson = projectDto.ContactPerson; - // projectModel.ProjectAddress = projectDto.ProjectAddress; - // projectModel.Name = projectDto.Name; - // projectModel.EndDate = projectDto.EndDate; - // projectModel.StartDate = projectDto.StartDate; - // //projectModel.TenantId = projectDto.TenantId; - // try - // { - // await _context.SaveChangesAsync(); - // }catch(Exception ex ) - // { - // throw ex; - // } - - // return projectModel; - //} - - - - - } -} diff --git a/Marco.Pms.DataAccess/Repository/FloorRepository.cs b/Marco.Pms.DataAccess/Repository/FloorRepository.cs deleted file mode 100644 index 202fdbb..0000000 --- a/Marco.Pms.DataAccess/Repository/FloorRepository.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Marco.Pms.DataAccess.Data; -using Marco.Pms.DataAccess.Repository; -using Marco.Pms.DataAccess.Repository.IRepository; -using Marco.Pms.Model.Projects; - -namespace BulkyBook.DataAccess.Repository -{ - public class FloorRepository : Repository, IFloorRepository - { - private readonly ApplicationDbContext _db; - public FloorRepository(ApplicationDbContext db) : base(db) - { - _db = db; - } - - - public void Update(Floor floor) - { - _db.Floor.Update(floor); - } - } -} diff --git a/Marco.Pms.DataAccess/Repository/IRepository/IActivityMasterRepository.cs b/Marco.Pms.DataAccess/Repository/IRepository/IActivityMasterRepository.cs deleted file mode 100644 index 71fe429..0000000 --- a/Marco.Pms.DataAccess/Repository/IRepository/IActivityMasterRepository.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Marco.Pms.Model.Entitlements; -using System.Linq.Expressions; - -namespace Marco.Pms.DataAccess.Repository.IRepository -{ - public interface IActivityMasterRepository : IRepository - { - void Update(ActivityMaster activity); - Task> GetAllAsync(Expression>? filter = null, string? includeProperties = null); - } - -} diff --git a/Marco.Pms.DataAccess/Repository/IRepository/IApplicationRolesRepository.cs b/Marco.Pms.DataAccess/Repository/IRepository/IApplicationRolesRepository.cs deleted file mode 100644 index df57350..0000000 --- a/Marco.Pms.DataAccess/Repository/IRepository/IApplicationRolesRepository.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Marco.Pms.Model.Entitlements; - -namespace Marco.Pms.DataAccess.Repository.IRepository -{ - public interface IApplicationRolesRepository : IRepository - { - void Update(ApplicationRole role); - } - -} diff --git a/Marco.Pms.DataAccess/Repository/IRepository/IApplicationUserRepository.cs b/Marco.Pms.DataAccess/Repository/IRepository/IApplicationUserRepository.cs deleted file mode 100644 index 7feb37b..0000000 --- a/Marco.Pms.DataAccess/Repository/IRepository/IApplicationUserRepository.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Marco.Pms.Model.Entitlements; - -namespace Marco.Pms.DataAccess.Repository.IRepository -{ - public interface IApplicationUserRepository : IRepository - { - - } -} diff --git a/Marco.Pms.DataAccess/Repository/IRepository/IAttendenceRepository.cs b/Marco.Pms.DataAccess/Repository/IRepository/IAttendenceRepository.cs deleted file mode 100644 index 6a3c67e..0000000 --- a/Marco.Pms.DataAccess/Repository/IRepository/IAttendenceRepository.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Marco.Pms.Model.AttendanceModule; - -namespace Marco.Pms.DataAccess.Repository.IRepository -{ - - public interface IAttendenceRepository : IRepository - { - void Update(Attendance employee); - } - -} diff --git a/Marco.Pms.DataAccess/Repository/IRepository/IBuildingRepository.cs b/Marco.Pms.DataAccess/Repository/IRepository/IBuildingRepository.cs deleted file mode 100644 index aedd6f3..0000000 --- a/Marco.Pms.DataAccess/Repository/IRepository/IBuildingRepository.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Marco.Pms.Model.Projects; - -namespace Marco.Pms.DataAccess.Repository.IRepository -{ - public interface IBuildingRepository : IRepository - { - void Update(Building building); - } - -} diff --git a/Marco.Pms.DataAccess/Repository/IRepository/IEmployeeRepository.cs b/Marco.Pms.DataAccess/Repository/IRepository/IEmployeeRepository.cs deleted file mode 100644 index ab48ec0..0000000 --- a/Marco.Pms.DataAccess/Repository/IRepository/IEmployeeRepository.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Marco.Pms.Model.Employees; -using System.Linq.Expressions; - -namespace Marco.Pms.DataAccess.Repository.IRepository -{ - - public interface IEmployeeRepository : IRepository - { - void Update(Employee employee); - Task> GetAsync(Expression>? filter = null, string? includeProperties = null); - } - -} diff --git a/Marco.Pms.DataAccess/Repository/IRepository/IFeatureRepository.cs b/Marco.Pms.DataAccess/Repository/IRepository/IFeatureRepository.cs deleted file mode 100644 index b35b898..0000000 --- a/Marco.Pms.DataAccess/Repository/IRepository/IFeatureRepository.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Marco.Pms.Model.Dtos.Project; -using Marco.Pms.Model.Entitlements; -using System.Linq.Expressions; - -namespace Marco.Pms.DataAccess.Repository.IRepository -{ - public interface IFeatureRepository : IRepository - { - void Update(Feature Feature); - Task> GetAsync(Expression>? filter = null, string? includeProperties = null); - Task> GetAllAsync(Expression>? filter = null, string? includeProperties = null); - Task CreateAsync(Feature feature); - // Task UpdateAsync(int id, UpdateFeatureDto Feature); - - // Task> GetAsync(int id, string? includeProperties = null); - } - -} diff --git a/Marco.Pms.DataAccess/Repository/IRepository/IFloorRepository.cs b/Marco.Pms.DataAccess/Repository/IRepository/IFloorRepository.cs deleted file mode 100644 index fcaf538..0000000 --- a/Marco.Pms.DataAccess/Repository/IRepository/IFloorRepository.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Marco.Pms.Model.Projects; - -namespace Marco.Pms.DataAccess.Repository.IRepository -{ - public interface IFloorRepository : IRepository - { - void Update(Floor floor); - } - -} diff --git a/Marco.Pms.DataAccess/Repository/IRepository/IProjectAllocationRepository.cs b/Marco.Pms.DataAccess/Repository/IRepository/IProjectAllocationRepository.cs deleted file mode 100644 index 6e9f128..0000000 --- a/Marco.Pms.DataAccess/Repository/IRepository/IProjectAllocationRepository.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Marco.Pms.Model.Dtos.Project; -using Marco.Pms.Model.Projects; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Text; -using System.Threading.Tasks; - -namespace Marco.Pms.DataAccess.Repository.IRepository -{ - public interface IProjectAllocationRepository - { - void Update(ProjectAllocation project); - Task> GetAsync(Expression>? filter = null, string? includeProperties = null); - Task> GetAllAsync(Expression>? filter = null, string? includeProperties = null); - Task CreateAsync(ProjectAllocation project); - Task UpdateAsync(int id, ProjectAllocation project); - } -} diff --git a/Marco.Pms.DataAccess/Repository/IRepository/IProjectRepository.cs b/Marco.Pms.DataAccess/Repository/IRepository/IProjectRepository.cs deleted file mode 100644 index ca9c902..0000000 --- a/Marco.Pms.DataAccess/Repository/IRepository/IProjectRepository.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Marco.Pms.Model.Dtos.Project; -using Marco.Pms.Model.Projects; -using System.Linq.Expressions; - -namespace Marco.Pms.DataAccess.Repository.IRepository -{ - public interface IProjectRepository : IRepository - { - void Update(Project project); - Task> GetAsync(Expression>? filter = null, string? includeProperties = null); - Task> GetAllAsync(Expression>? filter = null, string? includeProperties = null); - Task CreateAsync(Project project); - Task UpdateAsync(int id, UpdateProjectDto project); - - // Task> GetAsync(int id, string? includeProperties = null); - } - -} diff --git a/Marco.Pms.DataAccess/Repository/IRepository/IRepository.cs b/Marco.Pms.DataAccess/Repository/IRepository/IRepository.cs deleted file mode 100644 index 073b6f0..0000000 --- a/Marco.Pms.DataAccess/Repository/IRepository/IRepository.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Linq.Expressions; - -namespace Marco.Pms.DataAccess.Repository.IRepository -{ - public interface IRepository where T : class - { - // T - Category - IEnumerable GetAll(Expression>? filter, string? includeProperties = null); - //T GetFirstOrDefault(); - T Get(Expression> filter, string? includeProperties = null, bool tracked = false); - Task GetAsync(Expression> filter, bool tracked = false, params Expression>[] includeProperties); - void Add(T entity); - void Remove(T entity); - void RemoveRange(IEnumerable entity); - } -} diff --git a/Marco.Pms.DataAccess/Repository/IRepository/IStatusRepository.cs b/Marco.Pms.DataAccess/Repository/IRepository/IStatusRepository.cs deleted file mode 100644 index f86139b..0000000 --- a/Marco.Pms.DataAccess/Repository/IRepository/IStatusRepository.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Marco.Pms.Model.Entitlements; -using Marco.Pms.Model.Projects; - -namespace Marco.Pms.DataAccess.Repository.IRepository -{ - public interface IStatusRepository : IRepository - { - void Update(StatusMaster status); - } - -} diff --git a/Marco.Pms.DataAccess/Repository/IRepository/ITaskAllocationRepository.cs b/Marco.Pms.DataAccess/Repository/IRepository/ITaskAllocationRepository.cs deleted file mode 100644 index 00b07b1..0000000 --- a/Marco.Pms.DataAccess/Repository/IRepository/ITaskAllocationRepository.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Marco.Pms.Model.Activities; - -namespace Marco.Pms.DataAccess.Repository.IRepository -{ - - public interface ITaskAllocationRepository : IRepository - { - void Update(TaskAllocation employeeAllocation); - } - -} diff --git a/Marco.Pms.DataAccess/Repository/IRepository/IUnitOfWork.cs b/Marco.Pms.DataAccess/Repository/IRepository/IUnitOfWork.cs deleted file mode 100644 index 0994eba..0000000 --- a/Marco.Pms.DataAccess/Repository/IRepository/IUnitOfWork.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace Marco.Pms.DataAccess.Repository.IRepository -{ - public interface IUnitOfWork - { - IApplicationUserRepository ApplicationUser { get; } - - IEmployeeRepository Employee { get; } - ITaskAllocationRepository EmployeeAllocation - { get; } - IProjectRepository Project { get; } - IProjectAllocationRepository ProjectAllocation { get; } - - IBuildingRepository Building { get; } - IFloorRepository Floor { get; } - - IWorkAreaRepository WorkArea { get; } - IWorkItemRepository WorkItem { get; } - IWorkItemMappingReposiotry WorkItemMapping { get;} - - - IAttendenceRepository Attendence { get; } - IStatusRepository StatusMaster { get; } - IActivityMasterRepository ActivityMaster { get; } - IApplicationRolesRepository EmployeeRoles { get; } - IFeatureRepository Features { get; } - void Save(); - } -} diff --git a/Marco.Pms.DataAccess/Repository/IRepository/IWorkAreaRepository.cs b/Marco.Pms.DataAccess/Repository/IRepository/IWorkAreaRepository.cs deleted file mode 100644 index 7ae68d6..0000000 --- a/Marco.Pms.DataAccess/Repository/IRepository/IWorkAreaRepository.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Marco.Pms.Model.Projects; - -namespace Marco.Pms.DataAccess.Repository.IRepository -{ - public interface IWorkAreaRepository : IRepository - { - void Update(WorkArea workArea); - } - -} diff --git a/Marco.Pms.DataAccess/Repository/IRepository/IWorkItemMappingReposiotry.cs b/Marco.Pms.DataAccess/Repository/IRepository/IWorkItemMappingReposiotry.cs deleted file mode 100644 index c6f0cbc..0000000 --- a/Marco.Pms.DataAccess/Repository/IRepository/IWorkItemMappingReposiotry.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Marco.Pms.Model.Activities; - -namespace Marco.Pms.DataAccess.Repository.IRepository -{ - public interface IWorkItemMappingReposiotry : IRepository - { - void Update(WorkItemMapping mapping); - } -} diff --git a/Marco.Pms.DataAccess/Repository/IRepository/IWorkItemRepository.cs b/Marco.Pms.DataAccess/Repository/IRepository/IWorkItemRepository.cs deleted file mode 100644 index 0ee149e..0000000 --- a/Marco.Pms.DataAccess/Repository/IRepository/IWorkItemRepository.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Marco.Pms.Model.Activities; -using Marco.Pms.Model.Projects; - -namespace Marco.Pms.DataAccess.Repository.IRepository -{ - public interface IWorkItemRepository : IRepository - { - void Update(WorkItem workItem); - } - -} diff --git a/Marco.Pms.DataAccess/Repository/ProjectAllocationRepository.cs b/Marco.Pms.DataAccess/Repository/ProjectAllocationRepository.cs deleted file mode 100644 index ca356bd..0000000 --- a/Marco.Pms.DataAccess/Repository/ProjectAllocationRepository.cs +++ /dev/null @@ -1,84 +0,0 @@ -using Marco.Pms.DataAccess.Data; -using Marco.Pms.DataAccess.Repository.IRepository; -using Marco.Pms.Model.Dtos.Project; -using Marco.Pms.Model.Projects; -using Microsoft.EntityFrameworkCore; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Text; -using System.Threading.Tasks; - -namespace Marco.Pms.DataAccess.Repository -{ - public class ProjectAllocationRepository : Repository, IProjectAllocationRepository - { - private readonly ApplicationDbContext _context; - internal DbSet dbSet; - - public ProjectAllocationRepository(ApplicationDbContext db) : base(db) - { - _context = db; - this.dbSet = _context.Set(); - } - - - public void Update(ProjectAllocation project) - { - _context.ProjectAllocations.Update(project); - } - - public async Task CreateAsync(ProjectAllocation project) - { - await _context.ProjectAllocations.AddAsync(project); - await _context.SaveChangesAsync(); - return project; - } - - public Task> GetAllAsync(Expression>? filter = null, string? includeProperties = null) - { - throw new NotImplementedException(); - } - - public Task> GetAsync(Expression>? filter = null, string? includeProperties = null) - { - IQueryable query = _context.ProjectAllocations; - if (filter != null) - { - query.Where(filter); - } - if (!string.IsNullOrEmpty(includeProperties)) - { - foreach (var includeProp in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) - { - query = query.Include(includeProp); - } - } - return query.ToListAsync(); - } - - - public async Task UpdateAsync(int id, ProjectAllocation project) - { - var allocation = await _context.ProjectAllocations.FirstOrDefaultAsync(item => item.Id == id); - - if (allocation == null) - { - return null; - } - - allocation.ProjectId = project.ProjectId; - allocation.EmployeeId = project.EmployeeId; - allocation.AllocationDate = project.AllocationDate; - allocation.ReAllocationDate = project.ReAllocationDate; - allocation.TenantId = project.TenantId; - - - _context.ProjectAllocations.Update(allocation); - await _context.SaveChangesAsync(); - - return allocation; - } - } -} diff --git a/Marco.Pms.DataAccess/Repository/ProjectRepository.cs b/Marco.Pms.DataAccess/Repository/ProjectRepository.cs deleted file mode 100644 index bed7d6c..0000000 --- a/Marco.Pms.DataAccess/Repository/ProjectRepository.cs +++ /dev/null @@ -1,146 +0,0 @@ -using Marco.Pms.DataAccess.Data; -using Marco.Pms.DataAccess.Repository; -using Marco.Pms.DataAccess.Repository.IRepository; -using Marco.Pms.Model.Dtos.Project; -using Marco.Pms.Model.Entitlements; -using Marco.Pms.Model.Projects; -using Microsoft.EntityFrameworkCore; -using System.Linq; -using System.Linq.Expressions; -using System.Xml; -using System.Xml.Linq; -using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database; - -namespace BulkyBook.DataAccess.Repository -{ - public class ProjectRepository : Repository, IProjectRepository - { - private readonly ApplicationDbContext _context; - internal DbSet dbSet; - - public ProjectRepository(ApplicationDbContext db) : base(db) - { - _context = db; - this.dbSet = _context.Set(); - - } - - - public void Update(Project project) - { - _context.Projects.Update(project); - } - - - public Task> GetAllAsync(Expression>? filter = null, string? includeProperties = null) - { - - IQueryable query = _context.Projects; - if (filter != null) - { - query.Where(filter); - } - if (!string.IsNullOrEmpty(includeProperties)) - { - foreach (var includeProp in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) - { - query = query.Include(includeProp); - } - } - return query.ToListAsync(); - - - // return await _context.Projects.ToListAsync(); ; - } - public Task> GetAsync(Expression>? filter = null, string? includeProperties = null) - { - - IQueryable query = _context.Projects; - //IQueryable query2 = _context.Projects; - - Expression> filter1 = x => x.Id == 2; - if (filter != null) - { - query.Where(filter); - //var projects1= query2.Where(filter).ToListAsync(); - } - if (!string.IsNullOrEmpty(includeProperties)) - { - foreach (var includeProp in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) - { - query = query.Include(includeProp); - } - } - - return query.ToListAsync(); - - - // return await _context.Projects.ToListAsync(); ; - } - - public async Task CreateAsync(Project projectModel) - { - try - { - await _context.Projects.AddAsync(projectModel); - await _context.SaveChangesAsync(); - return projectModel; - } - catch (Exception ex) { throw ex; } - - } - - public async Task UpdateAsync(int id, UpdateProjectDto projectDto) - { - - var projectModel = await _context.Projects.FirstOrDefaultAsync(item => item.Id == id); - - if (projectModel == null) - { - return null; - } - - projectModel.ContactPerson = projectDto.ContactPerson; - projectModel.ProjectAddress = projectDto.ProjectAddress; - projectModel.Name = projectDto.Name; - projectModel.EndDate = projectDto.EndDate; - projectModel.StartDate = projectDto.StartDate; - //projectModel.TenantId = projectDto.TenantId; - try - { - await _context.SaveChangesAsync(); - }catch(Exception ex ) - { - throw ex; - } - - return projectModel; - } - - - - //public Task> GetAsync(int id, string? includeProperties = null) - //{ - - // IQueryable query = _context.Projects; - // query.Where(c=>c.Id == id); - // // Task project = _context.Projects.Where(c=>c.Id == id).SingleOrDefaultAsync(); - // //if (filter != null) - // //{ - // // query.Where(filter); - // //} - // //if (!string.IsNullOrEmpty(includeProperties)) - // //{ - // // foreach (var includeProp in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) - // // { - // // query = query.Include(includeProp); - // // } - // //} - // return query.ToListAsync(); - - - // // return await _context.Projects.ToListAsync(); ; - //} - - } -} diff --git a/Marco.Pms.DataAccess/Repository/Repository.cs b/Marco.Pms.DataAccess/Repository/Repository.cs deleted file mode 100644 index 7b69363..0000000 --- a/Marco.Pms.DataAccess/Repository/Repository.cs +++ /dev/null @@ -1,102 +0,0 @@ -using Marco.Pms.DataAccess.Data; -using Marco.Pms.DataAccess.Repository.IRepository; -using Microsoft.EntityFrameworkCore; -using System.Linq.Expressions; - -namespace Marco.Pms.DataAccess.Repository -{ - public class Repository : IRepository where T : class - { - private readonly ApplicationDbContext _context; - internal DbSet dbSet; - public Repository(ApplicationDbContext context) - { - _context = context; - this.dbSet = _context.Set(); - - //_db.Products.Include(u => u.Category); - } - public void Add(T entity) - { - dbSet.Add(entity); - } - - public T Get(Expression> filter, string? includeProperties = null, bool tracked = false) - { - IQueryable query = dbSet; - if (tracked) - { - query = query.Where(filter); - } - else - { - query = query.AsNoTracking().Where(filter); - } - - if (!string.IsNullOrEmpty(includeProperties)) - { - foreach (var includeProp in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) - { - query = query.Include(includeProp); - } - } - - return query.FirstOrDefault(); - - } - - public async Task GetAsync(Expression> filter, bool tracked = false, params Expression>[] includeProperties) - { - IQueryable query = dbSet; - if (tracked) - { - query = query.Where(filter); - } - else - { - query = query.AsNoTracking().Where(filter); - } - - if (includeProperties != null) - { - foreach (var includeProp in includeProperties) - { - query = query.Include(includeProp); - } - } - - return await query.SingleOrDefaultAsync(); - - } - - public IEnumerable GetAll(Expression>? filter = null, string? includeProperties = null) - { - IQueryable query = dbSet; - if(filter != null) - { - query.Where(filter); - } - if (!string.IsNullOrEmpty(includeProperties)) - { - foreach (var includeProp in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) - { - query = query.Include(includeProp); - } - } - return query.ToList(); - - } - - public void Remove(T entity) - { - dbSet.Remove(entity); - } - - public void RemoveRange(IEnumerable entity) - { - dbSet.RemoveRange(entity); - } - - - } -} diff --git a/Marco.Pms.DataAccess/Repository/StatusRepository.cs b/Marco.Pms.DataAccess/Repository/StatusRepository.cs deleted file mode 100644 index 2d9c92d..0000000 --- a/Marco.Pms.DataAccess/Repository/StatusRepository.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Marco.Pms.DataAccess.Data; -using Marco.Pms.DataAccess.Repository; -using Marco.Pms.DataAccess.Repository.IRepository; -using Marco.Pms.Model.Entitlements; -using Marco.Pms.Model.Projects; - -namespace BulkyBook.DataAccess.Repository -{ - public class StatusRepository : Repository, IStatusRepository - { - private readonly ApplicationDbContext _db; - public StatusRepository(ApplicationDbContext db) : base(db) - { - _db = db; - } - - - public void Update(StatusMaster status) - { - _db.StatusMasters.Update(status); - } - } -} diff --git a/Marco.Pms.DataAccess/Repository/TaskAllocationRepository.cs b/Marco.Pms.DataAccess/Repository/TaskAllocationRepository.cs deleted file mode 100644 index 13521f4..0000000 --- a/Marco.Pms.DataAccess/Repository/TaskAllocationRepository.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Marco.Pms.DataAccess.Data; -using Marco.Pms.DataAccess.Repository; -using Marco.Pms.DataAccess.Repository.IRepository; -using Marco.Pms.Model.Activities; - -namespace BulkyBook.DataAccess.Repository -{ - public class TaskAllocationRepository : Repository, ITaskAllocationRepository - { - private readonly ApplicationDbContext _db; - public TaskAllocationRepository(ApplicationDbContext db) : base(db) - { - _db = db; - } - - public void Update(TaskAllocation employeeAllocation) - { - _db.TaskAllocations.Update(employeeAllocation); - } - } -} diff --git a/Marco.Pms.DataAccess/Repository/UnitOfWork.cs b/Marco.Pms.DataAccess/Repository/UnitOfWork.cs deleted file mode 100644 index bac22da..0000000 --- a/Marco.Pms.DataAccess/Repository/UnitOfWork.cs +++ /dev/null @@ -1,64 +0,0 @@ -using BulkyBook.DataAccess.Repository; -using Marco.Pms.DataAccess.Data; -using Marco.Pms.DataAccess.Repository.IRepository; - -namespace Marco.Pms.DataAccess.Repository -{ - public class UnitOfWork : IUnitOfWork - { - private readonly ApplicationDbContext _db; - - public IApplicationUserRepository ApplicationUser { get; private set; } - - public IEmployeeRepository Employee { get; private set; } - public ITaskAllocationRepository EmployeeAllocation { get; private set; } - - public IProjectRepository Project { get; private set; } - public IProjectAllocationRepository ProjectAllocation { get; private set; } - - public IBuildingRepository Building { get; private set; } - public IFloorRepository Floor { get; private set; } - public IAttendenceRepository Attendence { get; private set; } - - public IWorkAreaRepository WorkArea { get; private set; } - - public IWorkItemRepository WorkItem { get; private set; } - - public IWorkItemMappingReposiotry WorkItemMapping { get; private set; } - - public IStatusRepository StatusMaster { get; private set; } - public IActivityMasterRepository ActivityMaster { get; private set; } - public IApplicationRolesRepository EmployeeRoles { get; private set; } - public IFeatureRepository Features { get; private set; } - - - public UnitOfWork(ApplicationDbContext db) - { - _db = db; - Employee = new EmployeeRepository(_db); - Project = new ProjectRepository(_db); - ProjectAllocation = new ProjectAllocationRepository(_db); - - Building = new BuildingRepository(_db); - Floor = new FloorRepository(_db); - WorkArea = new WorkAreaRepository(_db); - WorkItem = new WorkItemRepository(_db); - WorkItemMapping = new WorkItemMappingReporitury(_db); - - ApplicationUser = new ApplicationUserRepository(_db); - Attendence = new AttendenceRepository(_db); - EmployeeAllocation = new TaskAllocationRepository(_db); - - StatusMaster = new StatusRepository(_db); - ActivityMaster = new ActivityMasterRepository(_db); - EmployeeRoles = new ApplicationRolesRepository(_db); - Features = new FeaturesRepository(_db); - - } - - public void Save() - { - _db.SaveChanges(); - } - } -} diff --git a/Marco.Pms.DataAccess/Repository/WorkAreaRepository.cs b/Marco.Pms.DataAccess/Repository/WorkAreaRepository.cs deleted file mode 100644 index 0bdeb25..0000000 --- a/Marco.Pms.DataAccess/Repository/WorkAreaRepository.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Marco.Pms.DataAccess.Data; -using Marco.Pms.DataAccess.Repository; -using Marco.Pms.DataAccess.Repository.IRepository; -using Marco.Pms.Model.Projects; - -namespace BulkyBook.DataAccess.Repository -{ - public class WorkAreaRepository : Repository, IWorkAreaRepository - { - private readonly ApplicationDbContext _db; - public WorkAreaRepository(ApplicationDbContext db) : base(db) - { - _db = db; - } - - - public void Update(WorkArea workArea) - { - _db.WorkAreas.Update(workArea); - } - } -} diff --git a/Marco.Pms.DataAccess/Repository/WorkItemMappingReporitury.cs b/Marco.Pms.DataAccess/Repository/WorkItemMappingReporitury.cs deleted file mode 100644 index f70914e..0000000 --- a/Marco.Pms.DataAccess/Repository/WorkItemMappingReporitury.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Marco.Pms.DataAccess.Data; -using Marco.Pms.DataAccess.Repository; -using Marco.Pms.DataAccess.Repository.IRepository; -using Marco.Pms.Model.Activities; - -namespace BulkyBook.DataAccess.Repository -{ - public class WorkItemMappingReporitury : Repository, IWorkItemMappingReposiotry - { - private readonly ApplicationDbContext _db; - public WorkItemMappingReporitury(ApplicationDbContext db) : base(db) - { - _db = db; - } - - - public void Update(WorkItemMapping workItem) - { - _db.WorkItemMapping.Update(workItem); - } - } -} diff --git a/Marco.Pms.DataAccess/Repository/WorkItemRepository.cs b/Marco.Pms.DataAccess/Repository/WorkItemRepository.cs deleted file mode 100644 index 065ed89..0000000 --- a/Marco.Pms.DataAccess/Repository/WorkItemRepository.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Marco.Pms.DataAccess.Data; -using Marco.Pms.DataAccess.Repository; -using Marco.Pms.DataAccess.Repository.IRepository; -using Marco.Pms.Model.Activities; - -namespace BulkyBook.DataAccess.Repository -{ - public class WorkItemRepository : Repository, IWorkItemRepository - { - private readonly ApplicationDbContext _db; - public WorkItemRepository(ApplicationDbContext db) : base(db) - { - _db = db; - } - - - public void Update(WorkItem workItem) - { - _db.WorkItems.Update(workItem); - } - } -} diff --git a/Marco.Pms.Model/Activities/TaskAllocation.cs b/Marco.Pms.Model/Activities/TaskAllocation.cs index 43e5d65..6c99950 100644 --- a/Marco.Pms.Model/Activities/TaskAllocation.cs +++ b/Marco.Pms.Model/Activities/TaskAllocation.cs @@ -1,7 +1,7 @@ using Marco.Pms.Model.Employees; using Marco.Pms.Model.Entitlements; using Marco.Pms.Model.Projects; -using MarcoBMS.Utility; +using Marco.Pms.Utility; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using System.ComponentModel; using System.ComponentModel.DataAnnotations.Schema; diff --git a/Marco.Pms.Model/Dtos/Employees/CreateUserDto.cs b/Marco.Pms.Model/Dtos/Employees/CreateUserDto.cs index 5f295c0..7592fbd 100644 --- a/Marco.Pms.Model/Dtos/Employees/CreateUserDto.cs +++ b/Marco.Pms.Model/Dtos/Employees/CreateUserDto.cs @@ -30,8 +30,8 @@ namespace Marco.Pms.Model.Dtos.Employees public string? PanNumber { get; set; } - public IFormFile? Photo { get; set; } // To store the captured photo - public List? Documents { get; set; } + //public IFormFile? Photo { get; set; } // To store the captured photo + //public List? Documents { get; set; } public string JobRoleId { get; set; } diff --git a/Marco.Pms.Model/Dtos/Project/ProjectAllocationDot.cs b/Marco.Pms.Model/Dtos/Project/ProjectAllocationDot.cs index 08690ea..6d5604e 100644 --- a/Marco.Pms.Model/Dtos/Project/ProjectAllocationDot.cs +++ b/Marco.Pms.Model/Dtos/Project/ProjectAllocationDot.cs @@ -3,7 +3,7 @@ public class ProjectAllocationDot { public int EmpID { get; set; } - public Guid RoleID { get; set; } + public int JobRoleId { get; set; } public int ProjectId { get; set; } public bool Status { get; set; } diff --git a/Marco.Pms.Model/Dtos/ResetPasswordDto.cs b/Marco.Pms.Model/Dtos/ResetPasswordDto.cs index 5ad8573..971da66 100644 --- a/Marco.Pms.Model/Dtos/ResetPasswordDto.cs +++ b/Marco.Pms.Model/Dtos/ResetPasswordDto.cs @@ -14,8 +14,5 @@ namespace Marco.Pms.Model.Dtos [Required] [MinLength(6)] public string NewPassword { get; set; } - - [Compare("NewPassword", ErrorMessage = "Passwords do not match.")] - public string ConfirmPassword { get; set; } } } diff --git a/Marco.Pms.Model/Dtos/Util/EmailDot.cs b/Marco.Pms.Model/Dtos/Util/EmailDot.cs new file mode 100644 index 0000000..a09c921 --- /dev/null +++ b/Marco.Pms.Model/Dtos/Util/EmailDot.cs @@ -0,0 +1,11 @@ +namespace Marco.Pms.Model.Dtos.Util +{ + public class EmailDot + { + public string ToEmail { get; set; } + public string FromEmail { get; set; } + public string MailBody { get; set; } + public string MailSubject { get; set; } + + } +} diff --git a/Marco.Pms.Model/Employees/Employee.cs b/Marco.Pms.Model/Employees/Employee.cs index 303c995..7c8136b 100644 --- a/Marco.Pms.Model/Employees/Employee.cs +++ b/Marco.Pms.Model/Employees/Employee.cs @@ -15,11 +15,15 @@ namespace Marco.Pms.Model.Employees public string Gender { get; set; } public DateTime? BirthDate { get; set; } + public DateTime? JoiningDate { get; set; } + public string PeramnentAddress { 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; } @@ -34,6 +38,8 @@ namespace Marco.Pms.Model.Employees [DisplayName("TenantId")] public int TenantId { get; set; } + public bool IsActive { get; set; } = true; + [ValidateNever] [ForeignKey(nameof(TenantId))] public Tenant Tenant { get; set; } diff --git a/Marco.Pms.Model/Mapper/ApplicationRoleMapper.cs b/Marco.Pms.Model/Mapper/ApplicationRoleMapper.cs index 8468e3d..e2074ce 100644 --- a/Marco.Pms.Model/Mapper/ApplicationRoleMapper.cs +++ b/Marco.Pms.Model/Mapper/ApplicationRoleMapper.cs @@ -23,7 +23,6 @@ namespace Marco.Pms.Model.Mapper Id = new Guid(), Role = model.Role, Description = model.Description, - //FeaturePermissions = model.FeaturesPermission, TenantId = TenantId, }; } diff --git a/Marco.Pms.Model/Mapper/EmployeeMapper.cs b/Marco.Pms.Model/Mapper/EmployeeMapper.cs new file mode 100644 index 0000000..9290662 --- /dev/null +++ b/Marco.Pms.Model/Mapper/EmployeeMapper.cs @@ -0,0 +1,35 @@ +using Marco.Pms.Model.Employees; +using Marco.Pms.Model.ViewModels.Employee; + +namespace Marco.Pms.Model.Mapper +{ + public static class EmployeeMapper + { + public static EmployeeVM ToEmployeeVMFromEmployee(this Employee model) + { + return new EmployeeVM + { + Id = model.Id, + FirstName = model.FirstName, + LastName = model.LastName, + MiddleName = model.MiddleName, + 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, + PeramnentAddress = model.PeramnentAddress, + PhoneNumber = model.PhoneNumber, + Photo = model.Photo, + IsActive = model.IsActive, + JoiningDate = model.JoiningDate + }; + } + } +} diff --git a/Marco.Pms.Model/Mapper/ProjectMapper.cs b/Marco.Pms.Model/Mapper/ProjectMapper.cs index f48e026..6801a11 100644 --- a/Marco.Pms.Model/Mapper/ProjectMapper.cs +++ b/Marco.Pms.Model/Mapper/ProjectMapper.cs @@ -34,6 +34,19 @@ namespace Marco.Pms.Model.Mapper }; } + public static Project ToProjectFromUpdateProjectDto(this UpdateProjectDto projectModel, int TenantId) + { + return new Project + { + ContactPerson = projectModel.ContactPerson, + ProjectAddress = projectModel.ProjectAddress, + Name = projectModel.Name, + EndDate = projectModel.EndDate, + StartDate = projectModel.StartDate, + TenantId = TenantId, + ProjectStatusId = projectModel.ProjectStatusId + }; + } public static ProjectAllocation ToProjectAllocationFromProjectAllocationDto(this ProjectAllocationDot model, int TenantId) { @@ -41,7 +54,7 @@ namespace Marco.Pms.Model.Mapper { AllocationDate = DateTime.Now, EmployeeId = model.EmpID, - EmployeeRoleId = model.RoleID, + JobRoleId = model.JobRoleId, TenantId = TenantId, ProjectId = model.ProjectId }; diff --git a/Marco.Pms.Model/Projects/ProjectAllocation.cs b/Marco.Pms.Model/Projects/ProjectAllocation.cs index d7ef982..7752c1c 100644 --- a/Marco.Pms.Model/Projects/ProjectAllocation.cs +++ b/Marco.Pms.Model/Projects/ProjectAllocation.cs @@ -14,7 +14,7 @@ namespace Marco.Pms.Model.Projects [ValidateNever] public Employee Employee { get; set; } - public Guid? EmployeeRoleId { get; set; } + public int? JobRoleId { get; set; } //[ForeignKey("EmployeeRoleId")] //[ValidateNever] //public EmployeeRole EmployeeRole { get; set; } diff --git a/Marco.Pms.Model/ViewModels/Employee/EmployeeProfile.cs b/Marco.Pms.Model/ViewModels/Employee/EmployeeProfile.cs new file mode 100644 index 0000000..33e17b5 --- /dev/null +++ b/Marco.Pms.Model/ViewModels/Employee/EmployeeProfile.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Marco.Pms.Model.ViewModels.Employee +{ + public class EmployeeProfile + { + public EmployeeVM EmployeeInfo { get; set; } + public string[] Projects { get; set; } + public string[] FeaturePermissions { get; set; } + } +} diff --git a/Marco.Pms.Model/ViewModels/Employee/EmployeeVM.cs b/Marco.Pms.Model/ViewModels/Employee/EmployeeVM.cs new file mode 100644 index 0000000..0700a46 --- /dev/null +++ b/Marco.Pms.Model/ViewModels/Employee/EmployeeVM.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Marco.Pms.Model.ViewModels.Employee +{ + public class EmployeeVM + { + public int Id { get; set; } + public string FirstName { get; set; } + 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 PeramnentAddress { 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 bool IsActive { get; set; } = true; + public string? PanNumber { get; set; } + + public byte[]? Photo { get; set; } // To store the captured photo + + public string? ApplicationUserId { get; set; } + + public int? JobRoleId { get; set; } + public string JobRole { get; set; } + + } +} diff --git a/Marco.Pms.Services/Controllers/ActivityController.cs b/Marco.Pms.Services/Controllers/ActivityController.cs index 4acfb73..cab04af 100644 --- a/Marco.Pms.Services/Controllers/ActivityController.cs +++ b/Marco.Pms.Services/Controllers/ActivityController.cs @@ -1,14 +1,10 @@ using Marco.Pms.DataAccess.Data; -using Marco.Pms.DataAccess.Repository.IRepository; -using Marco.Pms.Model.Employees; using Marco.Pms.Model.Entitlements; -using MarcoBMS.Services.Service; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; -using Microsoft.EntityFrameworkCore; -namespace MarcoBMS.Services.Controllers +namespace ModelServices.Controllers { [Route("api/[controller]")] @@ -18,17 +14,13 @@ namespace MarcoBMS.Services.Controllers { private readonly ApplicationDbContext _context; private ApplicationUser _applicationUser; - private readonly IEmployeeRepository _empRepo; private readonly UserManager _userManager; - private readonly IEmailSender _emailSender; - public ActivityController(UserManager userManager, IEmailSender emailSender, IEmployeeRepository empRepo, ApplicationDbContext context) + public ActivityController(UserManager userManager, ApplicationDbContext context) { _context = context; - _empRepo = empRepo; _userManager = userManager; - _emailSender = emailSender; } //[HttpPost("checkin")] diff --git a/Marco.Pms.Services/Controllers/AttendanceController.cs b/Marco.Pms.Services/Controllers/AttendanceController.cs index c462f44..37b3471 100644 --- a/Marco.Pms.Services/Controllers/AttendanceController.cs +++ b/Marco.Pms.Services/Controllers/AttendanceController.cs @@ -1,5 +1,4 @@ using Marco.Pms.DataAccess.Data; -using Marco.Pms.DataAccess.Repository.IRepository; using Marco.Pms.Model.AttendanceModule; using Marco.Pms.Model.Dtos.Attendance; using Marco.Pms.Model.Employees; @@ -7,8 +6,6 @@ using Marco.Pms.Model.Projects; using Marco.Pms.Model.Utilities; using Marco.Pms.Model.ViewModels.Attendance; using MarcoBMS.Services.Helpers; -using MarcoBMS.Services.Service; -using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.CodeAnalysis; using Microsoft.EntityFrameworkCore; @@ -20,34 +17,26 @@ namespace MarcoBMS.Services.Controllers [Route("api/[controller]")] public class AttendanceController : ControllerBase { - private readonly IUnitOfWork _unitOfWork; private readonly ApplicationDbContext _context; - private readonly UserManager _userManager; - private readonly IEmailSender _emailSender; - private readonly IAttendenceRepository _attendenceRepository; private readonly EmployeeHelper _employeeHelper; - private readonly ProjectHelper _projectHelper; + private readonly ProjectsHelper _projectsHelper; + private readonly UserHelper _userHelper; - - - - public AttendanceController(UserManager userManager, IEmailSender emailSender, IEmployeeRepository empRepo, - IUnitOfWork unitOfWork, ApplicationDbContext context, IAttendenceRepository attendenceRepository, EmployeeHelper employeeHelper, ProjectHelper projectHelper) + public AttendanceController( + ApplicationDbContext context, EmployeeHelper employeeHelper, ProjectsHelper projectsHelper, UserHelper userHelper) { - _unitOfWork = unitOfWork; _context = context; - _userManager = userManager; - _emailSender = emailSender; - _attendenceRepository = attendenceRepository; _employeeHelper = employeeHelper; - _projectHelper = projectHelper; + _projectsHelper = projectsHelper; + _userHelper = userHelper; } private int GetTenantId() { - var tenant = User.FindFirst("TenantId")?.Value; - return (tenant != null ? Convert.ToInt32(tenant) : 1); + return _userHelper.GetTenantId(); + //var tenant = User.FindFirst("TenantId")?.Value; + //return (tenant != null ? Convert.ToInt32(tenant) : 1); } private int GetUserId() { @@ -91,18 +80,25 @@ namespace MarcoBMS.Services.Controllers /// ProjectID /// YYYY-MM-dd /// - [HttpGet("project/team")] + [HttpGet("project/log")] - public async Task EmployeeAttendanceByProject([FromQuery] int projectId, [FromQuery] string? date = null) + public async Task EmployeeAttendanceByDateRange([FromQuery] int projectId, [FromQuery] string? dateFrom = null, [FromQuery] string? dateTo = null) { int TenantId = GetUserId(); - DateTime forDate = new DateTime(); + DateTime fromDate = new DateTime(); + DateTime toDate = new DateTime(); - if (date != null && DateTime.TryParse(date, out forDate) == false) + if (dateFrom != null && DateTime.TryParse(dateFrom, out fromDate) == false) { - return StatusCode(400, ApiResponse.SuccessResponse(date, "Invalid Date", 400));// new { error = ex.Message }); + return StatusCode(400, ApiResponse.SuccessResponse(dateFrom, "Invalid Date", 400));// new { error = ex.Message }); } + if (dateTo != null && DateTime.TryParse(dateTo, out toDate) == false) + { + return StatusCode(400, ApiResponse.SuccessResponse(dateTo, "Invalid Date", 400));// new { error = ex.Message }); + + } + if (projectId <= 0) { return BadRequest("Project ID is required and must be greater than zero."); @@ -111,12 +107,14 @@ namespace MarcoBMS.Services.Controllers var result = new List(); Attendance attendance = null; - if (date == null) forDate = DateTime.UtcNow.Date; - - List lstAttendance = await _context.Attendes.Where(c => c.ProjectID == projectId && c.AttendanceDate.Date == forDate && c.TenantId == TenantId).ToListAsync(); + if (dateFrom == null) fromDate = DateTime.UtcNow.Date; + if (dateTo == null && dateFrom != null) toDate = fromDate.AddDays(-1); - List projectteam = await _projectHelper.GetTeamByProject(TenantId, projectId, true); + List lstAttendance = await _context.Attendes.Where(c => c.ProjectID == projectId && c.AttendanceDate.Date <= fromDate && c.AttendanceDate.Date >= toDate && c.TenantId == TenantId).ToListAsync(); + + + List projectteam = await _projectsHelper.GetTeamByProject(TenantId, projectId, true); foreach (ProjectAllocation teamMember in projectteam) { @@ -143,6 +141,68 @@ namespace MarcoBMS.Services.Controllers return Ok(ApiResponse.SuccessResponse(result, System.String.Format("{0} Attendance records fetched successfully", result.Count), 200)); } + /// + /// + /// + /// ProjectID + /// YYYY-MM-dd + /// + [HttpGet("project/team")] + + public async Task EmployeeAttendanceByProject([FromQuery] int projectId, [FromQuery] string? date = null) + { + int TenantId = GetUserId(); + DateTime forDate = new DateTime(); + + if (date != null && DateTime.TryParse(date, out forDate) == false) + { + return StatusCode(400, ApiResponse.SuccessResponse(date, "Invalid Date", 400));// new { error = ex.Message }); + + } + if (projectId <= 0) + { + return BadRequest("Project ID is required and must be greater than zero."); + } + + var result = new List(); + Attendance attendance = null; + + if (date == null) forDate = DateTime.UtcNow.Date; + + List lstAttendance = await _context.Attendes.Where(c => c.ProjectID == projectId && c.AttendanceDate.Date == forDate && c.TenantId == TenantId).ToListAsync(); + + + List projectteam = await _projectsHelper.GetTeamByProject(TenantId, projectId, true); + foreach (ProjectAllocation teamMember in projectteam) + { + + var result1 = new EmployeeAttendanceVM() + { + EmployeeAvatar = null, + EmployeeId = teamMember.EmployeeId, + FirstName = teamMember.Employee.FirstName, + LastName = teamMember.Employee.LastName + }; + + attendance = lstAttendance.Find(x => x.EmployeeID == teamMember.EmployeeId); + if (attendance != null) + { + result1.Id = attendance.Id; + result1.CheckInTime = attendance.InTime; + result1.CheckOutTime = attendance.OutTime; + result1.Activity = attendance.Activity; + } + + result.Add(result1); + } + + result.Sort(delegate (EmployeeAttendanceVM x, EmployeeAttendanceVM y) { + return x.FirstName.CompareTo(y.FirstName); + }); + + return Ok(ApiResponse.SuccessResponse(result, System.String.Format("{0} Attendance records fetched successfully", result.Count), 200)); + } + [HttpPost] [Route("record")] @@ -159,7 +219,7 @@ namespace MarcoBMS.Services.Controllers Attendance attendance = await _context.Attendes.FirstOrDefaultAsync(a => a.EmployeeID == recordAttendanceDot.EmployeeID && a.AttendanceDate.Date == recordAttendanceDot.Date.Date && a.TenantId == TenantId); ; - + if (attendance != null) { attendance.Comment = recordAttendanceDot.Comment; @@ -210,7 +270,7 @@ namespace MarcoBMS.Services.Controllers attendance = new Attendance(); attendance.TenantId = TenantId; attendance.AttendanceDate = recordAttendanceDot.Date; - // attendance.Activity = recordAttendanceDot.Action; + // attendance.Activity = recordAttendanceDot.Action; attendance.Comment = recordAttendanceDot.Comment; attendance.EmployeeID = recordAttendanceDot.EmployeeID; attendance.ProjectID = recordAttendanceDot.ProjectID; diff --git a/Marco.Pms.Services/Controllers/AuthController.cs b/Marco.Pms.Services/Controllers/AuthController.cs index d722b2a..2259142 100644 --- a/Marco.Pms.Services/Controllers/AuthController.cs +++ b/Marco.Pms.Services/Controllers/AuthController.cs @@ -1,10 +1,18 @@ using Marco.Pms.Model.Authentication; using Marco.Pms.Model.Dtos; +using Marco.Pms.Model.Dtos.Util; +using Marco.Pms.Model.Employees; +using Marco.Pms.Model.Entitlements; +using Marco.Pms.Model.Utilities; +using Marco.Pms.Model.ViewModels.Employee; +using MarcoBMS.Services.Helpers; using MarcoBMS.Services.Service; using Microsoft.AspNetCore.Cors; using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Identity.Data; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; +using System.Net; namespace MarcoBMS.Services.Controllers { @@ -15,12 +23,19 @@ namespace MarcoBMS.Services.Controllers private readonly UserManager _userManager; private readonly JwtSettings _jwtSettings; private readonly RefreshTokenService _refreshTokenService; - string tenentId = "1"; - public AuthController(UserManager userManager, JwtSettings jwtSettings, RefreshTokenService refreshTokenService) + private readonly IEmailSender _emailSender; + private readonly IConfiguration _configuration; + private readonly EmployeeHelper _employeeHelper; + //string tenentId = "1"; + public AuthController(UserManager userManager, JwtSettings jwtSettings, RefreshTokenService refreshTokenService, + IEmailSender emailSender, IConfiguration configuration, EmployeeHelper employeeHelper) { _userManager = userManager; _jwtSettings = jwtSettings; _refreshTokenService = refreshTokenService; + _emailSender = emailSender; + _configuration = configuration; + _employeeHelper = employeeHelper; } [HttpPost("login")] @@ -29,20 +44,21 @@ namespace MarcoBMS.Services.Controllers var user = await _userManager.FindByEmailAsync(loginDto.Username); var user1 = await _userManager.Users.FirstOrDefaultAsync(u => u.Email == loginDto.Username || u.PhoneNumber == loginDto.Username); - + if (user == null || !await _userManager.CheckPasswordAsync(user, loginDto.Password)) { return Unauthorized("Invalid username or password."); } - var token = _refreshTokenService.GenerateJwtToken(user.UserName, tenentId, _jwtSettings); - + Employee emp = await _employeeHelper.GetEmployeeByApplicationUserID(user.Id); //var refreshToken = GenerateRefreshToken(); - var refreshToken = await _refreshTokenService.CreateRefreshToken(user.Id, tenentId, _jwtSettings); + var token = _refreshTokenService.GenerateJwtToken(user.UserName, emp.TenantId.ToString(), _jwtSettings); - return Ok(new { token, refreshToken }); + var refreshToken = await _refreshTokenService.CreateRefreshToken(user.Id, emp.TenantId.ToString(), _jwtSettings); + + return Ok(ApiResponse.SuccessResponse(new { token = token, refreshToken = refreshToken }, "User logged in successfully.", 200)); } [HttpPost("logout")] @@ -72,7 +88,7 @@ namespace MarcoBMS.Services.Controllers } catch (Exception ex) { - // _logger.LogError(ex, "Error during logout"); + // _logger.LogError(ex, "Error during logout"); return StatusCode(500, new { Message = "Internal server error" }); } } @@ -106,10 +122,15 @@ namespace MarcoBMS.Services.Controllers // Generate new JWT token and refresh token var user = await _userManager.FindByIdAsync(refreshToken.UserId); - var newJwtToken = _refreshTokenService.GenerateJwtToken(user.UserName, tenentId, _jwtSettings); - var newRefreshToken = await _refreshTokenService.CreateRefreshToken(user.Id, tenentId, _jwtSettings); + if (user == null) + return BadRequest("Invalid request."); - return Ok(new { token = newJwtToken, refreshToken = newRefreshToken }); + Employee emp = await _employeeHelper.GetEmployeeByApplicationUserID(user.Id); + + var newJwtToken = _refreshTokenService.GenerateJwtToken(user.UserName, emp.TenantId.ToString(), _jwtSettings); + var newRefreshToken = await _refreshTokenService.CreateRefreshToken(user.Id, emp.TenantId.ToString(), _jwtSettings); + + return Ok(ApiResponse.SuccessResponse(new { token = newJwtToken, refreshToken = newRefreshToken }, "User refresh token generated successfully.", 200)); } [HttpPost("forgot-password")] @@ -118,10 +139,72 @@ namespace MarcoBMS.Services.Controllers var user = await _userManager.FindByEmailAsync(forgotPasswordDto.Email); if (user == null) return NotFound("User not found."); + /* SEND USER REGISTRATION MAIL*/ var token = await _userManager.GeneratePasswordResetTokenAsync(user); + var resetLink = $"{_configuration["AppSettings:WebFrontendUrl"]}/reset-password?token={WebUtility.UrlEncode(token)}"; + await _emailSender.SendResetPasswordEmail(user.Email, "", resetLink); + + + return Ok(ApiResponse.SuccessResponse(true, "Password reset link sent.", 200)); + } + + [HttpPost("reset-password")] + public async Task ResetPassword([FromBody] ResetPasswordDto model) + { + var user = await _userManager.FindByEmailAsync(model.Email); + if (user == null) + return BadRequest("Invalid request."); + + // var isTokenValid = await _userManager.VerifyUserTokenAsync(user,UserManager.ResetPasswordTokenPurpose, model.ResetCode); + var isTokenValid = await _userManager.VerifyUserTokenAsync( + user, + TokenOptions.DefaultProvider, // This is the token provider + UserManager.ResetPasswordTokenPurpose, + WebUtility.UrlDecode( model.Token) + ); + + + if (!isTokenValid) + return BadRequest("Invalid or expired token."); + + var result = await _userManager.ResetPasswordAsync(user, WebUtility.UrlDecode(model.Token), model.NewPassword); + if (!result.Succeeded) + return BadRequest(result.Errors); + + return Ok(ApiResponse.SuccessResponse(result.Succeeded, "Password reset successfully.", 200)); + } + + + + [HttpPost("sendmail")] + public async Task SendEmail([FromBody] EmailDot emailDot) + { + + + + var user = await _userManager.FindByEmailAsync(emailDot.ToEmail); + if (user == null) + { + return BadRequest("User not found."); + } + + /* New User*/ + //var token = await _userManager.GeneratePasswordResetTokenAsync(user); + //var resetLink = $"{_configuration["AppSettings:WebFrontendUrl"]}/reset-password?token={WebUtility.UrlEncode(token)}"; + + //await _emailSender.SendResetPasswordEmailOnRegister(emailDot.ToEmail, "Vikas", resetLink); + + + /* Forget password*/ + // var token = await _userManager.GeneratePasswordResetTokenAsync(user); + + var token = await _userManager.GenerateUserTokenAsync(user, TokenOptions.DefaultProvider, "ResetPassword"); + + var isTokenValid = await _userManager.VerifyUserTokenAsync(user, TokenOptions.DefaultProvider, "ResetPassword", token); + + var resetLink = $"{_configuration["AppSettings:WebFrontendUrl"]}/reset-password?token={WebUtility.UrlEncode(token)}"; + await _emailSender.SendResetPasswordEmail(user.Email, "", resetLink); - // Send token via email (implementation omitted) - // ... return Ok("Password reset link sent."); } diff --git a/Marco.Pms.Services/Controllers/EmployeeController.cs b/Marco.Pms.Services/Controllers/EmployeeController.cs index 18d3924..933a402 100644 --- a/Marco.Pms.Services/Controllers/EmployeeController.cs +++ b/Marco.Pms.Services/Controllers/EmployeeController.cs @@ -1,17 +1,19 @@ using Marco.Pms.DataAccess.Data; -using Marco.Pms.DataAccess.Repository.IRepository; using Marco.Pms.Model.Dtos.Employees; using Marco.Pms.Model.Employees; using Marco.Pms.Model.Entitlements; using Marco.Pms.Model.Mapper; using Marco.Pms.Model.Utilities; using Marco.Pms.Model.ViewModels; +using Marco.Pms.Model.ViewModels.Employee; +using MarcoBMS.Services.Helpers; using MarcoBMS.Services.Service; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using System.Data; +using System.Net; namespace MarcoBMS.Services.Controllers { @@ -22,18 +24,23 @@ namespace MarcoBMS.Services.Controllers public class EmployeeController : ControllerBase { - private readonly IUnitOfWork _unitOfWork; private readonly ApplicationDbContext _context; private readonly UserManager _userManager; private readonly IEmailSender _emailSender; + private readonly EmployeeHelper _employeeHelper; + private readonly UserHelper _userHelper; + private readonly IConfiguration _configuration; - public EmployeeController(UserManager userManager, IEmailSender emailSender, IEmployeeRepository empRepo, IUnitOfWork unitOfWork, ApplicationDbContext context) + public EmployeeController(UserManager userManager, IEmailSender emailSender, + ApplicationDbContext context, EmployeeHelper employeeHelper, UserHelper userHelper, IConfiguration configuration) { - _unitOfWork = unitOfWork; _context = context; _userManager = userManager; _emailSender = emailSender; + _employeeHelper = employeeHelper; + _userHelper = userHelper; + _configuration = configuration; } [HttpGet] @@ -89,7 +96,7 @@ namespace MarcoBMS.Services.Controllers if (existingItem == null) { - + _context.EmployeeRoleMappings.Add(mapping); } else @@ -99,11 +106,25 @@ namespace MarcoBMS.Services.Controllers } await _context.SaveChangesAsync(); } - catch (Exception ex) { + catch (Exception ex) + { } return Ok(ApiResponse.SuccessResponse("success", "Roles modified.", 200)); } + [HttpGet] + [Route("list/{projectid?}")] + public async Task GetEmployeesByProject(int? projectid) + { + if (!ModelState.IsValid) + { + return BadRequest(ModelState); + } + var result = await _employeeHelper.GetEmployeeByProjectId(GetTenantId(), projectid); + + return Ok(ApiResponse.SuccessResponse(result, "Filter applied.", 200)); + + } [HttpGet] [Route("search/{name}/{projectid?}")] public async Task SearchEmployee(string name, int? projectid) @@ -112,98 +133,37 @@ namespace MarcoBMS.Services.Controllers { return BadRequest(ModelState); } - int TenantId = GetTenantId(); - name = name.ToLower(); - int tenantId = GetTenantId(); - List employees = await _unitOfWork.Employee.GetAsync(c => c.TenantId == tenantId && (c.FirstName.ToLower().StartsWith(name) - || c.MiddleName.ToLower().StartsWith(name) || c.LastName.ToLower().StartsWith(name))); - - - employees = employees.Where(c => c.FirstName.ToLower().StartsWith(name) - || c.MiddleName.ToLower().StartsWith(name) || c.LastName.ToLower().StartsWith(name)).ToList(); - - if (projectid != null) - { - // conditions to e checked after project assignment - } - return Ok(ApiResponse.SuccessResponse(employees, "Filter applied.", 200)); + var result = await _employeeHelper.SearchEmployeeByProjectId(GetTenantId(), name.ToLower(), projectid); + return Ok(ApiResponse.SuccessResponse(result, "Filter applied.", 200)); } [HttpGet] - [Route("get/{projectid?}")] - public async Task GetEmployee(int? projectid) + [Route("profile/get/{employeeId}")] + public async Task GetEmployeeProfileById(int employeeId) { if (!ModelState.IsValid) { return BadRequest(ModelState); } - int TenantId = GetTenantId(); - List employees = await _unitOfWork.Employee.GetAsync(c => c.TenantId == TenantId); + Employee emp = await _employeeHelper.GetEmployeeByID(employeeId); + EmployeeVM employeeVM = EmployeeMapper.ToEmployeeVMFromEmployee(emp); - employees = employees.Where(c => c.TenantId == TenantId).ToList(); - - if (projectid != null) - { - // Fetch assigned project - } - - return Ok(employees); + return Ok(ApiResponse.SuccessResponse(employeeVM, "Employee Profile.", 200)); } - //[HttpGet] - //[Route("attendance/project/{projectid?}")] - //public async Task GetAttendanceList(int? projectid) - //{ - // if (!ModelState.IsValid) - // { - // return BadRequest(ModelState); - // } - // int TenantId = GetTenantId(); - - - // DateTime today = DateTime.Today; - - // var result = from employee in _context.ProjectAllocations - // join attendance in _context.Attendances - // on employee.Id equals attendance.EmployeeID into attendanceGroup - // from todayAttendance in attendanceGroup - // //.Where(a => a.InTimeLog.InTime == today) - // .DefaultIfEmpty() // LEFT JOIN - // select new - // { - // ProjectID = projectid, - // EmployeeId = employee.Id, - // FirstName = employee.Employee.FirstName, - // MiddleName = employee.Employee.MiddleName, - // LastName = employee.Employee.LastName, - // PhoneNumber = employee.Employee.PhoneNumber, - // RoleId = employee.Employee.JobRoleId, - // //InTime = todayAttendance.InTimeLog != null ? todayAttendance.InTimeLog.InTime : (DateTime?)null, - // //OutTime = todayAttendance.OutTimeLog != null ? todayAttendance.OutTimeLog.OutTime : (DateTime?)null, - // // WorkShift = todayAttendance.WorkShift, - // Latitude = todayAttendance.InTimeLog != null ? todayAttendance.InTimeLog.Latitude : null, - // Longitude = todayAttendance.InTimeLog != null ? todayAttendance.InTimeLog.Longitude : null, - // Comment = todayAttendance.Comment, - // }; - - - - // return Ok(result); - - //} private int GetTenantId() { - var tenant = User.FindFirst("TenantId")?.Value; - return (tenant != null ? Convert.ToInt32(tenant) : 1); + return _userHelper.GetTenantId(); } - [HttpPost("manage/quick")] - public async Task CreateQuickUser([FromBody] CreateQuickUserDto model) - { - return Ok("Pending implementation"); - } + //[HttpPost("manage/quick")] + //public async Task CreateQuickUser([FromBody] CreateQuickUserDto model) + //{ + // return Ok("Pending implementation"); + //} + [HttpPost("manage")] public async Task CreateUser([FromForm] CreateUserDto model) { @@ -211,144 +171,138 @@ namespace MarcoBMS.Services.Controllers return BadRequest("Invalid user data."); int TenantId = GetTenantId(); + string responsemessage = ""; + if (model.Email != null) { // Check if user already exists by email - var existingUser = await _userManager.FindByEmailAsync(model.Email); + IdentityUser? existingUser = await _userHelper.GetRegisteredUser(model.Email); if (existingUser != null) { - // Update existing user - //existingUser.Email = model.Email; // No need to update email - - //var updateResult = await _userManager.UpdateAsync(existingUser); - //if (!updateResult.Succeeded) - // return BadRequest(updateResult.Errors); + /* Identity user Exists - Create/update employee Employee */ // Update Employee record - var existingEmployee = await _context.Employees.FirstOrDefaultAsync(e => e.ApplicationUserId == existingUser.Id); + var existingEmployee = await _context.Employees.FirstOrDefaultAsync(e => e.ApplicationUserId == existingUser.Id || e.Email == model.Email || e.Id == model.Id); if (existingEmployee != null) { - existingEmployee.FirstName = model.FirstName; - existingEmployee.LastName = model.LastName; - existingEmployee.TenantId = TenantId; - existingEmployee.Email = model.Email; - existingEmployee.JobRoleId = Convert.ToInt32(model.JobRoleId); + existingEmployee = GetUpdateEmployeeModel(model, existingEmployee, existingUser); _context.Employees.Update(existingEmployee); } else { // Create Employee record if missing - var newEmployee = new Employee - { - ApplicationUserId = existingUser.Id, - FirstName = model.FirstName, - LastName = model.LastName, - Email = model.Email, - TenantId = TenantId, - CurrentAddress = model.CurrentAddress, - BirthDate = Convert.ToDateTime(model.BirthDate), - EmergencyPhoneNumber = model.EmergencyPhoneNumber, - AadharNumber = model.AadharNumber, - Gender = model.Gender, - MiddleName = model.MiddleName, - PanNumber = model.PanNumber, - PeramnentAddress = model.PeramnentAddress, - PhoneNumber = model.PhoneNumber, - Photo = GetFileDetails(model.Photo).Result.FileData, - JobRoleId = Convert.ToInt32(model.JobRoleId) - - }; + Employee newEmployee = GetNewEmployeeModel(model, TenantId, existingUser.Id); _context.Employees.Add(newEmployee); } await _context.SaveChangesAsync(); - return Ok(new { message = "User updated successfully." }); + responsemessage = "User updated successfully."; } - - var user = new ApplicationUser + else { - UserName = model.Email, - Email = model.Email, - EmailConfirmed = true - }; + var user = new ApplicationUser + { + UserName = model.Email, + Email = model.Email, + EmailConfirmed = true + }; - // Create Identity User - var result = await _userManager.CreateAsync(user, "User@123"); - if (!result.Succeeded) - return BadRequest(result.Errors); + // Create Identity User + var result = await _userManager.CreateAsync(user, "User@123"); + if (!result.Succeeded) + return BadRequest(result.Errors); - // Save Employee Data - var employee = new Employee - { - FirstName = model.FirstName, - LastName = model.LastName, - Email = model.Email, - TenantId = TenantId, - CurrentAddress = model.CurrentAddress, - BirthDate = Convert.ToDateTime(model.BirthDate), - EmergencyPhoneNumber = model.EmergencyPhoneNumber, - AadharNumber = model.AadharNumber, - Gender = model.Gender, - MiddleName = model.MiddleName, - PanNumber = model.PanNumber, - PeramnentAddress = model.PeramnentAddress, - PhoneNumber = model.PhoneNumber, - Photo = GetFileDetails(model.Photo).Result.FileData, - JobRoleId = Convert.ToInt32(model.JobRoleId) - }; - _context.Employees.Add(employee); - await _context.SaveChangesAsync(); + Employee newEmployee = GetNewEmployeeModel(model, TenantId, user.Id); + _context.Employees.Add(newEmployee); - var token = await _userManager.GeneratePasswordResetTokenAsync(user); - var resetLink = Url.Action("ResetPassword", "Account", new { token, email = user.Email }, Request.Scheme); + await _context.SaveChangesAsync(); - // Send Email - await _emailSender.SendEmailAsync(user.Email, "Set Password", $"Click here to set your password: {resetLink}"); + + /* SEND USER REGISTRATION MAIL*/ + var token = await _userManager.GeneratePasswordResetTokenAsync(user); + var resetLink = $"{_configuration["AppSettings:WebFrontendUrl"]}/reset-password?token={WebUtility.UrlEncode(token)}"; + await _emailSender.SendResetPasswordEmailOnRegister(user.Email, newEmployee.FirstName, resetLink); + + responsemessage = "User created successfully. PAssword reset link is sent to registered email"; + } } else { var existingEmployee = await _context.Employees.FirstOrDefaultAsync(e => e.Id == model.Id); if (existingEmployee != null) { - existingEmployee.FirstName = model.FirstName; - existingEmployee.LastName = model.LastName; - existingEmployee.TenantId = TenantId; - + existingEmployee = GetUpdateEmployeeModel(model, existingEmployee); _context.Employees.Update(existingEmployee); + responsemessage = "User updated successfully."; } else { // Create Employee record if missing - var newEmployee = new Employee - { - ApplicationUserId = null, - FirstName = model.FirstName, - LastName = model.LastName, - TenantId = TenantId, - CurrentAddress = model.CurrentAddress, - BirthDate = Convert.ToDateTime(model.BirthDate), - EmergencyPhoneNumber = model.EmergencyPhoneNumber, - AadharNumber = model.AadharNumber, - Gender = model.Gender, - MiddleName = model.MiddleName, - PanNumber = model.PanNumber, - PeramnentAddress = model.PeramnentAddress, - PhoneNumber = model.PhoneNumber, - Photo = GetFileDetails(model.Photo).Result.FileData + Employee newEmployee = GetNewEmployeeModel(model, TenantId, null); - }; _context.Employees.Add(newEmployee); } await _context.SaveChangesAsync(); + responsemessage = "User created successfully."; + } - // Generate Password Reset Link + return Ok(new { message = responsemessage }); + } + private static Employee GetNewEmployeeModel(CreateUserDto model, int TenantId, string? ApplicationUserId) + { + var newEmployee = new Employee + { + ApplicationUserId = ApplicationUserId, + FirstName = model.FirstName, + LastName = model.LastName, + Email = model.Email, + TenantId = TenantId, + CurrentAddress = model.CurrentAddress, + BirthDate = Convert.ToDateTime(model.BirthDate), + EmergencyPhoneNumber = model.EmergencyPhoneNumber, + EmergencyContactPerson = model.EmergencyContactPerson, + AadharNumber = model.AadharNumber, + Gender = model.Gender, + MiddleName = model.MiddleName, + PanNumber = model.PanNumber, + PeramnentAddress = model.PeramnentAddress, + PhoneNumber = model.PhoneNumber, + Photo = null, // GetFileDetails(model.Photo).Result.FileData, + JobRoleId = Convert.ToInt32(model.JobRoleId), + JoiningDate = Convert.ToDateTime(model.JoiningDate), - return Ok(new { message = "User created successfully. Password reset link sent." }); + }; + return newEmployee; + } + + private static Employee GetUpdateEmployeeModel(CreateUserDto model, Employee existingEmployee, IdentityUser? existingIdentityUser = null) + { + if (existingEmployee.ApplicationUserId == null && existingIdentityUser != null) + { + existingEmployee.ApplicationUserId = existingIdentityUser.Id; + } + existingEmployee.FirstName = model.FirstName; + existingEmployee.LastName = model.LastName; + existingEmployee.CurrentAddress = model.CurrentAddress; + existingEmployee.BirthDate = Convert.ToDateTime(model.BirthDate); + existingEmployee.JoiningDate = Convert.ToDateTime(model.JoiningDate); + existingEmployee.EmergencyPhoneNumber = model.EmergencyPhoneNumber; + existingEmployee.EmergencyContactPerson = model.EmergencyContactPerson; + existingEmployee.AadharNumber = model.AadharNumber; + existingEmployee.Gender = model.Gender; + existingEmployee.MiddleName = model.MiddleName; + existingEmployee.PanNumber = model.PanNumber; + existingEmployee.PeramnentAddress = model.PeramnentAddress; + existingEmployee.PhoneNumber = model.PhoneNumber; + existingEmployee.Photo = null; // GetFileDetails(model.Photo).Result.FileData, + existingEmployee.JobRoleId = Convert.ToInt32(model.JobRoleId); + + return existingEmployee; } private static async Task GetFileDetails(IFormFile file) diff --git a/Marco.Pms.Services/Controllers/FileController.cs b/Marco.Pms.Services/Controllers/FileController.cs index ab77138..ffec508 100644 --- a/Marco.Pms.Services/Controllers/FileController.cs +++ b/Marco.Pms.Services/Controllers/FileController.cs @@ -40,16 +40,16 @@ namespace MarcoBMS.Services.Controllers return imageName; } - [HttpPost("manage1")] - public async Task CreateUser_1([FromForm] CreateUserDto model) - { - if (model == null) - return BadRequest("Invalid user data."); + //[HttpPost("manage1")] + //public async Task CreateUser_1([FromForm] CreateUserDto model) + //{ + // if (model == null) + // return BadRequest("Invalid user data."); - await GetFileDetails(model.Photo); + // await GetFileDetails(model.Photo); - return Ok(new { message = "User created successfully. Password reset link sent." }); - } + // return Ok(new { message = "User created successfully. Password reset link sent." }); + //} private static async Task GetFileDetails(IFormFile file) { diff --git a/Marco.Pms.Services/Controllers/ProjectController.cs b/Marco.Pms.Services/Controllers/ProjectController.cs index 8b0fecd..4ca7a23 100644 --- a/Marco.Pms.Services/Controllers/ProjectController.cs +++ b/Marco.Pms.Services/Controllers/ProjectController.cs @@ -1,6 +1,4 @@ using Marco.Pms.DataAccess.Data; -using Marco.Pms.DataAccess.Repository; -using Marco.Pms.DataAccess.Repository.IRepository; using Marco.Pms.Model.Activities; using Marco.Pms.Model.Dtos.Project; using Marco.Pms.Model.Employees; @@ -9,6 +7,8 @@ using Marco.Pms.Model.Mapper; using Marco.Pms.Model.Projects; using Marco.Pms.Model.Utilities; using Marco.Pms.Model.ViewModels; +using Marco.Pms.Model.ViewModels.Employee; +using MarcoBMS.Services.Helpers; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; @@ -21,19 +21,21 @@ namespace MarcoBMS.Services.Controllers [Authorize] public class ProjectController : ControllerBase { - private readonly IUnitOfWork _unitOfWork; + //private readonly IUnitOfWork _unitOfWork; private readonly ApplicationDbContext _context; private ApplicationUser _applicationUser; - private readonly IProjectRepository _projectrepo; + // private readonly IProjectRepository _projectrepo; private readonly UserManager _userManager; + private readonly UserHelper _userHelper; - public ProjectController(UserManager userManager, IProjectRepository projectrepo, IUnitOfWork unitOfWork, ApplicationDbContext context) + + public ProjectController(UserManager userManager, ApplicationDbContext context, UserHelper userHelper) { - _unitOfWork = unitOfWork; + //_unitOfWork = unitOfWork; _context = context; - _projectrepo = projectrepo; + //_projectrepo = projectrepo; _userManager = userManager; - + _userHelper = userHelper; } [HttpGet("list")] public async Task GetAll() @@ -42,8 +44,7 @@ namespace MarcoBMS.Services.Controllers { return BadRequest(ModelState); } - List project = await _projectrepo.GetAllAsync(); - // var commentDto = comments.Select(x => x.ToCommentDto()); + List project = await _context.Projects.Where(c=>c.TenantId == _userHelper.GetTenantId()).ToListAsync(); return Ok(project); } @@ -56,9 +57,7 @@ namespace MarcoBMS.Services.Controllers return BadRequest(ModelState); } - var project = _projectrepo.Get(c => c.Id == id); //_context.Stock.FindAsync(id); - - // List project = await _projectrepo.GetAsync(id); + var project = await _context.Projects.Where(c => c.TenantId == _userHelper.GetTenantId() && c.Id == id).SingleOrDefaultAsync(); return Ok(project); } @@ -73,19 +72,17 @@ namespace MarcoBMS.Services.Controllers return BadRequest(ModelState); } - var projects = await _projectrepo.GetAsync((c => c.Id == id), includeProperties: "ProjectStatus,Tenant"); //_context.Stock.FindAsync(id); + var project = await _context.Projects.Where(c => c.TenantId == _userHelper.GetTenantId() && c.Id == id).Include(c=> c.ProjectStatus).SingleOrDefaultAsync(); // includeProperties: "ProjectStatus,Tenant"); //_context.Stock.FindAsync(id); - if (projects == null) + if (project == null) { - //vm.project = new Project(); - //vm.buildings = new List(); - //vm.floors = new List(); - //vm.workAreas = new List(); + return Ok(new ProjectVM()); + } else { - var project = projects.Where(c => c.Id == id).SingleOrDefault(); - ProjectDetailsVM vm = GetProjectViewModel(id, project); + //var project = projects.Where(c => c.Id == id).SingleOrDefault(); + ProjectDetailsVM vm = await GetProjectViewModel(id, project); ProjectVM projectVM = new ProjectVM(); projectVM.Id = vm.project.Id; @@ -132,25 +129,26 @@ namespace MarcoBMS.Services.Controllers return Ok(projectVM); } - return Ok(new ProjectVM()); + } - private ProjectDetailsVM GetProjectViewModel(int? id, Project project) + private async Task GetProjectViewModel(int? id, Project project) { ProjectDetailsVM vm = new ProjectDetailsVM(); // List buildings = _unitOfWork.Building.GetAll(c => c.ProjectId == id).ToList(); - List buildings = _context.Buildings.Where(c => c.ProjectId == id).ToList(); + List buildings = await _context.Buildings.Where(c => c.ProjectId == id).ToListAsync(); List idList = buildings.Select(o => o.Id).ToList(); // List floors = _unitOfWork.Floor.GetAll(c => idList.Contains(c.Id)).ToList(); - List floors = _context.Floor.Where(c => idList.Contains(c.BuildingId)).ToList(); + List floors = await _context.Floor.Where(c => idList.Contains(c.BuildingId)).ToListAsync(); idList = floors.Select(o => o.Id).ToList(); //List workAreas = _unitOfWork.WorkArea.GetAll(c => idList.Contains(c.Id), includeProperties: "WorkItems,WorkItems.ActivityMaster").ToList(); - List workAreas = _context.WorkAreas.Where(c => idList.Contains(c.FloorId)).ToList(); + List workAreas = await _context.WorkAreas.Where(c => idList.Contains(c.FloorId)).ToListAsync(); idList = floors.Select(o => o.Id).ToList(); - List workItems = _unitOfWork.WorkItem.GetAll(c => idList.Contains(c.WorkAreaId), includeProperties: "ActivityMaster").ToList(); + List workItems = await _context.WorkItems.Where(c => idList.Contains(c.WorkAreaId)).Include(c=>c.ActivityMaster).ToListAsync(); + // List workItems = _unitOfWork.WorkItem.GetAll(c => idList.Contains(c.WorkAreaId), includeProperties: "ActivityMaster").ToList(); vm.project = project; vm.buildings = buildings; @@ -163,8 +161,9 @@ namespace MarcoBMS.Services.Controllers private int GetTenantId() { - var tenant = User.FindFirst("TenantId")?.Value; - return (tenant != null ? Convert.ToInt32(tenant) : 1); + return _userHelper.GetTenantId(); + //var tenant = User.FindFirst("TenantId")?.Value; + //return (tenant != null ? Convert.ToInt32(tenant) : 1); } [HttpPost] @@ -176,26 +175,13 @@ namespace MarcoBMS.Services.Controllers } int TenantId = GetTenantId(); - var projectModel = projectDto.ToProjectFromCreateProjectDto(TenantId); + var project = projectDto.ToProjectFromCreateProjectDto(TenantId); - var result = await _projectrepo.CreateAsync(projectModel); + _context.Projects.Add(project); - return Ok(result); + await _context.SaveChangesAsync(); - } - - [HttpGet("get-allocation/{projectId:int}")] - public async Task GetAllocation([FromRoute] int projectId) - { - if (!ModelState.IsValid) - { - return BadRequest(ModelState); - } - - List allocations = await _unitOfWork.ProjectAllocation.GetAsync(c => c.ProjectId == projectId); - allocations = allocations.Where(c => c.ProjectId == projectId).ToList(); - - return Ok(allocations); + return Ok(ApiResponse.SuccessResponse(project.ToProjectDto(), "Success.", 200)); } [HttpPut] @@ -210,13 +196,14 @@ namespace MarcoBMS.Services.Controllers { int TenantId = GetTenantId(); updateProjectDto.TenantId = TenantId; - var projectModel = await _projectrepo.UpdateAsync(id, updateProjectDto); - if (projectModel == null) - { - return NotFound("Project not found"); - } - return Ok(projectModel.ToProjectDto()); + Project project = updateProjectDto.ToProjectFromUpdateProjectDto(TenantId); + _context.Projects.Update(project); + + await _context.SaveChangesAsync(); + + return Ok(ApiResponse.SuccessResponse(project.ToProjectDto(), "Success.", 200)); + } catch (Exception ex) { @@ -225,49 +212,96 @@ namespace MarcoBMS.Services.Controllers } - [HttpPost("assign-employee")] - public async Task AssignEmployee(int? allocationid, int employeeId, int projectId) + //[HttpPost("assign-employee")] + //public async Task AssignEmployee(int? allocationid, int employeeId, int projectId) + //{ + // var employee = await _context.Employees.FindAsync(employeeId); + // var project = _projectrepo.Get(c => c.Id == projectId); + // if (employee == null || project == null) + // { + // return NotFound(); + // } + + // // Logic to add the product to a new table (e.g., selected products) + + // if (allocationid == null) + // { + // // Add allocation + // ProjectAllocation allocation = new ProjectAllocation() + // { + // EmployeeId = employeeId, + // ProjectId = project.Id, + // AllocationDate = DateTime.UtcNow, + // //EmployeeRole = employee.Rol + // TenantId = project.TenantId + // }; + + // _unitOfWork.ProjectAllocation.CreateAsync(allocation); + // } + // else + // { + // //remove allocation + // var allocation = await _context.ProjectAllocations.FindAsync(allocationid); + // if (allocation != null) + // { + // allocation.ReAllocationDate = DateTime.UtcNow; + + // _unitOfWork.ProjectAllocation.UpdateAsync(allocation.Id, allocation); + // } + // else + // { + // return NotFound(); + // } + // } + + // return Ok(); + //} + + [HttpGet] + [Route("employees/get/{projectid?}/{includeInactive?}")] + public async Task GetEmployeeByProjectID(int? projectid, bool? includeInactive = false) { - var employee = await _context.Employees.FindAsync(employeeId); - var project = _projectrepo.Get(c => c.Id == projectId); - if (employee == null || project == null) + if (!ModelState.IsValid) { - return NotFound(); + return BadRequest(ModelState); } + int TenantId = GetTenantId(); - // Logic to add the product to a new table (e.g., selected products) - - if (allocationid == null) + if (projectid != null) { - // Add allocation - ProjectAllocation allocation = new ProjectAllocation() - { - EmployeeId = employeeId, - ProjectId = project.Id, - AllocationDate = DateTime.UtcNow, - //EmployeeRole = employee.Rol - TenantId = project.TenantId - }; + // Fetch assigned project + List result = new List(); - _unitOfWork.ProjectAllocation.CreateAsync(allocation); + if ((bool)includeInactive) + { + + result = await (from rpm in _context.Employees.Include(c => c.JobRole) + join fp in _context.ProjectAllocations.Where(c => c.TenantId == TenantId && c.ProjectId == projectid) + on rpm.Id equals fp.EmployeeId + select rpm).ToListAsync(); + }else + { + result = await (from rpm in _context.Employees.Include(c => c.JobRole) + join fp in _context.ProjectAllocations.Where(c => c.TenantId == TenantId && c.ProjectId == projectid && c.IsActive == true) + on rpm.Id equals fp.EmployeeId + select rpm).ToListAsync(); + } + + List resultVM = new List(); + foreach (Employee employee in result) + { + EmployeeVM vm = employee.ToEmployeeVMFromEmployee(); + resultVM.Add(vm); + } + + return Ok(ApiResponse.SuccessResponse(resultVM, "Success.", 200)); } else { - //remove allocation - var allocation = await _context.ProjectAllocations.FindAsync(allocationid); - if (allocation != null) - { - allocation.ReAllocationDate = DateTime.UtcNow; - - _unitOfWork.ProjectAllocation.UpdateAsync(allocation.Id, allocation); - } - else - { - return NotFound(); - } + return Ok(ApiResponse.ErrorResponse("Invalid Input Parameter", 422)); } - return Ok(); + } [HttpGet] @@ -280,25 +314,25 @@ namespace MarcoBMS.Services.Controllers } int TenantId = GetTenantId(); - var employees = await _context.ProjectAllocations.Where(c => c.TenantId == TenantId && c.ProjectId == projectId ).Include(e => e.Employee).Select(e=> new + + var employees = await _context.ProjectAllocations.Where(c => c.TenantId == TenantId && c.ProjectId == projectId).Include(e => e.Employee).Include(e => e.Employee.JobRole).Select(e => new { ID = e.Id, EmployeeId = e.EmployeeId, ProjectId = e.ProjectId, - RoleID = e.EmployeeRoleId, AllocationDate = e.AllocationDate, ReAllocationDate = e.ReAllocationDate, - FirstName = e.Employee.FirstName, - LastName = e.Employee.LastName, + FirstName = e.Employee.FirstName, + LastName = e.Employee.LastName, MiddleName = e.Employee.MiddleName, - IsActive = e.IsActive - + IsActive = e.IsActive, + JobRoleId = (e.JobRoleId != null ? e.JobRoleId : e.Employee.JobRoleId) }).ToListAsync(); return Ok(ApiResponse.SuccessResponse(employees, "Success.", 200)); } - [HttpPost("allocation")] + [HttpPost("allocation")] public async Task ManageAllocation(List projectAllocationDot) { if (projectAllocationDot != null) @@ -310,9 +344,9 @@ namespace MarcoBMS.Services.Controllers try { ProjectAllocation projectAllocation = item.ToProjectAllocationFromProjectAllocationDto(TenentID); - ProjectAllocation projectAllocationFromDb =await _context.ProjectAllocations.Where(c => c.EmployeeId == projectAllocation.EmployeeId - && c.ProjectId == projectAllocation.ProjectId - && c.ReAllocationDate == null + ProjectAllocation projectAllocationFromDb = await _context.ProjectAllocations.Where(c => c.EmployeeId == projectAllocation.EmployeeId + && c.ProjectId == projectAllocation.ProjectId + && c.ReAllocationDate == null && c.TenantId == TenentID).SingleOrDefaultAsync(); if (projectAllocationFromDb != null) @@ -321,11 +355,10 @@ namespace MarcoBMS.Services.Controllers if (item.Status) { - projectAllocationFromDb.EmployeeRoleId = projectAllocation.EmployeeRoleId; ; + projectAllocationFromDb.JobRoleId = projectAllocation.JobRoleId; ; projectAllocationFromDb.IsActive = true; - _context.Entry(projectAllocationFromDb).Property(e => e.EmployeeRoleId).IsModified = true; + _context.Entry(projectAllocationFromDb).Property(e => e.JobRoleId).IsModified = true; _context.Entry(projectAllocationFromDb).Property(e => e.IsActive).IsModified = true; - } else { @@ -333,7 +366,6 @@ namespace MarcoBMS.Services.Controllers projectAllocationFromDb.IsActive = false; _context.Entry(projectAllocationFromDb).Property(e => e.ReAllocationDate).IsModified = true; _context.Entry(projectAllocationFromDb).Property(e => e.IsActive).IsModified = true; - } await _context.SaveChangesAsync(); @@ -371,20 +403,15 @@ namespace MarcoBMS.Services.Controllers if (item.Id > 0) { //update - - _unitOfWork.WorkItem.Update(workItem); - + _context.WorkItems.Update(workItem); + await _context.SaveChangesAsync(); } else { - //create - _unitOfWork.WorkItem.Add(workItem); - + _context.WorkItems.Add(workItem); + await _context.SaveChangesAsync(); } - - _unitOfWork.Save(); - } return Ok(ApiResponse.SuccessResponse(null, "Data saved successfully.", 200)); @@ -410,15 +437,15 @@ namespace MarcoBMS.Services.Controllers if (item.Building.Id == 0) { //create - _unitOfWork.Building.Add(building); + _context.Buildings.Add(building); + await _context.SaveChangesAsync(); } else { //update - _unitOfWork.Building.Update(building); + _context.Buildings.Update(building); + await _context.SaveChangesAsync(); } - - _unitOfWork.Save(); } if (item.Floor != null) { @@ -428,16 +455,15 @@ namespace MarcoBMS.Services.Controllers if (item.Floor.Id == 0) { //create - _unitOfWork.Floor.Add(floor); + _context.Floor.Add(floor); + await _context.SaveChangesAsync(); } else { //update - _unitOfWork.Floor.Update(floor); + _context.Floor.Update(floor); + await _context.SaveChangesAsync(); } - - _unitOfWork.Save(); - } if (item.WorkArea != null) { @@ -447,15 +473,15 @@ namespace MarcoBMS.Services.Controllers if (item.WorkArea.Id == 0) { //create - _unitOfWork.WorkArea.Add(workArea); + _context.WorkAreas.Add(workArea); + await _context.SaveChangesAsync(); } else { //update - _unitOfWork.WorkArea.Update(workArea); + _context.WorkAreas.Update(workArea); + await _context.SaveChangesAsync(); } - - _unitOfWork.Save(); } } } diff --git a/Marco.Pms.Services/Controllers/RolesController.cs b/Marco.Pms.Services/Controllers/RolesController.cs index 800e7a2..8d654df 100644 --- a/Marco.Pms.Services/Controllers/RolesController.cs +++ b/Marco.Pms.Services/Controllers/RolesController.cs @@ -1,9 +1,11 @@ -using Marco.Pms.DataAccess.Data; +using Azure; +using Marco.Pms.DataAccess.Data; using Marco.Pms.Model.Dtos.Roles; using Marco.Pms.Model.Entitlements; using Marco.Pms.Model.Mapper; using Marco.Pms.Model.Utilities; using Marco.Pms.Model.ViewModels; +using MarcoBMS.Services.Helpers; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; @@ -18,13 +20,16 @@ namespace MarcoBMS.Services.Controllers public class RolesController : ControllerBase { private readonly ApplicationDbContext _context; + private readonly RolesHelper _rolesHelper; + private readonly UserManager _userManager; - public RolesController(UserManager userManager, ApplicationDbContext context) + public RolesController(UserManager userManager, ApplicationDbContext context, RolesHelper rolesHelper) { _context = context; _userManager = userManager; + _rolesHelper = rolesHelper; } @@ -154,8 +159,7 @@ namespace MarcoBMS.Services.Controllers } - - return Ok(applicationRoles); + return Ok(ApiResponse.SuccessResponse(applicationRoles, "Roles list fetched successfully.", 200)); } @@ -214,21 +218,34 @@ namespace MarcoBMS.Services.Controllers return NotFound("Project not found"); } + bool modified = false; foreach (var permission in updateRoleDto.FeaturesPermission) { var item = new RolePermissionMappings() { ApplicationRoleId = role.Id, FeaturePermissionId = permission.Id }; bool assigned = _context.RolePermissionMappings.Any(c => c.ApplicationRoleId == role.Id && c.FeaturePermissionId == permission.Id); - if (permission.IsEnabled && !assigned) - _context.RolePermissionMappings.Add(item); - else + if (permission.IsEnabled == false && assigned == true) + { _context.RolePermissionMappings.Remove(item); - + modified = true; + } + else if (permission.IsEnabled && !assigned) + { + _context.RolePermissionMappings.Add(item); + modified = true; + } } - return Ok(role.ToRoleVMFromApplicationRole()); + if (modified) + await _context.SaveChangesAsync(); + + ApplicationRolesVM response = role.ToRoleVMFromApplicationRole(); + List permissions = await _rolesHelper.GetFeaturePermissionByRoleID(response.Id); + response.FeaturePermission = permissions.Select(c => c.ToFeaturePermissionVMFromFeaturePermission()).ToList(); + + return Ok(ApiResponse.SuccessResponse(response, "Roles perimssions updated.", 200)); } catch (Exception ex) { - return Ok(null); + return Ok(ApiResponse.ErrorResponse( "RUnable to update roles perimssions.", 200)); } } @@ -269,7 +286,8 @@ namespace MarcoBMS.Services.Controllers FeaturePermission = featurePermissions }; - return Ok(vm); + return Ok(ApiResponse.SuccessResponse(vm, "Roles Perimssions fetched successfully.", 200)); + } } } diff --git a/Marco.Pms.Services/Controllers/TaskController.cs b/Marco.Pms.Services/Controllers/TaskController.cs index 9e5d978..3066f9f 100644 --- a/Marco.Pms.Services/Controllers/TaskController.cs +++ b/Marco.Pms.Services/Controllers/TaskController.cs @@ -1,8 +1,6 @@ using Marco.Pms.DataAccess.Data; -using Marco.Pms.DataAccess.Repository.IRepository; -using Marco.Pms.Model.Entitlements; +using MarcoBMS.Services.Helpers; using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; @@ -13,32 +11,23 @@ namespace MarcoBMS.Services.Controllers [ApiController] public class TaskController : ControllerBase { - private readonly IUnitOfWork _unitOfWork; private readonly ApplicationDbContext _context; - private ApplicationUser _applicationUser; - private readonly IActivityMasterRepository _activityRepo; - private readonly IHttpContextAccessor _httpContextAccessor; + private readonly UserHelper _userHelper; - public TaskController(IActivityMasterRepository activityRepo, IUnitOfWork unitOfWork, ApplicationDbContext context, IHttpContextAccessor httpContextAccessor) + + public TaskController(ApplicationDbContext context, UserHelper userHelper) { - _unitOfWork = unitOfWork; _context = context; - _activityRepo = activityRepo; - _httpContextAccessor = httpContextAccessor; + _userHelper = userHelper; } [HttpGet] [Route("activities")] public async Task GetActivities() { - var tenantId = _httpContextAccessor.HttpContext?.Items["TenantId"]?.ToString(); - - - var activities = await _activityRepo.GetAllAsync(c=>c.TenantId == Convert.ToInt32( tenantId)); + var activities = await _context.ActivityMasters.Where(c => c.TenantId == _userHelper.GetTenantId()).ToListAsync(); return Ok(activities); } - - } } diff --git a/Marco.Pms.Services/Controllers/UserController.cs b/Marco.Pms.Services/Controllers/UserController.cs new file mode 100644 index 0000000..b808a3c --- /dev/null +++ b/Marco.Pms.Services/Controllers/UserController.cs @@ -0,0 +1,68 @@ +using Marco.Pms.Model.Employees; +using Marco.Pms.Model.Entitlements; +using Marco.Pms.Model.Mapper; +using Marco.Pms.Model.Projects; +using Marco.Pms.Model.ViewModels.Employee; +using MarcoBMS.Services.Helpers; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace MarcoBMS.Services.Controllers +{ + [Route("api/[controller]")] + [ApiController] + [Authorize] + + public class UserController : ControllerBase + { + private readonly UserHelper _userHelper; + private readonly EmployeeHelper _employeeHelper; + + private readonly ProjectsHelper _projectsHelper; + private readonly RolesHelper _rolesHelper; + + public UserController(EmployeeHelper employeeHelper, ProjectsHelper projectsHelper, UserHelper userHelper, RolesHelper rolesHelper) + { + _userHelper = userHelper; + _employeeHelper = employeeHelper; + _projectsHelper = projectsHelper; + _rolesHelper = rolesHelper; + + } + [HttpGet("profile")] + public async Task GetUserProfileFromJwt() + { + if (!ModelState.IsValid) + { + return BadRequest(ModelState); + } + + var user = await _userHelper.GetCurrentUserAsync(); + Employee emp = await _employeeHelper.GetEmployeeByApplicationUserID(user.Id); + + List featurePermission = await _rolesHelper.GetFeaturePermissionByEmployeeID(emp.Id); + string[] projectsId = []; + + if (featurePermission != null && featurePermission.Exists(c => c.FeatureId.ToString() == "53176ebf-c75d-42e5-839f-4508ffac3def")) { + List projects = await _projectsHelper.GetAllProjectByTanentID(emp.TenantId); + projectsId = projects.Select(c=>c.Id.ToString()).ToArray(); + } + else + { + List allocation = await _projectsHelper.GetProjectByEmployeeID(emp.Id); + projectsId = allocation.Select(c => c.ProjectId.ToString()).ToArray(); + } + + + EmployeeVM employeeVM = EmployeeMapper.ToEmployeeVMFromEmployee(emp); + EmployeeProfile profile = new EmployeeProfile() + { + EmployeeInfo = employeeVM, + Projects = projectsId, + FeaturePermissions = featurePermission.Select(c => c.FeatureId.ToString()).ToArray(), + }; + + return Ok(profile); + } + } +} diff --git a/Marco.Pms.Services/EmailTemplates/forgot-password.html b/Marco.Pms.Services/EmailTemplates/forgot-password.html new file mode 100644 index 0000000..a944fd4 --- /dev/null +++ b/Marco.Pms.Services/EmailTemplates/forgot-password.html @@ -0,0 +1,565 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+ + +
+
+
+ + + + + + + + +
+ + + + + + + +
+ Sita +
+ +
+ + +
+
+
+ + +
+
+
+ + + + + +
+
+
+ + +
+
+
+ + + + + + + + +
+ + + + + +
+ + Image + +
+ +
+ + +
+
+
+ + +
+
+
+ + + + + +
+
+
+ + +
+
+
+ + + + + + + + +
+ + + + + +
+ + Image + +
+ +
+ + + + + + + +
+ +
+

{{MAIL_TITLE}}

+
+ +
+ + +
+
+
+ + +
+
+
+ + + + + +
+
+
+ + +
+
+
+ + + + + + + + +
+ +
+

Hello,

+

 

+

We have sent you this email in response to your request to reset your password on MarcoPMS.

+

 

+

To reset your password, please follow the link below:

+
+ +
+ + + + + + + +
+ + + + +
+ + + + + + + +
+ +
+

Please ignore this email if you did not request a password change.
 

+
+ +
+ + +
+
+
+ + +
+
+
+ + + + + +
+
+
+ + +
+
+
+ + + + + + + + +
+ +
+

Contact

+

1912  Mcwhorter Road, FL 11223

+

+111 222 333 | info [@] marcoaiot.com

+
+ +
+ + +
+
+
+ + +
+
+
+ + + + + + + + +
+ +
+
+ + + + + + + + +
+ + Facebook + +
+ + + + + + + + +
+ + Twitter + +
+ + + + + + + + +
+ + Instagram + +
+ + + + + + + + +
+ + LinkedIn + +
+ + +
+
+ +
+ + + + +
+
+
+ + +
+
+
+ + + + + +
+
+
+ + +
+
+
+ + + + + + + + +
+

Marco AIoT Technologies Pvt. Ltd. ©  All Rights Reserved

+ + + +
+ + +
+
+
+ + +
+
+
+
+
+
+ + +
+
+
+ + + + + + + + +
+ +
+ You're receiving this email because you have a MarcoPMS account. This email is not a marketing or promotional email. That is why this email does not contain an unsubscribe link. You will receive this email even if you have unsubscribed from MarcoPMS's marketing emails + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + diff --git a/Marco.Pms.Services/EmailTemplates/full-template.html b/Marco.Pms.Services/EmailTemplates/full-template.html new file mode 100644 index 0000000..925de8f --- /dev/null +++ b/Marco.Pms.Services/EmailTemplates/full-template.html @@ -0,0 +1,565 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+ + +
+
+
+ + + + + + + + +
+ + + + + + + +
+ Sita +
+ +
+ + +
+
+
+ + +
+
+
+ + + + + +
+
+
+ + +
+
+
+ + + + + + + + +
+ + + + + +
+ + Image + +
+ +
+ + +
+
+
+ + +
+
+
+ + + + + +
+
+
+ + +
+
+
+ + + + + + + + +
+ + + + + +
+ + Image + +
+ +
+ + + + + + + +
+ +
+

Please reset your password

+
+ +
+ + +
+
+
+ + +
+
+
+ + + + + +
+
+
+ + +
+
+
+ + + + + + + + +
+ +
+

Hello,

+

 

+

We have sent you this email in response to your request to reset your password on MarcoPMS.

+

 

+

To reset your password, please follow the link below:

+
+ +
+ + + + + + + +
+ + + + +
+ + + + + + + +
+ +
+

Please ignore this email if you did not request a password change.
 

+
+ +
+ + +
+
+
+ + +
+
+
+ + + + + +
+
+
+ + +
+
+
+ + + + + + + + +
+ +
+

Contact

+

1912  Mcwhorter Road, FL 11223

+

+111 222 333 | info [@] marcoaiot.com

+
+ +
+ + +
+
+
+ + +
+
+
+ + + + + + + + +
+ +
+
+ + + + + + + + +
+ + Facebook + +
+ + + + + + + + +
+ + Twitter + +
+ + + + + + + + +
+ + Instagram + +
+ + + + + + + + +
+ + LinkedIn + +
+ + +
+
+ +
+ + + + +
+
+
+ + +
+
+
+ + + + + +
+
+
+ + +
+
+
+ + + + + + + + +
+

Marco AIoT Technologies Pvt. Ltd. ©  All Rights Reserved

+ + + +
+ + +
+
+
+ + +
+
+
+
+
+
+ + +
+
+
+ + + + + + + + +
+ +
+ You're receiving this email because you have a MarcoPMS account. This email is not a marketing or promotional email. That is why this email does not contain an unsubscribe link. You will receive this email even if you have unsubscribed from MarcoPMS's marketing emails + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + diff --git a/Marco.Pms.Services/EmailTemplates/new-user-email.html b/Marco.Pms.Services/EmailTemplates/new-user-email.html new file mode 100644 index 0000000..aac8df2 --- /dev/null +++ b/Marco.Pms.Services/EmailTemplates/new-user-email.html @@ -0,0 +1,564 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+ + +
+
+
+ + + + + + + + +
+ + + + + + + +
+ Sita +
+ +
+ + +
+
+
+ + +
+
+
+ + + + + +
+
+
+ + +
+
+
+ + + + + + + + +
+ + + + + +
+ + Image + +
+ +
+ + +
+
+
+ + +
+
+
+ + + + + +
+
+
+ + +
+
+
+ + + + + + + + +
+ + + + + +
+ + Image + +
+ +
+ + + + + + + +
+ +
+

{{MAIL_TITLE}}

+
+ +
+ + +
+
+
+ + +
+
+
+ + + + + +
+
+
+ + +
+
+
+ + + + + + + + +
+ +
+

Hello {{RECEIVER_NAME}},

+

 

+

Welcome, You've joined your teammates on MarcoPMS. We have sent you this email to set your password on MarcoPMS.

+

 

+

To set your password, please follow the link below:

+
+ +
+ + + + + + + +
+ + + + +
+ + + + + + + +
+ +
+

Please ignore this email if you did not request a password change.
 

+
+ +
+ + +
+
+
+ + +
+
+
+ + + + + +
+
+
+ + +
+
+
+ + + + + + + + +
+ +
+

Contact

+

1912  Mcwhorter Road, FL 11223

+

+111 222 333 | info [@] marcoaiot.com

+
+ +
+ + +
+
+
+ + +
+
+
+ + + + + + + + +
+ +
+
+ + + + + + + + +
+ + Facebook + +
+ + + + + + + + +
+ + Twitter + +
+ + + + + + + + +
+ + Instagram + +
+ + + + + + + + +
+ + LinkedIn + +
+ + +
+
+ +
+ + + +
+
+
+ + +
+
+
+ + + + + +
+
+
+ + +
+
+
+ + + + + + + + +
+

Marco AIoT Technologies Pvt. Ltd. ©  All Rights Reserved

+ + + +
+ + +
+
+
+ + +
+
+
+
+
+
+ + +
+
+
+ + + + + + + + +
+ +
+ You're receiving this email because you have a MarcoPMS account. This email is not a marketing or promotional email. That is why this email does not contain an unsubscribe link. You will receive this email even if you have unsubscribed from MarcoPMS's marketing emails + +
+ +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + diff --git a/Marco.Pms.Services/Helpers/EmployeeHelper.cs b/Marco.Pms.Services/Helpers/EmployeeHelper.cs index c455781..ca7fae9 100644 --- a/Marco.Pms.Services/Helpers/EmployeeHelper.cs +++ b/Marco.Pms.Services/Helpers/EmployeeHelper.cs @@ -1,20 +1,101 @@ -using Marco.Pms.DataAccess.Data; + +using Marco.Pms.DataAccess.Data; using Marco.Pms.Model.Employees; +using Marco.Pms.Model.Mapper; +using Marco.Pms.Model.ViewModels.Employee; using Microsoft.EntityFrameworkCore; +using System.Collections.Generic; +using System.Runtime.Intrinsics.Arm; namespace MarcoBMS.Services.Helpers { public class EmployeeHelper { private readonly ApplicationDbContext _context; - public EmployeeHelper(ApplicationDbContext context) { + public EmployeeHelper(ApplicationDbContext context) + { _context = context; } - - public async Task GetEmployeeByID(int EmployeeID) { return await _context.Employees.FindAsync(EmployeeID); } + + public async Task GetEmployeeByApplicationUserID(string ApplicationUserID) + { + try + { + var result = await _context.Employees.Where(c => c.ApplicationUserId == ApplicationUserID).ToListAsync(); + + return await _context.Employees.Where(c => c.ApplicationUserId == ApplicationUserID).SingleOrDefaultAsync(); + } + catch (Exception ex) + { + return null; + } + } + + public async Task> SearchEmployeeByProjectId(int TenentId, string searchString, int? ProjectId) + { + try + { + List result = new List(); + if (ProjectId != null) + { + + result = await (from pa in _context.ProjectAllocations.Where(c => c.ProjectId == ProjectId) + join em in _context.Employees.Where(c => c.TenantId == TenentId).Include(fp => fp.JobRole) // Include Feature + on pa.EmployeeId equals em.Id + where em.FirstName.ToLower().Contains(searchString.ToLower()) || em.LastName.ToLower().Contains(searchString.ToLower()) + select em.ToEmployeeVMFromEmployee() + ) + .ToListAsync(); + + } + else + { + result = await _context.Employees.Where(c => c.TenantId == TenentId && + (c.FirstName.ToLower().Contains(searchString.ToLower()) || c.LastName.ToLower().Contains(searchString.ToLower()))).Include(fp => fp.JobRole) + .Select(c => c.ToEmployeeVMFromEmployee()).ToListAsync(); + } + + return result; + } + catch (Exception ex) + { + return new List(); + } + } + + public async Task> GetEmployeeByProjectId(int TenentId, int? ProjectId) + { + try + { + List result = new List(); + if (ProjectId != null) + { + + result = await (from pa in _context.ProjectAllocations.Where(c => c.ProjectId == ProjectId) + join em in _context.Employees.Where(c => c.TenantId == TenentId).Include(fp => fp.JobRole) // Include Feature + on pa.EmployeeId equals em.Id + select em.ToEmployeeVMFromEmployee() + ) + .ToListAsync(); + + } + else + { + result = await _context.Employees.Where(c => c.TenantId == TenentId).Include(fp => fp.JobRole) + .Select(c => c.ToEmployeeVMFromEmployee()).ToListAsync(); + } + + return result; + } + catch (Exception ex) + { + return new List(); + } + } } } + diff --git a/Marco.Pms.Services/Helpers/ProjectHelper.cs b/Marco.Pms.Services/Helpers/ProjectHelper.cs index 528a3b9..67455aa 100644 --- a/Marco.Pms.Services/Helpers/ProjectHelper.cs +++ b/Marco.Pms.Services/Helpers/ProjectHelper.cs @@ -4,7 +4,7 @@ using Microsoft.CodeAnalysis; using Microsoft.EntityFrameworkCore; -namespace MarcoBMS.Services.Helpers +namespace ModelServices.Helpers { public class ProjectHelper { diff --git a/Marco.Pms.Services/Helpers/ProjectsHelper.cs b/Marco.Pms.Services/Helpers/ProjectsHelper.cs new file mode 100644 index 0000000..7d306bc --- /dev/null +++ b/Marco.Pms.Services/Helpers/ProjectsHelper.cs @@ -0,0 +1,48 @@ +using Marco.Pms.DataAccess.Data; +using Marco.Pms.Model.Projects; +using Microsoft.EntityFrameworkCore; + +namespace MarcoBMS.Services.Helpers +{ + public class ProjectsHelper + { + private readonly ApplicationDbContext _context; + + public ProjectsHelper(ApplicationDbContext context) + { + _context = context; + } + + public async Task> GetAllProjectByTanentID(int tanentID) + { + List alloc = await _context.Projects.Where(c => c.TenantId == tanentID).ToListAsync(); + return alloc; + } + + public async Task> GetProjectByEmployeeID(int employeeID) + { + List alloc = await _context.ProjectAllocations.Where(c => c.EmployeeId ==employeeID && c.IsActive == true).Include(c=>c.Project).ToListAsync(); + return alloc; + } + + public async Task> GetTeamByProject(int TenantId, int ProjectId, bool IncludeInactive) + { + if (IncludeInactive) + { + + var employees = await _context.ProjectAllocations.Where(c => c.TenantId == TenantId && c.ProjectId == ProjectId).Include(e => e.Employee).ToListAsync(); + + return employees; + } + else + { + var employees = await _context.ProjectAllocations.Where(c => c.TenantId == TenantId && c.ProjectId == ProjectId && c.IsActive == true).Include(e => e.Employee).ToListAsync(); + + return employees; + } + } + + + + } +} diff --git a/Marco.Pms.Services/Helpers/RolesHelper.cs b/Marco.Pms.Services/Helpers/RolesHelper.cs new file mode 100644 index 0000000..9bf16fd --- /dev/null +++ b/Marco.Pms.Services/Helpers/RolesHelper.cs @@ -0,0 +1,53 @@ + + +using Marco.Pms.DataAccess.Data; +using Marco.Pms.Model.Entitlements; +using Microsoft.EntityFrameworkCore; + +namespace MarcoBMS.Services.Helpers +{ + public class RolesHelper + { + private readonly ApplicationDbContext _context; + public RolesHelper(ApplicationDbContext context) + { + _context = context; + } + + public async Task> GetFeaturePermissionByEmployeeID(int EmployeeID) + { + List roleMappings = await _context.EmployeeRoleMappings.Where(c => c.EmployeeId ==EmployeeID && c.IsEnabled == true).Select(c=>c.RoleId).ToListAsync(); + + // _context.RolePermissionMappings + + var result = await (from rpm in _context.RolePermissionMappings + join fp in _context.FeaturePermissions.Where(c=>c.IsEnabled == true).Include(fp => fp.Feature) // Include Feature + on rpm.FeaturePermissionId equals fp.Id + where roleMappings.Contains(rpm.ApplicationRoleId) + select fp) + .ToListAsync(); + + return result; + + // return null; + } + + public async Task> GetFeaturePermissionByRoleID(Guid roleId) + { + List roleMappings = await _context.RolePermissionMappings.Where(c => c.ApplicationRoleId == roleId ).Select(c => c.ApplicationRoleId).ToListAsync(); + + // _context.RolePermissionMappings + + var result = await (from rpm in _context.RolePermissionMappings.Where(c=>c.ApplicationRoleId == roleId) + join fp in _context.FeaturePermissions.Where(c => c.IsEnabled == true).Include(fp => fp.Feature) // Include Feature + on rpm.FeaturePermissionId equals fp.Id + select fp) + .ToListAsync(); + + return result; + + // return null; + } + + } +} diff --git a/Marco.Pms.Services/Helpers/UserHelper.cs b/Marco.Pms.Services/Helpers/UserHelper.cs new file mode 100644 index 0000000..4f1d42f --- /dev/null +++ b/Marco.Pms.Services/Helpers/UserHelper.cs @@ -0,0 +1,63 @@ +using Marco.Pms.Model.Dtos.Employees; +using Marco.Pms.Model.Entitlements; +using Microsoft.AspNetCore.Identity; +using System.Security.Claims; + +namespace MarcoBMS.Services.Helpers +{ + public class UserHelper + { + private readonly UserManager _userManager; + private readonly IHttpContextAccessor _httpContextAccessor; + + public UserHelper(UserManager userManager, IHttpContextAccessor httpContextAccessor) + { + _userManager = userManager; + _httpContextAccessor = httpContextAccessor; + } + + public int GetTenantId() + { + var tenant = _httpContextAccessor.HttpContext?.User.FindFirst("TenantId")?.Value; + return (tenant != null ? Convert.ToInt32(tenant) : 1); + } + + public async Task GetCurrentUserAsync() + { + var userId = _httpContextAccessor.HttpContext?.User.FindFirstValue(ClaimTypes.NameIdentifier); + + if (string.IsNullOrEmpty(userId)) + return null; + var user = await _userManager.FindByEmailAsync(userId); + return user; //await _userManager.FindByIdAsync(userId); + } + + public async Task GetCurrentUserProfileAsync() + { + + var user = await GetCurrentUserAsync(); + return user == null ? null : new + { + user.Id, + user.UserName, + user.Email, + user.PhoneNumber + }; + } + + public async Task GetRegisteredUser(string email) + { + //IdentityUser? user = await _userManager.Users + // .FirstOrDefaultAsync(u => u.Email == model.Email || u.PhoneNumber == model.PhoneNumber); + + + IdentityUser? user = await _userManager.FindByEmailAsync(email); + //if (user == null) + //{ + // user = await _userManager.Find(model.Email); + + //} + return user; + } + } +} diff --git a/Marco.Pms.Services/Marco.Pms.Services.csproj b/Marco.Pms.Services/Marco.Pms.Services.csproj index 2a1f97d..4e70e23 100644 --- a/Marco.Pms.Services/Marco.Pms.Services.csproj +++ b/Marco.Pms.Services/Marco.Pms.Services.csproj @@ -29,6 +29,9 @@ + + + diff --git a/Marco.Pms.Services/Middleware/LoggingMiddleware.cs b/Marco.Pms.Services/Middleware/LoggingMiddleware.cs new file mode 100644 index 0000000..28535b2 --- /dev/null +++ b/Marco.Pms.Services/Middleware/LoggingMiddleware.cs @@ -0,0 +1,64 @@ +using MarcoBMS.Services.Helpers; +using MarcoBMS.Services.Service; +using Serilog.Context; +using System.Diagnostics; + +namespace MarcoBMS.Services.Middleware +{ + public class LoggingMiddleware + { + private readonly RequestDelegate _next; + private readonly ILogger _logger; + private readonly ILoggingService _loggingService; + //private readonly UserHelper _userHelper; + public LoggingMiddleware(RequestDelegate next, ILogger logger, ILoggingService loggingService) + { + _next = next; + _logger = logger; + //_userHelper = userHelper; + _loggingService = loggingService; + } + + public async Task Invoke(HttpContext context) + { + var stopwatch = Stopwatch.StartNew(); + var response = context.Response; + var request = context.Request; + var tenant = context.User.FindFirst("TenantId")?.Value; + int tenantId = (tenant != null ? Convert.ToInt32(tenant) : 1); + + + using (LogContext.PushProperty("TenantId", tenantId)) + using (LogContext.PushProperty("TraceId", context.TraceIdentifier)) + using (LogContext.PushProperty("UserAgent", request.Headers["User-Agent"].ToString())) + using (LogContext.PushProperty("HttpMethod", request.Method)) + using (LogContext.PushProperty("Timestamp", DateTime.UtcNow)) + using (LogContext.PushProperty("IpAddress", context.Connection.RemoteIpAddress?.ToString())) + using (LogContext.PushProperty("RequestPath", request.Path)) + + + try + { + await _next(context); + stopwatch.Stop(); + using (LogContext.PushProperty("StatusCode", response.StatusCode.ToString())) + using (LogContext.PushProperty("ResponseTimeMs", stopwatch.ElapsedMilliseconds)) + using (LogContext.PushProperty("LogLevel", "Information")) + _logger.LogInformation("HTTP {method} {path} responded {statusCode} in {timeTaken} ms", request.Method,request.Path, response.StatusCode.ToString(),stopwatch.ElapsedMilliseconds); + } + catch (Exception ex) + { + stopwatch.Stop(); + using (LogContext.PushProperty("Error", ex)) + using (LogContext.PushProperty("StatusCode", "500")) + using (LogContext.PushProperty("ResponseTimeMs", stopwatch.ElapsedMilliseconds)) + using (LogContext.PushProperty("LogLevel", "Error")) + _logger.LogError("API Error{error}", ex.Message); + throw; + } + } + } + +} + + diff --git a/Marco.Pms.Services/Program.cs b/Marco.Pms.Services/Program.cs index c2a26b1..a01ea0e 100644 --- a/Marco.Pms.Services/Program.cs +++ b/Marco.Pms.Services/Program.cs @@ -1,7 +1,4 @@ -using BulkyBook.DataAccess.Repository; using Marco.Pms.DataAccess.Data; -using Marco.Pms.DataAccess.Repository; -using Marco.Pms.DataAccess.Repository.IRepository; using Marco.Pms.Model.Authentication; using Marco.Pms.Model.Utilities; using MarcoBMS.Services.Helpers; @@ -22,10 +19,10 @@ var builder = WebApplication.CreateBuilder(args); // Add Serilog Configuration builder.Host.UseSerilog((context, config) => { - config - .WriteTo.Console(); // Optional: Log to console - // .WriteTo.MongoDB("mongodb://localhost:27017/logs", collectionName: "api_logs"); -}); + config.ReadFrom.Configuration(context.Configuration); // Taking all configuration from appsetting.json + +}) +; // Add services builder.Services.AddCors(options => @@ -98,21 +95,23 @@ builder.Services.AddDbContext(options => builder.Services.AddMemoryCache(); -builder.Services.AddScoped(); -builder.Services.AddScoped(); -builder.Services.AddScoped(); -builder.Services.AddScoped(); -builder.Services.AddScoped(); -builder.Services.AddScoped(); -builder.Services.AddScoped(); - - - - -builder.Services.AddScoped(); +//builder.Services.AddScoped(); +//builder.Services.AddScoped(); +//builder.Services.AddScoped(); +//builder.Services.AddScoped(); +//builder.Services.AddScoped(); +//builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddSingleton(); + + +builder.Services.AddHttpContextAccessor(); var jwtSettings = builder.Configuration.GetSection("Jwt").Get(); builder.Services.AddAuthentication(options => @@ -150,10 +149,14 @@ if (app.Environment.IsDevelopment()) app.UseCors("DevCorsPolicy"); } +app.UseStaticFiles(); // Enables serving static files + app.UseSerilogRequestLogging(); // Log HTTP requests app.UseHttpsRedirection(); app.UseMiddleware(); app.UseMiddleware(); +app.UseMiddleware(); + app.UseAuthorization(); diff --git a/Marco.Pms.Services/Service/EmailSender.cs b/Marco.Pms.Services/Service/EmailSender.cs index a619601..fd357cf 100644 --- a/Marco.Pms.Services/Service/EmailSender.cs +++ b/Marco.Pms.Services/Service/EmailSender.cs @@ -5,13 +5,61 @@ using MimeKit; namespace MarcoBMS.Services.Service -{ public class EmailSender : IEmailSender +{ + public class EmailSender : IEmailSender { private readonly SmtpSettings _smtpSettings; + private readonly IConfiguration _configuration; - public EmailSender(IOptions emailSettings) + public EmailSender(IOptions emailSettings, IConfiguration configuration) { _smtpSettings = emailSettings.Value; + _configuration = configuration; + } + + public async Task GetEmailTemplate(string templateName, Dictionary replacements) + { + string path = Path.Combine(Directory.GetCurrentDirectory(), "EmailTemplates", $"{templateName}.html"); + + if (!File.Exists(path)) + throw new FileNotFoundException("Template file not found"); + + string content = await File.ReadAllTextAsync(path); + + foreach (var item in replacements) + { + content = content.Replace($"{{{{{item.Key}}}}}", item.Value); + } + + return content; + } + + public async Task SendResetPasswordEmailOnRegister(string toEmail, string toName, string resetLink) + { + var replacements = new Dictionary + { + { "MAIL_TITLE", "New registration,Reset Your Password" }, + { "RESET_PWD_URL", resetLink }, + { "RECEIVER_NAME", toName } + }; + + string emailBody = await GetEmailTemplate("new-user-email", replacements); + + await SendEmailAsync(toEmail, "New user registration, Reset Your Password", emailBody); + } + public async Task SendResetPasswordEmail(string toEmail, string userName, string resetLink) + { + var replacements = new Dictionary + { + { "MAIL_TITLE", "Reset Your Password" }, + { "RESET_PWD_URL", resetLink } + }; + + string emailBody = await GetEmailTemplate("forgot-password", replacements); + + + await SendEmailAsync(toEmail, "Reset Your Password", emailBody); + } public async Task SendEmailAsync(string toEmail, string subject, string body) diff --git a/Marco.Pms.Services/Service/IEmailSender.cs b/Marco.Pms.Services/Service/IEmailSender.cs index a5a5754..7ede524 100644 --- a/Marco.Pms.Services/Service/IEmailSender.cs +++ b/Marco.Pms.Services/Service/IEmailSender.cs @@ -2,6 +2,9 @@ { public interface IEmailSender { + Task SendResetPasswordEmail(string toEmail, string userName, string resetLink); + Task SendResetPasswordEmailOnRegister(string toEmail, string toName, string resetLink); + Task SendEmailAsync(string toEmail, string subject, string body); } } diff --git a/Marco.Pms.Services/Service/ILoggingService.cs b/Marco.Pms.Services/Service/ILoggingService.cs new file mode 100644 index 0000000..744ab19 --- /dev/null +++ b/Marco.Pms.Services/Service/ILoggingService.cs @@ -0,0 +1,15 @@ +using Serilog.Context; + +namespace MarcoBMS.Services.Service +{ + public interface ILoggingService + { + void LogInfo(string? message, params object[]? args); + void LogWarning(string? message, params object[]? args); + void LogError(Exception? ex, string? message, params object[]? args); + + } +} + + + diff --git a/Marco.Pms.Services/Service/LoggingServices.cs b/Marco.Pms.Services/Service/LoggingServices.cs new file mode 100644 index 0000000..aec6257 --- /dev/null +++ b/Marco.Pms.Services/Service/LoggingServices.cs @@ -0,0 +1,35 @@ +using Serilog.Context; + +namespace MarcoBMS.Services.Service +{ + public class LoggingService : ILoggingService + { + private readonly ILogger _logger; + + public LoggingService(ILogger logger) + { + _logger = logger; + } + + public void LogError(Exception? ex, string? message, params object[]? args) + { + using (LogContext.PushProperty("Error", ex)) + using (LogContext.PushProperty("LogLevel", "Error")) + _logger.LogError(message, args); + } + + public void LogInfo(string? message, params object[]? args) + { + using (LogContext.PushProperty("LogLevel", "Information")) + _logger.LogInformation(message, args); + } + + public void LogWarning(string? message, params object[]? args) + { + using (LogContext.PushProperty("LogLevel", "Warning")) + _logger.LogWarning(message,args); + } + } + +} + diff --git a/Marco.Pms.Services/appsettings.json b/Marco.Pms.Services/appsettings.json index bf639e3..868c367 100644 --- a/Marco.Pms.Services/appsettings.json +++ b/Marco.Pms.Services/appsettings.json @@ -1,14 +1,75 @@ { - "Logging": { - "LogLevel": { + "Serilog": { + "Using": [ + "Serilog.Sinks.Console", + "Serilog.Sinks.MongoDB", + "Serilog.Sinks.Async" + ], + "MinimumLevel": { "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } + "Override": { + "Microsoft": "Warning", + "Microsoft.EntityFrameworkCore.Database.Command": "Warning", + "Microsoft.AspNetCore.Mvc.Infrastructure": "Warning", + "Serilog.AspNetCore.RequestLoggingMiddleware": "Warning" + } + }, + "WriteTo": [ + { + "Name": "Async", + "Args": { + "configure": [ + { + "Name": "MongoDB", + "Args": { + "databaseUrl": "mongodb://localhost:27017/DotNetLogs", + //"databaseUrl": "mongodb://devuser:xxxxx@147.93.98.152:27017/MarcoPMS?authSource=admin", + "collectionName": "application_logs", + "batchPostingLimit": 50, + "cappedMaxSizeMb": "1024", + "cappedMaxDocuments": "1000", + "rollingInterval": "Day" + //"outputTemplate": "[{Timestamp:yyyy/MM/dd HH:mm} {Level:u3}] {SourceContext}:{NewLine} {Message:lj}{Exception}{NewLine}" + } + }, + { + "Name": "File", + "Args": { + "path": "logs/myapp-.log", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {Message:lj}{NewLine}{Exception}", + "fileSizeLimitBytes": 1073741824, // 1 GB + "retainedFileCountLimit": 100, // Retain 100 files + "buffered": true, // use async logging + "flushToDiskInterval": "00:00:30" // flush every 30 seconds + } + }, + { + "Name": "Console", + "Args": { + "outputTemplate": "[{Timestamp:yyyy/MM/dd HH:mm} {Level:u3}] {SourceContext}:{NewLine} {Message:lj}{NewLine}{Properties:j}{Exception}{NewLine}" + } + } + ] + } + } + + ], + "Enrich": [ + "FromLogContext", + "WithMachineName", + "WithThreadId" + ] }, + "ConnectionStrings": { // "DefaultConnectionString": "Server=103.50.160.45;User ID=marcowvh_admin;Password=Marcoemp@123;Database=marcowvh_empattendanceci", - //"DefaultConnectionString": "Server=localhost;port=3333;User ID=root;Password=root;Database=MarcoBMS1", - "DefaultConnectionString": "Server=147.93.98.152;User ID=root;Password=MySqlUser@123$;Database=MarcoBMS1" + "DefaultConnectionString": "Server=localhost;port=3333;User ID=root;Password=root;Database=MarcoBMS1", + // "DefaultConnectionString": "Server=147.93.98.152;User ID=devuser;Password=AppUser@123$;Database=MarcoBMS1" + }, + "AppSettings": { + "WebFrontendUrl": "http://localhost:5173", + "ImagesBaseUrl": "http://localhost:5173" }, "AllowedHosts": "*", "Jwt": { diff --git a/Marco.Pms.Services/wwwroot/logos/marco-aiot-tech-logo.jpg b/Marco.Pms.Services/wwwroot/logos/marco-aiot-tech-logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0ca11bf7af1574bc9151345e5b12444628f54ff6 GIT binary patch literal 22241 zcmdSAc|4Tw|37*Q*^PaTkv(h4mTi=5Ns>^usfdsy*_n~Djb%cpgplke`-l`XUKeeGHV<%JF)=p* z=;-KxVDJZ^O#wy#{fQI*{DLnA@RyO9k&%Ick(G(*Br`iJJ3AXI8yg2F4;Kd~Hzyk# zmjD+xFCRZYKRZNFNPtg>hmW7{pPSIpgYRKrWMO1v;p1TA;QK%QqJ06lnSsI+vGjD3 zzzJ?TdTu&eCjbQiI!5qm|9Rm5`9*gEe8!VZ%q*;I;01MDzzI5f`V$QF|2#E#bp-f- zfPtHl=k&RYCwZ;!GD-UJsXa@{W0ty9)y{uo5HEfH-jgU6RslgFVG$WwIr%dR>Kd9_ z+81<;E*qPenwej*xoK->f9tk`tJ{5dj|ZM!{!aq}gMvdspTCHXiH(a#rKY_~&&YiJ z=52n#hr*9V#U-WHHMMp14UJ9BUpqRxx_f%ReIFVg866v+_&vFRTU`3Hyt4Xtjj*%3 zw|{U*JUaeoUUUHce@^Sa&Fo+1#SPBu1Oo#-1JghAqB{`;4tj0|#?$9c@?5lLy6eX) zsrHPS?@~%$RXdB+`5Sotdrt;g1*Fv%WC;IE?LTJrKQ^(b|4TFbZxj1p=QRni)6;>A zN6!tw0E$gMN*?(C#i(&5XreW%WYfgU?j4uAs@`jm_pnY}`WVE?tgkzkE99JM&*7s1?K2HDK+u$|ijK+Mv(`I91D?0|QdJ^#OBK`Ms9Bb$rf{JL?8$kf zF-3IjAKbWipD;_T%w|#rilVTqzQ2%o4<;JGf4ljm!v)pW&15!y=|Yhko-`nU2BeG( zI{kq2lEw5&_*|5KEu~B-w_NR_9RzIeEF%75e#qw+dm$u- z_Uw`ZIIaw}e_(jul$r zJIVAU?{GF^Rv2S$ELA=jfjbCf;i#BtuX$@HM`ta^{G;dB3GXQ|>}vGPaY>@>%^KYp z%-Wcac-liP%ZL)E!d7mGUC?P$ocGrNU!uIn#^3z4sIQB-`XuQ;sO?(w%DcTZ;A2(y zH+00rdr1C+N~49jE*d~jcB;zQZFf-_Y_(yywVRwCacYxAp8@sZmBA0X%C<;W`FwC- zv&#&Nq&=UGC@{J?QaYq`dTw!v}2^;Z=K@%R}Ac2^Jlhf;*p*6+^ZeYrc2RE3gD^ z-wRW*1j20jtPL6Y?AZvAMN9|gMS000?9>Bsq3q!w77r*0LoQ&sXVX;=^mT1w z93$I4N=$t@Mge>Oxdb0u%FTXmaPzs8 zM|if(CIZ-BZr?ZPw1dWA=ilenG@w>)mA5IbK0ePwHf8Q$iKKT>2dw{DkpKNbcVt9zTt7xf(*SP>?^?6v z#w4P^)6Yjq@azS96E4#zj)(%1Jaz0XvPVo!U(n$}?Y79&>A91a3fG?fNP)n&%!N-*+(&2%%4~Ca=ZypJtTj9354!O-Y?fa3{f}4(lJ<4ZSMQ}&r z=Y}^sQ=4TaTNCdH+n-W&OX}-!O4f#6v0t4CH`cS&uuE(9AO!lQEvlV*h!8S zH_5$ujC^fv%s&*I_a6xN56Xc9u0)-NH)zEo-Dm)_xrc{L8-~D1RV8Mu9!;NSLK}of zjEKeB>2a!=1Z^IXp8n0P_K3bWxc4f-hL}`7rQRIy>Rpc~w^G#F-I*XoM);z9hr|if z1=WOb=W^n1=iAsgJ);sQuj8M2XL6Qz)-LUstu)Cs+|dDmQ>?)89F^tI;wBOoOXhQI zZ<8k&6lzvftXY*>`3Ic)=B^Vk06eu7JCO_ktdvR27dTO-h@7j{fjQJrrD!>gZ;t|| zdW6Xi>0z@fBazGyv8d8wVd=DAbnsMoLlBu?jRrWkjTzg-$oL5p0_j_1h(4 zEnE}33yNMF+(T^Xe+S1va zI3FWHHM`Ex5R|qis5U)gCDY$o?qKfzpgdQJ2<=O|!l8b~*($$Ako4wAclZW+0zrc3%iT>2Dc5}xX-UsBTm>+Yjh%a*j z>S(?Phlc{qW({?%F(IsTQGsPK+CqE$$8L&i!AK5AhzP3I$=8SKF+Z!iav{(U&ZyMZ z>Q!7amtN%EIC&t@c8Uf>B_TQtv?&-3%t{Njvjdz;cHokyPw`~EmxY}9!d`TcuGjNJ_(?uqg9 zK7KNVoi?3aGVvV+obR8%^xm8!DjByvrjC;aPt>-FSBEfDWoHzYsH{v2aL9G0zrLFT zq;Mh{Htofi1O*8?7A8boeafUSJMAJzg-G%0VP8 zgbUOVd)f^o@gD?DAM&g_I32_*y2{+_eb2*m{R01S2@PQIqU6?Y@-F055InBeqI~=v zn$oO>JpvdjHYIi4}`BZTz`4Gl=^ltFUZ(l%%TNy~hBUJ*nzsTVfw6 zJpAgYhBNFUK`_3Sq^0b-u*v!}tR+I>gxS>(UWS46%PBFp4!;1wTBz33m|#JNEK`DP zd@&Je_kvzIrp!~Oc9pqzMl`ZRYQ%oeo1_qaatP+3`iv@qM`Zc%1^GEjA7_7;=LiU1 zW3N897II_~s!+TMKMO|ty*7@&RAowzvR;^2DTn{paePU$?a|~=;LfaCSmdTCJ_<@dL$@e%PKMR|4%-0ckZd)y>0#PBcbD3V^C z2Jl&(vTKv7dHMHvv|LZp={-|u^7l2{FPo`qe(;~45t+z#?p6=|qE2+&ET5-&UE9$7 zNQPQ4kCAGInK;h(*L9}#Q7}0|li>Ipn5p${11Vw_hOCU&tO-~cV13}P5mVq_bmd;- zNTp!B?FT2d&Z0A)xJ20$F0cocxhSj(XF@Ap5`K#WH=*5<%csHRlQhL`{nA(0jA=K##7k!CRzFh;X!6z4; ztH#N?I5C%@la0AX)gc+CtZH_`VnE65>bbJmsd-NY5@J1jq6NPbNH*iQ#7E9H<)BWG$n}M&V>){JGJL~ zO}>b+$a0KS`=pongwV*Kg1b`xi*xwd@f^Gl8AUeoTTm5x;P9v5^;T`)s;cCD?bC}X zPKbPLagxC*{FbBBvuElS65?+F8sGpB=BA|PE1O7{s6X2j@q)1`wIpR%TLJ3j;}2-D z=A$6)-l;d-6OUtsY(okJ)0*XOb7WRoxi_R=@IKh~_0E;MBgpDfUHj?u9aA!|)q(RE z)*b#Vh&#BHzm5Qp+df$k=3Xu|DPfp$>4&z`$z|<%L8*849}&N?BGN=gk_K_ATOc*A z?v}DaU(vZ0L7THE*`A2P2IQ9q^b5H}`5rP~*=;c4#0RKGW106|i_Gu!`&1A!MySNA z+TLOARF2Og7k3{mT-lVSx;}7_i)%X*JT_o4oYxA%(tb-_j8NYjkLK*DmUBy~Pi~`2 zw)kQhqf5g!_R+I(kvX; zRZ+QBxv(Xb3}#sR_v|oUWcw-V*nY&RtS3-`l5A za_FRD^gI@r3*UbKBb_wM7U!haoLZR(VGw`+96l<8)PmQ;o>!0=NjBlv2bCqcCNE-~ zzOj3q<(BrxMp81}zt9&wF=QB@U)i)J z1%#VXO6pn~_m!{tu(h|{C8%+$m@SDeCBP-F`z>(R-)G{!=iRq+cSSd&Iv-!7>kl>EWCVk;huA~X4^~*|YFIA_F1T3Zd{{#a#oczR zLAR!wN?X^r&twKN$1givA(cpS*Wl#EvTeB*}_pPPplM>S4%3vWH*yYlC=*)&&} zgjm`1cDc{Ku4sa8;|<&xPBZ3#oA7P!7-6$5W@#{e8sTjYo)Hc=_Hl9hb0>mP>&8vf zAH(kZ95i^rq8?cFNi6LP3-?OQk8fc%EJ*IF@Vb?bBb6cfTC}j|MX9l;_rqVvZS@O; zoV&mz{Krheza16>t~*SLT+Ph_Wfa`ypW2(KahBzA8_Dtd;*ZxmvRN<@XMWA6jOt7(@~kce%lB4Z)@)k4pt_aSn3AY&jhZaf2}Dl!6rxtJqfr|nmO!* z!l4da@QBREf-|fQ^H1&eGHJl2c8fp9f3@$|NB6^i?~7gAuYI%iXv?WJwYNXi;+(#@I^7Z+?|?nhL9!ty-gwi1 z!tqf&V+0LMXN+awk`>__DDfHCW9JAsaGhy%4sT&~WZ)YM-|~VVKWf6vVz|8P4FrD$ zD0|p6T3BjbtIyb3!x=@RJ_F~ z<~fCZ(T<=iln~J66{4>TKLU3#b#PPNYGQ7|Nx;vT@5x`bCphsW>Et0@=#wAjhnT#7 zGZ*RcyHqw&8Xy-0p(F&tkJUnnUTuFswC<(>-)1^!z`dDFYGO{C$a~0Y0+oeOV46qm zMzX$7hN<=sAx1ic`Yfb+trnZxVlZ5kIONix0XK4@!Gi|mcZEd&$g@!Xc?&qo4*2+Q7|yJU*ncTSVqF zqF!ylVJOdeX@F^$A#{L0VjcWyTyxB5fLFG=#zW~Gq2}pxpuUFC`aSEL8k>O~9U?N+s?wRRyB}{E9%|X!XpW$yZ~XWX0WkbxJT5Br)iv|!CwmVf(I?H+a^^vlopi9g4YZt2+*g1R%tQpD`L+Rlu+b9GkkI6FJ_hO(#LMmHU*(@`YmsDrsI zdnMszbMaJ;nzToonc@<)MrbEt9s7Bv%}k7Ejy$E*K;COov%s_Lul?IUonzx;yyf_7 zFYvu!K zHB#}&`#B{XxeZx?j}*nimRyEt!1|af1-O1PDV!eMb_L)n-UYRCk^l`jw)BG|?Z3eA z4zMFlC?^e=81$t9AIACUh-L7PAg8{p%3>U_h>V|=O;zfr~VU~a5<>D7p1k9%S-R{2pvd>^=AKMCjPrPzQ z>ers7u5q$arlrAf_^ihn%~L zO-DqJFWZv^nW&dlqmc)^pJ~7#7=26k5nsUF&#hjJBU%xpZU7-Q>yI7NlKoE6#Zr?r zh!l7Y9B+IAvO!opmy&`D8lawNH-zSm&bOVVL>n-M8xrG-gI79{kj;QxUN4^VLwoz6 zajR36rF^`QtUs<^&yrr_KChvGUOeW7y6TD5jAN~sJs+6ikn--*glEP#UxtvS1uo$H zUPY+L6>_Fk+}weh7wp(p<}Mk`Dk+B@@B`j@aEfJy&|zx2dov=_!z-aqB3jb6 z`z*g9^m_#e=?HdY`z`g$gEYVg#@8ppAb6muT3AOJ8Ls^yDk5EqQLDtN5Ai1t~t&HfwT=mLBGtbH{9xZ>CZ52G= z+=Xle;WPVZT1c#?e18V+HsHI@ZK4iT1%f*+;l-Z?R0gNrs`{nweVzUAIQ{EIh7bvk zpPh86hTaC8;`G=68QwL*9G+;c$^%hoa zbWiVzQdL<2lL=k=t0nG<=e8c+d$MZ>Yr(3Uf~1Gx7buxz#|0}+P>SE)CSMA=Jn2)~ zFIMjOHKax$;PewKX0bM#oxOq2Q9>s!Fr~od!rcj08?l6hp62u6mkH1p8oB(z?wb`A zQca^SXC&U-7tKrI9x-D`IFx2@8aVZia_{6xrYqOS-ui}p4t2B$CnY=Fte)%}qaf$m zj6?pRn3Ko_`!6QRFmd9d1)egE5>s*ue7pHFl|D|2Lw5T4u1^os+Xj5>0gC8NSR3*r z(=RHY?~GxDXwWIA{!F5qJipoT^Lvj)4 zI_(Ug!>;z{vYOJ}8t>oe*0#|te8R*Wnf4dXh3J4a^hAf7O9xMn6f$lHekrc@r`Rzw=AGH|_*$;&A*zrchI>M0pd7dx2f&@Gja+J;Lr#eMQaE*1Ve=nzcdWxt(||iousu%<0=grWNyOen z7{RI6(p8W5!J>m1aaQ<4L%K}-Vc z^geDVI3<-6Wrf5Y?~_-Hx)j?L%tdRToMx{qVl-R5h=I^2mqnIsp4l7?g4y75_`eWb zSQh-eh8(_n2V+(K?mI_39N(JZCj@N-klf`^JbhoNx~<&ntoe!@E(>@S67!PWhnys` z^U?Z25~A!y*HHJ6ttX5qewE6A;}q|CJf?H&)YFG!10OO?a(%lV?z0jVsjU1U+zM6^ zAw|wa$ikofwgLjr!qp)ADz!cV)Q2axp0HES#%`_n2io<4X+9CzZtO$l{Ck+oi4a-y za|+&Ca1b-S@xs^nG=%Zy-tK^&e@#hy7vj9j?6j9w+RTilO#jH%P@j7F?U`@i?paBv z`oG;Ycz`G>ne}!^8p|to9zY@k6fOM%{718mqP;^b-g85 z9tJ%^kDfg)lgu+rwaQu;C%w(2W>tD0u2cX>MTR>#)Uhd*m5!u4OZ`a$Y9C?mD3Q^e z>rXT*3M`?=4N)dCFP}WNK0IynJhDjWzTEN}K$!-g?FQN76Y&j6@c|Xe3)#dn^&UGf z>0Y9)*66n+hn!Rs)C(VM7@@p@_s4DwkSu~54jhRozPJIltEpwGDaembZtW3tdIirw z#S?QXN?#4KzTJ){Dl)Z0<8`jW@u^;E!Ss%-;p_Sia>3?++lSRcvz4SND<<@HNNq7D zhXyRn!)tmd{LT>SF$ll$MRH_5`h$>^QPVDGHl@dETTCnUkp@xupIT2ZVmZSNhheqh z=PUnCQj!C+l63ya8b+|(cpQ=R=+}RiTKTRsEv%3Qw5Zp%pd^6}?4H{`el!9^CC2!i z3s~>@xV25e*oP@!^vWK+`Gh>lMBvA70!UL>6@>g&?yD;J78TUT$wF6+VD>>J(OHD(1ECw0UMD zUKrJqc;TMoU*Y)MP!7v->UYi1#Bw=-Es)QHMUar5b=szw9FithOZ?kuU zX~FQ+E9m+n4G2c+Pz&`gfN*;NDnOSiSmefo25|d&qe#bC1CVFwyf};Kr}EXhQ}%n}^WB{G*?bJZ z4?#nIM#2Qk_6MlUpgxln?6M-U{6?;pDDJ3X9YC=g+c2p0!a(tM4CQ$4))jlHt=G%I z@&3t3nAL-P6ri} zy98|X!@Ilt{$8rJt3CEj&t4QipQ(QZ)_Z?3?PkL(|Dl~?hzo6E;g*A15X~vuy4I<= zhcBx^DI+nybTy^+hMLZ+0GZpj?mVC7hI=C0<=YGE4+A)s#oR@BF!WfKK`?P-Pqr z!TVBKb!dPH_E9`SEI3f!*Fa?EcfaS|z=`)5!)di2unYK{?)fWrO zA~uWpxycq>Wu^k3RHvXlE96ktUk%#jcCt0=B9{7nTz!4k^mnCe*7N5(pY)Ne6gCj3 zevsLl@Z(+CY`BQ@Djlo1O}noLH{lt&y(WTw`@!{#)Fust|8=H){lb~bypImfr>E1t zrk4DC!Wsq3cEB)EVyH?};rBu7hpw{cv0Q7zaKW%@H^Qx{;e;H!E^n>Y;InO)KS4np z(dFY>Y99pf1?JM#rxfIcrE|W}8A4w`@pk(6HGHQmItQg531|uk6eY*@+Dp*@CAGzN7@^Xqv zo|G|bsScpSN(O~?R03iM#toJ=l3<*O6J*VCcYO3=0!I~g+{eH%T~LsN!BaF*{chm- zn$zrv>q5ZAn5H6TnZTv;*5PJsMs(Ls$+ZJ>-D98QoM=)wnI12YPU0lC^;zL7(~2M* zo_MRmK5q{Zb1y=l(Dz1R(O1<~TS6-rDnSXJhRZhX%B_NT9PR7IHaFHfmN8@)W$ffN zrAWf_-`k3RSL}s(4@`8lLpfn?XtDLf=9NUfySQxCYrFTxTFr6ZeX$`9mlQMJlUxWjg5Z_A;F8yfmI!s50omEW7quJpZ~$a@*d#=Q)a8^c;rC4%cA01?uO zkZZD1n=>AM6d=s2JzaHqi2Fzx;RB-Feb^F`NKXUcpxW2`*|tk5QO`;WI`Afz6iw!( zE-!vPPBlTP-EQlb1&;SBL(Dr=eRLgcVMf8mR-*jMkMfRsiLO)@XZ+8O#h*n4sYPt3 zqbQu8SV{vNH3Kt6J}7F}-4*Fm?8dw-;^{;g9@*)aMVggw6VJ#+`@r0=Nk~=$op7z; z3bIylUzl=zh4061iKxAgJstT#QGe1$Q~g^&XySMwvRzO^NCoK*<(`y6P^Y>CPa5xW z_&mHxjos1cL$*KK!oj1V92IQnT8oMSNz= zz~-p2jmx7jGRC*Lmt?eviD^|N7|mb%Tr1TN_am>fvri(swQu;LXzjCxi1;-%@bB3O%(gppHxPuPV}H#NvQufDzhl~$z31e(-f6LYOZ8!^ zQO~(5qN%hmd(tVC^$2L{GC++iF@tkckOM7r&!9{2c)Mo4Do_3!)u$7YYzQWM>q#f% z+^zlfqkcbMZHgNLv}ZF|%wJ^QFz_pJ(kAJ3e5I%HDdb+MhNXqTUq_969Yf?DVi3k`UWB5Mv~mri?w&anLviqZ@A z4nV-%;sknB7y0+d=V*W`0$xJ2PloTR(tyTX(p~b8@JG^Qcfx|494Yi427E=lv3b)# z6QsfS2`iLX3`nx_*5CZ9RW|KB?$1g4@Y|}yD=4*G;2@*d#oRghL}{|Q#-Zs>31{}l z8E?UZ15M4LSr;cW$(UINm7NRPtnZ(gYmh*y!O%xZuABSqzd&s&3$C6w#i0cv-dZH7 zs0ly3_rlE8~1RIazHr zuEzrdS5<|T4>22{HwkQ~TLX-3UyBv_||pLd0* zjdiZ9PvgX5tM8Y)8_a*Na{zUO$^&wux52U2@m3Q7eHyl{HIJs8o;R_q#XjG7Y{;}5VI0vyGDNn^ zQdP)j8XMd2udKr_mBgqxdd@pIjMW_g@;+GP8pp1OM5`4a<3tS?Tz?1k-V~@m;HA!Wag(5R9w4W&~;OFHKk9zc|(`)*uF}PVqTL!afN74 zWd$*tk%a);Krcp!ew`J?*Qb>`c{$t~VLT{ND!k_^^>I#_H3KRE3$~xJ?GB!r$8-$D zhrSS`s^XzB;kFSBE?4b!X3@SON`6b(s39q?Ch2*<)CcrOO~fVwyb~!(J-u$ALAXEv zd0gXm__u69w+8@gNRfv2a%4vQjQvFaFh&^RvgYkzR~Yg1gx_H>HWC%E5sXZP_4Yi9>$N zAcNTZ=^k>GST;0Ar`5`vkZ?-LMqET zT||fU;Q2GF#|N4BEB*?4SK~UY8!Qq+G9?xkAKS(lYD?7tNM((gaBkut&i6M7XP35! zW}Y@aSyOc0$KsVLd+&GK#gvN-1t%`HGc`&?dLIkZfS7AUP_JF~U7!I}o&y-!3r%#} zj)Lx)P@$lnRduBS-Np3ZK?#tHt)n)P;2?_#?Z&?Udn|U46e0FTkXuB49pE8~Ix=`3k7iA&m#Y23-ueT7`nX(wtX7X3-`5TXOofV1ICQ}h z@-?GDMJ9&>axJD`=J8qK44Laar`*OZKwUcCgN_7yV6qXCUIttQM6OKXpO!S=r(8#Z zpH}|76@Z0^?lMWtM=3P4TP5WvQ*sd!6Tt)Rp^?M;S%!ltlD??mtnDrZXlv55lo2jw ziAdAEcmiYr{+z13n)_S)JpN}UE<&5<+sPuYH0FuKN0&O}C#W(Kr12;@GB4Y~{p3|A zNX)r6^u8V54)IsPT<}P9aZ2btWMG?v>_sVn%@>Qy))F5d+U1Dh)tW7EEPJAIQA6@Z zZt6d`Ha7frj9X9MVS&G@-kHPSME*|ez}Dn;s?zn$Q_ek|aeudu_d*fd3?0+?C&(Kj6#bR5(La)944EzQe5#Ua32c_eDzPJIwG#LRU z^ANzpa0nRR^pF`!$zwJ+OHo zwoN!#_tKcMx#n@qoA(Zm)0fN?u9&67I7OK<<*CzkgDtDIU~q3V;X&iDC)6G7Q|WRs z#P>l)=95}K>ON{q#w2)edrc9)dr(OEq!&hVB%-ZG!d(vR>~!ww-0~E0@)4_R!)d{O z{P?jM-N!p|hpr20)TW9zjYUYT4ipfJ42Q@TA6m+j?w0-T37}VdS0=P{qe(1T8*DTe z)}4=~aARY^(vQUi4Iq>PRBy%KFn7pgP4`^2Z;}f6;{0-TljAC5-9c7K_mHEr#0BT} z+qcwGuY8gc*1sr01@mHuTsYV_ldlD~WY7SXFep{Sl&lui4mp-WLO^+%34++-O}bt9 z#u*UJ1VO9S8y(+_eh~ma=}85BnwQ7%tu?J7;oY}gEn9?xnSRKX{DnUq=by(!!8qGQ zy`HSOaN{A-WaZ*M?kJ1Tf+qDfZx*F_q8E*2p1fbw?iEj;{15+!X(^M;=RswutL(y6 z*yGS&eMBtbmLtxUb-A1qrp>s?Cr@_Ug_bY7_DM#4H<#dtsV?jN`sQ=KOF{icch~Jx zT;IRUN9l6IN0mV*8~QtFL96>sVI!fagTm(2mVT)%Po_8-|Lj*pzJB!`t%kd)*L{lv_2FduJ;Pqi(6Rh`PQgXrb_@p@LG&yqN_7Q(Tr?jk z=qBQ28eTm~GYQkFXWpDx;!(t#9+Xm02B)dtb0izl4#OWu!)13;TybIYw<~0CAgoUd z@3`%o==;}xTE^z1Vs?IVTpIIsES74je{;p0y;n@kis7stR|E%u)P+`KH;V|61GACs zxv#0e*K}0!zmGSImnO;7R%-L8jMz;pXqIL31PZU{F2LumweBT}!;l zGbA)UT)jKhqU?2Vhsp4{BiBa@H+i&`z*sCI4p3RPNxH#1d(LaQthEnhX+W`2|HsqE z73C==G5)Wj(2`)wM0z(^2of$7bJ=GhuwiqJn1_y$NT)uE4MgVLSS=9GARs! z^z)bBS#rE&#!#$RgXE=~U_G{KM?zXv@pI0ME|z^^kX6OvCJ)> zZ$g+>`I4ID#NnER=KVAJG6I!vYYe1`&la%B$okl?s=P$s?p%&MqGjI4H+r8uW1W+C z4xL6)H8taI+uF^}xU)$49=-nHs;jkPL}jU&&rQTKQbn*G@OUJrO-Jap*Tb`(lWX2~ znI?f5*Slx(qNht3KlmKc3keO#Z8R&I)iKHO6BJ>)`%_yM_oSN^g&OcJm>p`}=#k@2 z$H5<>7ReehN;SZLre@)<=+j@pXZ=*N2rjT}466^}Ze9NIt(KcF_^O+Ks{gZN7Q9gx zmP;>Ue(H^Z99bK^uw0!Q@$PTOt%i}s7WBQXSL%9_8A_Vxq+LsXdJnA@M_Ctc&=m)M}cj4uam6yZq+X_OarNReP&E20vXuT{5nPPsq1&=oUv>-2p_ zhO9Y1)-^$ewZbchOu55r3iq1amvhzz`d!wyL=W@x$9}GV+a$i)3rlF}m;D|_I#)Dj zaYDcA{VR(lvzr2zi!qZ=)U>txo$^s1x3<#buYB*Hmd{5S{c~UfCXMv*J-UDvMvj}o z_HuOa$A^%A(ZX1f9^_{*7x9t@_At@drHhd?00VkOdoLpFLHPtSp44^F?Yt9$-P2y* z`-wdd`&VVVdJ0DUv+J?Llt2S^Z2G95JN8+Rqzy#<3OUGu#Z>+>ZP#CMoM61 zKCq@Qa|p_kUAW_*%a|gYg|OvNX(d+GXjd;mzvuCmrZ$=3$gROyy1Cn;6p6RZDOw2l zTt24r!|sslo39_=f;7rjVYU6!MJBL&5rOlB?l9GWMVkMRtw&i0l@#B}&&{8qgJIvYB>TDj7|n(e0J z+_=`;QMhSNXH-X64Z79_6wA}3;nm|K^&zUKf!wMN8f5?@V$Fvh7L5ex&hfZh^!0og zy_8|n^tcq%sIu65Ak~H8t+HVUK0^`&bYjKkzG}REN@}d=;*jfIw95I}OXr(_QZggRtsRixcEdpn*Z&3$7!K%1Q2z5Q$L-MV=vrSshr0Tj54YCF`XhhM zIZF3FexfGCJ^pqiKT;b>v_^8!fYsb!M=&z#=g7vUurF3ILD$XM=Qzn{q;H%tH5pWn zyD!B6P0Qn-1)nx6w|;=kQ`F%ijbAQYggkG4vMMfBYuc365!h>4|NcEBgK=Q%-QBqB ztX0}y@!o`k2W|~-aOomvtWnL{?KgCybVaBo-gqdL6^Z}Zw@|bhhI=~v-ojhoODG^6 zb@oK;D{fifZ>A|M2?)=HH)8STxs#{cRLFElrZxZ8=EEol-BV59!sM7X`rjcrd(fu{ zLi?DG(tpY-Q@Dg|xq}ZQ>Ty4P>U>z|ubiLNGPOawVBfrlOojf(d9Q!YeEq*O{y*EN z^7(DA$X7wQ0RERjwgV$%^k2%CirXMr{I^nPqyb2E{ym!P=T-l;V7c~Rze%zx_`c8H z2X6;9Bm8~6{wxjGdRv(9FrTo>xe9TScA$7rO0ZtJOw>LYbO~fx%`#qr0WVO1;`l?Azs&_JOQrwXWLh>n=t1(rMK}=M#Lq%K7ZUwjh4C9w^ra z(i8H0mIH6!smdKJ3FV&Z@i;wL=a_J-6>QVFWN(%ol+LcR`z&z`?E7yx0E+1= zT|I5q9XResQ{ z96i%j^T8v1_fFk8Q*J5Go*&cXi95y~0xLoM`7=icyXvXd)oG&}Sev~a6w&eEBAE8Q z=3=3um^LA@!>6W;tf<_O9Yn!o(HeG5E<%Vm0n2o`541XZy9 z%xl0Cytdmdt}sTn5Avy$KI`QDHgP=la;}F_orB%I0_k_0=WQSe8x-jb?DIqkDdh$B zP2HhlZp0v55e!#Lz55s<+kqkBTFpYX{|)?d6~|0eSFxwo6NhOD@8Z#@Z^GXnHO5Vd$g1fTR71!18@|Z;Id>K`rpw*H48!>K+&yB0|W%r8h6nL36BXaC${=@x3 zyd|N!e#o%*r#64KIY}dEM)mW=(7OvWneNm-{u`5u3syuKaAC_-dq9D1J`WRGQ}!p& zcYHc&(Nbd3SNb~&c=LK^DDSk>yR`I&sg9>q$^7&w!KS24>`!^ z*Qm29ESn#SSWOO@b|WK1)XStMJQjV()b8k2aoX-kVd9yJW=svc>VM zo<8Xm^*5Yv?;Bcoe8|H4{vC2)xQsQm4MO#ToR z;k-FgA|sF%`q}5t%2Y2!Gasvky-x$CAh@2d&`EW~KyIzm;F?3ybct^PF;QX5^AuuU znE$3Fd*jz8_}L4Sl&^@FV@YA9enD24ziZ6}x@{gTiW(I7FZq0|X82tKy!!x)x1V8Z z|3vJ8Cw%2m(j^+$UEqwejN@tnGIhovUDyU6suP@8P4KlbDs6ssXG z`TS?#iQMJ!O;yqZvOTe#bg2)|d*J)qv-o$POnn7TE$)`tJFB{BwGMV?k*k6pLf592 zH@{s{*raA*jYrDDDt&&du5ZK4A7Fk|1Rb2GR2!UnV2Q(WPzOVc67_fEQ&*Co40GA zU%F$PBqb5~&^N}xA~^Reyw;^+QTa(1`)0n&n*F0RuBJ00PUQi=!;~lcs$cK6}u4#M@X2ds9zPUh3JD6Fr

LFg60w}lXkZpu)3{S@Vgy{2nBU>>xZ(A-Wh--bI*k~Bb5l=D1?Rxx z-~x4UlyAxBmfLMbe*UTxQ7l@~yM^JtvrSXz#`8Ifc^&EB)dn#?NkV5zjIZc?jNmoq zUxd{i_8d^&AOK=o&&yjM3rif70uKagJidp$agx4IcwS{bZ7A{b!wHuDyBA9Rmfi6Q z@0zSPM(qEUuWs;+LmzwR5%Nc?)MWUWFwon$}{QYM%|>PQM!e&`$eR`XcL! zC&O-61c*lr`@|VSY>(#bIXtY}naxJzFuF34D>x(UWQ^#({ez{r-eReg#rs0{|BP0L z+~}`<-twY0)xKe6*V#HD^^Z+*)uVB8n^n_+2A}oyTmR2D0m4599KHGP=`2G~c^#@| z!CvaYK?#-v-`|23gXgdJig0)THwUnpa1H-np@M_X`@dJS_~?EGv-MC<6XCcrRUV?f zUE{C)b!FTvb>x|J*kB6bWoX%1viCS_;WPFD>{tPGSt%4Ns%$GK3OF1f`ua{nsHl1@ z4M2iD3GoF~(WwK_zR0h@(11BGt>V1DtiFeYgI4(gs?kOcVB(Xnh>u~^s+OKC(VW4>odsVh(gpSUhQoamR}J#aemiYBR0Hf=VE7ejXNM8zx7HX1E zFy<~;ZT&1XJ(l)Nu^FoShkA4Ctwwh_pd`Wx2T6#Syz?-F=yj*8%E2EYa+rN$mfb`j z$alj(Q$(C^@x6GC7bXOdMDeE_2~yh7y>F+oA@6+B!&ExK%Esw-3o=%nQG-;Gnh;>V zBe7|I<_K6HsF6_1xE%4pXdC>tU;KD#z#j2J$7{JNYG-_-hZ6!=ZG87jWZwMW-V}1}Cc1pGzh6f}G(^(*CO{yWLwj0HVa}ff${bL&4OO`(V zv1IN|OmAjmVoz4ZoXN(SFgm?pBiTabtK6w%NGHR*ZSRSKVkpqGLMDeCATt6ZO4ks=2}Rp@P10c4MDc;bX`6 zc+1Q?3dgL|X3mGH>j7##@Gr7pO2DrOBB&yWw32RD4PPFqyLC3rU^%|0cz5zGm*P+M zmlhYy^gdMigvjOe!Sx^;cz=ovQ?#558!{AvL1v<<8ChZD32ch$^kko*`hx0g zN+Eqb(AUT6dPCb^!{@BBKbz9HdFdJ!Yq(Zm*Zv}|hCl%nz{;8z6_Nqwiu&e-^rYYp z{{W)Gj{Pa)EduLPyxdhfw)WKCpicehcw}!dX8!>(`%bFVANy+}&)<*jy?BScVat)p zLBC|}|9e_;P3SVURCiEk`MMh8rb_HCEv;AL_%g_7O)=kXlm8~Zh-hC&{$+{5rJ<<} z(A99$60Y$SaLm1BEm!ddMN&knp*+$~ShN&}ljJ3MaV#rOTZJ1njMQ9fduFHgL}^O3 zF=_|qS#VCklQaY*0V~SSu96u`SOUI4iLM|7h}8lLLdi~)IBL8^GN(phRf>S0FX}O6 z8+eZUol9MK**B+$e4E0oQNvhxoABYNVLyqb;|%E3)4r|UHP^pynsL=gXR;{MT|YX3 zu$tA5yYGGdJ5X;>pEQ*Uzj6b4QM47gaCa*`giCk-#nE+0Y)!>tWv-3Bi?OWdwX4is zI6zmE5J~=GM5m(hmJg7Uw4--=EyX$}qVQ^v4v0%JJDiiq43wNwY)(x6tN#75TaUl2 z5!8`aM2eUGO1x3Lme9KPbMkIoq{3^0fg{wUyre1#DfHzh*eZA%y$8ml*qzs`29At} zy!a@(Muk(lGi1@xZ2IK+T>Vhdi{rdW<~q_9xGyVwfM1~~3ZNVbS_j1k>BRn!mTLO+ zAG3O`&73NSn_7it1J*r9W~{Wtu)1SFwuAgtsoVS%`^S5}Dbo+IY>F zTS95zuR)Rz1dQ8d{JUfPnX90{7sTrL%~`%Sst+WOgmG4*De~Nm+>-(i+!Ib~KjV%H_{3eei!ExZ)yst2Cau;Aw-F(N z=-*;T8rds+AU06WTDK0%+_lUf}mz~hgTFUC zEPa^q!Dn9Odr%`LKStp-*IDE=QK6?;+7csl+ZwV(#eYF}S);=tgDeDyYtL~yqW>rh z@+HFRqC6%y>Tj_P+=z*GrS=s@j$bSxFxcQ4%B=|edFIky@v{|SXO3q>R?9@Yi0Wpu z@&ps6`KxJqw88lPBH@k6;@c%SXmSvl09n65G!mJj20*F+5|^bwJ$YaG=DxP{qsP4y zZGx^sd z>Y4W(XmRJ<%%7&0V179awz_S*pZ?HL}7(|V-CN)P%Tntc=gQ}&B2*8t14E&N(vnNoVZZi~_U%^0|j6oZiD{o2Fq_TyQKGyK**aB;d=q=FPWF}l{`i|j#R~KnT@f}XjKW|{E?KcF`ilU7P)$%?(9~h?EPPVb2seMW&!Q~t`jdSvF*jdX@k<`! ziUI!Z`YZ+T97R z>9+9LS;1L3{giRHZwRCv)ZGx#^-U5YtBBv5MR+wl7l(E)}prC6DCbE+b(#`x{gJ?pwoj4g0!{6 zb{mPwcP>cZBC?%jCE%j%LaYE>hInc--fmH2bqhKAa|{2vuthGtH7CC*R*ZBY)%es7 zFNL`H4z10`2+CNw=m`4f;jLT(6eufyqX%*U@`o6=B7{65bm9vBqrx=bqeHEofo{2* zmM-Zo0RC1anty_)%bgoX?LZjM)B1a4WqzV0a(hhkLKC8cMtfy`&@!jmLQgUKSug}@ zKo!)Vyt_N;J500P<_$0N@||Hy93}GRq4UvmnCir1J;#ZD_~%A+Zbv#XpvX9!!|i47)Bl~t#e*e`G6Uzo|NKebm&xh7U;=aG~140{m=AY^J8x}mUx ze@UQT-^4EH38z07XV3ahk;&2ry&AE=L&b4XsF%&TjmXGH$bn+Rt# zh_!?}Abp-c4ZB3*%P!zv^9;^F=m{xJ9R1;+!)fgo#_LaB@ac_{9EdhJG+20Y;1tvi zMFO?l2jMFx`y;<*y?ck zfJ8_^A!iZU$Tt@CwPHIBA1G-aYUP0IYSo)v!@t|y7DWyBlr%u^y|4?Ksjl}?)pDb;m?&<#07fF)Yu_@pulsqJs6ZV zMsf@;?R}k`)AZ|R!0TUw#DpjB$R(IyUNUQbmKQTUDO7wwWILdF>!>>5rSs8jMjLJm zB8R5t124pc()tr%YhH(dx&c&h#>CcpAoS@5SW~i>i3>Hhz*?68a}5we&(N4gkN5x$ z%MQR>f%Rt20ZG2|z>q8p08WIw0`#cYEB@uEa@23DPaQDP1xIJwLc zJ?a5whd~8N<;}n|HSM_%2qT=U$Sl&w)iv1DXyoqJkW`Na_A&|SKsor2?tI{alz zU~RugmK@WLlgDtU|F!3;N4CVw^z2U