Compare commits

..

2 Commits

27 changed files with 8519 additions and 28 deletions

View File

@ -9,6 +9,7 @@ using Marco.Pms.Model.Expenses;
using Marco.Pms.Model.Forum;
using Marco.Pms.Model.Mail;
using Marco.Pms.Model.Master;
using Marco.Pms.Model.OrganizationModel;
using Marco.Pms.Model.Projects;
using Marco.Pms.Model.Roles;
using Marco.Pms.Model.TenantModels;
@ -39,6 +40,8 @@ namespace Marco.Pms.DataAccess.Data
public DbSet<SubscriptionPlanDetails> SubscriptionPlanDetails { get; set; }
public DbSet<TenantSubscriptions> TenantSubscriptions { get; set; }
public DbSet<ApplicationUser> ApplicationUsers { get; set; }
public DbSet<ServiceMaster> ServiceMasters { get; set; }
public DbSet<ActivityGroupMaster> ActivityGroupMasters { get; set; }
public DbSet<ActivityMaster> ActivityMasters { get; set; }
public DbSet<Project> Projects { get; set; }
public DbSet<ProjectAllocation> ProjectAllocations { get; set; }
@ -117,6 +120,17 @@ namespace Marco.Pms.DataAccess.Data
public DbSet<AttachmentVersionMapping> AttachmentVersionMappings { get; set; }
public DbSet<AttachmentTagMapping> AttachmentTagMappings { get; set; }
public DbSet<GlobalServiceMaster> GlobalServiceMasters { get; set; }
public DbSet<GlobalActivityGroupMaster> GlobalActivityGroupMasters { get; set; }
public DbSet<GlobalActivityMaster> GlobalActivityMasters { get; set; }
public DbSet<Organization> Organizations { get; set; }
public DbSet<OrgTypeMaster> OrgTypeMasters { get; set; }
public DbSet<TenantOrgMapping> TenantOrgMappings { get; set; }
public DbSet<OrgServiceMapping> OrgServiceMappings { get; set; }
public DbSet<ProjectServiceMapping> ProjectServiceMappings { get; set; }
public DbSet<ProjectOrgMapping> ProjectOrgMappings { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
@ -132,6 +146,7 @@ namespace Marco.Pms.DataAccess.Data
.HasForeignKey(e => e.UserId)
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity<TenantStatus>().HasData(
new TenantStatus
{
@ -150,6 +165,21 @@ namespace Marco.Pms.DataAccess.Data
}
);
modelBuilder.Entity<Organization>().HasData(
new Organization
{
Id = Guid.Parse("4e3a6d31-c640-40f7-8d67-6c109fcdb9ea"),
Name = "MarcoBMS",
ContactPerson = "Admin",
Email = "admin@marcoaiot.com",
ContactNumber = "123456789",
Address = "2nd Floor, Fullora Building, Tejas CHS, behind Kothrud Stand, Tejas Society, Dahanukar Colony, Kothrud, Pune, Maharashtra 411038",
CreatedAt = DateTime.MinValue,
SPRID = 5400,
IsActive = true
}
);
modelBuilder.Entity<Tenant>().HasData(
new Tenant
{
@ -197,6 +227,7 @@ namespace Marco.Pms.DataAccess.Data
Status = "Completed"
}
);
modelBuilder.Entity<Project>().HasData(
new Project
{
@ -226,6 +257,7 @@ namespace Marco.Pms.DataAccess.Data
new Industry { Id = Guid.Parse("8a0d6134-2dbe-4e0a-b250-ff34cb7b9df0"), Name = "Education & Training" }
);
modelBuilder.Entity<TicketStatusMaster>().HasData(
new TicketStatusMaster
{
@ -273,6 +305,7 @@ namespace Marco.Pms.DataAccess.Data
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
}
);
modelBuilder.Entity<TicketTypeMaster>().HasData(
new TicketTypeMaster
{
@ -291,6 +324,7 @@ namespace Marco.Pms.DataAccess.Data
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
}
);
modelBuilder.Entity<TicketPriorityMaster>().HasData(
new TicketPriorityMaster
{
@ -338,6 +372,7 @@ namespace Marco.Pms.DataAccess.Data
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
}
);
modelBuilder.Entity<TicketTagMaster>().HasData(
new TicketTagMaster
{
@ -383,6 +418,7 @@ namespace Marco.Pms.DataAccess.Data
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
}
);
modelBuilder.Entity<WorkStatusMaster>().HasData(
new WorkStatusMaster
{
@ -750,7 +786,7 @@ namespace Marco.Pms.DataAccess.Data
Name = "Project Documents",
Description = "Project documents are formal records that outline the plans, progress, and details necessary to execute and manage a project effectively.",
EntityTypeId = Guid.Parse("c8fe7115-aa27-43bc-99f4-7b05fabe436e"),
CreatedAt = DateTime.UtcNow,
CreatedAt = new DateTime(2025, 9, 15, 12, 42, 3, 202, DateTimeKind.Utc),
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
},
new DocumentCategoryMaster
@ -759,10 +795,10 @@ namespace Marco.Pms.DataAccess.Data
Name = "Employee Documents",
Description = "Employment details along with legal IDs like passports or drivers licenses to verify identity and work authorization.",
EntityTypeId = Guid.Parse("dbb9555a-7a0c-40f2-a9ed-f0463f1ceed7"),
CreatedAt = DateTime.UtcNow,
CreatedAt = new DateTime(2025, 9, 15, 12, 42, 3, 202, DateTimeKind.Utc),
TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")
}
);
);
modelBuilder.Entity<DocumentTypeMaster>().HasData(
new DocumentTypeMaster
@ -945,6 +981,29 @@ namespace Marco.Pms.DataAccess.Data
}
);
modelBuilder.Entity<OrgTypeMaster>().HasData(
new OrgTypeMaster
{
Id = Guid.Parse("743806fe-d991-4079-b223-e4e2da44f435"),
Name = "Tenant"
},
new OrgTypeMaster
{
Id = Guid.Parse("5ee49bcd-b6d3-482f-9aaf-484afe04abec"),
Name = "Service Provider"
},
new OrgTypeMaster
{
Id = Guid.Parse("a283356a-9b02-4029-afb7-e65c703efdd4"),
Name = "Sub-Contractor"
},
new OrgTypeMaster
{
Id = Guid.Parse("b1877a3b-8832-47b1-bbe3-dc7e98672f49"),
Name = "PMC"
}
);
modelBuilder.Entity<Module>().HasData(
new Module
{

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,757 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional
namespace Marco.Pms.DataAccess.Migrations
{
/// <inheritdoc />
public partial class Added_Tables_Related_To_Organizations : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.UpdateData(
table: "ActivityMasters",
keyColumn: "UnitOfMeasurement",
keyValue: null,
column: "UnitOfMeasurement",
value: "");
migrationBuilder.AlterColumn<string>(
name: "UnitOfMeasurement",
table: "ActivityMasters",
type: "longtext",
nullable: false,
oldClrType: typeof(string),
oldType: "longtext",
oldNullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.UpdateData(
table: "ActivityMasters",
keyColumn: "ActivityName",
keyValue: null,
column: "ActivityName",
value: "");
migrationBuilder.AlterColumn<string>(
name: "ActivityName",
table: "ActivityMasters",
type: "longtext",
nullable: false,
oldClrType: typeof(string),
oldType: "longtext",
oldNullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AddColumn<Guid>(
name: "ActivityGroupId",
table: "ActivityMasters",
type: "char(36)",
nullable: true,
collation: "ascii_general_ci");
migrationBuilder.AddColumn<bool>(
name: "IsSystem",
table: "ActivityMasters",
type: "tinyint(1)",
nullable: false,
defaultValue: false);
migrationBuilder.CreateTable(
name: "GlobalServiceMasters",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Name = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Description = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_GlobalServiceMasters", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "Organizations",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Name = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Email = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ContactPerson = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Address = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ContactNumber = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
SPRID = table.Column<double>(type: "double", nullable: false),
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
CreatedById = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
UpdatedById = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
UpdatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: true),
IsActive = table.Column<bool>(type: "tinyint(1)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Organizations", x => x.Id);
table.ForeignKey(
name: "FK_Organizations_Employees_CreatedById",
column: x => x.CreatedById,
principalTable: "Employees",
principalColumn: "Id");
table.ForeignKey(
name: "FK_Organizations_Employees_UpdatedById",
column: x => x.UpdatedById,
principalTable: "Employees",
principalColumn: "Id");
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "OrgTypeMasters",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Name = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_OrgTypeMasters", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "ServiceMasters",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Name = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Description = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
IsSystem = table.Column<bool>(type: "tinyint(1)", nullable: false),
TenantId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci")
},
constraints: table =>
{
table.PrimaryKey("PK_ServiceMasters", x => x.Id);
table.ForeignKey(
name: "FK_ServiceMasters_Tenants_TenantId",
column: x => x.TenantId,
principalTable: "Tenants",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "GlobalActivityGroupMasters",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Name = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Description = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ServiceId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci")
},
constraints: table =>
{
table.PrimaryKey("PK_GlobalActivityGroupMasters", x => x.Id);
table.ForeignKey(
name: "FK_GlobalActivityGroupMasters_GlobalServiceMasters_ServiceId",
column: x => x.ServiceId,
principalTable: "GlobalServiceMasters",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "OrgServiceMappings",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
OrganizationId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
ServiceId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci")
},
constraints: table =>
{
table.PrimaryKey("PK_OrgServiceMappings", x => x.Id);
table.ForeignKey(
name: "FK_OrgServiceMappings_GlobalServiceMasters_ServiceId",
column: x => x.ServiceId,
principalTable: "GlobalServiceMasters",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_OrgServiceMappings_Organizations_OrganizationId",
column: x => x.OrganizationId,
principalTable: "Organizations",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "TenantOrgMappings",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
OrganizationId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
SPRID = table.Column<double>(type: "double", nullable: false),
IsActive = table.Column<bool>(type: "tinyint(1)", nullable: false),
AssignedDate = table.Column<DateTime>(type: "datetime(6)", nullable: false),
ReassignedDate = table.Column<DateTime>(type: "datetime(6)", nullable: true),
TenantId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci")
},
constraints: table =>
{
table.PrimaryKey("PK_TenantOrgMappings", x => x.Id);
table.ForeignKey(
name: "FK_TenantOrgMappings_Organizations_OrganizationId",
column: x => x.OrganizationId,
principalTable: "Organizations",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_TenantOrgMappings_Tenants_TenantId",
column: x => x.TenantId,
principalTable: "Tenants",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "ActivityGroupMasters",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Name = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Description = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ServiceId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
IsSystem = table.Column<bool>(type: "tinyint(1)", nullable: false),
TenantId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci")
},
constraints: table =>
{
table.PrimaryKey("PK_ActivityGroupMasters", x => x.Id);
table.ForeignKey(
name: "FK_ActivityGroupMasters_ServiceMasters_ServiceId",
column: x => x.ServiceId,
principalTable: "ServiceMasters",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_ActivityGroupMasters_Tenants_TenantId",
column: x => x.TenantId,
principalTable: "Tenants",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "ProjectServiceMappings",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
ServiceId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
ProjectId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
PlannedStartDate = table.Column<DateTime>(type: "datetime(6)", nullable: false),
PlannedEndDate = table.Column<DateTime>(type: "datetime(6)", nullable: false),
ActualStartDate = table.Column<DateTime>(type: "datetime(6)", nullable: false),
ActualEndDate = table.Column<DateTime>(type: "datetime(6)", nullable: true),
TenantId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci")
},
constraints: table =>
{
table.PrimaryKey("PK_ProjectServiceMappings", x => x.Id);
table.ForeignKey(
name: "FK_ProjectServiceMappings_Projects_ProjectId",
column: x => x.ProjectId,
principalTable: "Projects",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_ProjectServiceMappings_ServiceMasters_ServiceId",
column: x => x.ServiceId,
principalTable: "ServiceMasters",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_ProjectServiceMappings_Tenants_TenantId",
column: x => x.TenantId,
principalTable: "Tenants",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "GlobalActivityMasters",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
ActivityName = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
UnitOfMeasurement = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ActivityGroupId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
IsActive = table.Column<bool>(type: "tinyint(1)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_GlobalActivityMasters", x => x.Id);
table.ForeignKey(
name: "FK_GlobalActivityMasters_GlobalActivityGroupMasters_ActivityGro~",
column: x => x.ActivityGroupId,
principalTable: "GlobalActivityGroupMasters",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "ProjectOrgMappings",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
OrganizationId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
ParentOrganizationId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
ProjectServiceId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
OrganizationTypeId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
AssignedDate = table.Column<DateTime>(type: "datetime(6)", nullable: false),
CompletionDate = table.Column<DateTime>(type: "datetime(6)", nullable: true),
TenantId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci")
},
constraints: table =>
{
table.PrimaryKey("PK_ProjectOrgMappings", x => x.Id);
table.ForeignKey(
name: "FK_ProjectOrgMappings_OrgTypeMasters_OrganizationTypeId",
column: x => x.OrganizationTypeId,
principalTable: "OrgTypeMasters",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_ProjectOrgMappings_Organizations_OrganizationId",
column: x => x.OrganizationId,
principalTable: "Organizations",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_ProjectOrgMappings_Organizations_ParentOrganizationId",
column: x => x.ParentOrganizationId,
principalTable: "Organizations",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_ProjectOrgMappings_ProjectServiceMappings_ProjectServiceId",
column: x => x.ProjectServiceId,
principalTable: "ProjectServiceMappings",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_ProjectOrgMappings_Tenants_TenantId",
column: x => x.TenantId,
principalTable: "Tenants",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.UpdateData(
table: "DocumentCategoryMasters",
keyColumn: "Id",
keyValue: new Guid("2d9fb9cf-db53-476b-a452-492e88e2b51f"),
column: "CreatedAt",
value: new DateTime(2025, 9, 15, 12, 42, 3, 202, DateTimeKind.Utc));
migrationBuilder.UpdateData(
table: "DocumentCategoryMasters",
keyColumn: "Id",
keyValue: new Guid("cfbff269-072b-477a-b48b-72cdc57dd1d3"),
column: "CreatedAt",
value: new DateTime(2025, 9, 15, 12, 42, 3, 202, DateTimeKind.Utc));
migrationBuilder.UpdateData(
table: "DocumentTypeMasters",
keyColumn: "Id",
keyValue: new Guid("07ca7182-9ac0-4407-b988-59901170cb86"),
column: "CreatedAt",
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc));
migrationBuilder.UpdateData(
table: "DocumentTypeMasters",
keyColumn: "Id",
keyValue: new Guid("16c40b80-c207-4a0c-a4d3-381414afe35a"),
column: "CreatedAt",
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc));
migrationBuilder.UpdateData(
table: "DocumentTypeMasters",
keyColumn: "Id",
keyValue: new Guid("260abd7e-c96d-4ae4-a29b-9b5bb5d24ebd"),
column: "CreatedAt",
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc));
migrationBuilder.UpdateData(
table: "DocumentTypeMasters",
keyColumn: "Id",
keyValue: new Guid("2d1d7441-46a8-425e-9395-94d0956f8e91"),
column: "CreatedAt",
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc));
migrationBuilder.UpdateData(
table: "DocumentTypeMasters",
keyColumn: "Id",
keyValue: new Guid("336225ac-67f3-4e14-ba7a-8fad03cf2832"),
column: "CreatedAt",
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc));
migrationBuilder.UpdateData(
table: "DocumentTypeMasters",
keyColumn: "Id",
keyValue: new Guid("5668de00-5d84-47f7-b9b5-7fefd1219f05"),
column: "CreatedAt",
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc));
migrationBuilder.UpdateData(
table: "DocumentTypeMasters",
keyColumn: "Id",
keyValue: new Guid("6344393b-9bb1-45f8-b620-9f6e279d012c"),
column: "CreatedAt",
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc));
migrationBuilder.UpdateData(
table: "DocumentTypeMasters",
keyColumn: "Id",
keyValue: new Guid("7cc41c91-23cb-442b-badd-f932138d149f"),
column: "CreatedAt",
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc));
migrationBuilder.UpdateData(
table: "DocumentTypeMasters",
keyColumn: "Id",
keyValue: new Guid("846e89a9-5735-45ec-a21d-c97f85a94ada"),
column: "CreatedAt",
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc));
migrationBuilder.UpdateData(
table: "DocumentTypeMasters",
keyColumn: "Id",
keyValue: new Guid("a1a190ba-c4a8-432f-b26d-1231ca1d44bc"),
column: "CreatedAt",
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc));
migrationBuilder.UpdateData(
table: "DocumentTypeMasters",
keyColumn: "Id",
keyValue: new Guid("f76d8215-d399-4f0e-b414-12e427f50be3"),
column: "CreatedAt",
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc));
migrationBuilder.InsertData(
table: "OrgTypeMasters",
columns: new[] { "Id", "Name" },
values: new object[,]
{
{ new Guid("5ee49bcd-b6d3-482f-9aaf-484afe04abec"), "Service Provider" },
{ new Guid("743806fe-d991-4079-b223-e4e2da44f435"), "Tenant" },
{ new Guid("a283356a-9b02-4029-afb7-e65c703efdd4"), "Sub-Contractor" },
{ new Guid("b1877a3b-8832-47b1-bbe3-dc7e98672f49"), "PMC" }
});
migrationBuilder.InsertData(
table: "Organizations",
columns: new[] { "Id", "Address", "ContactNumber", "ContactPerson", "CreatedAt", "CreatedById", "Email", "IsActive", "Name", "SPRID", "UpdatedAt", "UpdatedById" },
values: new object[] { new Guid("4e3a6d31-c640-40f7-8d67-6c109fcdb9ea"), "2nd Floor, Fullora Building, Tejas CHS, behind Kothrud Stand, Tejas Society, Dahanukar Colony, Kothrud, Pune, Maharashtra 411038", "123456789", "Admin", new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), null, "admin@marcoaiot.com", true, "MarcoBMS", 5400.0, null, null });
migrationBuilder.CreateIndex(
name: "IX_ActivityMasters_ActivityGroupId",
table: "ActivityMasters",
column: "ActivityGroupId");
migrationBuilder.CreateIndex(
name: "IX_ActivityGroupMasters_ServiceId",
table: "ActivityGroupMasters",
column: "ServiceId");
migrationBuilder.CreateIndex(
name: "IX_ActivityGroupMasters_TenantId",
table: "ActivityGroupMasters",
column: "TenantId");
migrationBuilder.CreateIndex(
name: "IX_GlobalActivityGroupMasters_ServiceId",
table: "GlobalActivityGroupMasters",
column: "ServiceId");
migrationBuilder.CreateIndex(
name: "IX_GlobalActivityMasters_ActivityGroupId",
table: "GlobalActivityMasters",
column: "ActivityGroupId");
migrationBuilder.CreateIndex(
name: "IX_Organizations_CreatedById",
table: "Organizations",
column: "CreatedById");
migrationBuilder.CreateIndex(
name: "IX_Organizations_UpdatedById",
table: "Organizations",
column: "UpdatedById");
migrationBuilder.CreateIndex(
name: "IX_OrgServiceMappings_OrganizationId",
table: "OrgServiceMappings",
column: "OrganizationId");
migrationBuilder.CreateIndex(
name: "IX_OrgServiceMappings_ServiceId",
table: "OrgServiceMappings",
column: "ServiceId");
migrationBuilder.CreateIndex(
name: "IX_ProjectOrgMappings_OrganizationId",
table: "ProjectOrgMappings",
column: "OrganizationId");
migrationBuilder.CreateIndex(
name: "IX_ProjectOrgMappings_OrganizationTypeId",
table: "ProjectOrgMappings",
column: "OrganizationTypeId");
migrationBuilder.CreateIndex(
name: "IX_ProjectOrgMappings_ParentOrganizationId",
table: "ProjectOrgMappings",
column: "ParentOrganizationId");
migrationBuilder.CreateIndex(
name: "IX_ProjectOrgMappings_ProjectServiceId",
table: "ProjectOrgMappings",
column: "ProjectServiceId");
migrationBuilder.CreateIndex(
name: "IX_ProjectOrgMappings_TenantId",
table: "ProjectOrgMappings",
column: "TenantId");
migrationBuilder.CreateIndex(
name: "IX_ProjectServiceMappings_ProjectId",
table: "ProjectServiceMappings",
column: "ProjectId");
migrationBuilder.CreateIndex(
name: "IX_ProjectServiceMappings_ServiceId",
table: "ProjectServiceMappings",
column: "ServiceId");
migrationBuilder.CreateIndex(
name: "IX_ProjectServiceMappings_TenantId",
table: "ProjectServiceMappings",
column: "TenantId");
migrationBuilder.CreateIndex(
name: "IX_ServiceMasters_TenantId",
table: "ServiceMasters",
column: "TenantId");
migrationBuilder.CreateIndex(
name: "IX_TenantOrgMappings_OrganizationId",
table: "TenantOrgMappings",
column: "OrganizationId");
migrationBuilder.CreateIndex(
name: "IX_TenantOrgMappings_TenantId",
table: "TenantOrgMappings",
column: "TenantId");
migrationBuilder.AddForeignKey(
name: "FK_ActivityMasters_ActivityGroupMasters_ActivityGroupId",
table: "ActivityMasters",
column: "ActivityGroupId",
principalTable: "ActivityGroupMasters",
principalColumn: "Id");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_ActivityMasters_ActivityGroupMasters_ActivityGroupId",
table: "ActivityMasters");
migrationBuilder.DropTable(
name: "ActivityGroupMasters");
migrationBuilder.DropTable(
name: "GlobalActivityMasters");
migrationBuilder.DropTable(
name: "OrgServiceMappings");
migrationBuilder.DropTable(
name: "ProjectOrgMappings");
migrationBuilder.DropTable(
name: "TenantOrgMappings");
migrationBuilder.DropTable(
name: "GlobalActivityGroupMasters");
migrationBuilder.DropTable(
name: "OrgTypeMasters");
migrationBuilder.DropTable(
name: "ProjectServiceMappings");
migrationBuilder.DropTable(
name: "Organizations");
migrationBuilder.DropTable(
name: "GlobalServiceMasters");
migrationBuilder.DropTable(
name: "ServiceMasters");
migrationBuilder.DropIndex(
name: "IX_ActivityMasters_ActivityGroupId",
table: "ActivityMasters");
migrationBuilder.DropColumn(
name: "ActivityGroupId",
table: "ActivityMasters");
migrationBuilder.DropColumn(
name: "IsSystem",
table: "ActivityMasters");
migrationBuilder.AlterColumn<string>(
name: "UnitOfMeasurement",
table: "ActivityMasters",
type: "longtext",
nullable: true,
oldClrType: typeof(string),
oldType: "longtext")
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AlterColumn<string>(
name: "ActivityName",
table: "ActivityMasters",
type: "longtext",
nullable: true,
oldClrType: typeof(string),
oldType: "longtext")
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.UpdateData(
table: "DocumentCategoryMasters",
keyColumn: "Id",
keyValue: new Guid("2d9fb9cf-db53-476b-a452-492e88e2b51f"),
column: "CreatedAt",
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6233));
migrationBuilder.UpdateData(
table: "DocumentCategoryMasters",
keyColumn: "Id",
keyValue: new Guid("cfbff269-072b-477a-b48b-72cdc57dd1d3"),
column: "CreatedAt",
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6226));
migrationBuilder.UpdateData(
table: "DocumentTypeMasters",
keyColumn: "Id",
keyValue: new Guid("07ca7182-9ac0-4407-b988-59901170cb86"),
column: "CreatedAt",
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6307));
migrationBuilder.UpdateData(
table: "DocumentTypeMasters",
keyColumn: "Id",
keyValue: new Guid("16c40b80-c207-4a0c-a4d3-381414afe35a"),
column: "CreatedAt",
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6290));
migrationBuilder.UpdateData(
table: "DocumentTypeMasters",
keyColumn: "Id",
keyValue: new Guid("260abd7e-c96d-4ae4-a29b-9b5bb5d24ebd"),
column: "CreatedAt",
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6298));
migrationBuilder.UpdateData(
table: "DocumentTypeMasters",
keyColumn: "Id",
keyValue: new Guid("2d1d7441-46a8-425e-9395-94d0956f8e91"),
column: "CreatedAt",
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6286));
migrationBuilder.UpdateData(
table: "DocumentTypeMasters",
keyColumn: "Id",
keyValue: new Guid("336225ac-67f3-4e14-ba7a-8fad03cf2832"),
column: "CreatedAt",
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6275));
migrationBuilder.UpdateData(
table: "DocumentTypeMasters",
keyColumn: "Id",
keyValue: new Guid("5668de00-5d84-47f7-b9b5-7fefd1219f05"),
column: "CreatedAt",
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6319));
migrationBuilder.UpdateData(
table: "DocumentTypeMasters",
keyColumn: "Id",
keyValue: new Guid("6344393b-9bb1-45f8-b620-9f6e279d012c"),
column: "CreatedAt",
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6282));
migrationBuilder.UpdateData(
table: "DocumentTypeMasters",
keyColumn: "Id",
keyValue: new Guid("7cc41c91-23cb-442b-badd-f932138d149f"),
column: "CreatedAt",
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6314));
migrationBuilder.UpdateData(
table: "DocumentTypeMasters",
keyColumn: "Id",
keyValue: new Guid("846e89a9-5735-45ec-a21d-c97f85a94ada"),
column: "CreatedAt",
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6311));
migrationBuilder.UpdateData(
table: "DocumentTypeMasters",
keyColumn: "Id",
keyValue: new Guid("a1a190ba-c4a8-432f-b26d-1231ca1d44bc"),
column: "CreatedAt",
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6302));
migrationBuilder.UpdateData(
table: "DocumentTypeMasters",
keyColumn: "Id",
keyValue: new Guid("f76d8215-d399-4f0e-b414-12e427f50be3"),
column: "CreatedAt",
value: new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6295));
}
}
}

