Implemented functionality to upload captured attendance images to Amazon S3 and record associated data in the database.
This commit is contained in:
parent
6c99a625b5
commit
4d0901b4dd
@ -1,8 +1,10 @@
|
||||
using Marco.Pms.Model.Activities;
|
||||
using Marco.Pms.Model.AttendanceModule;
|
||||
using Marco.Pms.Model.Authentication;
|
||||
using Marco.Pms.Model.DocumentManager;
|
||||
using Marco.Pms.Model.Employees;
|
||||
using Marco.Pms.Model.Entitlements;
|
||||
using Marco.Pms.Model.Forum;
|
||||
using Marco.Pms.Model.Industries;
|
||||
using Marco.Pms.Model.Projects;
|
||||
using Marco.Pms.Model.Utilities;
|
||||
@ -57,7 +59,7 @@ namespace Marco.Pms.DataAccess.Data
|
||||
public DbSet<Attendance> Attendes { get; set; }
|
||||
|
||||
public DbSet<AttendanceLog> AttendanceLogs { get; set; }
|
||||
// public DbSet<AttendLog> AttendLogs { get; set; }
|
||||
// public DbSet<AttendLog> AttendLogs { get; set; }
|
||||
|
||||
|
||||
|
||||
@ -72,10 +74,20 @@ namespace Marco.Pms.DataAccess.Data
|
||||
public DbSet<JobRole> JobRoles { get; set; }
|
||||
public DbSet<RolePermissionMappings> RolePermissionMappings { get; set; }
|
||||
|
||||
public DbSet<Industry>Industries { get; set; }
|
||||
public DbSet<ActivityCheckList>ActivityCheckLists { get; set; }
|
||||
public DbSet<Industry> Industries { get; set; }
|
||||
public DbSet<ActivityCheckList> ActivityCheckLists { get; set; }
|
||||
public DbSet<CheckListMappings> CheckListMappings { get; set; }
|
||||
public DbSet<Inquiries> Inquiries { get; set; }
|
||||
public DbSet<TicketForum> Tickets { get; set; }
|
||||
public DbSet<TicketAttachment> TicketAttachments { get; set; }
|
||||
public DbSet<TicketComment> TicketComments { get; set; }
|
||||
public DbSet<TicketStatusMaster> TicketStatusMasters { get; set; }
|
||||
public DbSet<TicketTypeMaster> TicketTypeMasters { get; set; }
|
||||
public DbSet<TicketPriorityMaster> TicketPriorityMasters { get; set; }
|
||||
public DbSet<TicketTagMaster> TicketTagMasters { get; set; }
|
||||
public DbSet<Document> Documents { get; set; }
|
||||
public DbSet<TicketTag> TicketTags { get; set; }
|
||||
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
@ -136,7 +148,7 @@ namespace Marco.Pms.DataAccess.Data
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Tenant>().HasData(
|
||||
new Tenant { Id = 1, Name = "MarcoBMS", ContactName = "Admin", ContactNumber = "123456789", Description = "", DomainName = "www.marcobms.org",IndustryId = 1, OnBoardingDate = DateTime.MinValue }
|
||||
new Tenant { Id = 1, Name = "MarcoBMS", ContactName = "Admin", ContactNumber = "123456789", Description = "", DomainName = "www.marcobms.org", IndustryId = 1, OnBoardingDate = DateTime.MinValue }
|
||||
);
|
||||
|
||||
modelBuilder.Entity<StatusMaster>().HasData(
|
||||
@ -284,16 +296,144 @@ namespace Marco.Pms.DataAccess.Data
|
||||
}
|
||||
);
|
||||
modelBuilder.Entity<Industry>().HasData(
|
||||
new Industry {Id = 1,Name = "Information Technology (IT) Services"},
|
||||
new Industry { Id = 2,Name = "Manufacturing & Production" },
|
||||
new Industry { Id = 3,Name = "Energy & Resources" },
|
||||
new Industry { Id = 4,Name = "Finance & Professional Services" },
|
||||
new Industry { Id = 1, Name = "Information Technology (IT) Services" },
|
||||
new Industry { Id = 2, Name = "Manufacturing & Production" },
|
||||
new Industry { Id = 3, Name = "Energy & Resources" },
|
||||
new Industry { Id = 4, Name = "Finance & Professional Services" },
|
||||
new Industry { Id = 5, Name = "Hospitals and Healthcare Services" },
|
||||
new Industry { Id = 6, Name = "Social Services" },
|
||||
new Industry { Id = 7, Name = "Retail & Consumer Services" },
|
||||
new Industry { Id = 8, Name = "Transportation & Logistics" },
|
||||
new Industry { Id = 9, Name = "Education & Training" }
|
||||
|
||||
);
|
||||
modelBuilder.Entity<TicketStatusMaster>().HasData(
|
||||
new TicketStatusMaster
|
||||
{
|
||||
Id = new Guid("6b0c409b-3e80-4165-8b39-f3fcacb4c797"),
|
||||
Name = "New",
|
||||
Description = "This is a newly created issue.",
|
||||
ColorCode = "#FFCC99",
|
||||
IsDefault = true,
|
||||
TenantId = 1
|
||||
},
|
||||
new TicketStatusMaster
|
||||
{
|
||||
Id = new Guid("6c5ac37d-5b7d-40f3-adec-2dabaa5cca86"),
|
||||
Name = "Assigned",
|
||||
Description = "Assigned to employee or team of employees",
|
||||
ColorCode = "#E6FF99",
|
||||
IsDefault = true,
|
||||
TenantId = 1
|
||||
},
|
||||
new TicketStatusMaster
|
||||
{
|
||||
Id = new Guid("7f96bcd5-0c66-411b-8a1d-9d1a4785194e"),
|
||||
Name = "In Progress",
|
||||
Description = "These issues are currently in progress",
|
||||
ColorCode = "#99E6FF",
|
||||
IsDefault = true,
|
||||
TenantId = 1
|
||||
},
|
||||
new TicketStatusMaster
|
||||
{
|
||||
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
|
||||
Name = "In Review",
|
||||
Description = "These issues are currently under review",
|
||||
ColorCode = "#6c757d",
|
||||
IsDefault = true,
|
||||
TenantId = 1
|
||||
},
|
||||
new TicketStatusMaster
|
||||
{
|
||||
Id = new Guid("8ff85685-a875-4f21-aa95-d99551315fcc"),
|
||||
Name = "Done",
|
||||
Description = "The following issues are resolved and closed",
|
||||
ColorCode = "#B399FF",
|
||||
IsDefault = true,
|
||||
TenantId = 1
|
||||
}
|
||||
);
|
||||
modelBuilder.Entity<TicketTypeMaster>().HasData(
|
||||
new TicketTypeMaster
|
||||
{
|
||||
Id = new Guid("c74e5480-2b71-483c-8f4a-1a9c69c32603"),
|
||||
Name = "Quality Issue",
|
||||
Description = "An identified problem that affects the performance, reliability, or standards of a product or service",
|
||||
IsDefault = true,
|
||||
TenantId = 1
|
||||
},
|
||||
new TicketTypeMaster
|
||||
{
|
||||
Id = new Guid("d1f55eab-9898-4e46-9f03-b263e33e5d38"),
|
||||
Name = "Help Desk",
|
||||
Description = "A support service that assists users with technical issues, requests, or inquiries.",
|
||||
IsDefault = true,
|
||||
TenantId = 1
|
||||
}
|
||||
);
|
||||
modelBuilder.Entity<TicketPriorityMaster>().HasData(
|
||||
new TicketPriorityMaster
|
||||
{
|
||||
Id = new Guid("188d29b3-10f3-42d0-9587-1a46ae7a0320"),
|
||||
Name = "Low",
|
||||
ColorCode = "008000",
|
||||
Level = 1,
|
||||
IsDefault = true,
|
||||
TenantId = 1
|
||||
},
|
||||
new TicketPriorityMaster
|
||||
{
|
||||
Id = new Guid("0919bc84-9f82-4ecf-98c7-962755dd9a97"),
|
||||
Name = "Medium",
|
||||
ColorCode = "FFFF00",
|
||||
Level = 2,
|
||||
IsDefault = true,
|
||||
TenantId = 1
|
||||
}, new TicketPriorityMaster
|
||||
{
|
||||
Id = new Guid("a13b7e59-16fd-4665-b5cf-a97399e8445a"),
|
||||
Name = "High",
|
||||
ColorCode = "#FFA500",
|
||||
Level = 3,
|
||||
IsDefault = true,
|
||||
TenantId = 1
|
||||
}, new TicketPriorityMaster
|
||||
{
|
||||
Id = new Guid("f340fbc3-c9fd-46aa-b063-0093418830e4"),
|
||||
Name = "Critical",
|
||||
ColorCode = "#FFA500",
|
||||
Level = 4,
|
||||
IsDefault = true,
|
||||
TenantId = 1
|
||||
},
|
||||
new TicketPriorityMaster
|
||||
{
|
||||
Id = new Guid("44a7b91d-a0dd-45d1-8616-4d2f71e16401"),
|
||||
Name = "Urgent",
|
||||
ColorCode = "#FF0000",
|
||||
Level = 5,
|
||||
IsDefault = true,
|
||||
TenantId = 1
|
||||
}
|
||||
);
|
||||
modelBuilder.Entity<TicketTagMaster>().HasData(
|
||||
new TicketTagMaster
|
||||
{
|
||||
Id = new Guid("ef6c2a65-f61d-4537-9650-a7ab7f8d98db"),
|
||||
Name = "Quality Issue",
|
||||
ColorCode = "#e59866",
|
||||
IsDefault = true,
|
||||
TenantId = 1
|
||||
},
|
||||
new TicketTagMaster
|
||||
{
|
||||
Id = new Guid("5a168569-8ad7-4422-8db6-51ef25caddeb"),
|
||||
Name = "Help Desk",
|
||||
ColorCode = "#85c1e9",
|
||||
IsDefault = true,
|
||||
TenantId = 1
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@ -360,7 +500,7 @@ namespace Marco.Pms.DataAccess.Data
|
||||
);
|
||||
|
||||
modelBuilder.Entity<FeaturePermission>().HasData(
|
||||
new FeaturePermission { Id = new Guid("6ea44136-987e-44ba-9e5d-1cf8f5837ebc"), FeatureId = new Guid("53176ebf-c75d-42e5-839f-4508ffac3def"), IsEnabled = true, Name = "View Project" , Description=""},
|
||||
new FeaturePermission { Id = new Guid("6ea44136-987e-44ba-9e5d-1cf8f5837ebc"), FeatureId = new Guid("53176ebf-c75d-42e5-839f-4508ffac3def"), IsEnabled = true, Name = "View Project", Description = "" },
|
||||
new FeaturePermission { Id = new Guid("172fc9b6-755b-4f62-ab26-55c34a330614"), FeatureId = new Guid("53176ebf-c75d-42e5-839f-4508ffac3def"), IsEnabled = true, Name = "Manage Project", Description = "" },
|
||||
new FeaturePermission { Id = new Guid("b94802ce-0689-4643-9e1d-11c86950c35b"), FeatureId = new Guid("53176ebf-c75d-42e5-839f-4508ffac3def"), IsEnabled = true, Name = "Manage Team", Description = "" },
|
||||
|
||||
|
@ -1,32 +0,0 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Marco.Pms.Model.Authentication;
|
||||
using Marco.Pms.Model.Forum;
|
||||
|
||||
namespace Marco.Pms.DataAccess.Data
|
||||
{
|
||||
public class ForumDbContext : IdentityDbContext<IdentityUser>
|
||||
{
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
|
||||
public ForumDbContext(DbContextOptions<ApplicationDbContext> options, IHttpContextAccessor httpContextAccessor) : base(options)
|
||||
{
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
|
||||
}
|
||||
|
||||
public DbSet<TicketForum> Tickets { get; set; }
|
||||
public DbSet<TicketAttachment> TicketAttachments { get; set; }
|
||||
public DbSet<TicketComment> TicketComments { get; set; }
|
||||
public DbSet<TicketStatusMaster> TicketStatusMasters { get; set; }
|
||||
public DbSet<TicketTypeMaster> TicketTypeMasters { get; set; }
|
||||
|
||||
}
|
||||
}
|
2632
Marco.Pms.DataAccess/Migrations/20250423090827_Added_Forum_Tables.Designer.cs
generated
Normal file
2632
Marco.Pms.DataAccess/Migrations/20250423090827_Added_Forum_Tables.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,376 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
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_Forum_Tables : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Documents",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
BatchId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
FileName = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
S3Key = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
ThumbS3Key = table.Column<string>(type: "longtext", nullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Base64Data = table.Column<string>(type: "longtext", nullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
FileSize = table.Column<long>(type: "bigint", nullable: false),
|
||||
ContentType = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
UploadedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
TenantId = table.Column<int>(type: "int", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Documents", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Documents_Tenants_TenantId",
|
||||
column: x => x.TenantId,
|
||||
principalTable: "Tenants",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "TicketComments",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
TicketId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
AuthorId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
MessageText = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
SentAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
ParentMessageId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
|
||||
TenantId = table.Column<int>(type: "int", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_TicketComments", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_TicketComments_Tenants_TenantId",
|
||||
column: x => x.TenantId,
|
||||
principalTable: "Tenants",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "TicketPriorityMasters",
|
||||
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"),
|
||||
Level = table.Column<int>(type: "int", nullable: false),
|
||||
ColorCode = table.Column<string>(type: "longtext", nullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
IsDefault = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
TenantId = table.Column<int>(type: "int", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_TicketPriorityMasters", x => x.Id);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "TicketStatusMasters",
|
||||
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: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
ColorCode = table.Column<string>(type: "longtext", nullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
IsDefault = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
TenantId = table.Column<int>(type: "int", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_TicketStatusMasters", x => x.Id);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "TicketTagMasters",
|
||||
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"),
|
||||
ColorCode = table.Column<string>(type: "longtext", nullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
TenantId = table.Column<int>(type: "int", nullable: false),
|
||||
IsDefault = table.Column<bool>(type: "tinyint(1)", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_TicketTagMasters", x => x.Id);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "TicketTypeMasters",
|
||||
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: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
IsDefault = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
TenantId = table.Column<int>(type: "int", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_TicketTypeMasters", x => x.Id);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Tickets",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
Subject = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Description = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
StatusId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
TypeId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
CreatedById = table.Column<int>(type: "int", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
LinkedActivityId = table.Column<int>(type: "int", nullable: false),
|
||||
PriorityId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
TenantId = table.Column<int>(type: "int", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Tickets", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Tickets_Tenants_TenantId",
|
||||
column: x => x.TenantId,
|
||||
principalTable: "Tenants",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_Tickets_TicketPriorityMasters_PriorityId",
|
||||
column: x => x.PriorityId,
|
||||
principalTable: "TicketPriorityMasters",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_Tickets_TicketStatusMasters_StatusId",
|
||||
column: x => x.StatusId,
|
||||
principalTable: "TicketStatusMasters",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_Tickets_TicketTypeMasters_TypeId",
|
||||
column: x => x.TypeId,
|
||||
principalTable: "TicketTypeMasters",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "TicketAttachments",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
TicketId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
CommentId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
FileName = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
FileId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_TicketAttachments", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_TicketAttachments_TicketComments_CommentId",
|
||||
column: x => x.CommentId,
|
||||
principalTable: "TicketComments",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_TicketAttachments_Tickets_TicketId",
|
||||
column: x => x.TicketId,
|
||||
principalTable: "Tickets",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "TicketTags",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
TicketId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
TagId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_TicketTags", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_TicketTags_TicketTagMasters_TagId",
|
||||
column: x => x.TagId,
|
||||
principalTable: "TicketTagMasters",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_TicketTags_Tickets_TicketId",
|
||||
column: x => x.TicketId,
|
||||
principalTable: "Tickets",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "TicketPriorityMasters",
|
||||
columns: new[] { "Id", "ColorCode", "IsDefault", "Level", "Name", "TenantId" },
|
||||
values: new object[,]
|
||||
{
|
||||
{ new Guid("0919bc84-9f82-4ecf-98c7-962755dd9a97"), "FFFF00", true, 2, "Medium", 1 },
|
||||
{ new Guid("188d29b3-10f3-42d0-9587-1a46ae7a0320"), "008000", true, 1, "Low", 1 },
|
||||
{ new Guid("44a7b91d-a0dd-45d1-8616-4d2f71e16401"), "#FF0000", true, 5, "Urgent", 1 },
|
||||
{ new Guid("a13b7e59-16fd-4665-b5cf-a97399e8445a"), "#FFA500", true, 3, "High", 1 },
|
||||
{ new Guid("f340fbc3-c9fd-46aa-b063-0093418830e4"), "#FFA500", true, 4, "Critical", 1 }
|
||||
});
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "TicketStatusMasters",
|
||||
columns: new[] { "Id", "ColorCode", "Description", "IsDefault", "Name", "TenantId" },
|
||||
values: new object[,]
|
||||
{
|
||||
{ new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), "#6c757d", "These issues are currently under review", true, "In Review", 1 },
|
||||
{ new Guid("6b0c409b-3e80-4165-8b39-f3fcacb4c797"), "#FFCC99", "This is a newly created issue.", true, "New", 1 },
|
||||
{ new Guid("6c5ac37d-5b7d-40f3-adec-2dabaa5cca86"), "#E6FF99", "Assigned to employee or team of employees", true, "Assigned", 1 },
|
||||
{ new Guid("7f96bcd5-0c66-411b-8a1d-9d1a4785194e"), "#99E6FF", "These issues are currently in progress", true, "In Progress", 1 },
|
||||
{ new Guid("8ff85685-a875-4f21-aa95-d99551315fcc"), "#B399FF", "The following issues are resolved and closed", true, "Done", 1 }
|
||||
});
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "TicketTagMasters",
|
||||
columns: new[] { "Id", "ColorCode", "IsDefault", "Name", "TenantId" },
|
||||
values: new object[,]
|
||||
{
|
||||
{ new Guid("5a168569-8ad7-4422-8db6-51ef25caddeb"), "#85c1e9", true, "Help Desk", 1 },
|
||||
{ new Guid("ef6c2a65-f61d-4537-9650-a7ab7f8d98db"), "#e59866", true, "Quality Issue", 1 }
|
||||
});
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "TicketTypeMasters",
|
||||
columns: new[] { "Id", "Description", "IsDefault", "Name", "TenantId" },
|
||||
values: new object[,]
|
||||
{
|
||||
{ new Guid("c74e5480-2b71-483c-8f4a-1a9c69c32603"), "An identified problem that affects the performance, reliability, or standards of a product or service", true, "Quality Issue", 1 },
|
||||
{ new Guid("d1f55eab-9898-4e46-9f03-b263e33e5d38"), "A support service that assists users with technical issues, requests, or inquiries.", true, "Help Desk", 1 }
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Documents_TenantId",
|
||||
table: "Documents",
|
||||
column: "TenantId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TicketAttachments_CommentId",
|
||||
table: "TicketAttachments",
|
||||
column: "CommentId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TicketAttachments_TicketId",
|
||||
table: "TicketAttachments",
|
||||
column: "TicketId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TicketComments_TenantId",
|
||||
table: "TicketComments",
|
||||
column: "TenantId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Tickets_PriorityId",
|
||||
table: "Tickets",
|
||||
column: "PriorityId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Tickets_StatusId",
|
||||
table: "Tickets",
|
||||
column: "StatusId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Tickets_TenantId",
|
||||
table: "Tickets",
|
||||
column: "TenantId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Tickets_TypeId",
|
||||
table: "Tickets",
|
||||
column: "TypeId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TicketTags_TagId",
|
||||
table: "TicketTags",
|
||||
column: "TagId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TicketTags_TicketId",
|
||||
table: "TicketTags",
|
||||
column: "TicketId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "Documents");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "TicketAttachments");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "TicketTags");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "TicketComments");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "TicketTagMasters");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Tickets");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "TicketPriorityMasters");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "TicketStatusMasters");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "TicketTypeMasters");
|
||||
}
|
||||
}
|
||||
}
|
2643
Marco.Pms.DataAccess/Migrations/20250423091727_Added_Foreign_Key_In_Attendance_Log.Designer.cs
generated
Normal file
2643
Marco.Pms.DataAccess/Migrations/20250423091727_Added_Foreign_Key_In_Attendance_Log.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Marco.Pms.DataAccess.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Added_Foreign_Key_In_Attendance_Log : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "DocumentId",
|
||||
table: "AttendanceLogs",
|
||||
type: "char(36)",
|
||||
nullable: true,
|
||||
collation: "ascii_general_ci");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AttendanceLogs_DocumentId",
|
||||
table: "AttendanceLogs",
|
||||
column: "DocumentId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_AttendanceLogs_Documents_DocumentId",
|
||||
table: "AttendanceLogs",
|
||||
column: "DocumentId",
|
||||
principalTable: "Documents",
|
||||
principalColumn: "Id");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_AttendanceLogs_Documents_DocumentId",
|
||||
table: "AttendanceLogs");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_AttendanceLogs_DocumentId",
|
||||
table: "AttendanceLogs");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "DocumentId",
|
||||
table: "AttendanceLogs");
|
||||
}
|
||||
}
|
||||
}
|
@ -200,6 +200,9 @@ namespace Marco.Pms.DataAccess.Migrations
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<Guid?>("DocumentId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<int>("EmployeeID")
|
||||
.HasColumnType("int");
|
||||
|
||||
@ -225,6 +228,8 @@ namespace Marco.Pms.DataAccess.Migrations
|
||||
|
||||
b.HasIndex("AttendanceId");
|
||||
|
||||
b.HasIndex("DocumentId");
|
||||
|
||||
b.HasIndex("EmployeeID");
|
||||
|
||||
b.HasIndex("TenantId");
|
||||
@ -270,6 +275,49 @@ namespace Marco.Pms.DataAccess.Migrations
|
||||
b.ToTable("RefreshTokens");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.DocumentManager.Document", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<string>("Base64Data")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<Guid>("BatchId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<string>("ContentType")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("FileName")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<long>("FileSize")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<string>("S3Key")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("ThumbS3Key")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("UploadedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("TenantId");
|
||||
|
||||
b.ToTable("Documents");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.Employees.Employee", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@ -1103,6 +1151,369 @@ namespace Marco.Pms.DataAccess.Migrations
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.Forum.TicketAttachment", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<Guid>("CommentId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<Guid>("FileId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<string>("FileName")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<Guid>("TicketId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CommentId");
|
||||
|
||||
b.HasIndex("TicketId");
|
||||
|
||||
b.ToTable("TicketAttachments");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.Forum.TicketComment", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<Guid>("AuthorId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<string>("MessageText")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<Guid?>("ParentMessageId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<DateTime>("SentAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<Guid>("TicketId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("TenantId");
|
||||
|
||||
b.ToTable("TicketComments");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.Forum.TicketForum", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<int>("CreatedById")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("LinkedActivityId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<Guid>("PriorityId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<Guid>("StatusId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<string>("Subject")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<Guid>("TypeId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("PriorityId");
|
||||
|
||||
b.HasIndex("StatusId");
|
||||
|
||||
b.HasIndex("TenantId");
|
||||
|
||||
b.HasIndex("TypeId");
|
||||
|
||||
b.ToTable("Tickets");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.Forum.TicketPriorityMaster", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<string>("ColorCode")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<bool>("IsDefault")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<int>("Level")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("TicketPriorityMasters");
|
||||
|
||||
b.HasData(
|
||||
new
|
||||
{
|
||||
Id = new Guid("188d29b3-10f3-42d0-9587-1a46ae7a0320"),
|
||||
ColorCode = "008000",
|
||||
IsDefault = true,
|
||||
Level = 1,
|
||||
Name = "Low",
|
||||
TenantId = 1
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("0919bc84-9f82-4ecf-98c7-962755dd9a97"),
|
||||
ColorCode = "FFFF00",
|
||||
IsDefault = true,
|
||||
Level = 2,
|
||||
Name = "Medium",
|
||||
TenantId = 1
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("a13b7e59-16fd-4665-b5cf-a97399e8445a"),
|
||||
ColorCode = "#FFA500",
|
||||
IsDefault = true,
|
||||
Level = 3,
|
||||
Name = "High",
|
||||
TenantId = 1
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("f340fbc3-c9fd-46aa-b063-0093418830e4"),
|
||||
ColorCode = "#FFA500",
|
||||
IsDefault = true,
|
||||
Level = 4,
|
||||
Name = "Critical",
|
||||
TenantId = 1
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("44a7b91d-a0dd-45d1-8616-4d2f71e16401"),
|
||||
ColorCode = "#FF0000",
|
||||
IsDefault = true,
|
||||
Level = 5,
|
||||
Name = "Urgent",
|
||||
TenantId = 1
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.Forum.TicketStatusMaster", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<string>("ColorCode")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<bool>("IsDefault")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("TicketStatusMasters");
|
||||
|
||||
b.HasData(
|
||||
new
|
||||
{
|
||||
Id = new Guid("6b0c409b-3e80-4165-8b39-f3fcacb4c797"),
|
||||
ColorCode = "#FFCC99",
|
||||
Description = "This is a newly created issue.",
|
||||
IsDefault = true,
|
||||
Name = "New",
|
||||
TenantId = 1
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("6c5ac37d-5b7d-40f3-adec-2dabaa5cca86"),
|
||||
ColorCode = "#E6FF99",
|
||||
Description = "Assigned to employee or team of employees",
|
||||
IsDefault = true,
|
||||
Name = "Assigned",
|
||||
TenantId = 1
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("7f96bcd5-0c66-411b-8a1d-9d1a4785194e"),
|
||||
ColorCode = "#99E6FF",
|
||||
Description = "These issues are currently in progress",
|
||||
IsDefault = true,
|
||||
Name = "In Progress",
|
||||
TenantId = 1
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"),
|
||||
ColorCode = "#6c757d",
|
||||
Description = "These issues are currently under review",
|
||||
IsDefault = true,
|
||||
Name = "In Review",
|
||||
TenantId = 1
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("8ff85685-a875-4f21-aa95-d99551315fcc"),
|
||||
ColorCode = "#B399FF",
|
||||
Description = "The following issues are resolved and closed",
|
||||
IsDefault = true,
|
||||
Name = "Done",
|
||||
TenantId = 1
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.Forum.TicketTag", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<Guid>("TagId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<Guid>("TicketId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("TagId");
|
||||
|
||||
b.HasIndex("TicketId");
|
||||
|
||||
b.ToTable("TicketTags");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.Forum.TicketTagMaster", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<string>("ColorCode")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<bool>("IsDefault")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("TicketTagMasters");
|
||||
|
||||
b.HasData(
|
||||
new
|
||||
{
|
||||
Id = new Guid("ef6c2a65-f61d-4537-9650-a7ab7f8d98db"),
|
||||
ColorCode = "#e59866",
|
||||
IsDefault = true,
|
||||
Name = "Quality Issue",
|
||||
TenantId = 1
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("5a168569-8ad7-4422-8db6-51ef25caddeb"),
|
||||
ColorCode = "#85c1e9",
|
||||
IsDefault = true,
|
||||
Name = "Help Desk",
|
||||
TenantId = 1
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.Forum.TicketTypeMaster", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<bool>("IsDefault")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("TicketTypeMasters");
|
||||
|
||||
b.HasData(
|
||||
new
|
||||
{
|
||||
Id = new Guid("c74e5480-2b71-483c-8f4a-1a9c69c32603"),
|
||||
Description = "An identified problem that affects the performance, reliability, or standards of a product or service",
|
||||
IsDefault = true,
|
||||
Name = "Quality Issue",
|
||||
TenantId = 1
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = new Guid("d1f55eab-9898-4e46-9f03-b263e33e5d38"),
|
||||
Description = "A support service that assists users with technical issues, requests, or inquiries.",
|
||||
IsDefault = true,
|
||||
Name = "Help Desk",
|
||||
TenantId = 1
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.Industries.Industry", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@ -1756,6 +2167,10 @@ namespace Marco.Pms.DataAccess.Migrations
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Marco.Pms.Model.DocumentManager.Document", "Document")
|
||||
.WithMany()
|
||||
.HasForeignKey("DocumentId");
|
||||
|
||||
b.HasOne("Marco.Pms.Model.Employees.Employee", "Employee")
|
||||
.WithMany()
|
||||
.HasForeignKey("EmployeeID")
|
||||
@ -1774,6 +2189,8 @@ namespace Marco.Pms.DataAccess.Migrations
|
||||
|
||||
b.Navigation("Attendance");
|
||||
|
||||
b.Navigation("Document");
|
||||
|
||||
b.Navigation("Employee");
|
||||
|
||||
b.Navigation("Tenant");
|
||||
@ -1791,6 +2208,17 @@ namespace Marco.Pms.DataAccess.Migrations
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.DocumentManager.Document", b =>
|
||||
{
|
||||
b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant")
|
||||
.WithMany()
|
||||
.HasForeignKey("TenantId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Tenant");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.Employees.Employee", b =>
|
||||
{
|
||||
b.HasOne("Marco.Pms.Model.Entitlements.ApplicationUser", "ApplicationUser")
|
||||
@ -1940,6 +2368,90 @@ namespace Marco.Pms.DataAccess.Migrations
|
||||
b.Navigation("Industry");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.Forum.TicketAttachment", b =>
|
||||
{
|
||||
b.HasOne("Marco.Pms.Model.Forum.TicketComment", "TicketComment")
|
||||
.WithMany("Attachments")
|
||||
.HasForeignKey("CommentId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Marco.Pms.Model.Forum.TicketForum", "Ticket")
|
||||
.WithMany()
|
||||
.HasForeignKey("TicketId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ticket");
|
||||
|
||||
b.Navigation("TicketComment");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.Forum.TicketComment", b =>
|
||||
{
|
||||
b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant")
|
||||
.WithMany()
|
||||
.HasForeignKey("TenantId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Tenant");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.Forum.TicketForum", b =>
|
||||
{
|
||||
b.HasOne("Marco.Pms.Model.Forum.TicketPriorityMaster", "Priority")
|
||||
.WithMany()
|
||||
.HasForeignKey("PriorityId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Marco.Pms.Model.Forum.TicketStatusMaster", "TicketStatusMaster")
|
||||
.WithMany()
|
||||
.HasForeignKey("StatusId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant")
|
||||
.WithMany()
|
||||
.HasForeignKey("TenantId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Marco.Pms.Model.Forum.TicketTypeMaster", "TicketTypeMaster")
|
||||
.WithMany()
|
||||
.HasForeignKey("TypeId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Priority");
|
||||
|
||||
b.Navigation("Tenant");
|
||||
|
||||
b.Navigation("TicketStatusMaster");
|
||||
|
||||
b.Navigation("TicketTypeMaster");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.Forum.TicketTag", b =>
|
||||
{
|
||||
b.HasOne("Marco.Pms.Model.Forum.TicketTagMaster", "Tag")
|
||||
.WithMany()
|
||||
.HasForeignKey("TagId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Marco.Pms.Model.Forum.TicketForum", "Ticket")
|
||||
.WithMany()
|
||||
.HasForeignKey("TicketId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Tag");
|
||||
|
||||
b.Navigation("Ticket");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.Projects.Building", b =>
|
||||
{
|
||||
b.HasOne("Marco.Pms.Model.Entitlements.Tenant", "Tenant")
|
||||
@ -2117,6 +2629,11 @@ namespace Marco.Pms.DataAccess.Migrations
|
||||
{
|
||||
b.Navigation("FeaturePermissions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Marco.Pms.Model.Forum.TicketComment", b =>
|
||||
{
|
||||
b.Navigation("Attachments");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Marco.Pms.Model.DocumentManager;
|
||||
using Marco.Pms.Model.Dtos.Attendance;
|
||||
using Marco.Pms.Model.Employees;
|
||||
using Marco.Pms.Model.Entitlements;
|
||||
@ -41,6 +42,10 @@ namespace Marco.Pms.Model.AttendanceModule
|
||||
[ValidateNever]
|
||||
public Employee? UpdatedByEmployee { get; set; }
|
||||
|
||||
public Guid? DocumentId { get; set; }
|
||||
[ForeignKey("DocumentId")]
|
||||
[ValidateNever]
|
||||
public Document? Document { get; set; }
|
||||
|
||||
[DisplayName("TenantId")]
|
||||
public int TenantId { get; set; }
|
||||
|
@ -1,6 +1,6 @@
|
||||
using Marco.Pms.Model.Entitlements;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Marco.Pms.Model.Entitlements;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Marco.Pms.Model.DocumentManager
|
||||
{
|
||||
@ -18,7 +18,9 @@ namespace Marco.Pms.Model.DocumentManager
|
||||
/// </summary>
|
||||
public string? ThumbS3Key { get; set; }
|
||||
|
||||
public int FileSize { get; set; }
|
||||
public string? Base64Data { get; set; }
|
||||
|
||||
public long FileSize { get; set; }
|
||||
public string ContentType { get; set; } = string.Empty;
|
||||
public DateTime UploadedAt { get; set; }
|
||||
|
||||
|
@ -18,7 +18,7 @@ namespace Marco.Pms.Model.Dtos.Attendance
|
||||
|
||||
public ATTENDANCE_MARK_TYPE Action { get; set; }
|
||||
|
||||
public List<FileUploadModel>? Image { get; set; }
|
||||
public FileUploadModel? Image { get; set; }
|
||||
}
|
||||
|
||||
public enum ATTENDANCE_MARK_TYPE
|
||||
|
@ -1,5 +1,5 @@
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
|
||||
namespace Marco.Pms.Model.Forum
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
using Marco.Pms.Model.Entitlements;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.ComponentModel;
|
||||
using Marco.Pms.Model.Entitlements;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
|
||||
namespace Marco.Pms.Model.Forum
|
||||
{
|
||||
@ -18,19 +18,19 @@ namespace Marco.Pms.Model.Forum
|
||||
[ValidateNever]
|
||||
[ForeignKey(nameof(TypeId))]
|
||||
public TicketTypeMaster? TicketTypeMaster { get; set; }
|
||||
public Guid CreatedById { get; set; }
|
||||
public int CreatedById { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public Guid? LinkedActivityId { get; set; } // task or project ID
|
||||
public int LinkedActivityId { get; set; } // task or project ID
|
||||
|
||||
public ICollection<TicketComment>? Comments { get; set; }
|
||||
public ICollection<TicketAttachment>? Attachments { get; set; }
|
||||
//public ICollection<TicketComment>? Comments { get; set; } // view model
|
||||
//public ICollection<TicketAttachment>? Attachments { get; set; } // view model
|
||||
|
||||
public Guid PriorityId { get; set; }
|
||||
[ValidateNever]
|
||||
[ForeignKey(nameof(PriorityId))]
|
||||
public TicketPriorityMaster? Priority { get; set; }
|
||||
|
||||
public ICollection<TicketTag>? Tags { get; set; }
|
||||
//public ICollection<TicketTag>? Tags { get; set; } // view model
|
||||
|
||||
|
||||
[DisplayName("TenantId")]
|
||||
|
@ -1,19 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Marco.Pms.Model.Forum
|
||||
namespace Marco.Pms.Model.Forum
|
||||
{
|
||||
public class TicketPriorityMaster
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string Name { get; set; } // e.g., Low, Medium, High, Critical
|
||||
public string Name { get; set; } = string.Empty; // e.g., Low, Medium, High, Critical
|
||||
public int Level { get; set; } // 1 = Low, 2 = Medium...
|
||||
public string? ColorCode { get; set; }
|
||||
public bool IsDefault { get; set; }
|
||||
public Guid TenantId { get; set; }
|
||||
public int TenantId { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
public string? Description { get; set; }
|
||||
public string? ColorCode { get; set; } // e.g., "#FF0000"
|
||||
public bool IsDefault { get; set; } // true for system defaults
|
||||
public Guid TenantId { get; set; } // or nullable if global
|
||||
public int TenantId { get; set; } // or nullable if global
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,11 +2,12 @@
|
||||
{
|
||||
public class TicketTag
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public Guid TicketId { get; set; }
|
||||
public TicketForum Ticket { get; set; }
|
||||
public TicketForum Ticket { get; set; } = new TicketForum();
|
||||
|
||||
public Guid TagId { get; set; }
|
||||
public TicketTagMaster Tag { get; set; }
|
||||
public TicketTagMaster Tag { get; set; } = new TicketTagMaster();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
public Guid Id { get; set; }
|
||||
public string Name { get; set; } = string.Empty; // e.g., "Bug", "UI", "Urgent"
|
||||
public string? ColorCode { get; set; }
|
||||
public Guid TenantId { get; set; }
|
||||
public int TenantId { get; set; }
|
||||
public bool IsDefault { get; set; }
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
public string Name { get; set; } = string.Empty; // e.g., "Quality Issue"
|
||||
public string? Description { get; set; }
|
||||
public bool IsDefault { get; set; } // true for system defaults
|
||||
public Guid TenantId { get; set; }
|
||||
public int TenantId { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
|
10
Marco.Pms.Model/Utilities/AWSSettings.cs
Normal file
10
Marco.Pms.Model/Utilities/AWSSettings.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace Marco.Pms.Model.Utilities
|
||||
{
|
||||
public class AWSSettings
|
||||
{
|
||||
public string AccessKey { get; set; } = string.Empty;
|
||||
public string SecretKey { get; set; } = string.Empty;
|
||||
public string Region { get; set; } = string.Empty;
|
||||
public string BucketName { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
@ -14,5 +14,11 @@ namespace Marco.Pms.Model.ViewModels.Attendance
|
||||
public string? JobRoleName { get; set; }
|
||||
public ATTENDANCE_MARK_TYPE Activity { get; set; }
|
||||
|
||||
public string? ThumbPreSignedUrl { get; set; }
|
||||
public string? PreSignedUrl { get; set; }
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -6,10 +6,12 @@ using Marco.Pms.Model.Employees;
|
||||
using Marco.Pms.Model.Projects;
|
||||
using Marco.Pms.Model.Utilities;
|
||||
using Marco.Pms.Model.ViewModels.Attendance;
|
||||
using Marco.Pms.Services.Service;
|
||||
using MarcoBMS.Services.Helpers;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Document = Marco.Pms.Model.DocumentManager.Document;
|
||||
|
||||
namespace MarcoBMS.Services.Controllers
|
||||
{
|
||||
@ -21,15 +23,17 @@ namespace MarcoBMS.Services.Controllers
|
||||
private readonly EmployeeHelper _employeeHelper;
|
||||
private readonly ProjectsHelper _projectsHelper;
|
||||
private readonly UserHelper _userHelper;
|
||||
private readonly S3UploadService _s3Service;
|
||||
|
||||
|
||||
public AttendanceController(
|
||||
ApplicationDbContext context, EmployeeHelper employeeHelper, ProjectsHelper projectsHelper, UserHelper userHelper)
|
||||
ApplicationDbContext context, EmployeeHelper employeeHelper, ProjectsHelper projectsHelper, UserHelper userHelper, S3UploadService s3Service)
|
||||
{
|
||||
_context = context;
|
||||
_employeeHelper = employeeHelper;
|
||||
_projectsHelper = projectsHelper;
|
||||
_userHelper = userHelper;
|
||||
_s3Service = s3Service;
|
||||
}
|
||||
|
||||
private int GetTenantId()
|
||||
@ -101,7 +105,7 @@ namespace MarcoBMS.Services.Controllers
|
||||
Attendance? attendance = null;
|
||||
|
||||
if (dateFrom == null) fromDate = DateTime.UtcNow.Date;
|
||||
if (dateTo == null && dateFrom != null) toDate = fromDate.AddDays(-1);
|
||||
if (dateTo == null && dateFrom != null) toDate = fromDate.AddDays(-1);
|
||||
|
||||
|
||||
List<Attendance> lstAttendance = await _context.Attendes.Where(c => c.ProjectID == projectId && c.AttendanceDate.Date <= fromDate && c.AttendanceDate.Date >= toDate && c.TenantId == TenantId).ToListAsync();
|
||||
@ -199,7 +203,8 @@ namespace MarcoBMS.Services.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
result.Sort(delegate (EmployeeAttendanceVM x, EmployeeAttendanceVM y) {
|
||||
result.Sort(delegate (EmployeeAttendanceVM x, EmployeeAttendanceVM y)
|
||||
{
|
||||
//return x.FirstName.CompareTo(y.FirstName);
|
||||
return string.Compare(x.FirstName, y.FirstName, StringComparison.Ordinal);
|
||||
});
|
||||
@ -223,29 +228,30 @@ namespace MarcoBMS.Services.Controllers
|
||||
|
||||
foreach (Attendance attende in lstAttendance)
|
||||
{
|
||||
var result1 = new EmployeeAttendanceVM()
|
||||
{
|
||||
Id = attende.Id,
|
||||
CheckInTime = attende.InTime,
|
||||
CheckOutTime = attende.OutTime,
|
||||
Activity = attende.Activity,
|
||||
EmployeeAvatar = null,
|
||||
EmployeeId = attende.EmployeeID,
|
||||
|
||||
};
|
||||
var result1 = new EmployeeAttendanceVM()
|
||||
{
|
||||
Id = attende.Id,
|
||||
CheckInTime = attende.InTime,
|
||||
CheckOutTime = attende.OutTime,
|
||||
Activity = attende.Activity,
|
||||
EmployeeAvatar = null,
|
||||
EmployeeId = attende.EmployeeID,
|
||||
|
||||
};
|
||||
|
||||
var teamMember = projectteam.Find(m => m.EmployeeId == attende.EmployeeID);
|
||||
if (teamMember != null && teamMember.Employee.JobRole != null)
|
||||
{
|
||||
if (teamMember != null && teamMember.Employee.JobRole != null)
|
||||
{
|
||||
result1.FirstName = teamMember.Employee.FirstName;
|
||||
result1.LastName = teamMember.Employee.LastName;
|
||||
result1.JobRoleName = teamMember.Employee.JobRole.Name;
|
||||
}
|
||||
}
|
||||
|
||||
result.Add(result1);
|
||||
result.Add(result1);
|
||||
}
|
||||
|
||||
result.Sort(delegate (EmployeeAttendanceVM x, EmployeeAttendanceVM y) {
|
||||
result.Sort(delegate (EmployeeAttendanceVM x, EmployeeAttendanceVM y)
|
||||
{
|
||||
return string.Compare(x.FirstName, y.FirstName, StringComparison.Ordinal);
|
||||
});
|
||||
|
||||
@ -273,7 +279,7 @@ namespace MarcoBMS.Services.Controllers
|
||||
{
|
||||
Attendance? attendance = await _context.Attendes.FirstOrDefaultAsync(a => a.Id == recordAttendanceDot.Id && a.TenantId == TenantId); ;
|
||||
|
||||
if (recordAttendanceDot.MarkTime == null) return BadRequest(ApiResponse<object>.ErrorResponse("Invalid Mark Time", "Invalid Mark Time",400));
|
||||
if (recordAttendanceDot.MarkTime == null) return BadRequest(ApiResponse<object>.ErrorResponse("Invalid Mark Time", "Invalid Mark Time", 400));
|
||||
|
||||
DateTime finalDateTime = GetDateFromTimeStamp(recordAttendanceDot.Date, recordAttendanceDot.MarkTime);
|
||||
if (recordAttendanceDot.Comment == null) return BadRequest(ApiResponse<object>.ErrorResponse("Invalid Comment", "Invalid Comment", 400));
|
||||
@ -372,7 +378,7 @@ namespace MarcoBMS.Services.Controllers
|
||||
await transaction.CommitAsync(); // Commit transaction
|
||||
|
||||
Employee employee = await _employeeHelper.GetEmployeeByID(recordAttendanceDot.EmployeeID);
|
||||
if(employee.JobRole != null)
|
||||
if (employee.JobRole != null)
|
||||
{
|
||||
EmployeeAttendanceVM vm = new EmployeeAttendanceVM()
|
||||
{
|
||||
@ -400,6 +406,193 @@ namespace MarcoBMS.Services.Controllers
|
||||
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("record-image")]
|
||||
public async Task<IActionResult> RecordAttendanceWithImage([FromBody] RecordAttendanceDot recordAttendanceDot)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
var errors = ModelState.Values
|
||||
.SelectMany(v => v.Errors)
|
||||
.Select(e => e.ErrorMessage)
|
||||
.ToList();
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid data", errors, 400));
|
||||
}
|
||||
|
||||
int TenantId = GetTenantId();
|
||||
|
||||
using var transaction = await _context.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
Attendance? attendance = await _context.Attendes.FirstOrDefaultAsync(a => a.Id == recordAttendanceDot.Id && a.TenantId == TenantId); ;
|
||||
|
||||
if (recordAttendanceDot.MarkTime == null) return BadRequest(ApiResponse<object>.ErrorResponse("Invalid Mark Time", "Invalid Mark Time", 400));
|
||||
|
||||
DateTime finalDateTime = GetDateFromTimeStamp(recordAttendanceDot.Date, recordAttendanceDot.MarkTime);
|
||||
if (recordAttendanceDot.Comment == null) return BadRequest(ApiResponse<object>.ErrorResponse("Invalid Comment", "Invalid Comment", 400));
|
||||
|
||||
if (attendance != null)
|
||||
{
|
||||
attendance.Comment = recordAttendanceDot.Comment;
|
||||
if (recordAttendanceDot.Action == ATTENDANCE_MARK_TYPE.CHECK_IN)
|
||||
{
|
||||
attendance.OutTime = null;
|
||||
attendance.Activity = ATTENDANCE_MARK_TYPE.CHECK_OUT;
|
||||
}
|
||||
else if (recordAttendanceDot.Action == ATTENDANCE_MARK_TYPE.CHECK_OUT)
|
||||
{
|
||||
attendance.IsApproved = true;
|
||||
attendance.Activity = ATTENDANCE_MARK_TYPE.REGULARIZE;
|
||||
|
||||
|
||||
//string timeString = "10:30 PM"; // Format: "hh:mm tt"
|
||||
|
||||
attendance.OutTime = finalDateTime;
|
||||
}
|
||||
else if (recordAttendanceDot.Action == ATTENDANCE_MARK_TYPE.REQUEST_REGULARIZE)
|
||||
{
|
||||
DateTime date = attendance.AttendanceDate;
|
||||
finalDateTime = GetDateFromTimeStamp(date.Date, recordAttendanceDot.MarkTime);
|
||||
attendance.OutTime = finalDateTime;
|
||||
attendance.Activity = ATTENDANCE_MARK_TYPE.REQUEST_REGULARIZE;
|
||||
// do nothing
|
||||
}
|
||||
else if (recordAttendanceDot.Action == ATTENDANCE_MARK_TYPE.REGULARIZE)
|
||||
{
|
||||
attendance.IsApproved = true;
|
||||
attendance.Activity = ATTENDANCE_MARK_TYPE.REGULARIZE;
|
||||
// do nothing
|
||||
}
|
||||
else if (recordAttendanceDot.Action == ATTENDANCE_MARK_TYPE.REGULARIZE_REJECT)
|
||||
{
|
||||
attendance.IsApproved = false;
|
||||
attendance.Activity = ATTENDANCE_MARK_TYPE.REGULARIZE_REJECT;
|
||||
// do nothing
|
||||
}
|
||||
attendance.Date = DateTime.UtcNow;
|
||||
|
||||
// update code
|
||||
_context.Attendes.Update(attendance);
|
||||
}
|
||||
else
|
||||
{
|
||||
attendance = new Attendance();
|
||||
attendance.TenantId = TenantId;
|
||||
attendance.AttendanceDate = recordAttendanceDot.Date;
|
||||
// attendance.Activity = recordAttendanceDot.Action;
|
||||
attendance.Comment = recordAttendanceDot.Comment;
|
||||
attendance.EmployeeID = recordAttendanceDot.EmployeeID;
|
||||
attendance.ProjectID = recordAttendanceDot.ProjectID;
|
||||
attendance.Date = DateTime.UtcNow;
|
||||
|
||||
|
||||
|
||||
attendance.InTime = finalDateTime;
|
||||
attendance.OutTime = null;
|
||||
attendance.Activity = ATTENDANCE_MARK_TYPE.CHECK_OUT;
|
||||
|
||||
_context.Attendes.Add(attendance);
|
||||
|
||||
}
|
||||
|
||||
byte[] fileBytes;
|
||||
var Image = recordAttendanceDot.Image;
|
||||
if (string.IsNullOrEmpty(Image.Base64Data))
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Base64 data is missing", "Base64 data is missing", 400));
|
||||
try
|
||||
{
|
||||
//If base64 has a data URI prefix, strip it
|
||||
var base64 = Image.Base64Data.Contains(",")
|
||||
? Image.Base64Data.Substring(Image.Base64Data.IndexOf(",") + 1)
|
||||
: Image.Base64Data;
|
||||
|
||||
fileBytes = Convert.FromBase64String(base64);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse(ex.Message, ex, 400)); ;
|
||||
}
|
||||
|
||||
using var stream = new MemoryStream(fileBytes);
|
||||
var objectKey = await _s3Service.UploadFileAsync(stream, Image.FileName, Image.ContentType);
|
||||
//var objectKey = await _s3Service.UploadFileAsync(Image.FileName, Image.ContentType);
|
||||
var preSignedUrl = await _s3Service.GeneratePreSignedUrlAsync(objectKey);
|
||||
|
||||
Document document = new Document
|
||||
{
|
||||
FileName = Image.FileName,
|
||||
ContentType = Image.ContentType,
|
||||
S3Key = objectKey,
|
||||
Base64Data = Image.Base64Data,
|
||||
FileSize = Image.FileSize,
|
||||
UploadedAt = recordAttendanceDot.Date,
|
||||
TenantId = TenantId
|
||||
};
|
||||
_context.Documents.Add(document);
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
|
||||
|
||||
|
||||
// Step 3: Always insert a new log entry
|
||||
var attendanceLog = new AttendanceLog
|
||||
{
|
||||
AttendanceId = attendance.Id, // Use existing or new AttendanceId
|
||||
Activity = attendance.Activity,
|
||||
|
||||
ActivityTime = finalDateTime,
|
||||
Comment = recordAttendanceDot.Comment,
|
||||
EmployeeID = recordAttendanceDot.EmployeeID,
|
||||
Latitude = recordAttendanceDot.Latitude,
|
||||
Longitude = recordAttendanceDot.Longitude,
|
||||
DocumentId = document.Id,
|
||||
TenantId = TenantId,
|
||||
UpdatedBy = recordAttendanceDot.EmployeeID,
|
||||
UpdatedOn = recordAttendanceDot.Date
|
||||
};
|
||||
//if (recordAttendanceDot.Image != null && recordAttendanceDot.Image.Count > 0)
|
||||
//{
|
||||
// attendanceLog.Photo = recordAttendanceDot.Image[0].Base64Data;
|
||||
//}
|
||||
|
||||
|
||||
_context.AttendanceLogs.Add(attendanceLog);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
await transaction.CommitAsync(); // Commit transaction
|
||||
|
||||
Employee employee = await _employeeHelper.GetEmployeeByID(recordAttendanceDot.EmployeeID);
|
||||
if (employee.JobRole != null)
|
||||
{
|
||||
EmployeeAttendanceVM vm = new EmployeeAttendanceVM()
|
||||
{
|
||||
CheckInTime = attendance.InTime,
|
||||
CheckOutTime = attendance.OutTime,
|
||||
EmployeeAvatar = null,
|
||||
EmployeeId = recordAttendanceDot.EmployeeID,
|
||||
FirstName = employee.FirstName,
|
||||
LastName = employee.LastName,
|
||||
Id = attendance.Id,
|
||||
Activity = attendance.Activity,
|
||||
JobRoleName = employee.JobRole.Name,
|
||||
ThumbPreSignedUrl = preSignedUrl,
|
||||
PreSignedUrl = preSignedUrl
|
||||
};
|
||||
|
||||
return Ok(ApiResponse<object>.SuccessResponse(vm, "Attendance marked successfully.", 200));
|
||||
}
|
||||
return Ok(ApiResponse<object>.SuccessResponse(new EmployeeAttendanceVM(), "Attendance marked successfully.", 200));
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await transaction.RollbackAsync(); // Rollback on failure
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse(ex.Message, ex, 400));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static DateTime GetDateFromTimeStamp(DateTime date, string timeString)
|
||||
{
|
||||
//DateTime date = recordAttendanceDot.Date;
|
||||
|
@ -1,3 +1,5 @@
|
||||
using Marco.Pms.Model.Utilities;
|
||||
using Marco.Pms.Services.Service;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace MarcoBMS.Services.Controllers
|
||||
@ -12,10 +14,12 @@ namespace MarcoBMS.Services.Controllers
|
||||
};
|
||||
|
||||
private readonly ILogger<WeatherForecastController> _logger;
|
||||
private readonly S3UploadService _s3Service;
|
||||
|
||||
public WeatherForecastController(ILogger<WeatherForecastController> logger)
|
||||
public WeatherForecastController(ILogger<WeatherForecastController> logger, S3UploadService s3Service)
|
||||
{
|
||||
_logger = logger;
|
||||
_s3Service = s3Service;
|
||||
}
|
||||
|
||||
[HttpGet(Name = "GetWeatherForecast")]
|
||||
@ -29,5 +33,41 @@ namespace MarcoBMS.Services.Controllers
|
||||
})
|
||||
.ToArray();
|
||||
}
|
||||
[HttpPost("upload-image")]
|
||||
public async Task<IActionResult> SendToSThree([FromBody] FileUploadModel Image)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Image.Base64Data))
|
||||
return BadRequest("Base64 data is missing");
|
||||
|
||||
byte[] fileBytes;
|
||||
|
||||
try
|
||||
{
|
||||
//If base64 has a data URI prefix, strip it
|
||||
var base64 = Image.Base64Data.Contains(",")
|
||||
? Image.Base64Data.Substring(Image.Base64Data.IndexOf(",") + 1)
|
||||
: Image.Base64Data;
|
||||
|
||||
fileBytes = Convert.FromBase64String(base64);
|
||||
}
|
||||
catch (Exception error)
|
||||
{
|
||||
//return BadRequest("Invalid base64 string.");
|
||||
return BadRequest(error);
|
||||
}
|
||||
|
||||
using var stream = new MemoryStream(fileBytes);
|
||||
var objectKey = await _s3Service.UploadFileAsync(stream, Image.FileName, Image.ContentType);
|
||||
//var objectKey = await _s3Service.UploadFileAsync(Image.FileName, Image.ContentType);
|
||||
var preSignedUrl = await _s3Service.GeneratePreSignedUrlAsync(objectKey);
|
||||
|
||||
return Ok(new
|
||||
{
|
||||
objectKey,
|
||||
url = preSignedUrl
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AWSSDK.S3" Version="3.7.416.13" />
|
||||
<PackageReference Include="MailKit" Version="4.9.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.20" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.12" />
|
||||
|
@ -1,6 +1,8 @@
|
||||
using System.Text;
|
||||
using Marco.Pms.DataAccess.Data;
|
||||
using Marco.Pms.Model.Authentication;
|
||||
using Marco.Pms.Model.Utilities;
|
||||
using Marco.Pms.Services.Service;
|
||||
using MarcoBMS.Services.Helpers;
|
||||
using MarcoBMS.Services.Middleware;
|
||||
using MarcoBMS.Services.Service;
|
||||
@ -10,7 +12,6 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Serilog;
|
||||
using System.Text;
|
||||
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
@ -87,6 +88,9 @@ builder.Services.AddSwaggerGen(option =>
|
||||
builder.Services.Configure<SmtpSettings>(builder.Configuration.GetSection("EmailSettings"));
|
||||
builder.Services.AddTransient<IEmailSender, EmailSender>();
|
||||
|
||||
builder.Services.Configure<AWSSettings>(builder.Configuration.GetSection("AWS")); // For uploading images to aws s3
|
||||
builder.Services.AddTransient<S3UploadService>();
|
||||
|
||||
builder.Services.AddIdentity<IdentityUser, IdentityRole>().AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultTokenProviders();
|
||||
|
||||
|
||||
@ -96,10 +100,7 @@ builder.Services.AddDbContext<ApplicationDbContext>(options =>
|
||||
{
|
||||
options.UseMySql(connString, ServerVersion.AutoDetect(connString));
|
||||
});
|
||||
builder.Services.AddDbContext<ForumDbContext>(options =>
|
||||
{
|
||||
options.UseMySql(connString, ServerVersion.AutoDetect(connString));
|
||||
});
|
||||
|
||||
|
||||
builder.Services.AddMemoryCache();
|
||||
|
||||
@ -123,7 +124,7 @@ builder.Services.AddSingleton<ILoggingService, LoggingService>();
|
||||
builder.Services.AddHttpContextAccessor();
|
||||
|
||||
var jwtSettings = builder.Configuration.GetSection("Jwt").Get<JwtSettings>();
|
||||
if(jwtSettings != null && jwtSettings.Key != null)
|
||||
if (jwtSettings != null && jwtSettings.Key != null)
|
||||
{
|
||||
builder.Services.AddAuthentication(options =>
|
||||
{
|
||||
@ -166,7 +167,8 @@ if (app.Environment.IsDevelopment())
|
||||
app.UseSwaggerUI();
|
||||
// Use CORS in the pipeline
|
||||
app.UseCors("DevCorsPolicy");
|
||||
}else
|
||||
}
|
||||
else
|
||||
{
|
||||
//if (app.Environment.IsProduction())
|
||||
//{
|
||||
|
59
Marco.Pms.Services/Service/S3UploadService.cs
Normal file
59
Marco.Pms.Services/Service/S3UploadService.cs
Normal file
@ -0,0 +1,59 @@
|
||||
using Amazon.S3;
|
||||
using Amazon.S3.Model;
|
||||
using Amazon.S3.Transfer;
|
||||
using Marco.Pms.Model.Utilities;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Marco.Pms.Services.Service
|
||||
{
|
||||
|
||||
public class S3UploadService
|
||||
{
|
||||
private readonly IAmazonS3 _s3Client;
|
||||
private readonly string _bucketName = "your-bucket-name";
|
||||
|
||||
public S3UploadService(IOptions<AWSSettings> awsOptions)
|
||||
{
|
||||
var settings = awsOptions.Value;
|
||||
|
||||
var region = Amazon.RegionEndpoint.GetBySystemName(settings.Region);
|
||||
_bucketName = settings.BucketName;
|
||||
|
||||
_s3Client = new AmazonS3Client(settings.AccessKey, settings.SecretKey, region);
|
||||
}
|
||||
//public async Task<string> UploadFileAsync(string fileName, string contentType)
|
||||
public async Task<string> UploadFileAsync(Stream fileStream, string fileName, string contentType)
|
||||
{
|
||||
// Generate a unique object key (you can customize this)
|
||||
var objectKey = $"{Guid.NewGuid()}_{fileName}";
|
||||
|
||||
var uploadRequest = new TransferUtilityUploadRequest
|
||||
{
|
||||
InputStream = fileStream,
|
||||
Key = objectKey,
|
||||
BucketName = _bucketName,
|
||||
ContentType = contentType,
|
||||
AutoCloseStream = true
|
||||
};
|
||||
|
||||
var transferUtility = new TransferUtility(_s3Client);
|
||||
await transferUtility.UploadAsync(uploadRequest);
|
||||
|
||||
return objectKey;
|
||||
}
|
||||
public async Task<string> GeneratePreSignedUrlAsync(string objectKey)
|
||||
{
|
||||
int expiresInMinutes = 1;
|
||||
var request = new GetPreSignedUrlRequest
|
||||
{
|
||||
BucketName = _bucketName,
|
||||
Key = objectKey,
|
||||
Expires = DateTime.UtcNow.AddMinutes(expiresInMinutes),
|
||||
Verb = HttpVerb.GET // for download
|
||||
};
|
||||
|
||||
string url = _s3Client.GetPreSignedURL(request);
|
||||
return url;
|
||||
}
|
||||
}
|
||||
}
|
@ -96,7 +96,14 @@
|
||||
"Password": "qrtq wfuj hwpp fhqr"
|
||||
},
|
||||
"Contact": {
|
||||
"Emails": "ashutosh.nehete@marcoaiot.com;vikas@marcoaiot.com;umesh@marcoait.com"
|
||||
//"Emails": "ashutosh.nehete@marcoaiot.com;vikas@marcoaiot.com;umesh@marcoait.com"
|
||||
"Emails": "ashutosh.nehete@marcoaiot.com"
|
||||
},
|
||||
"AWS": {
|
||||
"AccessKey": "AKIARZDBH3VDMSUUY2FX",
|
||||
"SecretKey": "NTS5XXgZINQbU6ctpNuLXtIY/Qk9GCgD9Rr5yNJP",
|
||||
"Region": "us-east-1",
|
||||
"BucketName": "testenv-marco-pms-documents"
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user