View File

@ -931,7 +931,7 @@ namespace Marco.Pms.DataAccess.Migrations
new
{
Id = new Guid("cfbff269-072b-477a-b48b-72cdc57dd1d3"),
CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6226),
CreatedAt = new DateTime(2025, 9, 15, 12, 42, 3, 202, DateTimeKind.Utc),
Description = "Project documents are formal records that outline the plans, progress, and details necessary to execute and manage a project effectively.",
EntityTypeId = new Guid("c8fe7115-aa27-43bc-99f4-7b05fabe436e"),
Name = "Project Documents",
@ -940,7 +940,7 @@ namespace Marco.Pms.DataAccess.Migrations
new
{
Id = new Guid("2d9fb9cf-db53-476b-a452-492e88e2b51f"),
CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6233),
CreatedAt = new DateTime(2025, 9, 15, 12, 42, 3, 202, DateTimeKind.Utc),
Description = "Employment details along with legal IDs like passports or drivers licenses to verify identity and work authorization.",
EntityTypeId = new Guid("dbb9555a-7a0c-40f2-a9ed-f0463f1ceed7"),
Name = "Employee Documents",
@ -1026,7 +1026,7 @@ namespace Marco.Pms.DataAccess.Migrations
{
Id = new Guid("336225ac-67f3-4e14-ba7a-8fad03cf2832"),
AllowedContentType = "application/pdf,image/jpeg",
CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6275),
CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc),
DocumentCategoryId = new Guid("2d9fb9cf-db53-476b-a452-492e88e2b51f"),
IsActive = true,
IsMandatory = true,
@ -1041,7 +1041,7 @@ namespace Marco.Pms.DataAccess.Migrations
{
Id = new Guid("6344393b-9bb1-45f8-b620-9f6e279d012c"),
AllowedContentType = "application/pdf,image/jpeg",
CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6282),
CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc),
DocumentCategoryId = new Guid("2d9fb9cf-db53-476b-a452-492e88e2b51f"),
IsActive = true,
IsMandatory = true,
@ -1056,7 +1056,7 @@ namespace Marco.Pms.DataAccess.Migrations
{
Id = new Guid("2d1d7441-46a8-425e-9395-94d0956f8e91"),
AllowedContentType = "application/pdf,image/jpeg",
CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6286),
CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc),
DocumentCategoryId = new Guid("2d9fb9cf-db53-476b-a452-492e88e2b51f"),
IsActive = true,
IsMandatory = true,
@ -1071,7 +1071,7 @@ namespace Marco.Pms.DataAccess.Migrations
{
Id = new Guid("16c40b80-c207-4a0c-a4d3-381414afe35a"),
AllowedContentType = "application/pdf,image/jpeg",
CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6290),
CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc),
DocumentCategoryId = new Guid("2d9fb9cf-db53-476b-a452-492e88e2b51f"),
IsActive = true,
IsMandatory = true,
@ -1086,7 +1086,7 @@ namespace Marco.Pms.DataAccess.Migrations
{
Id = new Guid("f76d8215-d399-4f0e-b414-12e427f50be3"),
AllowedContentType = "application/pdf,image/jpeg",
CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6295),
CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc),
DocumentCategoryId = new Guid("2d9fb9cf-db53-476b-a452-492e88e2b51f"),
IsActive = true,
IsMandatory = true,
@ -1101,7 +1101,7 @@ namespace Marco.Pms.DataAccess.Migrations
{
Id = new Guid("260abd7e-c96d-4ae4-a29b-9b5bb5d24ebd"),
AllowedContentType = "application/pdf,application/msword,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.openxmlformats-officedocument.wordprocessingml.document",
CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6298),
CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc),
DocumentCategoryId = new Guid("cfbff269-072b-477a-b48b-72cdc57dd1d3"),
IsActive = true,
IsMandatory = false,
@ -1115,7 +1115,7 @@ namespace Marco.Pms.DataAccess.Migrations
{
Id = new Guid("a1a190ba-c4a8-432f-b26d-1231ca1d44bc"),
AllowedContentType = "application/pdf,application/msword,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.openxmlformats-officedocument.wordprocessingml.document",
CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6302),
CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc),
DocumentCategoryId = new Guid("cfbff269-072b-477a-b48b-72cdc57dd1d3"),
IsActive = true,
IsMandatory = false,
@ -1129,7 +1129,7 @@ namespace Marco.Pms.DataAccess.Migrations
{
Id = new Guid("07ca7182-9ac0-4407-b988-59901170cb86"),
AllowedContentType = "application/pdf,application/msword,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.openxmlformats-officedocument.wordprocessingml.document",
CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6307),
CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc),
DocumentCategoryId = new Guid("cfbff269-072b-477a-b48b-72cdc57dd1d3"),
IsActive = true,
IsMandatory = false,
@ -1143,7 +1143,7 @@ namespace Marco.Pms.DataAccess.Migrations
{
Id = new Guid("846e89a9-5735-45ec-a21d-c97f85a94ada"),
AllowedContentType = "application/pdf,application/msword,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.openxmlformats-officedocument.wordprocessingml.document",
CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6311),
CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc),
DocumentCategoryId = new Guid("cfbff269-072b-477a-b48b-72cdc57dd1d3"),
IsActive = true,
IsMandatory = false,
@ -1157,7 +1157,7 @@ namespace Marco.Pms.DataAccess.Migrations
{
Id = new Guid("7cc41c91-23cb-442b-badd-f932138d149f"),
AllowedContentType = "application/pdf,application/msword,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.openxmlformats-officedocument.wordprocessingml.document",
CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6314),
CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc),
DocumentCategoryId = new Guid("cfbff269-072b-477a-b48b-72cdc57dd1d3"),
IsActive = true,
IsMandatory = false,
@ -1171,7 +1171,7 @@ namespace Marco.Pms.DataAccess.Migrations
{
Id = new Guid("5668de00-5d84-47f7-b9b5-7fefd1219f05"),
AllowedContentType = "application/pdf,image/vnd.dwg,application/acad",
CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc).AddTicks(6319),
CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc),
DocumentCategoryId = new Guid("cfbff269-072b-477a-b48b-72cdc57dd1d3"),
IsActive = true,
IsMandatory = false,
@ -2346,26 +2346,68 @@ namespace Marco.Pms.DataAccess.Migrations
b.ToTable("MailingList");
});
modelBuilder.Entity("Marco.Pms.Model.Master.ActivityGroupMaster", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("longtext");
b.Property<bool>("IsSystem")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.Property<Guid>("ServiceId")
.HasColumnType("char(36)");
b.Property<Guid>("TenantId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("ServiceId");
b.HasIndex("TenantId");
b.ToTable("ActivityGroupMasters");
});
modelBuilder.Entity("Marco.Pms.Model.Master.ActivityMaster", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<Guid?>("ActivityGroupId")
.HasColumnType("char(36)");
b.Property<string>("ActivityName")
.IsRequired()
.HasColumnType("longtext");
b.Property<bool>("IsActive")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsSystem")
.HasColumnType("tinyint(1)");
b.Property<Guid>("TenantId")
.HasColumnType("char(36)");
b.Property<string>("UnitOfMeasurement")
.IsRequired()
.HasColumnType("longtext");
b.HasKey("Id");
b.HasIndex("ActivityGroupId");
b.HasIndex("TenantId");
b.ToTable("ActivityMasters");
@ -2796,6 +2838,76 @@ namespace Marco.Pms.DataAccess.Migrations
});
});
modelBuilder.Entity("Marco.Pms.Model.Master.GlobalActivityGroupMaster", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.Property<Guid>("ServiceId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("ServiceId");
b.ToTable("GlobalActivityGroupMasters");
});
modelBuilder.Entity("Marco.Pms.Model.Master.GlobalActivityMaster", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<Guid>("ActivityGroupId")
.HasColumnType("char(36)");
b.Property<string>("ActivityName")
.IsRequired()
.HasColumnType("longtext");
b.Property<bool>("IsActive")
.HasColumnType("tinyint(1)");
b.Property<string>("UnitOfMeasurement")
.IsRequired()
.HasColumnType("longtext");
b.HasKey("Id");
b.HasIndex("ActivityGroupId");
b.ToTable("GlobalActivityMasters");
});
modelBuilder.Entity("Marco.Pms.Model.Master.GlobalServiceMaster", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.HasKey("Id");
b.ToTable("GlobalServiceMasters");
});
modelBuilder.Entity("Marco.Pms.Model.Master.Industry", b =>
{
b.Property<Guid>("Id")
@ -2970,6 +3082,33 @@ namespace Marco.Pms.DataAccess.Migrations
});
});
modelBuilder.Entity("Marco.Pms.Model.Master.ServiceMaster", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("longtext");
b.Property<bool>("IsSystem")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.Property<Guid>("TenantId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId");
b.ToTable("ServiceMasters");
});
modelBuilder.Entity("Marco.Pms.Model.Master.StatusMaster", b =>
{
b.Property<Guid>("Id")
@ -3371,6 +3510,244 @@ namespace Marco.Pms.DataAccess.Migrations
});
});
modelBuilder.Entity("Marco.Pms.Model.OrganizationModel.OrgServiceMapping", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<Guid>("OrganizationId")
.HasColumnType("char(36)");
b.Property<Guid>("ServiceId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("OrganizationId");
b.HasIndex("ServiceId");
b.ToTable("OrgServiceMappings");
});
modelBuilder.Entity("Marco.Pms.Model.OrganizationModel.OrgTypeMaster", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.HasKey("Id");
b.ToTable("OrgTypeMasters");
b.HasData(
new
{
Id = new Guid("743806fe-d991-4079-b223-e4e2da44f435"),
Name = "Tenant"
},
new
{
Id = new Guid("5ee49bcd-b6d3-482f-9aaf-484afe04abec"),
Name = "Service Provider"
},
new
{
Id = new Guid("a283356a-9b02-4029-afb7-e65c703efdd4"),
Name = "Sub-Contractor"
},
new
{
Id = new Guid("b1877a3b-8832-47b1-bbe3-dc7e98672f49"),
Name = "PMC"
});
});
modelBuilder.Entity("Marco.Pms.Model.OrganizationModel.Organization", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("Address")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("ContactNumber")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("ContactPerson")
.IsRequired()
.HasColumnType("longtext");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<Guid?>("CreatedById")
.HasColumnType("char(36)");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("longtext");
b.Property<bool>("IsActive")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.Property<double>("SPRID")
.HasColumnType("double");
b.Property<DateTime?>("UpdatedAt")
.HasColumnType("datetime(6)");
b.Property<Guid?>("UpdatedById")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("CreatedById");
b.HasIndex("UpdatedById");
b.ToTable("Organizations");
b.HasData(
new
{
Id = new Guid("4e3a6d31-c640-40f7-8d67-6c109fcdb9ea"),
Address = "2nd Floor, Fullora Building, Tejas CHS, behind Kothrud Stand, Tejas Society, Dahanukar Colony, Kothrud, Pune, Maharashtra 411038",
ContactNumber = "123456789",
ContactPerson = "Admin",
CreatedAt = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
Email = "admin@marcoaiot.com",
IsActive = true,
Name = "MarcoBMS",
SPRID = 5400.0
});
});
modelBuilder.Entity("Marco.Pms.Model.OrganizationModel.ProjectOrgMapping", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<DateTime>("AssignedDate")
.HasColumnType("datetime(6)");
b.Property<DateTime?>("CompletionDate")
.HasColumnType("datetime(6)");
b.Property<Guid>("OrganizationId")
.HasColumnType("char(36)");
b.Property<Guid>("OrganizationTypeId")
.HasColumnType("char(36)");
b.Property<Guid>("ParentOrganizationId")
.HasColumnType("char(36)");
b.Property<Guid>("ProjectServiceId")
.HasColumnType("char(36)");
b.Property<Guid>("TenantId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("OrganizationId");
b.HasIndex("OrganizationTypeId");
b.HasIndex("ParentOrganizationId");
b.HasIndex("ProjectServiceId");
b.HasIndex("TenantId");
b.ToTable("ProjectOrgMappings");
});
modelBuilder.Entity("Marco.Pms.Model.OrganizationModel.ProjectServiceMapping", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<DateTime?>("ActualEndDate")
.HasColumnType("datetime(6)");
b.Property<DateTime>("ActualStartDate")
.HasColumnType("datetime(6)");
b.Property<DateTime>("PlannedEndDate")
.HasColumnType("datetime(6)");
b.Property<DateTime>("PlannedStartDate")
.HasColumnType("datetime(6)");
b.Property<Guid>("ProjectId")
.HasColumnType("char(36)");
b.Property<Guid>("ServiceId")
.HasColumnType("char(36)");
b.Property<Guid>("TenantId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("ProjectId");
b.HasIndex("ServiceId");
b.HasIndex("TenantId");
b.ToTable("ProjectServiceMappings");
});
modelBuilder.Entity("Marco.Pms.Model.OrganizationModel.TenantOrgMapping", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<DateTime>("AssignedDate")
.HasColumnType("datetime(6)");
b.Property<bool>("IsActive")
.HasColumnType("tinyint(1)");
b.Property<Guid>("OrganizationId")
.HasColumnType("char(36)");
b.Property<DateTime?>("ReassignedDate")
.HasColumnType("datetime(6)");
b.Property<double>("SPRID")
.HasColumnType("double");
b.Property<Guid>("TenantId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("OrganizationId");
b.HasIndex("TenantId");
b.ToTable("TenantOrgMappings");
});
modelBuilder.Entity("Marco.Pms.Model.Projects.Building", b =>
{
b.Property<Guid>("Id")
@ -5139,14 +5516,39 @@ namespace Marco.Pms.DataAccess.Migrations
b.Navigation("MailBody");
});
modelBuilder.Entity("Marco.Pms.Model.Master.ActivityMaster", b =>
modelBuilder.Entity("Marco.Pms.Model.Master.ActivityGroupMaster", b =>
{
b.HasOne("Marco.Pms.Model.Master.ServiceMaster", "Service")
.WithMany()
.HasForeignKey("ServiceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant")
.WithMany()
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Service");
b.Navigation("Tenant");
});
modelBuilder.Entity("Marco.Pms.Model.Master.ActivityMaster", b =>
{
b.HasOne("Marco.Pms.Model.Master.ActivityGroupMaster", "ActivityGroup")
.WithMany()
.HasForeignKey("ActivityGroupId");
b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant")
.WithMany()
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("ActivityGroup");
b.Navigation("Tenant");
});
@ -5172,6 +5574,28 @@ namespace Marco.Pms.DataAccess.Migrations
b.Navigation("Module");
});
modelBuilder.Entity("Marco.Pms.Model.Master.GlobalActivityGroupMaster", b =>
{
b.HasOne("Marco.Pms.Model.Master.GlobalServiceMaster", "Service")
.WithMany()
.HasForeignKey("ServiceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Service");
});
modelBuilder.Entity("Marco.Pms.Model.Master.GlobalActivityMaster", b =>
{
b.HasOne("Marco.Pms.Model.Master.GlobalActivityGroupMaster", "ActivityGroup")
.WithMany()
.HasForeignKey("ActivityGroupId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("ActivityGroup");
});
modelBuilder.Entity("Marco.Pms.Model.Master.PaymentModeMatser", b =>
{
b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant")
@ -5183,6 +5607,17 @@ namespace Marco.Pms.DataAccess.Migrations
b.Navigation("Tenant");
});
modelBuilder.Entity("Marco.Pms.Model.Master.ServiceMaster", b =>
{
b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant")
.WithMany()
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Tenant");
});
modelBuilder.Entity("Marco.Pms.Model.Master.WorkCategoryMaster", b =>
{
b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant")
@ -5205,6 +5640,129 @@ namespace Marco.Pms.DataAccess.Migrations
b.Navigation("Tenant");
});
modelBuilder.Entity("Marco.Pms.Model.OrganizationModel.OrgServiceMapping", b =>
{
b.HasOne("Marco.Pms.Model.OrganizationModel.Organization", "Organization")
.WithMany()
.HasForeignKey("OrganizationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Marco.Pms.Model.Master.GlobalServiceMaster", "Service")
.WithMany()
.HasForeignKey("ServiceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Organization");
b.Navigation("Service");
});
modelBuilder.Entity("Marco.Pms.Model.OrganizationModel.Organization", b =>
{
b.HasOne("Marco.Pms.Model.Employees.Employee", "CreatedBy")
.WithMany()
.HasForeignKey("CreatedById");
b.HasOne("Marco.Pms.Model.Employees.Employee", "UpdatedBy")
.WithMany()
.HasForeignKey("UpdatedById");
b.Navigation("CreatedBy");
b.Navigation("UpdatedBy");
});
modelBuilder.Entity("Marco.Pms.Model.OrganizationModel.ProjectOrgMapping", b =>
{
b.HasOne("Marco.Pms.Model.OrganizationModel.Organization", "Organization")
.WithMany()
.HasForeignKey("OrganizationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Marco.Pms.Model.OrganizationModel.OrgTypeMaster", "OrganizationType")
.WithMany()
.HasForeignKey("OrganizationTypeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Marco.Pms.Model.OrganizationModel.Organization", "ParentOrganization")
.WithMany()
.HasForeignKey("ParentOrganizationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Marco.Pms.Model.OrganizationModel.ProjectServiceMapping", "ProjectService")
.WithMany()
.HasForeignKey("ProjectServiceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant")
.WithMany()
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Organization");
b.Navigation("OrganizationType");
b.Navigation("ParentOrganization");
b.Navigation("ProjectService");
b.Navigation("Tenant");
});
modelBuilder.Entity("Marco.Pms.Model.OrganizationModel.ProjectServiceMapping", b =>
{
b.HasOne("Marco.Pms.Model.Projects.Project", "Project")
.WithMany()
.HasForeignKey("ProjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Marco.Pms.Model.Master.ServiceMaster", "Service")
.WithMany()
.HasForeignKey("ServiceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant")
.WithMany()
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Project");
b.Navigation("Service");
b.Navigation("Tenant");
});
modelBuilder.Entity("Marco.Pms.Model.OrganizationModel.TenantOrgMapping", b =>
{
b.HasOne("Marco.Pms.Model.OrganizationModel.Organization", "Organization")
.WithMany()
.HasForeignKey("OrganizationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant")
.WithMany()
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Organization");
b.Navigation("Tenant");
});
modelBuilder.Entity("Marco.Pms.Model.Projects.Building", b =>
{
b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant")

View File

@ -2,8 +2,9 @@
{
public class CreateActivityMasterDto
{
public string? ActivityName { get; set; }
public string? UnitOfMeasurement { get; set; }
public required Guid ActitvityGroupId { get; set; }
public required string ActivityName { get; set; }
public required string UnitOfMeasurement { get; set; }
public List<CreateCheckListDto>? CheckList { get; set; }
}
}

View File

@ -3,7 +3,7 @@
public class CreateCheckListDto
{
public Guid? Id { get; set; }
public string? Description { get; set; }
public bool IsMandatory { get; set; }
public required string Description { get; set; }
public required bool IsMandatory { get; set; }
}
}

View File

@ -0,0 +1,10 @@
namespace Marco.Pms.Model.Dtos.Master
{
public class ActivityGroupDto
{
public Guid? Id { get; set; }
public required string Name { get; set; }
public required string Description { get; set; }
public required Guid ServiceId { get; set; }
}
}

View File

@ -0,0 +1,9 @@
namespace Marco.Pms.Model.Dtos.Master
{
public class ServiceMasterDto
{
public Guid? Id { get; set; }
public required string Name { get; set; }
public required string Description { get; set; }
}
}

View File

@ -0,0 +1,20 @@
using Marco.Pms.Model.Utilities;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using System.ComponentModel.DataAnnotations.Schema;
namespace Marco.Pms.Model.Master
{
public class ActivityGroupMaster : TenantRelation
{
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public Guid ServiceId { get; set; }
[ValidateNever]
[ForeignKey("ServiceId")]
public ServiceMaster? Service { get; set; }
public bool IsActive { get; set; } = true;
public bool IsSystem { get; set; } = false;
}
}

View File

@ -1,14 +1,20 @@
using Marco.Pms.Model.Utilities;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using System.ComponentModel.DataAnnotations.Schema;
namespace Marco.Pms.Model.Master
{
public class ActivityMaster : TenantRelation
{
public Guid Id { get; set; }
public string? ActivityName { get; set; }
public string? UnitOfMeasurement { get; set; }
public string ActivityName { get; set; } = string.Empty;
public string UnitOfMeasurement { get; set; } = string.Empty;
public Guid? ActivityGroupId { get; set; }
[ValidateNever]
[ForeignKey("ActivityGroupId")]
public ActivityGroupMaster? ActivityGroup { get; set; }
public bool IsActive { get; set; } = true;
public bool IsSystem { get; set; } = false;
}
}

View File

@ -0,0 +1,17 @@
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using System.ComponentModel.DataAnnotations.Schema;
namespace Marco.Pms.Model.Master
{
public class GlobalActivityGroupMaster
{
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public Guid ServiceId { get; set; }
[ValidateNever]
[ForeignKey("ServiceId")]
public GlobalServiceMaster? Service { get; set; }
}
}

View File

@ -0,0 +1,18 @@
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using System.ComponentModel.DataAnnotations.Schema;
namespace Marco.Pms.Model.Master
{
public class GlobalActivityMaster
{
public Guid Id { get; set; }
public string ActivityName { get; set; } = string.Empty;
public string UnitOfMeasurement { get; set; } = string.Empty;
public Guid ActivityGroupId { get; set; }
[ValidateNever]
[ForeignKey("ActivityGroupId")]
public GlobalActivityGroupMaster? ActivityGroup { get; set; }
public bool IsActive { get; set; } = true;
}
}

View File

@ -0,0 +1,9 @@
namespace Marco.Pms.Model.Master
{
public class GlobalServiceMaster
{
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,13 @@
using Marco.Pms.Model.Utilities;
namespace Marco.Pms.Model.Master
{
public class ServiceMaster : TenantRelation
{
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public bool IsActive { get; set; } = true;
public bool IsSystem { get; set; } = false;
}
}

View File

@ -0,0 +1,21 @@
using Marco.Pms.Model.Master;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using System.ComponentModel.DataAnnotations.Schema;
namespace Marco.Pms.Model.OrganizationModel
{
public class OrgServiceMapping
{
public Guid Id { get; set; }
public Guid OrganizationId { get; set; }
[ValidateNever]
[ForeignKey("OrganizationId")]
public Organization? Organization { get; set; }
public Guid ServiceId { get; set; }
[ValidateNever]
[ForeignKey("ServiceId")]
public GlobalServiceMaster? Service { get; set; }
}
}

View File

@ -0,0 +1,8 @@
namespace Marco.Pms.Model.OrganizationModel
{
public class OrgTypeMaster
{
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,30 @@
using Marco.Pms.Model.Employees;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using System.ComponentModel.DataAnnotations.Schema;
namespace Marco.Pms.Model.OrganizationModel
{
public class Organization
{
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public string ContactPerson { get; set; } = string.Empty;
public string Address { get; set; } = string.Empty;
public string ContactNumber { get; set; } = string.Empty;
public double SPRID { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public Guid? CreatedById { get; set; }
[ValidateNever]
[ForeignKey("CreatedById")]
public Employee? CreatedBy { get; set; }
public Guid? UpdatedById { get; set; }
[ValidateNever]
[ForeignKey("UpdatedById")]
public Employee? UpdatedBy { get; set; }
public DateTime? UpdatedAt { get; set; }
public bool IsActive { get; set; } = true;
}
}

View File

@ -0,0 +1,33 @@
using Marco.Pms.Model.Utilities;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using System.ComponentModel.DataAnnotations.Schema;
namespace Marco.Pms.Model.OrganizationModel
{
public class ProjectOrgMapping : TenantRelation
{
public Guid Id { get; set; }
public Guid OrganizationId { get; set; }
[ValidateNever]
[ForeignKey("OrganizationId")]
public Organization? Organization { get; set; }
public Guid ParentOrganizationId { get; set; }
[ValidateNever]
[ForeignKey("ParentOrganizationId")]
public Organization? ParentOrganization { get; set; }
public Guid ProjectServiceId { get; set; }
[ValidateNever]
[ForeignKey("ProjectServiceId")]
public ProjectServiceMapping? ProjectService { get; set; }
public Guid OrganizationTypeId { get; set; }
[ValidateNever]
[ForeignKey("OrganizationTypeId")]
public OrgTypeMaster? OrganizationType { get; set; }
public DateTime AssignedDate { get; set; }
public DateTime? CompletionDate { get; set; }
}
}

View File

@ -0,0 +1,27 @@
using Marco.Pms.Model.Master;
using Marco.Pms.Model.Projects;
using Marco.Pms.Model.Utilities;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using System.ComponentModel.DataAnnotations.Schema;
namespace Marco.Pms.Model.OrganizationModel
{
public class ProjectServiceMapping : TenantRelation
{
public Guid Id { get; set; }
public Guid ServiceId { get; set; }
[ValidateNever]
[ForeignKey("ServiceId")]
public ServiceMaster? Service { get; set; }
public Guid ProjectId { get; set; }
[ValidateNever]
[ForeignKey("ProjectId")]
public Project? Project { get; set; }
public DateTime PlannedStartDate { get; set; }
public DateTime PlannedEndDate { get; set; }
public DateTime ActualStartDate { get; set; }
public DateTime? ActualEndDate { get; set; }
}
}

View File

@ -0,0 +1,20 @@
using Marco.Pms.Model.Utilities;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using System.ComponentModel.DataAnnotations.Schema;
namespace Marco.Pms.Model.OrganizationModel
{
public class TenantOrgMapping : TenantRelation
{
public Guid Id { get; set; }
public Guid OrganizationId { get; set; }
[ValidateNever]
[ForeignKey("OrganizationId")]
public Organization? Organization { get; set; }
public double SPRID { get; set; }
public bool IsActive { get; set; } = true;
public DateTime AssignedDate { get; set; }
public DateTime? ReassignedDate { get; set; }
}
}

View File

@ -1,4 +1,6 @@
namespace Marco.Pms.Model.ViewModels.Activities
using Marco.Pms.Model.ViewModels.Master;
namespace Marco.Pms.Model.ViewModels.Activities
{
public class ActivityVM
{
@ -7,5 +9,8 @@
public string? UnitOfMeasurement { get; set; }
public List<CheckListVM>? CheckLists { get; set; }
public ActivityGroupMasterVM? ActivityGroup { get; set; }
public bool IsActive { get; set; } = true;
public bool IsSystem { get; set; } = false;
}
}

View File

@ -0,0 +1,12 @@
namespace Marco.Pms.Model.ViewModels.Master
{
public class ActivityGroupMasterVM
{
public Guid Id { get; set; }
public string? Name { get; set; }
public string? Description { get; set; }
public ServiceMasterVM? Service { get; set; }
public bool IsSystem { get; set; }
public bool IsActive { get; set; }
}
}

View File

@ -0,0 +1,11 @@
namespace Marco.Pms.Model.ViewModels.Master
{
public class ServiceMasterVM
{
public Guid Id { get; set; }
public string? Name { get; set; }
public string? Description { get; set; }
public bool IsSystem { get; set; }
public bool IsActive { get; set; }
}
}

View File

@ -38,6 +38,78 @@ namespace Marco.Pms.Services.Controllers
tenantId = userHelper.GetTenantId();
}
#region =================================================================== Services APIs ===================================================================
[HttpGet("service/list")]
public async Task<IActionResult> GetServices()
{
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _masterService.GetServicesAsync(loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
[HttpPost("service/create")]
public async Task<IActionResult> CreateService([FromBody] ServiceMasterDto serviceMasterDto)
{
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _masterService.CreateServiceAsync(serviceMasterDto, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
[HttpPut("service/edit/{id}")]
public async Task<IActionResult> UpdateService(Guid id, [FromBody] ServiceMasterDto serviceMasterDto)
{
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _masterService.UpdateServiceAsync(id, serviceMasterDto, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
[HttpDelete("service/delete/{id}")]
public async Task<IActionResult> DeleteService(Guid id, [FromQuery] bool active = false)
{
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _masterService.DeleteServiceAsync(id, active, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
#endregion
#region =================================================================== Activity Group APIs ===================================================================
[HttpGet("activity-group/list")]
public async Task<IActionResult> GetActivityGroups()
{
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _masterService.GetActivityGroupsAsync(loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
[HttpPost("activity-group/create")]
public async Task<IActionResult> CreateActivityGroup([FromBody] ActivityGroupDto activityGroupDto)
{
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _masterService.CreateActivityGroupAsync(activityGroupDto, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
[HttpPut("activity-group/edit/{id}")]
public async Task<IActionResult> UpdateActivityGroup(Guid id, [FromBody] ActivityGroupDto activityGroupDto)
{
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _masterService.UpdateActivityGroupAsync(id, activityGroupDto, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
[HttpDelete("activity-group/delete/{id}")]
public async Task<IActionResult> DeleteActivityGroup(Guid id, [FromQuery] bool active = false)
{
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _masterService.DeleteActivityGroupAsync(id, active, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
#endregion
#region =================================================================== Activity APIs ===================================================================
[HttpGet]

View File

@ -1,9 +1,10 @@
using AutoMapper;
using Marco.Pms.Model.Directory;
using Marco.Pms.Model.Dtos.Directory;
using Marco.Pms.Model.AppMenu;
using Marco.Pms.Model.Directory;
using Marco.Pms.Model.DocumentManager;
using Marco.Pms.Model.Dtos.Activities;
using Marco.Pms.Model.Dtos.AppMenu;
using Marco.Pms.Model.Dtos.Directory;
using Marco.Pms.Model.Dtos.DocumentManager;
using Marco.Pms.Model.Dtos.Expenses;
using Marco.Pms.Model.Dtos.Master;
@ -233,6 +234,44 @@ namespace Marco.Pms.Services.MappingProfiles
CreateMap<FeaturePermission, FeaturePermissionVM>();
#region ======================================================= Service Master =======================================================
CreateMap<ServiceMasterDto, ServiceMaster>()
.ForMember(
dest => dest.Id,
// Explicitly and safely convert nullable Guid to non-nullable Guid
opt => opt.MapFrom(src => src.Id ?? Guid.Empty)
);
CreateMap<ServiceMaster, ServiceMasterVM>();
#endregion
#region ======================================================= Activity Group Master =======================================================
CreateMap<ServiceMasterDto, ActivityGroupMaster>()
.ForMember(
dest => dest.Id,
// Explicitly and safely convert nullable Guid to non-nullable Guid
opt => opt.MapFrom(src => src.Id ?? Guid.Empty)
);
CreateMap<ActivityGroupMaster, ActivityGroupMasterVM>();
#endregion
#region ======================================================= Activity Master =======================================================
CreateMap<CreateActivityMasterDto, ActivityMaster>();
CreateMap<CreateCheckListDto, ActivityCheckList>()
.ForMember(
dest => dest.Id,
// Explicitly and safely convert nullable Guid to non-nullable Guid
opt => opt.MapFrom(src => src.Id ?? Guid.Empty)
);
CreateMap<ActivityCheckList, CheckListVM>();
CreateMap<ActivityMaster, ActivityVM>();
#endregion
#region ======================================================= Expenses Type Master =======================================================
CreateMap<ExpensesTypeMasterDto, ExpensesTypeMaster>()

View File

@ -3,6 +3,7 @@ using Marco.Pms.DataAccess.Data;
using Marco.Pms.Helpers.Utility;
using Marco.Pms.Model.Directory;
using Marco.Pms.Model.DocumentManager;
using Marco.Pms.Model.Dtos.Activities;
using Marco.Pms.Model.Dtos.DocumentManager;
using Marco.Pms.Model.Dtos.Master;
using Marco.Pms.Model.Employees;
@ -11,6 +12,7 @@ using Marco.Pms.Model.Mapper;
using Marco.Pms.Model.Master;
using Marco.Pms.Model.MongoDBModels.Utility;
using Marco.Pms.Model.Utilities;
using Marco.Pms.Model.ViewModels.Activities;
using Marco.Pms.Model.ViewModels.DocumentManager;
using Marco.Pms.Model.ViewModels.Master;
using Marco.Pms.Services.Helpers;
@ -49,6 +51,645 @@ namespace Marco.Pms.Services.Service
_cache = cache;
}
#region =================================================================== Services APIs ===================================================================
public async Task<ApiResponse<object>> GetServicesAsync(Employee loggedInEmployee, Guid tenantId)
{
_logger.LogInfo("GetServices called");
try
{
// Step 1: Fetch services for the tenant
var services = await _context.ServiceMasters
.Where(s => s.TenantId == tenantId && s.IsActive)
.Select(s => _mapper.Map<ServiceMasterVM>(s))
.ToListAsync();
_logger.LogInfo("Fetched {Count} service records for tenantId: {TenantId}", services.Count, tenantId);
return ApiResponse<object>.SuccessResponse(services, $"{services.Count} record(s) of services fetched successfully", 200);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error fetching services");
return ApiResponse<object>.ErrorResponse("An error occurred while fetching services", ex.Message, 500);
}
}
public async Task<ApiResponse<object>> CreateServiceAsync(ServiceMasterDto serviceMasterDto, Employee loggedInEmployee, Guid tenantId)
{
_logger.LogInfo("CreateService called with Name: {ServiceName}", serviceMasterDto.Name);
try
{
// Step 1: Permission check
var hasManagePermission = await _permission.HasPermission(PermissionsMaster.ManageMasters, loggedInEmployee.Id);
if (!hasManagePermission)
{
_logger.LogWarning("Access denied for employeeId: {EmployeeId}", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("You don't have access", "You don't have permission to take this action", 403);
}
// Step 2: Check for duplicate name
bool isExist = await _context.ServiceMasters
.AnyAsync(s => s.TenantId == tenantId && s.Name == serviceMasterDto.Name);
if (isExist)
{
_logger.LogWarning("Duplicate service name '{ServiceName}' attempted by employeeId: {EmployeeId}", serviceMasterDto.Name, loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse(
$"Service with name '{serviceMasterDto.Name}' already exists",
$"Service with name '{serviceMasterDto.Name}' already exists", 400);
}
// Step 3: Save new service
ServiceMaster service = _mapper.Map<ServiceMaster>(serviceMasterDto);
service.TenantId = tenantId;
service.IsActive = true;
service.IsSystem = false;
_context.ServiceMasters.Add(service);
await _context.SaveChangesAsync();
var response = _mapper.Map<ServiceMasterVM>(service);
_logger.LogInfo("New service '{ServiceName}' created successfully by employeeId: {EmployeeId}", service.Name, loggedInEmployee.Id);
return ApiResponse<object>.SuccessResponse(response, "New service created successfully", 201);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error creating service");
return ApiResponse<object>.ErrorResponse("Failed to create service", ex.Message, 500);
}
}
public async Task<ApiResponse<object>> UpdateServiceAsync(Guid id, ServiceMasterDto serviceMasterDto, Employee loggedInEmployee, Guid tenantId)
{
_logger.LogInfo("UpdateService called for Id: {Id}", id);
try
{
// Step 1: Permission check
var hasPermission = await _permission.HasPermission(PermissionsMaster.ManageMasters, loggedInEmployee.Id);
if (!hasPermission)
{
_logger.LogWarning("Access denied. EmployeeId: {EmployeeId} lacks Manage_Master permission.", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Access denied", "You don't have permission to take this action", 403);
}
// Step 2: Input validation
if (serviceMasterDto.Id != id)
{
_logger.LogWarning("Invalid input data provided for UpdateService. Id: {Id}", id);
return ApiResponse<object>.ErrorResponse("Invalid input", "Please provide valid service data", 400);
}
// Step 3: Retrieve service
var service = await _context.ServiceMasters
.FirstOrDefaultAsync(s => s.Id == id && s.TenantId == tenantId && s.IsActive);
if (service == null)
{
_logger.LogWarning("Service not found for Id: {Id}, Tenant: {TenantId}", id, tenantId);
return ApiResponse<object>.ErrorResponse("Service not found", "The requested service does not exist", 404);
}
// Step 4: Update and save
service.Name = serviceMasterDto.Name.Trim();
service.Description = serviceMasterDto.Description.Trim();
await _context.SaveChangesAsync();
var response = _mapper.Map<ServiceMasterVM>(service);
_logger.LogInfo("Service updated successfully. Id: {Id}, TenantId: {TenantId}", service.Id, tenantId);
return ApiResponse<object>.SuccessResponse(response, "Service updated successfully", 200);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error while updating service Id: {Id}.", id);
return ApiResponse<object>.ErrorResponse("An error occurred while updating the service", ex.Message, 500);
}
}
public async Task<ApiResponse<object>> DeleteServiceAsync(Guid id, bool active, Employee loggedInEmployee, Guid tenantId)
{
_logger.LogInfo("DeleteService called with ServiceId: {ServiceId}, IsActive: {IsActive}", id, active);
try
{
// Step 1: Get validate permission
var hasPermission = await _permission.HasPermission(PermissionsMaster.ManageMasters, loggedInEmployee.Id);
if (!hasPermission)
{
_logger.LogWarning("Access denied. EmployeeId: {EmployeeId} does not have Manage_Master permission.", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Access denied", "You don't have permission to delete services", 403);
}
// Step 2: Check if the service exists
var service = await _context.ServiceMasters
.FirstOrDefaultAsync(s => s.Id == id && s.TenantId == tenantId);
if (service == null)
{
_logger.LogWarning("Service not found. ServiceId: {ServiceId}", id);
return ApiResponse<object>.ErrorResponse("Service not found", "Service not found or already deleted", 404);
}
// Protect system-defined service
if (service.IsSystem)
{
_logger.LogWarning("Attempt to delete system-defined service. ServiceId: {ServiceId}", id);
return ApiResponse<object>.ErrorResponse("Cannot delete system-defined service", "This service is system-defined and cannot be deleted", 400);
}
// Step 3: Soft delete or restore
service.IsActive = active;
await _context.SaveChangesAsync();
var status = active ? "restored" : "deactivated";
_logger.LogInfo("Service {ServiceId} has been {Status} successfully by EmployeeId: {EmployeeId}", id, status, loggedInEmployee.Id);
return ApiResponse<object>.SuccessResponse(new { }, $"Service {status} successfully", 200);
}
catch (Exception ex)
{
_logger.LogError(ex, "Unexpected error occurred while deleting service {ServiceId}", id);
return ApiResponse<object>.ErrorResponse("Error deleting service", ex.Message, 500);
}
}
#endregion
#region =================================================================== Activity Group APIs ===================================================================
public async Task<ApiResponse<object>> GetActivityGroupsAsync(Employee loggedInEmployee, Guid tenantId)
{
_logger.LogInfo("GetActivityGroups called");
try
{
// Step 1: Fetch all activity groups for the tenant
var activityGroups = await _context.ActivityGroupMasters
.Include(ag => ag.Service)
.Where(ag => ag.TenantId == tenantId && ag.IsActive)
.Select(ag => _mapper.Map<ActivityGroupMasterVM>(ag))
.ToListAsync();
_logger.LogInfo("{Count} activity group(s) fetched for tenantId: {TenantId}", activityGroups.Count, tenantId);
return ApiResponse<object>.SuccessResponse(activityGroups, $"{activityGroups.Count} record(s) of activity groups fetched successfully", 200);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error fetching activity groups");
return ApiResponse<object>.ErrorResponse("An error occurred while fetching activity groups", ex.Message, 500);
}
}
public async Task<ApiResponse<object>> CreateActivityGroupAsync(ActivityGroupDto activityGroupDto, Employee loggedInEmployee, Guid tenantId)
{
_logger.LogInfo("CreateActivityGroup called with Name: {Name}", activityGroupDto.Name);
try
{
// Step 1: Check Manage Master permission
var hasPermission = await _permission.HasPermission(PermissionsMaster.ManageMasters, loggedInEmployee.Id);
if (!hasPermission)
{
_logger.LogWarning("Access denied. EmployeeId: {EmployeeId} lacks Manage_Master permission", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Access denied", "You don't have permission to take this action", 403);
}
// Step 2: Check for duplicate name within ActivityGroupMasters
bool isExist = await _context.ActivityGroupMasters
.AnyAsync(ag => ag.TenantId == tenantId && ag.Name.ToLower() == activityGroupDto.Name.ToLower());
if (isExist)
{
_logger.LogWarning("Duplicate activity group name '{Name}' attempted by employeeId: {EmployeeId}", activityGroupDto.Name, loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse(
$"Activity group with name '{activityGroupDto.Name}' already exists",
$"Activity group with name '{activityGroupDto.Name}' already exists", 400);
}
// Step 3: Map and persist
var activityGroup = _mapper.Map<ActivityGroupMaster>(activityGroupDto);
activityGroup.TenantId = tenantId;
activityGroup.IsActive = true;
activityGroup.IsSystem = false;
_context.ActivityGroupMasters.Add(activityGroup);
await _context.SaveChangesAsync();
var service = await _context.ServiceMasters.FirstOrDefaultAsync(s => s.Id == activityGroup.ServiceId);
var response = _mapper.Map<ActivityGroupMasterVM>(activityGroup);
_logger.LogInfo("New activity group '{Name}' created successfully by employeeId: {EmployeeId}", activityGroup.Name, loggedInEmployee.Id);
return ApiResponse<object>.SuccessResponse(response, "New activity group created successfully", 201);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error creating activity group");
return ApiResponse<object>.ErrorResponse("Failed to create activity group", ex.Message, 500);
}
}
public async Task<ApiResponse<object>> UpdateActivityGroupAsync(Guid id, ActivityGroupDto activityGroupDto, Employee loggedInEmployee, Guid tenantId)
{
_logger.LogInfo("UpdateActivityGroup called for Id: {Id}", id);
try
{
// Step 1: Permission check
var hasPermission = await _permission.HasPermission(PermissionsMaster.ManageMasters, loggedInEmployee.Id);
if (!hasPermission)
{
_logger.LogWarning("Access denied. EmployeeId: {EmployeeId} lacks Manage_Master permission.", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Access denied", "You don't have permission to take this action", 403);
}
// Step 2: Input validation
if (activityGroupDto.Id != id)
{
_logger.LogWarning("Invalid input for activity group update. Id: {Id}", id);
return ApiResponse<object>.ErrorResponse("Invalid input", "Please provide valid data to update activity group", 400);
}
var service = await _context.ServiceMasters.FirstOrDefaultAsync(s => s.Id == activityGroupDto.ServiceId && s.IsActive);
if (service == null)
{
_logger.LogWarning("User tries to update activity group, but service not found");
return ApiResponse<object>.ErrorResponse("Invalid service ID", "Please provide valid service ID to update activity group", 400);
}
// Step 3: Retrieve existing activity group
var activityGroup = await _context.ActivityGroupMasters
.Include(ag => ag.Service)
.FirstOrDefaultAsync(ag => ag.Id == id && ag.TenantId == tenantId && ag.IsActive);
if (activityGroup == null)
{
_logger.LogWarning("Activity group not found. Id: {Id}, TenantId: {TenantId}", id, tenantId);
return ApiResponse<object>.ErrorResponse("Activity group not found", "No such activity group exists", 404);
}
// Step 4: Update and save
activityGroup.Name = activityGroupDto.Name.Trim();
activityGroup.Description = activityGroupDto.Description.Trim();
await _context.SaveChangesAsync();
var response = _mapper.Map<ActivityGroupMasterVM>(activityGroup);
_logger.LogInfo("Activity group updated successfully. Id: {Id}, TenantId: {TenantId}", activityGroup.Id, tenantId);
return ApiResponse<object>.SuccessResponse(response, "Activity group updated successfully", 200);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error while updating activity group Id: {Id}", id);
return ApiResponse<object>.ErrorResponse("An error occurred while updating the activity group", ex.Message, 500);
}
}
public async Task<ApiResponse<object>> DeleteActivityGroupAsync(Guid id, bool isActive, Employee loggedInEmployee, Guid tenantId)
{
_logger.LogInfo("DeleteActivityGroup called with ActivityGroupId: {ActivityGroupId}, IsActive: {IsActive}", id, isActive);
try
{
// Step 1: Permission check
var hasPermission = await _permission.HasPermission(PermissionsMaster.ManageMasters, loggedInEmployee.Id);
if (!hasPermission)
{
_logger.LogWarning("Access denied. EmployeeId: {EmployeeId} does not have Manage_Master permission.", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Access denied", "You don't have permission to delete activity groups", 403);
}
// Step 2: Fetch the activity group
var activityGroup = await _context.ActivityGroupMasters
.FirstOrDefaultAsync(ag => ag.Id == id && ag.TenantId == tenantId);
if (activityGroup == null)
{
_logger.LogWarning("ActivityGroup not found. Id: {ActivityGroupId}", id);
return ApiResponse<object>.ErrorResponse("Activity group not found", "Activity group not found or already deleted", 404);
}
//Protect system-defined activity group
if (activityGroup.IsSystem)
{
_logger.LogWarning("Attempt to delete system-defined activity group. Id: {ActivityGroupId}", id);
return ApiResponse<object>.ErrorResponse("Cannot delete system-defined activity group", "This activity group is system-defined and cannot be deleted", 400);
}
// Step 3: Perform soft delete or restore
activityGroup.IsActive = isActive;
await _context.SaveChangesAsync();
var status = isActive ? "restored" : "deactivated";
_logger.LogInfo("ActivityGroup {ActivityGroupId} has been {Status} by EmployeeId: {EmployeeId}", id, status, loggedInEmployee.Id);
return ApiResponse<object>.SuccessResponse(new { }, $"Activity group {status} successfully", 200);
}
catch (Exception ex)
{
_logger.LogError(ex, "Unexpected error occurred while deleting ActivityGroup {ActivityGroupId}", id);
return ApiResponse<object>.ErrorResponse("Error deleting activity group", ex.Message, 500);
}
}
#endregion
#region =================================================================== Activity APIs ===================================================================
public async Task<ApiResponse<object>> GetActivitiesMasterAsync(Employee loggedInEmployee, Guid tenantId)
{
_logger.LogInfo("GetActivitiesMaster called");
try
{
// Step 1: Fetch all active activities for the tenant
var activities = await _context.ActivityMasters
.Include(c => c.ActivityGroup)
.ThenInclude(ag => ag!.Service)
.Where(c => c.TenantId == tenantId && c.IsActive)
.ToListAsync();
if (activities.Count == 0)
{
_logger.LogWarning("No active activities found for tenantId: {TenantId}", tenantId);
return ApiResponse<object>.SuccessResponse(new List<ActivityVM>(), "No activity records found", 200);
}
// Step 2: Fetch all checklists for those activities in a single query to avoid N+1
var activityIds = activities.Select(a => a.Id).ToList();
var checkLists = await _context.ActivityCheckLists
.Where(c => c.TenantId == tenantId && activityIds.Contains(c.ActivityId))
.ToListAsync();
// Step 3: Group checklists by activity
var groupedChecklists = checkLists
.GroupBy(c => c.ActivityId)
.ToDictionary(g => g.Key, g => g.ToList());
// Step 4: Map to ViewModel
var activityVMs = activities.Select(activity =>
{
var checklistForActivity = groupedChecklists.ContainsKey(activity.Id)
? groupedChecklists[activity.Id]
: new List<ActivityCheckList>();
var response = _mapper.Map<ActivityVM>(activity);
response.CheckLists = _mapper.Map<List<CheckListVM>>(checklistForActivity);
return response;
}).ToList();
_logger.LogInfo("{Count} activity records fetched successfully for tenantId: {TenantId}", activityVMs.Count, tenantId);
return ApiResponse<object>.SuccessResponse(activityVMs, $"{activityVMs.Count} activity records fetched successfully", 200);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error occurred in GetActivitiesMaster");
return ApiResponse<object>.ErrorResponse("Failed to fetch activity records", ex.Message, 500);
}
}
public async Task<ApiResponse<object>> CreateActivityAsync(CreateActivityMasterDto createActivity, Employee loggedInEmployee, Guid tenantId)
{
_logger.LogInfo("CreateActivity called with ActivityName: {Name}", createActivity?.ActivityName ?? "null");
try
{
// Step 1: Validate input
if (createActivity == null)
{
_logger.LogWarning("Null request body received in CreateActivity");
return ApiResponse<object>.ErrorResponse("Invalid input", "Activity data is required", 400);
}
var activityGroup = await _context.ActivityGroupMasters
.Include(ag => ag.Service)
.FirstOrDefaultAsync(ag => ag.Id == createActivity.ActitvityGroupId && ag.TenantId == tenantId);
if (activityGroup == null)
{
_logger.LogWarning("User tried to create new activity, but not found activity group");
return ApiResponse<object>.ErrorResponse("Invalid input", "Activity data is required", 400);
}
// Step 2: Check permissions
var hasPermission = await _permission.HasPermission(PermissionsMaster.ManageMasters, loggedInEmployee.Id);
if (!hasPermission)
{
_logger.LogWarning("Access denied. EmployeeId: {EmployeeId} does not have Manage_Master permission.", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Access denied", "You don't have permission to perform this action", 403);
}
// Step 3: Convert DTO to entity and add activity
var activityMaster = _mapper.Map<ActivityMaster>(createActivity);
activityMaster.TenantId = tenantId;
_context.ActivityMasters.Add(activityMaster);
await _context.SaveChangesAsync();
List<CheckListVM> checkListVMs = new();
// Step 4: Handle checklist items if present
if (createActivity.CheckList?.Any() == true)
{
var activityCheckLists = createActivity.CheckList
.Select(c =>
{
var response = _mapper.Map<ActivityCheckList>(c);
response.ActivityId = activityMaster.Id;
response.IsChecked = false;
response.TenantId = tenantId;
return response;
})
.ToList();
_context.ActivityCheckLists.AddRange(activityCheckLists);
await _context.SaveChangesAsync();
checkListVMs = activityCheckLists
.Select(c =>
{
var response = _mapper.Map<CheckListVM>(c);
return response;
})
.ToList();
}
// Step 5: Prepare final response
var activityVM = _mapper.Map<ActivityVM>(activityMaster);
activityVM.CheckLists = checkListVMs;
_logger.LogInfo("Activity '{Name}' created successfully for tenant {TenantId}", activityMaster.ActivityName, tenantId);
return ApiResponse<object>.SuccessResponse(activityVM, "Activity created successfully", 201);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error occurred while creating activity");
return ApiResponse<object>.ErrorResponse("An error occurred while creating activity", ex.Message, 500);
}
}
public async Task<ApiResponse<object>> UpdateActivityAsync(Guid id, CreateActivityMasterDto createActivity, Employee loggedInEmployee, Guid tenantId)
{
_logger.LogInfo("UpdateActivity called for ActivityId: {ActivityId}", id);
try
{
// Step 1: Validate input
if (createActivity == null || string.IsNullOrWhiteSpace(createActivity.ActivityName) || string.IsNullOrWhiteSpace(createActivity.UnitOfMeasurement))
{
_logger.LogWarning("Invalid activity update input for ActivityId: {ActivityId}", id);
return ApiResponse<object>.ErrorResponse("Invalid input", "ActivityName and UnitOfMeasurement are required", 400);
}
// Step 2: Check permissions
var hasPermission = await _permission.HasPermission(PermissionsMaster.ManageMasters, loggedInEmployee.Id);
if (!hasPermission)
{
_logger.LogWarning("Access denied for employeeId: {EmployeeId}", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Access denied", "You don't have permission to update activities", 403);
}
// Step 3: Validate service, activity group, and activity existence
var activityGroup = await _context.ActivityGroupMasters.Include(ag => ag.Service).FirstOrDefaultAsync(ag => ag.Id == createActivity.ActitvityGroupId && ag.IsActive);
if (activityGroup == null)
{
_logger.LogWarning("User tries to update activity, but cannot able found activity group or service");
return ApiResponse<object>.ErrorResponse("Invalid activity group ID or service ID", "Please provide valid activity group ID or service ID to update activity group", 400);
}
var activity = await _context.ActivityMasters
.Include(a => a.ActivityGroup)
.ThenInclude(ag => ag!.Service)
.FirstOrDefaultAsync(a => a.Id == id && a.IsActive && a.TenantId == tenantId);
if (activity == null)
{
_logger.LogWarning("Activity not found for ActivityId: {ActivityId}, TenantId: {TenantId}", id, tenantId);
return ApiResponse<object>.ErrorResponse("Activity not found", "Activity not found", 404);
}
// Step 4: Update activity core data
activity.ActivityName = createActivity.ActivityName.Trim();
activity.UnitOfMeasurement = createActivity.UnitOfMeasurement.Trim();
activity.ActivityGroupId = createActivity.ActitvityGroupId;
await _context.SaveChangesAsync();
// Step 5: Handle checklist updates
var existingChecklists = await _context.ActivityCheckLists
.AsNoTracking()
.Where(c => c.ActivityId == activity.Id)
.ToListAsync();
var updatedChecklistVMs = new List<CheckListVM>();
if (createActivity.CheckList != null && createActivity.CheckList.Any())
{
var incomingCheckIds = createActivity.CheckList.Where(c => c.Id != null).Select(c => c.Id!.Value).ToHashSet();
// Prepare lists
var newChecks = createActivity.CheckList.Where(c => c.Id == null);
var updates = createActivity.CheckList.Where(c => c.Id != null && existingChecklists.Any(ec => ec.Id == c.Id));
var deletes = existingChecklists.Where(ec => !incomingCheckIds.Contains(ec.Id)).ToList();
var toAdd = newChecks
.Select(c =>
{
var response = _mapper.Map<ActivityCheckList>(c);
response.ActivityId = activity.Id;
response.IsChecked = false;
response.TenantId = tenantId;
return response;
})
.ToList();
var toUpdate = updates
.Select(c =>
{
var response = _mapper.Map<ActivityCheckList>(c);
response.ActivityId = activity.Id;
response.TenantId = tenantId;
return response;
})
.ToList();
_context.ActivityCheckLists.AddRange(toAdd);
_context.ActivityCheckLists.UpdateRange(toUpdate);
_context.ActivityCheckLists.RemoveRange(deletes);
await _context.SaveChangesAsync();
// Prepare view model
updatedChecklistVMs = toAdd.Concat(toUpdate)
.Select(c => _mapper.Map<CheckListVM>(c))
.ToList();
}
else if (existingChecklists.Any())
{
// If no checklist provided, remove all existing
_context.ActivityCheckLists.RemoveRange(existingChecklists);
await _context.SaveChangesAsync();
}
// Step 6: Prepare response
var activityVM = _mapper.Map<ActivityVM>(activity);
activityVM.CheckLists = updatedChecklistVMs;
_logger.LogInfo("Activity updated successfully. ActivityId: {ActivityId}, TenantId: {TenantId}", activity.Id, tenantId);
return ApiResponse<object>.SuccessResponse(activityVM, "Activity updated successfully", 200);
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception in UpdateActivity");
return ApiResponse<object>.ErrorResponse("Error updating activity", ex.Message, 500);
}
}
public async Task<ApiResponse<object>> DeleteActivityAsync(Guid id, bool isActive, Employee loggedInEmployee, Guid tenantId)
{
_logger.LogInfo("DeleteActivity called with ActivityId: {ActivityId}, IsActive: {IsActive}", id, isActive);
try
{
// Step 1: Validate permission
var hasPermission = await _permission.HasPermission(PermissionsMaster.ManageMasters, loggedInEmployee.Id);
if (!hasPermission)
{
_logger.LogWarning("Access denied for EmployeeId: {EmployeeId}", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Access denied", "You don't have permission to delete activities", 403);
}
// Step 2: Fetch the activity
var activity = await _context.ActivityMasters
.FirstOrDefaultAsync(a => a.Id == id && a.TenantId == tenantId);
if (activity == null)
{
_logger.LogWarning("Activity not found. ActivityId: {ActivityId}", id);
return ApiResponse<object>.ErrorResponse("Activity not found", "Activity not found or already deleted", 404);
}
// Step 3: Perform soft delete/restore
activity.IsActive = isActive;
await _context.SaveChangesAsync();
string status = isActive ? "restored" : "deactivated";
_logger.LogInfo("Activity {ActivityId} {Status} successfully by EmployeeId: {EmployeeId}", id, status, loggedInEmployee.Id);
return ApiResponse<object>.SuccessResponse(new { }, $"Activity {status} successfully", 200);
}
catch (Exception ex)
{
_logger.LogError(ex, "Unexpected error while deleting activity {ActivityId}", id);
return ApiResponse<object>.ErrorResponse("Error deleting activity", ex.Message, 500);
}
}
#endregion
#region =================================================================== Contact Category APIs ===================================================================
public async Task<ApiResponse<object>> CreateContactCategory(CreateContactCategoryDto contactCategoryDto, Employee loggedInEmployee, Guid tenantId)

View File

@ -7,6 +7,20 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces
{
public interface IMasterService
{
#region =================================================================== Service Master APIs ===================================================================
Task<ApiResponse<object>> GetServicesAsync(Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> CreateServiceAsync(ServiceMasterDto serviceMasterDto, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> UpdateServiceAsync(Guid id, ServiceMasterDto serviceMasterDto, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> DeleteServiceAsync(Guid id, bool active, Employee loggedInEmployee, Guid tenantId);
#endregion
#region =================================================================== Activity Group Master APIs ===================================================================
Task<ApiResponse<object>> GetActivityGroupsAsync(Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> CreateActivityGroupAsync(ActivityGroupDto activityGroupDto, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> UpdateActivityGroupAsync(Guid id, ActivityGroupDto activityGroupDto, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> DeleteActivityGroupAsync(Guid id, bool isActive, Employee loggedInEmployee, Guid tenantId);
#endregion
#region =================================================================== Contact Category APIs ===================================================================
Task<ApiResponse<object>> CreateContactCategory(CreateContactCategoryDto contactCategoryDto, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> UpdateContactCategory(Guid id, UpdateContactCategoryDto contactCategoryDto, Employee loggedInEmployee, Guid tenantId);
@ -14,6 +28,7 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces
Task<ApiResponse<object>> GetContactCategoryById(Guid id, Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> DeleteContactCategory(Guid id, Employee loggedInEmployee, Guid tenantId);
#endregion
#region =================================================================== Contact Tag APIs ===================================================================
Task<ApiResponse<Object>> GetContactTags(Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> CreateContactTag(CreateContactTagDto contactTagDto, Employee loggedInEmployee, Guid tenantId);
@ -21,6 +36,7 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces
Task<ApiResponse<object>> DeleteContactTag(Guid id, Employee loggedInEmployee, Guid tenantId);
#endregion
#region =================================================================== Work Status APIs ===================================================================
Task<ApiResponse<object>> GetWorkStatusList(Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> CreateWorkStatus(CreateWorkStatusMasterDto createWorkStatusDto, Employee loggedInEmployee, Guid tenantId);