Push user rights branh

This commit is contained in:
Vikas Nale 2025-03-25 13:01:56 +05:30
parent 17d42f2cdf
commit 0ea14ff112
86 changed files with 8871 additions and 1524 deletions

View File

@ -4,7 +4,7 @@ using Marco.Pms.Model.Authentication;
using Marco.Pms.Model.Employees;
using Marco.Pms.Model.Entitlements;
using Marco.Pms.Model.Projects;
using MarcoBMS.Utility;
using Marco.Pms.Utility;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
@ -300,19 +300,19 @@ namespace Marco.Pms.DataAccess.Data
Id = 1,
Name = "Project",
Description = "Project Module",
Key = Guid.NewGuid().ToString()
Key = "b04da7e9-0406-409c-ac7f-b97256e6ea02"
}, new Module
{
Id = 2,
Name = "Employee",
Description = "Employee Module",
Key = Guid.NewGuid().ToString()
Key = "0971c7fb-6ce1-458a-ae3f-8d3205893637"
}, new Module
{
Id = 3,
Name = "Masters",
Description = "Masters Module",
Key = Guid.NewGuid().ToString()
Key = "504ec132-e6a9-422f-8f85-050602cfce05"
});

View File

@ -1,15 +1,10 @@
using Marco.Pms.DataAccess.Data;
using Marco.Pms.DataAccess.Repository;
using Marco.Pms.DataAccess.Repository.IRepository;
using Marco.Pms.Model.Activities;
using Marco.Pms.Model.Employees;
using Marco.Pms.Model.Entitlements;
using Marco.Pms.Model.Projects;
using Marco.Pms.Model.ViewModels;
using MarcoBMS.Utility;
using Marco.Pms.Utility;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using System.Text.Json;
namespace Marco.Pms.DataAccess.Initializer
{
@ -19,14 +14,14 @@ namespace Marco.Pms.DataAccess.Initializer
private readonly ApplicationDbContext _db;
private readonly UserManager<IdentityUser> _userManager;
private readonly RoleManager<IdentityRole> _roleManager;
private readonly IUnitOfWork _unitOfWork;
//private readonly IUnitOfWork _unitOfWork;
public DBInitializer(UserManager<IdentityUser> userManager, RoleManager<IdentityRole> roleManager, ApplicationDbContext db, IUnitOfWork unitOfWork)
public DBInitializer(UserManager<IdentityUser> userManager, RoleManager<IdentityRole> roleManager, ApplicationDbContext db)
{
_userManager = userManager;
_roleManager = roleManager;
_db = db;
_unitOfWork = unitOfWork;
//_unitOfWork = unitOfWork;
}
public void Initialize()

View File

@ -7,9 +7,9 @@
</PropertyGroup>
<ItemGroup>
<Compile Remove="Repository\IRepository\**" />
<EmbeddedResource Remove="Repository\IRepository\**" />
<None Remove="Repository\IRepository\**" />
<Compile Remove="Repository\**" />
<EmbeddedResource Remove="Repository\**" />
<None Remove="Repository\**" />
</ItemGroup>
<ItemGroup>
@ -19,26 +19,6 @@
<Compile Remove="Migrations\20240927100058_AddModels.Designer.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="Repository\IRepository\IApplicationUserRepository.cs" />
<Compile Include="Repository\IRepository\IApplicationRolesRepository.cs" />
<Compile Include="Repository\IRepository\IFeatureRepository.cs" />
<Compile Include="Repository\IRepository\ITaskAllocationRepository.cs" />
<Compile Include="Repository\IRepository\IAttendenceRepository.cs" />
<Compile Include="Repository\IRepository\IEmployeeRepository.cs" />
<Compile Include="Repository\IRepository\IBuildingRepository.cs" />
<Compile Include="Repository\IRepository\IFloorRepository.cs" />
<Compile Include="Repository\IRepository\IActivityMasterRepository.cs" />
<Compile Include="Repository\IRepository\IProjectAllocationRepository.cs" />
<Compile Include="Repository\IRepository\IStatusRepository.cs" />
<Compile Include="Repository\IRepository\IWorkAreaRepository.cs" />
<Compile Include="Repository\IRepository\IWorkItemMappingReposiotry.cs" />
<Compile Include="Repository\IRepository\IWorkItemRepository.cs" />
<Compile Include="Repository\IRepository\IProjectRepository.cs" />
<Compile Include="Repository\IRepository\IRepository.cs" />
<Compile Include="Repository\IRepository\IUnitOfWork.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Marco.Pms.Model\Marco.Pms.Model.csproj" />
<ProjectReference Include="..\Marco.Pms.Utility\Marco.Pms.Utility.csproj" />

View File

@ -0,0 +1,40 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Marco.Pms.DataAccess.Migrations
{
/// <inheritdoc />
public partial class addEmergencyContactPersonInEmployeeModel : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "EmergencyContactPerson",
table: "Employees",
type: "longtext",
nullable: false)
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AddColumn<bool>(
name: "IsActive",
table: "Employees",
type: "tinyint(1)",
nullable: false,
defaultValue: false);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "EmergencyContactPerson",
table: "Employees");
migrationBuilder.DropColumn(
name: "IsActive",
table: "Employees");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,40 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Marco.Pms.DataAccess.Migrations
{
/// <inheritdoc />
public partial class addJobRoleIdInProjectAllocation : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "EmployeeRoleId",
table: "ProjectAllocations");
migrationBuilder.AddColumn<int>(
name: "JobRoleId",
table: "ProjectAllocations",
type: "int",
nullable: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "JobRoleId",
table: "ProjectAllocations");
migrationBuilder.AddColumn<Guid>(
name: "EmployeeRoleId",
table: "ProjectAllocations",
type: "char(36)",
nullable: true,
collation: "ascii_general_ci");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Marco.Pms.DataAccess.Migrations
{
/// <inheritdoc />
public partial class addJoiningDateToEmployee : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<DateTime>(
name: "JoiningDate",
table: "Employees",
type: "datetime(6)",
nullable: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "JoiningDate",
table: "Employees");
}
}
}

View File

@ -302,6 +302,10 @@ namespace Marco.Pms.DataAccess.Migrations
b.Property<string>("Email")
.HasColumnType("longtext");
b.Property<string>("EmergencyContactPerson")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("EmergencyPhoneNumber")
.IsRequired()
.HasColumnType("longtext");
@ -314,9 +318,15 @@ namespace Marco.Pms.DataAccess.Migrations
.IsRequired()
.HasColumnType("longtext");
b.Property<bool>("IsActive")
.HasColumnType("tinyint(1)");
b.Property<int?>("JobRoleId")
.HasColumnType("int");
b.Property<DateTime?>("JoiningDate")
.HasColumnType("datetime(6)");
b.Property<string>("LastName")
.IsRequired()
.HasColumnType("longtext");
@ -1193,12 +1203,12 @@ namespace Marco.Pms.DataAccess.Migrations
b.Property<int>("EmployeeId")
.HasColumnType("int");
b.Property<Guid?>("EmployeeRoleId")
.HasColumnType("char(36)");
b.Property<bool>("IsActive")
.HasColumnType("tinyint(1)");
b.Property<int?>("JobRoleId")
.HasColumnType("int");
b.Property<int>("ProjectId")
.HasColumnType("int");

View File

@ -1,47 +0,0 @@
using Marco.Pms.DataAccess.Data;
using Marco.Pms.DataAccess.Repository;
using Marco.Pms.DataAccess.Repository.IRepository;
using Marco.Pms.Model.Entitlements;
using Marco.Pms.Model.Projects;
using Microsoft.EntityFrameworkCore;
using System.Linq.Expressions;
using System.Linq;
namespace BulkyBook.DataAccess.Repository
{
public class ActivityMasterRepository : Repository<ActivityMaster>, IActivityMasterRepository
{
private readonly ApplicationDbContext _context;
public ActivityMasterRepository(ApplicationDbContext context) : base(context)
{
_context = context;
}
public void Update(ActivityMaster status)
{
_context.ActivityMasters.Update(status);
}
public Task<List<ActivityMaster>> GetAllAsync(Expression<Func<ActivityMaster, bool>>? filter = null, string? includeProperties = null)
{
IQueryable<ActivityMaster> query = _context.ActivityMasters;
if (filter != null)
{
query.Where(filter);
}
if (!string.IsNullOrEmpty(includeProperties))
{
foreach (var includeProp in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProp);
}
}
return query.ToListAsync();
// return await _context.Projects.ToListAsync(); ;
}
}
}

View File

@ -1,23 +0,0 @@
using Marco.Pms.DataAccess.Data;
using Marco.Pms.DataAccess.Repository;
using Marco.Pms.DataAccess.Repository.IRepository;
using Marco.Pms.Model.Entitlements;
using Marco.Pms.Model.Projects;
namespace BulkyBook.DataAccess.Repository
{
public class ApplicationRolesRepository : Repository<ApplicationRole>, IApplicationRolesRepository
{
private readonly ApplicationDbContext _db;
public ApplicationRolesRepository(ApplicationDbContext db) : base(db)
{
_db = db;
}
public void Update(ApplicationRole status)
{
_db.ApplicationRoles.Update(status);
}
}
}

View File

@ -1,21 +0,0 @@
using Marco.Pms.DataAccess.Data;
using Marco.Pms.DataAccess.Repository.IRepository;
using Marco.Pms.Model.Entitlements;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Marco.Pms.DataAccess.Repository
{
public class ApplicationUserRepository : Repository<ApplicationUser>, IApplicationUserRepository
{
private readonly ApplicationDbContext _db;
public ApplicationUserRepository(ApplicationDbContext db) : base(db)
{
_db = db;
}
}
}

View File

@ -1,22 +0,0 @@
using Marco.Pms.DataAccess.Data;
using Marco.Pms.DataAccess.Repository;
using Marco.Pms.DataAccess.Repository.IRepository;
using Marco.Pms.Model.AttendanceModule;
namespace BulkyBook.DataAccess.Repository
{
public class AttendenceRepository : Repository<Attendance>, IAttendenceRepository
{
private readonly ApplicationDbContext _db;
public AttendenceRepository(ApplicationDbContext db) : base(db)
{
_db = db;
}
public void Update(Attendance attendance)
{
_db.Attendes.Update(attendance);
}
}
}

View File

@ -1,22 +0,0 @@
using Marco.Pms.DataAccess.Data;
using Marco.Pms.DataAccess.Repository;
using Marco.Pms.DataAccess.Repository.IRepository;
using Marco.Pms.Model.Projects;
namespace BulkyBook.DataAccess.Repository
{
public class BuildingRepository : Repository<Building>, IBuildingRepository
{
private readonly ApplicationDbContext _db;
public BuildingRepository(ApplicationDbContext db) : base(db)
{
_db = db;
}
public void Update(Building building)
{
_db.Buildings.Update(building);
}
}
}

View File

@ -1,47 +0,0 @@
using Marco.Pms.DataAccess.Data;
using Marco.Pms.DataAccess.Repository;
using Marco.Pms.DataAccess.Repository.IRepository;
using Marco.Pms.Model.Employees;
using Marco.Pms.Model.Projects;
using Microsoft.EntityFrameworkCore;
using System.Linq.Expressions;
using System.Linq;
namespace BulkyBook.DataAccess.Repository
{
public class EmployeeRepository : Repository<Employee>, IEmployeeRepository
{
private readonly ApplicationDbContext _context;
public EmployeeRepository(ApplicationDbContext db) : base(db)
{
_context = db;
}
public void Update(Employee employee)
{
_context.Employees.Update(employee);
}
public Task<List<Employee>> GetAsync(Expression<Func<Employee, bool>>? filter = null, string? includeProperties = null)
{
IQueryable<Employee> query = _context.Employees;
if (filter != null)
{
query.Where(filter);
}
if (!string.IsNullOrEmpty(includeProperties))
{
foreach (var includeProp in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProp);
}
}
return query.ToListAsync();
// return await _context.Projects.ToListAsync(); ;
}
}
}

View File

@ -1,119 +0,0 @@
using Marco.Pms.DataAccess.Data;
using Marco.Pms.DataAccess.Repository;
using Marco.Pms.DataAccess.Repository.IRepository;
using Marco.Pms.Model.Entitlements;
using Marco.Pms.Model.Projects;
using Microsoft.EntityFrameworkCore;
using System.Linq.Expressions;
namespace BulkyBook.DataAccess.Repository
{
public class FeaturesRepository : Repository<Feature>, IFeatureRepository
{
private readonly ApplicationDbContext _context;
internal DbSet<Feature> dbSet;
public FeaturesRepository(ApplicationDbContext db): base(db)
{
_context = db;
this.dbSet = _context.Set<Feature>();
}
public void Update(Feature project)
{
_context.Features.Update(project);
}
public Task<List<Feature>> GetAllAsync(Expression<Func<Feature, bool>>? filter = null, string? includeProperties = null)
{
IQueryable<Feature> query = _context.Features;
if (filter != null)
{
query.Where(filter);
}
if (!string.IsNullOrEmpty(includeProperties))
{
foreach (var includeProp in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProp);
}
}
return query.ToListAsync();
// return await _context.Projects.ToListAsync(); ;
}
public Task<List<Feature>> GetAsync(Expression<Func<Feature, bool>>? filter = null, string? includeProperties = null)
{
IQueryable<Feature> query = _context.Features;
if (filter != null)
{
query.Where(filter);
//var projects1= query2.Where(filter).ToListAsync();
}
if (!string.IsNullOrEmpty(includeProperties))
{
foreach (var includeProp in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProp);
}
}
return query.ToListAsync();
// return await _context.Projects.ToListAsync(); ;
}
public async Task<Feature> CreateAsync(Feature projectModel)
{
try
{
await _context.Features.AddAsync(projectModel);
await _context.SaveChangesAsync();
return projectModel;
}
catch (Exception ex) { throw ex; }
}
//public async Task<Feature> UpdateAsync(int id, UpdateFeatureDto projectDto)
//{
// var projectModel = await _context.Features.FirstOrDefaultAsync(item => item.Id == id);
// if (projectModel == null)
// {
// return null;
// }
// projectModel.ContactPerson = projectDto.ContactPerson;
// projectModel.ProjectAddress = projectDto.ProjectAddress;
// projectModel.Name = projectDto.Name;
// projectModel.EndDate = projectDto.EndDate;
// projectModel.StartDate = projectDto.StartDate;
// //projectModel.TenantId = projectDto.TenantId;
// try
// {
// await _context.SaveChangesAsync();
// }catch(Exception ex )
// {
// throw ex;
// }
// return projectModel;
//}
}
}

View File

@ -1,22 +0,0 @@
using Marco.Pms.DataAccess.Data;
using Marco.Pms.DataAccess.Repository;
using Marco.Pms.DataAccess.Repository.IRepository;
using Marco.Pms.Model.Projects;
namespace BulkyBook.DataAccess.Repository
{
public class FloorRepository : Repository<Floor>, IFloorRepository
{
private readonly ApplicationDbContext _db;
public FloorRepository(ApplicationDbContext db) : base(db)
{
_db = db;
}
public void Update(Floor floor)
{
_db.Floor.Update(floor);
}
}
}

View File

@ -1,12 +0,0 @@
using Marco.Pms.Model.Entitlements;
using System.Linq.Expressions;
namespace Marco.Pms.DataAccess.Repository.IRepository
{
public interface IActivityMasterRepository : IRepository<ActivityMaster>
{
void Update(ActivityMaster activity);
Task<List<ActivityMaster>> GetAllAsync(Expression<Func<ActivityMaster, bool>>? filter = null, string? includeProperties = null);
}
}

View File

@ -1,10 +0,0 @@
using Marco.Pms.Model.Entitlements;
namespace Marco.Pms.DataAccess.Repository.IRepository
{
public interface IApplicationRolesRepository : IRepository<ApplicationRole>
{
void Update(ApplicationRole role);
}
}

View File

@ -1,9 +0,0 @@
using Marco.Pms.Model.Entitlements;
namespace Marco.Pms.DataAccess.Repository.IRepository
{
public interface IApplicationUserRepository : IRepository<ApplicationUser>
{
}
}

View File

@ -1,11 +0,0 @@
using Marco.Pms.Model.AttendanceModule;
namespace Marco.Pms.DataAccess.Repository.IRepository
{
public interface IAttendenceRepository : IRepository<Attendance>
{
void Update(Attendance employee);
}
}

View File

@ -1,10 +0,0 @@
using Marco.Pms.Model.Projects;
namespace Marco.Pms.DataAccess.Repository.IRepository
{
public interface IBuildingRepository : IRepository<Building>
{
void Update(Building building);
}
}

View File

@ -1,13 +0,0 @@
using Marco.Pms.Model.Employees;
using System.Linq.Expressions;
namespace Marco.Pms.DataAccess.Repository.IRepository
{
public interface IEmployeeRepository : IRepository<Employee>
{
void Update(Employee employee);
Task<List<Employee>> GetAsync(Expression<Func<Employee, bool>>? filter = null, string? includeProperties = null);
}
}

View File

@ -1,18 +0,0 @@
using Marco.Pms.Model.Dtos.Project;
using Marco.Pms.Model.Entitlements;
using System.Linq.Expressions;
namespace Marco.Pms.DataAccess.Repository.IRepository
{
public interface IFeatureRepository : IRepository<Feature>
{
void Update(Feature Feature);
Task<List<Feature>> GetAsync(Expression<Func<Feature, bool>>? filter = null, string? includeProperties = null);
Task<List<Feature>> GetAllAsync(Expression<Func<Feature, bool>>? filter = null, string? includeProperties = null);
Task<Feature> CreateAsync(Feature feature);
// Task<Feature> UpdateAsync(int id, UpdateFeatureDto Feature);
// Task<List<Project>> GetAsync(int id, string? includeProperties = null);
}
}

View File

@ -1,10 +0,0 @@
using Marco.Pms.Model.Projects;
namespace Marco.Pms.DataAccess.Repository.IRepository
{
public interface IFloorRepository : IRepository<Floor>
{
void Update(Floor floor);
}
}

View File

@ -1,20 +0,0 @@
using Marco.Pms.Model.Dtos.Project;
using Marco.Pms.Model.Projects;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace Marco.Pms.DataAccess.Repository.IRepository
{
public interface IProjectAllocationRepository
{
void Update(ProjectAllocation project);
Task<List<ProjectAllocation>> GetAsync(Expression<Func<ProjectAllocation, bool>>? filter = null, string? includeProperties = null);
Task<List<ProjectAllocation>> GetAllAsync(Expression<Func<ProjectAllocation, bool>>? filter = null, string? includeProperties = null);
Task<ProjectAllocation> CreateAsync(ProjectAllocation project);
Task<ProjectAllocation> UpdateAsync(int id, ProjectAllocation project);
}
}

View File

@ -1,18 +0,0 @@
using Marco.Pms.Model.Dtos.Project;
using Marco.Pms.Model.Projects;
using System.Linq.Expressions;
namespace Marco.Pms.DataAccess.Repository.IRepository
{
public interface IProjectRepository : IRepository<Project>
{
void Update(Project project);
Task<List<Project>> GetAsync(Expression<Func<Project, bool>>? filter = null, string? includeProperties = null);
Task<List<Project>> GetAllAsync(Expression<Func<Project, bool>>? filter = null, string? includeProperties = null);
Task<Project> CreateAsync(Project project);
Task<Project> UpdateAsync(int id, UpdateProjectDto project);
// Task<List<Project>> GetAsync(int id, string? includeProperties = null);
}
}

View File

@ -1,16 +0,0 @@
using System.Linq.Expressions;
namespace Marco.Pms.DataAccess.Repository.IRepository
{
public interface IRepository<T> where T : class
{
// T - Category
IEnumerable<T> GetAll(Expression<Func<T, bool>>? filter, string? includeProperties = null);
//T GetFirstOrDefault();
T Get(Expression<Func<T, bool>> filter, string? includeProperties = null, bool tracked = false);
Task<T> GetAsync(Expression<Func<T, bool>> filter, bool tracked = false, params Expression<Func<T, object>>[] includeProperties);
void Add(T entity);
void Remove(T entity);
void RemoveRange(IEnumerable<T> entity);
}
}

View File

@ -1,11 +0,0 @@
using Marco.Pms.Model.Entitlements;
using Marco.Pms.Model.Projects;
namespace Marco.Pms.DataAccess.Repository.IRepository
{
public interface IStatusRepository : IRepository<StatusMaster>
{
void Update(StatusMaster status);
}
}

View File

@ -1,11 +0,0 @@
using Marco.Pms.Model.Activities;
namespace Marco.Pms.DataAccess.Repository.IRepository
{
public interface ITaskAllocationRepository : IRepository<TaskAllocation>
{
void Update(TaskAllocation employeeAllocation);
}
}

View File

@ -1,28 +0,0 @@
namespace Marco.Pms.DataAccess.Repository.IRepository
{
public interface IUnitOfWork
{
IApplicationUserRepository ApplicationUser { get; }
IEmployeeRepository Employee { get; }
ITaskAllocationRepository EmployeeAllocation
{ get; }
IProjectRepository Project { get; }
IProjectAllocationRepository ProjectAllocation { get; }
IBuildingRepository Building { get; }
IFloorRepository Floor { get; }
IWorkAreaRepository WorkArea { get; }
IWorkItemRepository WorkItem { get; }
IWorkItemMappingReposiotry WorkItemMapping { get;}
IAttendenceRepository Attendence { get; }
IStatusRepository StatusMaster { get; }
IActivityMasterRepository ActivityMaster { get; }
IApplicationRolesRepository EmployeeRoles { get; }
IFeatureRepository Features { get; }
void Save();
}
}

View File

@ -1,10 +0,0 @@
using Marco.Pms.Model.Projects;
namespace Marco.Pms.DataAccess.Repository.IRepository
{
public interface IWorkAreaRepository : IRepository<WorkArea>
{
void Update(WorkArea workArea);
}
}

View File

@ -1,9 +0,0 @@
using Marco.Pms.Model.Activities;
namespace Marco.Pms.DataAccess.Repository.IRepository
{
public interface IWorkItemMappingReposiotry : IRepository<WorkItemMapping>
{
void Update(WorkItemMapping mapping);
}
}

View File

@ -1,11 +0,0 @@
using Marco.Pms.Model.Activities;
using Marco.Pms.Model.Projects;
namespace Marco.Pms.DataAccess.Repository.IRepository
{
public interface IWorkItemRepository : IRepository<WorkItem>
{
void Update(WorkItem workItem);
}
}

View File

@ -1,84 +0,0 @@
using Marco.Pms.DataAccess.Data;
using Marco.Pms.DataAccess.Repository.IRepository;
using Marco.Pms.Model.Dtos.Project;
using Marco.Pms.Model.Projects;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace Marco.Pms.DataAccess.Repository
{
public class ProjectAllocationRepository : Repository<ProjectAllocation>, IProjectAllocationRepository
{
private readonly ApplicationDbContext _context;
internal DbSet<ProjectAllocation> dbSet;
public ProjectAllocationRepository(ApplicationDbContext db) : base(db)
{
_context = db;
this.dbSet = _context.Set<ProjectAllocation>();
}
public void Update(ProjectAllocation project)
{
_context.ProjectAllocations.Update(project);
}
public async Task<ProjectAllocation> CreateAsync(ProjectAllocation project)
{
await _context.ProjectAllocations.AddAsync(project);
await _context.SaveChangesAsync();
return project;
}
public Task<List<ProjectAllocation>> GetAllAsync(Expression<Func<ProjectAllocation, bool>>? filter = null, string? includeProperties = null)
{
throw new NotImplementedException();
}
public Task<List<ProjectAllocation>> GetAsync(Expression<Func<ProjectAllocation, bool>>? filter = null, string? includeProperties = null)
{
IQueryable<ProjectAllocation> query = _context.ProjectAllocations;
if (filter != null)
{
query.Where(filter);
}
if (!string.IsNullOrEmpty(includeProperties))
{
foreach (var includeProp in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProp);
}
}
return query.ToListAsync();
}
public async Task<ProjectAllocation> UpdateAsync(int id, ProjectAllocation project)
{
var allocation = await _context.ProjectAllocations.FirstOrDefaultAsync(item => item.Id == id);
if (allocation == null)
{
return null;
}
allocation.ProjectId = project.ProjectId;
allocation.EmployeeId = project.EmployeeId;
allocation.AllocationDate = project.AllocationDate;
allocation.ReAllocationDate = project.ReAllocationDate;
allocation.TenantId = project.TenantId;
_context.ProjectAllocations.Update(allocation);
await _context.SaveChangesAsync();
return allocation;
}
}
}

View File

@ -1,146 +0,0 @@
using Marco.Pms.DataAccess.Data;
using Marco.Pms.DataAccess.Repository;
using Marco.Pms.DataAccess.Repository.IRepository;
using Marco.Pms.Model.Dtos.Project;
using Marco.Pms.Model.Entitlements;
using Marco.Pms.Model.Projects;
using Microsoft.EntityFrameworkCore;
using System.Linq;
using System.Linq.Expressions;
using System.Xml;
using System.Xml.Linq;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database;
namespace BulkyBook.DataAccess.Repository
{
public class ProjectRepository : Repository<Project>, IProjectRepository
{
private readonly ApplicationDbContext _context;
internal DbSet<Project> dbSet;
public ProjectRepository(ApplicationDbContext db) : base(db)
{
_context = db;
this.dbSet = _context.Set<Project>();
}
public void Update(Project project)
{
_context.Projects.Update(project);
}
public Task<List<Project>> GetAllAsync(Expression<Func<Project, bool>>? filter = null, string? includeProperties = null)
{
IQueryable<Project> query = _context.Projects;
if (filter != null)
{
query.Where(filter);
}
if (!string.IsNullOrEmpty(includeProperties))
{
foreach (var includeProp in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProp);
}
}
return query.ToListAsync();
// return await _context.Projects.ToListAsync(); ;
}
public Task<List<Project>> GetAsync(Expression<Func<Project, bool>>? filter = null, string? includeProperties = null)
{
IQueryable<Project> query = _context.Projects;
//IQueryable<Project> query2 = _context.Projects;
Expression<Func<Project, bool>> filter1 = x => x.Id == 2;
if (filter != null)
{
query.Where(filter);
//var projects1= query2.Where(filter).ToListAsync();
}
if (!string.IsNullOrEmpty(includeProperties))
{
foreach (var includeProp in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProp);
}
}
return query.ToListAsync();
// return await _context.Projects.ToListAsync(); ;
}
public async Task<Project> CreateAsync(Project projectModel)
{
try
{
await _context.Projects.AddAsync(projectModel);
await _context.SaveChangesAsync();
return projectModel;
}
catch (Exception ex) { throw ex; }
}
public async Task<Project> UpdateAsync(int id, UpdateProjectDto projectDto)
{
var projectModel = await _context.Projects.FirstOrDefaultAsync(item => item.Id == id);
if (projectModel == null)
{
return null;
}
projectModel.ContactPerson = projectDto.ContactPerson;
projectModel.ProjectAddress = projectDto.ProjectAddress;
projectModel.Name = projectDto.Name;
projectModel.EndDate = projectDto.EndDate;
projectModel.StartDate = projectDto.StartDate;
//projectModel.TenantId = projectDto.TenantId;
try
{
await _context.SaveChangesAsync();
}catch(Exception ex )
{
throw ex;
}
return projectModel;
}
//public Task<List<Project>> GetAsync(int id, string? includeProperties = null)
//{
// IQueryable<Project> query = _context.Projects;
// query.Where(c=>c.Id == id);
// // Task<Project> project = _context.Projects.Where(c=>c.Id == id).SingleOrDefaultAsync();
// //if (filter != null)
// //{
// // query.Where(filter);
// //}
// //if (!string.IsNullOrEmpty(includeProperties))
// //{
// // foreach (var includeProp in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
// // {
// // query = query.Include(includeProp);
// // }
// //}
// return query.ToListAsync();
// // return await _context.Projects.ToListAsync(); ;
//}
}
}

View File

@ -1,102 +0,0 @@
using Marco.Pms.DataAccess.Data;
using Marco.Pms.DataAccess.Repository.IRepository;
using Microsoft.EntityFrameworkCore;
using System.Linq.Expressions;
namespace Marco.Pms.DataAccess.Repository
{
public class Repository<T> : IRepository<T> where T : class
{
private readonly ApplicationDbContext _context;
internal DbSet<T> dbSet;
public Repository(ApplicationDbContext context)
{
_context = context;
this.dbSet = _context.Set<T>();
//_db.Products.Include(u => u.Category);
}
public void Add(T entity)
{
dbSet.Add(entity);
}
public T Get(Expression<Func<T, bool>> filter, string? includeProperties = null, bool tracked = false)
{
IQueryable<T> query = dbSet;
if (tracked)
{
query = query.Where(filter);
}
else
{
query = query.AsNoTracking().Where(filter);
}
if (!string.IsNullOrEmpty(includeProperties))
{
foreach (var includeProp in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProp);
}
}
return query.FirstOrDefault();
}
public async Task<T> GetAsync(Expression<Func<T, bool>> filter, bool tracked = false, params Expression<Func<T, object>>[] includeProperties)
{
IQueryable<T> query = dbSet;
if (tracked)
{
query = query.Where(filter);
}
else
{
query = query.AsNoTracking().Where(filter);
}
if (includeProperties != null)
{
foreach (var includeProp in includeProperties)
{
query = query.Include(includeProp);
}
}
return await query.SingleOrDefaultAsync();
}
public IEnumerable<T> GetAll(Expression<Func<T, bool>>? filter = null, string? includeProperties = null)
{
IQueryable<T> query = dbSet;
if(filter != null)
{
query.Where(filter);
}
if (!string.IsNullOrEmpty(includeProperties))
{
foreach (var includeProp in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProp);
}
}
return query.ToList();
}
public void Remove(T entity)
{
dbSet.Remove(entity);
}
public void RemoveRange(IEnumerable<T> entity)
{
dbSet.RemoveRange(entity);
}
}
}

View File

@ -1,23 +0,0 @@
using Marco.Pms.DataAccess.Data;
using Marco.Pms.DataAccess.Repository;
using Marco.Pms.DataAccess.Repository.IRepository;
using Marco.Pms.Model.Entitlements;
using Marco.Pms.Model.Projects;
namespace BulkyBook.DataAccess.Repository
{
public class StatusRepository : Repository<StatusMaster>, IStatusRepository
{
private readonly ApplicationDbContext _db;
public StatusRepository(ApplicationDbContext db) : base(db)
{
_db = db;
}
public void Update(StatusMaster status)
{
_db.StatusMasters.Update(status);
}
}
}

View File

@ -1,21 +0,0 @@
using Marco.Pms.DataAccess.Data;
using Marco.Pms.DataAccess.Repository;
using Marco.Pms.DataAccess.Repository.IRepository;
using Marco.Pms.Model.Activities;
namespace BulkyBook.DataAccess.Repository
{
public class TaskAllocationRepository : Repository<TaskAllocation>, ITaskAllocationRepository
{
private readonly ApplicationDbContext _db;
public TaskAllocationRepository(ApplicationDbContext db) : base(db)
{
_db = db;
}
public void Update(TaskAllocation employeeAllocation)
{
_db.TaskAllocations.Update(employeeAllocation);
}
}
}

View File

@ -1,64 +0,0 @@
using BulkyBook.DataAccess.Repository;
using Marco.Pms.DataAccess.Data;
using Marco.Pms.DataAccess.Repository.IRepository;
namespace Marco.Pms.DataAccess.Repository
{
public class UnitOfWork : IUnitOfWork
{
private readonly ApplicationDbContext _db;
public IApplicationUserRepository ApplicationUser { get; private set; }
public IEmployeeRepository Employee { get; private set; }
public ITaskAllocationRepository EmployeeAllocation { get; private set; }
public IProjectRepository Project { get; private set; }
public IProjectAllocationRepository ProjectAllocation { get; private set; }
public IBuildingRepository Building { get; private set; }
public IFloorRepository Floor { get; private set; }
public IAttendenceRepository Attendence { get; private set; }
public IWorkAreaRepository WorkArea { get; private set; }
public IWorkItemRepository WorkItem { get; private set; }
public IWorkItemMappingReposiotry WorkItemMapping { get; private set; }
public IStatusRepository StatusMaster { get; private set; }
public IActivityMasterRepository ActivityMaster { get; private set; }
public IApplicationRolesRepository EmployeeRoles { get; private set; }
public IFeatureRepository Features { get; private set; }
public UnitOfWork(ApplicationDbContext db)
{
_db = db;
Employee = new EmployeeRepository(_db);
Project = new ProjectRepository(_db);
ProjectAllocation = new ProjectAllocationRepository(_db);
Building = new BuildingRepository(_db);
Floor = new FloorRepository(_db);
WorkArea = new WorkAreaRepository(_db);
WorkItem = new WorkItemRepository(_db);
WorkItemMapping = new WorkItemMappingReporitury(_db);
ApplicationUser = new ApplicationUserRepository(_db);
Attendence = new AttendenceRepository(_db);
EmployeeAllocation = new TaskAllocationRepository(_db);
StatusMaster = new StatusRepository(_db);
ActivityMaster = new ActivityMasterRepository(_db);
EmployeeRoles = new ApplicationRolesRepository(_db);
Features = new FeaturesRepository(_db);
}
public void Save()
{
_db.SaveChanges();
}
}
}

View File

@ -1,22 +0,0 @@
using Marco.Pms.DataAccess.Data;
using Marco.Pms.DataAccess.Repository;
using Marco.Pms.DataAccess.Repository.IRepository;
using Marco.Pms.Model.Projects;
namespace BulkyBook.DataAccess.Repository
{
public class WorkAreaRepository : Repository<WorkArea>, IWorkAreaRepository
{
private readonly ApplicationDbContext _db;
public WorkAreaRepository(ApplicationDbContext db) : base(db)
{
_db = db;
}
public void Update(WorkArea workArea)
{
_db.WorkAreas.Update(workArea);
}
}
}

View File

@ -1,22 +0,0 @@
using Marco.Pms.DataAccess.Data;
using Marco.Pms.DataAccess.Repository;
using Marco.Pms.DataAccess.Repository.IRepository;
using Marco.Pms.Model.Activities;
namespace BulkyBook.DataAccess.Repository
{
public class WorkItemMappingReporitury : Repository<WorkItemMapping>, IWorkItemMappingReposiotry
{
private readonly ApplicationDbContext _db;
public WorkItemMappingReporitury(ApplicationDbContext db) : base(db)
{
_db = db;
}
public void Update(WorkItemMapping workItem)
{
_db.WorkItemMapping.Update(workItem);
}
}
}

View File

@ -1,22 +0,0 @@
using Marco.Pms.DataAccess.Data;
using Marco.Pms.DataAccess.Repository;
using Marco.Pms.DataAccess.Repository.IRepository;
using Marco.Pms.Model.Activities;
namespace BulkyBook.DataAccess.Repository
{
public class WorkItemRepository : Repository<WorkItem>, IWorkItemRepository
{
private readonly ApplicationDbContext _db;
public WorkItemRepository(ApplicationDbContext db) : base(db)
{
_db = db;
}
public void Update(WorkItem workItem)
{
_db.WorkItems.Update(workItem);
}
}
}

View File

@ -1,7 +1,7 @@
using Marco.Pms.Model.Employees;
using Marco.Pms.Model.Entitlements;
using Marco.Pms.Model.Projects;
using MarcoBMS.Utility;
using Marco.Pms.Utility;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations.Schema;

View File

@ -30,8 +30,8 @@ namespace Marco.Pms.Model.Dtos.Employees
public string? PanNumber { get; set; }
public IFormFile? Photo { get; set; } // To store the captured photo
public List<IFormFile>? Documents { get; set; }
//public IFormFile? Photo { get; set; } // To store the captured photo
//public List<IFormFile>? Documents { get; set; }
public string JobRoleId { get; set; }

View File

@ -3,7 +3,7 @@
public class ProjectAllocationDot
{
public int EmpID { get; set; }
public Guid RoleID { get; set; }
public int JobRoleId { get; set; }
public int ProjectId { get; set; }
public bool Status { get; set; }

View File

@ -14,8 +14,5 @@ namespace Marco.Pms.Model.Dtos
[Required]
[MinLength(6)]
public string NewPassword { get; set; }
[Compare("NewPassword", ErrorMessage = "Passwords do not match.")]
public string ConfirmPassword { get; set; }
}
}

View File

@ -0,0 +1,11 @@
namespace Marco.Pms.Model.Dtos.Util
{
public class EmailDot
{
public string ToEmail { get; set; }
public string FromEmail { get; set; }
public string MailBody { get; set; }
public string MailSubject { get; set; }
}
}

View File

@ -15,11 +15,15 @@ namespace Marco.Pms.Model.Employees
public string Gender { get; set; }
public DateTime? BirthDate { get; set; }
public DateTime? JoiningDate { get; set; }
public string PeramnentAddress { get; set; }
public string CurrentAddress { get; set; }
public string PhoneNumber { get; set; }
public string EmergencyPhoneNumber { get; set; }
public string EmergencyContactPerson { get; set; }
public string? AadharNumber { get; set; }
@ -34,6 +38,8 @@ namespace Marco.Pms.Model.Employees
[DisplayName("TenantId")]
public int TenantId { get; set; }
public bool IsActive { get; set; } = true;
[ValidateNever]
[ForeignKey(nameof(TenantId))]
public Tenant Tenant { get; set; }

View File

@ -23,7 +23,6 @@ namespace Marco.Pms.Model.Mapper
Id = new Guid(),
Role = model.Role,
Description = model.Description,
//FeaturePermissions = model.FeaturesPermission,
TenantId = TenantId,
};
}

View File

@ -0,0 +1,35 @@
using Marco.Pms.Model.Employees;
using Marco.Pms.Model.ViewModels.Employee;
namespace Marco.Pms.Model.Mapper
{
public static class EmployeeMapper
{
public static EmployeeVM ToEmployeeVMFromEmployee(this Employee model)
{
return new EmployeeVM
{
Id = model.Id,
FirstName = model.FirstName,
LastName = model.LastName,
MiddleName = model.MiddleName,
Email = model.Email,
CurrentAddress = model.CurrentAddress,
BirthDate = model.BirthDate,
AadharNumber = model.AadharNumber,
ApplicationUserId = model.ApplicationUserId,
EmergencyPhoneNumber = model.EmergencyPhoneNumber,
EmergencyContactPerson = model.EmergencyContactPerson,
Gender = model.Gender,
JobRole = (model.JobRole != null ? model.JobRole.Name : null),
JobRoleId = model.JobRoleId,
PanNumber = model.PanNumber,
PeramnentAddress = model.PeramnentAddress,
PhoneNumber = model.PhoneNumber,
Photo = model.Photo,
IsActive = model.IsActive,
JoiningDate = model.JoiningDate
};
}
}
}

View File

@ -34,6 +34,19 @@ namespace Marco.Pms.Model.Mapper
};
}
public static Project ToProjectFromUpdateProjectDto(this UpdateProjectDto projectModel, int TenantId)
{
return new Project
{
ContactPerson = projectModel.ContactPerson,
ProjectAddress = projectModel.ProjectAddress,
Name = projectModel.Name,
EndDate = projectModel.EndDate,
StartDate = projectModel.StartDate,
TenantId = TenantId,
ProjectStatusId = projectModel.ProjectStatusId
};
}
public static ProjectAllocation ToProjectAllocationFromProjectAllocationDto(this ProjectAllocationDot model, int TenantId)
{
@ -41,7 +54,7 @@ namespace Marco.Pms.Model.Mapper
{
AllocationDate = DateTime.Now,
EmployeeId = model.EmpID,
EmployeeRoleId = model.RoleID,
JobRoleId = model.JobRoleId,
TenantId = TenantId,
ProjectId = model.ProjectId
};

View File

@ -14,7 +14,7 @@ namespace Marco.Pms.Model.Projects
[ValidateNever]
public Employee Employee { get; set; }
public Guid? EmployeeRoleId { get; set; }
public int? JobRoleId { get; set; }
//[ForeignKey("EmployeeRoleId")]
//[ValidateNever]
//public EmployeeRole EmployeeRole { get; set; }

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Marco.Pms.Model.ViewModels.Employee
{
public class EmployeeProfile
{
public EmployeeVM EmployeeInfo { get; set; }
public string[] Projects { get; set; }
public string[] FeaturePermissions { get; set; }
}
}

View File

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Marco.Pms.Model.ViewModels.Employee
{
public class EmployeeVM
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string? MiddleName { get; set; }
public string? Email { get; set; }
public string Gender { get; set; }
public DateTime? BirthDate { get; set; }
public DateTime? JoiningDate { get; set; }
public string PeramnentAddress { get; set; }
public string CurrentAddress { get; set; }
public string PhoneNumber { get; set; }
public string EmergencyPhoneNumber { get; set; }
public string EmergencyContactPerson { get; set; }
public string? AadharNumber { get; set; }
public bool IsActive { get; set; } = true;
public string? PanNumber { get; set; }
public byte[]? Photo { get; set; } // To store the captured photo
public string? ApplicationUserId { get; set; }
public int? JobRoleId { get; set; }
public string JobRole { get; set; }
}
}

View File

@ -1,14 +1,10 @@
using Marco.Pms.DataAccess.Data;
using Marco.Pms.DataAccess.Repository.IRepository;
using Marco.Pms.Model.Employees;
using Marco.Pms.Model.Entitlements;
using MarcoBMS.Services.Service;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace MarcoBMS.Services.Controllers
namespace ModelServices.Controllers
{
[Route("api/[controller]")]
@ -18,17 +14,13 @@ namespace MarcoBMS.Services.Controllers
{
private readonly ApplicationDbContext _context;
private ApplicationUser _applicationUser;
private readonly IEmployeeRepository _empRepo;
private readonly UserManager<IdentityUser> _userManager;
private readonly IEmailSender _emailSender;
public ActivityController(UserManager<IdentityUser> userManager, IEmailSender emailSender, IEmployeeRepository empRepo, ApplicationDbContext context)
public ActivityController(UserManager<IdentityUser> userManager, ApplicationDbContext context)
{
_context = context;
_empRepo = empRepo;
_userManager = userManager;
_emailSender = emailSender;
}
//[HttpPost("checkin")]

View File

@ -1,5 +1,4 @@
using Marco.Pms.DataAccess.Data;
using Marco.Pms.DataAccess.Repository.IRepository;
using Marco.Pms.Model.AttendanceModule;
using Marco.Pms.Model.Dtos.Attendance;
using Marco.Pms.Model.Employees;
@ -7,8 +6,6 @@ using Marco.Pms.Model.Projects;
using Marco.Pms.Model.Utilities;
using Marco.Pms.Model.ViewModels.Attendance;
using MarcoBMS.Services.Helpers;
using MarcoBMS.Services.Service;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.CodeAnalysis;
using Microsoft.EntityFrameworkCore;
@ -20,34 +17,26 @@ namespace MarcoBMS.Services.Controllers
[Route("api/[controller]")]
public class AttendanceController : ControllerBase
{
private readonly IUnitOfWork _unitOfWork;
private readonly ApplicationDbContext _context;
private readonly UserManager<IdentityUser> _userManager;
private readonly IEmailSender _emailSender;
private readonly IAttendenceRepository _attendenceRepository;
private readonly EmployeeHelper _employeeHelper;
private readonly ProjectHelper _projectHelper;
private readonly ProjectsHelper _projectsHelper;
private readonly UserHelper _userHelper;
public AttendanceController(UserManager<IdentityUser> userManager, IEmailSender emailSender, IEmployeeRepository empRepo,
IUnitOfWork unitOfWork, ApplicationDbContext context, IAttendenceRepository attendenceRepository, EmployeeHelper employeeHelper, ProjectHelper projectHelper)
public AttendanceController(
ApplicationDbContext context, EmployeeHelper employeeHelper, ProjectsHelper projectsHelper, UserHelper userHelper)
{
_unitOfWork = unitOfWork;
_context = context;
_userManager = userManager;
_emailSender = emailSender;
_attendenceRepository = attendenceRepository;
_employeeHelper = employeeHelper;
_projectHelper = projectHelper;
_projectsHelper = projectsHelper;
_userHelper = userHelper;
}
private int GetTenantId()
{
var tenant = User.FindFirst("TenantId")?.Value;
return (tenant != null ? Convert.ToInt32(tenant) : 1);
return _userHelper.GetTenantId();
//var tenant = User.FindFirst("TenantId")?.Value;
//return (tenant != null ? Convert.ToInt32(tenant) : 1);
}
private int GetUserId()
{
@ -85,6 +74,73 @@ namespace MarcoBMS.Services.Controllers
}
/// <summary>
///
/// </summary>
/// <param name="projectId">ProjectID</param>
/// <param name="date">YYYY-MM-dd</param>
/// <returns></returns>
[HttpGet("project/log")]
public async Task<IActionResult> EmployeeAttendanceByDateRange([FromQuery] int projectId, [FromQuery] string? dateFrom = null, [FromQuery] string? dateTo = null)
{
int TenantId = GetUserId();
DateTime fromDate = new DateTime();
DateTime toDate = new DateTime();
if (dateFrom != null && DateTime.TryParse(dateFrom, out fromDate) == false)
{
return StatusCode(400, ApiResponse<object>.SuccessResponse(dateFrom, "Invalid Date", 400));// new { error = ex.Message });
}
if (dateTo != null && DateTime.TryParse(dateTo, out toDate) == false)
{
return StatusCode(400, ApiResponse<object>.SuccessResponse(dateTo, "Invalid Date", 400));// new { error = ex.Message });
}
if (projectId <= 0)
{
return BadRequest("Project ID is required and must be greater than zero.");
}
var result = new List<EmployeeAttendanceVM>();
Attendance attendance = null;
if (dateFrom == null) fromDate = DateTime.UtcNow.Date;
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();
List<ProjectAllocation> projectteam = await _projectsHelper.GetTeamByProject(TenantId, projectId, true);
foreach (ProjectAllocation teamMember in projectteam)
{
var result1 = new EmployeeAttendanceVM()
{
EmployeeAvatar = null,
EmployeeId = teamMember.EmployeeId,
FirstName = teamMember.Employee.FirstName,
LastName = teamMember.Employee.LastName
};
attendance = lstAttendance.Find(x => x.EmployeeID == teamMember.EmployeeId);
if (attendance != null)
{
result1.Id = attendance.Id;
result1.CheckInTime = attendance.InTime;
result1.CheckOutTime = attendance.OutTime;
result1.Activity = attendance.Activity;
}
result.Add(result1);
}
return Ok(ApiResponse<object>.SuccessResponse(result, System.String.Format("{0} Attendance records fetched successfully", result.Count), 200));
}
/// <summary>
///
/// </summary>
@ -116,7 +172,7 @@ namespace MarcoBMS.Services.Controllers
List<Attendance> lstAttendance = await _context.Attendes.Where(c => c.ProjectID == projectId && c.AttendanceDate.Date == forDate && c.TenantId == TenantId).ToListAsync();
List<ProjectAllocation> projectteam = await _projectHelper.GetTeamByProject(TenantId, projectId, true);
List<ProjectAllocation> projectteam = await _projectsHelper.GetTeamByProject(TenantId, projectId, true);
foreach (ProjectAllocation teamMember in projectteam)
{
@ -140,6 +196,10 @@ namespace MarcoBMS.Services.Controllers
result.Add(result1);
}
result.Sort(delegate (EmployeeAttendanceVM x, EmployeeAttendanceVM y) {
return x.FirstName.CompareTo(y.FirstName);
});
return Ok(ApiResponse<object>.SuccessResponse(result, System.String.Format("{0} Attendance records fetched successfully", result.Count), 200));
}
@ -210,7 +270,7 @@ namespace MarcoBMS.Services.Controllers
attendance = new Attendance();
attendance.TenantId = TenantId;
attendance.AttendanceDate = recordAttendanceDot.Date;
// attendance.Activity = recordAttendanceDot.Action;
// attendance.Activity = recordAttendanceDot.Action;
attendance.Comment = recordAttendanceDot.Comment;
attendance.EmployeeID = recordAttendanceDot.EmployeeID;
attendance.ProjectID = recordAttendanceDot.ProjectID;

View File

@ -1,10 +1,18 @@
using Marco.Pms.Model.Authentication;
using Marco.Pms.Model.Dtos;
using Marco.Pms.Model.Dtos.Util;
using Marco.Pms.Model.Employees;
using Marco.Pms.Model.Entitlements;
using Marco.Pms.Model.Utilities;
using Marco.Pms.Model.ViewModels.Employee;
using MarcoBMS.Services.Helpers;
using MarcoBMS.Services.Service;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.Data;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Net;
namespace MarcoBMS.Services.Controllers
{
@ -15,12 +23,19 @@ namespace MarcoBMS.Services.Controllers
private readonly UserManager<IdentityUser> _userManager;
private readonly JwtSettings _jwtSettings;
private readonly RefreshTokenService _refreshTokenService;
string tenentId = "1";
public AuthController(UserManager<IdentityUser> userManager, JwtSettings jwtSettings, RefreshTokenService refreshTokenService)
private readonly IEmailSender _emailSender;
private readonly IConfiguration _configuration;
private readonly EmployeeHelper _employeeHelper;
//string tenentId = "1";
public AuthController(UserManager<IdentityUser> userManager, JwtSettings jwtSettings, RefreshTokenService refreshTokenService,
IEmailSender emailSender, IConfiguration configuration, EmployeeHelper employeeHelper)
{
_userManager = userManager;
_jwtSettings = jwtSettings;
_refreshTokenService = refreshTokenService;
_emailSender = emailSender;
_configuration = configuration;
_employeeHelper = employeeHelper;
}
[HttpPost("login")]
@ -35,14 +50,15 @@ namespace MarcoBMS.Services.Controllers
return Unauthorized("Invalid username or password.");
}
var token = _refreshTokenService.GenerateJwtToken(user.UserName, tenentId, _jwtSettings);
Employee emp = await _employeeHelper.GetEmployeeByApplicationUserID(user.Id);
//var refreshToken = GenerateRefreshToken();
var refreshToken = await _refreshTokenService.CreateRefreshToken(user.Id, tenentId, _jwtSettings);
var token = _refreshTokenService.GenerateJwtToken(user.UserName, emp.TenantId.ToString(), _jwtSettings);
return Ok(new { token, refreshToken });
var refreshToken = await _refreshTokenService.CreateRefreshToken(user.Id, emp.TenantId.ToString(), _jwtSettings);
return Ok(ApiResponse<object>.SuccessResponse(new { token = token, refreshToken = refreshToken }, "User logged in successfully.", 200));
}
[HttpPost("logout")]
@ -72,7 +88,7 @@ namespace MarcoBMS.Services.Controllers
}
catch (Exception ex)
{
// _logger.LogError(ex, "Error during logout");
// _logger.LogError(ex, "Error during logout");
return StatusCode(500, new { Message = "Internal server error" });
}
}
@ -106,10 +122,15 @@ namespace MarcoBMS.Services.Controllers
// Generate new JWT token and refresh token
var user = await _userManager.FindByIdAsync(refreshToken.UserId);
var newJwtToken = _refreshTokenService.GenerateJwtToken(user.UserName, tenentId, _jwtSettings);
var newRefreshToken = await _refreshTokenService.CreateRefreshToken(user.Id, tenentId, _jwtSettings);
if (user == null)
return BadRequest("Invalid request.");
return Ok(new { token = newJwtToken, refreshToken = newRefreshToken });
Employee emp = await _employeeHelper.GetEmployeeByApplicationUserID(user.Id);
var newJwtToken = _refreshTokenService.GenerateJwtToken(user.UserName, emp.TenantId.ToString(), _jwtSettings);
var newRefreshToken = await _refreshTokenService.CreateRefreshToken(user.Id, emp.TenantId.ToString(), _jwtSettings);
return Ok(ApiResponse<object>.SuccessResponse(new { token = newJwtToken, refreshToken = newRefreshToken }, "User refresh token generated successfully.", 200));
}
[HttpPost("forgot-password")]
@ -118,10 +139,72 @@ namespace MarcoBMS.Services.Controllers
var user = await _userManager.FindByEmailAsync(forgotPasswordDto.Email);
if (user == null) return NotFound("User not found.");
/* SEND USER REGISTRATION MAIL*/
var token = await _userManager.GeneratePasswordResetTokenAsync(user);
var resetLink = $"{_configuration["AppSettings:WebFrontendUrl"]}/reset-password?token={WebUtility.UrlEncode(token)}";
await _emailSender.SendResetPasswordEmail(user.Email, "", resetLink);
return Ok(ApiResponse<object>.SuccessResponse(true, "Password reset link sent.", 200));
}
[HttpPost("reset-password")]
public async Task<IActionResult> ResetPassword([FromBody] ResetPasswordDto model)
{
var user = await _userManager.FindByEmailAsync(model.Email);
if (user == null)
return BadRequest("Invalid request.");
// var isTokenValid = await _userManager.VerifyUserTokenAsync(user,UserManager<ApplicationUser>.ResetPasswordTokenPurpose, model.ResetCode);
var isTokenValid = await _userManager.VerifyUserTokenAsync(
user,
TokenOptions.DefaultProvider, // This is the token provider
UserManager<ApplicationUser>.ResetPasswordTokenPurpose,
WebUtility.UrlDecode( model.Token)
);
if (!isTokenValid)
return BadRequest("Invalid or expired token.");
var result = await _userManager.ResetPasswordAsync(user, WebUtility.UrlDecode(model.Token), model.NewPassword);
if (!result.Succeeded)
return BadRequest(result.Errors);
return Ok(ApiResponse<object>.SuccessResponse(result.Succeeded, "Password reset successfully.", 200));
}
[HttpPost("sendmail")]
public async Task<IActionResult> SendEmail([FromBody] EmailDot emailDot)
{
var user = await _userManager.FindByEmailAsync(emailDot.ToEmail);
if (user == null)
{
return BadRequest("User not found.");
}
/* New User*/
//var token = await _userManager.GeneratePasswordResetTokenAsync(user);
//var resetLink = $"{_configuration["AppSettings:WebFrontendUrl"]}/reset-password?token={WebUtility.UrlEncode(token)}";
//await _emailSender.SendResetPasswordEmailOnRegister(emailDot.ToEmail, "Vikas", resetLink);
/* Forget password*/
// var token = await _userManager.GeneratePasswordResetTokenAsync(user);
var token = await _userManager.GenerateUserTokenAsync(user, TokenOptions.DefaultProvider, "ResetPassword");
var isTokenValid = await _userManager.VerifyUserTokenAsync(user, TokenOptions.DefaultProvider, "ResetPassword", token);
var resetLink = $"{_configuration["AppSettings:WebFrontendUrl"]}/reset-password?token={WebUtility.UrlEncode(token)}";
await _emailSender.SendResetPasswordEmail(user.Email, "", resetLink);
// Send token via email (implementation omitted)
// ...
return Ok("Password reset link sent.");
}

View File

@ -1,17 +1,19 @@
using Marco.Pms.DataAccess.Data;
using Marco.Pms.DataAccess.Repository.IRepository;
using Marco.Pms.Model.Dtos.Employees;
using Marco.Pms.Model.Employees;
using Marco.Pms.Model.Entitlements;
using Marco.Pms.Model.Mapper;
using Marco.Pms.Model.Utilities;
using Marco.Pms.Model.ViewModels;
using Marco.Pms.Model.ViewModels.Employee;
using MarcoBMS.Services.Helpers;
using MarcoBMS.Services.Service;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Data;
using System.Net;
namespace MarcoBMS.Services.Controllers
{
@ -22,18 +24,23 @@ namespace MarcoBMS.Services.Controllers
public class EmployeeController : ControllerBase
{
private readonly IUnitOfWork _unitOfWork;
private readonly ApplicationDbContext _context;
private readonly UserManager<IdentityUser> _userManager;
private readonly IEmailSender _emailSender;
private readonly EmployeeHelper _employeeHelper;
private readonly UserHelper _userHelper;
private readonly IConfiguration _configuration;
public EmployeeController(UserManager<IdentityUser> userManager, IEmailSender emailSender, IEmployeeRepository empRepo, IUnitOfWork unitOfWork, ApplicationDbContext context)
public EmployeeController(UserManager<IdentityUser> userManager, IEmailSender emailSender,
ApplicationDbContext context, EmployeeHelper employeeHelper, UserHelper userHelper, IConfiguration configuration)
{
_unitOfWork = unitOfWork;
_context = context;
_userManager = userManager;
_emailSender = emailSender;
_employeeHelper = employeeHelper;
_userHelper = userHelper;
_configuration = configuration;
}
[HttpGet]
@ -99,11 +106,25 @@ namespace MarcoBMS.Services.Controllers
}
await _context.SaveChangesAsync();
}
catch (Exception ex) {
catch (Exception ex)
{
}
return Ok(ApiResponse<object>.SuccessResponse("success", "Roles modified.", 200));
}
[HttpGet]
[Route("list/{projectid?}")]
public async Task<IActionResult> GetEmployeesByProject(int? projectid)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var result = await _employeeHelper.GetEmployeeByProjectId(GetTenantId(), projectid);
return Ok(ApiResponse<object>.SuccessResponse(result, "Filter applied.", 200));
}
[HttpGet]
[Route("search/{name}/{projectid?}")]
public async Task<IActionResult> SearchEmployee(string name, int? projectid)
@ -112,98 +133,37 @@ namespace MarcoBMS.Services.Controllers
{
return BadRequest(ModelState);
}
int TenantId = GetTenantId();
name = name.ToLower();
int tenantId = GetTenantId();
List<Employee> employees = await _unitOfWork.Employee.GetAsync(c => c.TenantId == tenantId && (c.FirstName.ToLower().StartsWith(name)
|| c.MiddleName.ToLower().StartsWith(name) || c.LastName.ToLower().StartsWith(name)));
employees = employees.Where(c => c.FirstName.ToLower().StartsWith(name)
|| c.MiddleName.ToLower().StartsWith(name) || c.LastName.ToLower().StartsWith(name)).ToList();
if (projectid != null)
{
// conditions to e checked after project assignment
}
return Ok(ApiResponse<object>.SuccessResponse(employees, "Filter applied.", 200));
var result = await _employeeHelper.SearchEmployeeByProjectId(GetTenantId(), name.ToLower(), projectid);
return Ok(ApiResponse<object>.SuccessResponse(result, "Filter applied.", 200));
}
[HttpGet]
[Route("get/{projectid?}")]
public async Task<IActionResult> GetEmployee(int? projectid)
[Route("profile/get/{employeeId}")]
public async Task<IActionResult> GetEmployeeProfileById(int employeeId)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
int TenantId = GetTenantId();
List<Employee> employees = await _unitOfWork.Employee.GetAsync(c => c.TenantId == TenantId);
Employee emp = await _employeeHelper.GetEmployeeByID(employeeId);
EmployeeVM employeeVM = EmployeeMapper.ToEmployeeVMFromEmployee(emp);
employees = employees.Where(c => c.TenantId == TenantId).ToList();
if (projectid != null)
{
// Fetch assigned project
}
return Ok(employees);
return Ok(ApiResponse<object>.SuccessResponse(employeeVM, "Employee Profile.", 200));
}
//[HttpGet]
//[Route("attendance/project/{projectid?}")]
//public async Task<IActionResult> GetAttendanceList(int? projectid)
//{
// if (!ModelState.IsValid)
// {
// return BadRequest(ModelState);
// }
// int TenantId = GetTenantId();
// DateTime today = DateTime.Today;
// var result = from employee in _context.ProjectAllocations
// join attendance in _context.Attendances
// on employee.Id equals attendance.EmployeeID into attendanceGroup
// from todayAttendance in attendanceGroup
// //.Where(a => a.InTimeLog.InTime == today)
// .DefaultIfEmpty() // LEFT JOIN
// select new
// {
// ProjectID = projectid,
// EmployeeId = employee.Id,
// FirstName = employee.Employee.FirstName,
// MiddleName = employee.Employee.MiddleName,
// LastName = employee.Employee.LastName,
// PhoneNumber = employee.Employee.PhoneNumber,
// RoleId = employee.Employee.JobRoleId,
// //InTime = todayAttendance.InTimeLog != null ? todayAttendance.InTimeLog.InTime : (DateTime?)null,
// //OutTime = todayAttendance.OutTimeLog != null ? todayAttendance.OutTimeLog.OutTime : (DateTime?)null,
// // WorkShift = todayAttendance.WorkShift,
// Latitude = todayAttendance.InTimeLog != null ? todayAttendance.InTimeLog.Latitude : null,
// Longitude = todayAttendance.InTimeLog != null ? todayAttendance.InTimeLog.Longitude : null,
// Comment = todayAttendance.Comment,
// };
// return Ok(result);
//}
private int GetTenantId()
{
var tenant = User.FindFirst("TenantId")?.Value;
return (tenant != null ? Convert.ToInt32(tenant) : 1);
return _userHelper.GetTenantId();
}
[HttpPost("manage/quick")]
public async Task<IActionResult> CreateQuickUser([FromBody] CreateQuickUserDto model)
{
return Ok("Pending implementation");
}
//[HttpPost("manage/quick")]
//public async Task<IActionResult> CreateQuickUser([FromBody] CreateQuickUserDto model)
//{
// return Ok("Pending implementation");
//}
[HttpPost("manage")]
public async Task<IActionResult> CreateUser([FromForm] CreateUserDto model)
{
@ -211,144 +171,138 @@ namespace MarcoBMS.Services.Controllers
return BadRequest("Invalid user data.");
int TenantId = GetTenantId();
string responsemessage = "";
if (model.Email != null)
{
// Check if user already exists by email
var existingUser = await _userManager.FindByEmailAsync(model.Email);
IdentityUser? existingUser = await _userHelper.GetRegisteredUser(model.Email);
if (existingUser != null)
{
// Update existing user
//existingUser.Email = model.Email; // No need to update email
//var updateResult = await _userManager.UpdateAsync(existingUser);
//if (!updateResult.Succeeded)
// return BadRequest(updateResult.Errors);
/* Identity user Exists - Create/update employee Employee */
// Update Employee record
var existingEmployee = await _context.Employees.FirstOrDefaultAsync(e => e.ApplicationUserId == existingUser.Id);
var existingEmployee = await _context.Employees.FirstOrDefaultAsync(e => e.ApplicationUserId == existingUser.Id || e.Email == model.Email || e.Id == model.Id);
if (existingEmployee != null)
{
existingEmployee.FirstName = model.FirstName;
existingEmployee.LastName = model.LastName;
existingEmployee.TenantId = TenantId;
existingEmployee.Email = model.Email;
existingEmployee.JobRoleId = Convert.ToInt32(model.JobRoleId);
existingEmployee = GetUpdateEmployeeModel(model, existingEmployee, existingUser);
_context.Employees.Update(existingEmployee);
}
else
{
// Create Employee record if missing
var newEmployee = new Employee
{
ApplicationUserId = existingUser.Id,
FirstName = model.FirstName,
LastName = model.LastName,
Email = model.Email,
TenantId = TenantId,
CurrentAddress = model.CurrentAddress,
BirthDate = Convert.ToDateTime(model.BirthDate),
EmergencyPhoneNumber = model.EmergencyPhoneNumber,
AadharNumber = model.AadharNumber,
Gender = model.Gender,
MiddleName = model.MiddleName,
PanNumber = model.PanNumber,
PeramnentAddress = model.PeramnentAddress,
PhoneNumber = model.PhoneNumber,
Photo = GetFileDetails(model.Photo).Result.FileData,
JobRoleId = Convert.ToInt32(model.JobRoleId)
};
Employee newEmployee = GetNewEmployeeModel(model, TenantId, existingUser.Id);
_context.Employees.Add(newEmployee);
}
await _context.SaveChangesAsync();
return Ok(new { message = "User updated successfully." });
responsemessage = "User updated successfully.";
}
var user = new ApplicationUser
else
{
UserName = model.Email,
Email = model.Email,
EmailConfirmed = true
};
var user = new ApplicationUser
{
UserName = model.Email,
Email = model.Email,
EmailConfirmed = true
};
// Create Identity User
var result = await _userManager.CreateAsync(user, "User@123");
if (!result.Succeeded)
return BadRequest(result.Errors);
// Create Identity User
var result = await _userManager.CreateAsync(user, "User@123");
if (!result.Succeeded)
return BadRequest(result.Errors);
// Save Employee Data
var employee = new Employee
{
FirstName = model.FirstName,
LastName = model.LastName,
Email = model.Email,
TenantId = TenantId,
CurrentAddress = model.CurrentAddress,
BirthDate = Convert.ToDateTime(model.BirthDate),
EmergencyPhoneNumber = model.EmergencyPhoneNumber,
AadharNumber = model.AadharNumber,
Gender = model.Gender,
MiddleName = model.MiddleName,
PanNumber = model.PanNumber,
PeramnentAddress = model.PeramnentAddress,
PhoneNumber = model.PhoneNumber,
Photo = GetFileDetails(model.Photo).Result.FileData,
JobRoleId = Convert.ToInt32(model.JobRoleId)
};
_context.Employees.Add(employee);
await _context.SaveChangesAsync();
Employee newEmployee = GetNewEmployeeModel(model, TenantId, user.Id);
_context.Employees.Add(newEmployee);
var token = await _userManager.GeneratePasswordResetTokenAsync(user);
var resetLink = Url.Action("ResetPassword", "Account", new { token, email = user.Email }, Request.Scheme);
await _context.SaveChangesAsync();
// Send Email
await _emailSender.SendEmailAsync(user.Email, "Set Password", $"Click here to set your password: {resetLink}");
/* SEND USER REGISTRATION MAIL*/
var token = await _userManager.GeneratePasswordResetTokenAsync(user);
var resetLink = $"{_configuration["AppSettings:WebFrontendUrl"]}/reset-password?token={WebUtility.UrlEncode(token)}";
await _emailSender.SendResetPasswordEmailOnRegister(user.Email, newEmployee.FirstName, resetLink);
responsemessage = "User created successfully. PAssword reset link is sent to registered email";
}
}
else
{
var existingEmployee = await _context.Employees.FirstOrDefaultAsync(e => e.Id == model.Id);
if (existingEmployee != null)
{
existingEmployee.FirstName = model.FirstName;
existingEmployee.LastName = model.LastName;
existingEmployee.TenantId = TenantId;
existingEmployee = GetUpdateEmployeeModel(model, existingEmployee);
_context.Employees.Update(existingEmployee);
responsemessage = "User updated successfully.";
}
else
{
// Create Employee record if missing
var newEmployee = new Employee
{
ApplicationUserId = null,
FirstName = model.FirstName,
LastName = model.LastName,
TenantId = TenantId,
CurrentAddress = model.CurrentAddress,
BirthDate = Convert.ToDateTime(model.BirthDate),
EmergencyPhoneNumber = model.EmergencyPhoneNumber,
AadharNumber = model.AadharNumber,
Gender = model.Gender,
MiddleName = model.MiddleName,
PanNumber = model.PanNumber,
PeramnentAddress = model.PeramnentAddress,
PhoneNumber = model.PhoneNumber,
Photo = GetFileDetails(model.Photo).Result.FileData
Employee newEmployee = GetNewEmployeeModel(model, TenantId, null);
};
_context.Employees.Add(newEmployee);
}
await _context.SaveChangesAsync();
responsemessage = "User created successfully.";
}
// Generate Password Reset Link
return Ok(new { message = responsemessage });
}
private static Employee GetNewEmployeeModel(CreateUserDto model, int TenantId, string? ApplicationUserId)
{
var newEmployee = new Employee
{
ApplicationUserId = ApplicationUserId,
FirstName = model.FirstName,
LastName = model.LastName,
Email = model.Email,
TenantId = TenantId,
CurrentAddress = model.CurrentAddress,
BirthDate = Convert.ToDateTime(model.BirthDate),
EmergencyPhoneNumber = model.EmergencyPhoneNumber,
EmergencyContactPerson = model.EmergencyContactPerson,
AadharNumber = model.AadharNumber,
Gender = model.Gender,
MiddleName = model.MiddleName,
PanNumber = model.PanNumber,
PeramnentAddress = model.PeramnentAddress,
PhoneNumber = model.PhoneNumber,
Photo = null, // GetFileDetails(model.Photo).Result.FileData,
JobRoleId = Convert.ToInt32(model.JobRoleId),
JoiningDate = Convert.ToDateTime(model.JoiningDate),
return Ok(new { message = "User created successfully. Password reset link sent." });
};
return newEmployee;
}
private static Employee GetUpdateEmployeeModel(CreateUserDto model, Employee existingEmployee, IdentityUser? existingIdentityUser = null)
{
if (existingEmployee.ApplicationUserId == null && existingIdentityUser != null)
{
existingEmployee.ApplicationUserId = existingIdentityUser.Id;
}
existingEmployee.FirstName = model.FirstName;
existingEmployee.LastName = model.LastName;
existingEmployee.CurrentAddress = model.CurrentAddress;
existingEmployee.BirthDate = Convert.ToDateTime(model.BirthDate);
existingEmployee.JoiningDate = Convert.ToDateTime(model.JoiningDate);
existingEmployee.EmergencyPhoneNumber = model.EmergencyPhoneNumber;
existingEmployee.EmergencyContactPerson = model.EmergencyContactPerson;
existingEmployee.AadharNumber = model.AadharNumber;
existingEmployee.Gender = model.Gender;
existingEmployee.MiddleName = model.MiddleName;
existingEmployee.PanNumber = model.PanNumber;
existingEmployee.PeramnentAddress = model.PeramnentAddress;
existingEmployee.PhoneNumber = model.PhoneNumber;
existingEmployee.Photo = null; // GetFileDetails(model.Photo).Result.FileData,
existingEmployee.JobRoleId = Convert.ToInt32(model.JobRoleId);
return existingEmployee;
}
private static async Task<FileDetails> GetFileDetails(IFormFile file)

View File

@ -40,16 +40,16 @@ namespace MarcoBMS.Services.Controllers
return imageName;
}
[HttpPost("manage1")]
public async Task<IActionResult> CreateUser_1([FromForm] CreateUserDto model)
{
if (model == null)
return BadRequest("Invalid user data.");
//[HttpPost("manage1")]
//public async Task<IActionResult> CreateUser_1([FromForm] CreateUserDto model)
//{
// if (model == null)
// return BadRequest("Invalid user data.");
await GetFileDetails(model.Photo);
// await GetFileDetails(model.Photo);
return Ok(new { message = "User created successfully. Password reset link sent." });
}
// return Ok(new { message = "User created successfully. Password reset link sent." });
//}
private static async Task<FileDetails> GetFileDetails(IFormFile file)
{

View File

@ -1,6 +1,4 @@
using Marco.Pms.DataAccess.Data;
using Marco.Pms.DataAccess.Repository;
using Marco.Pms.DataAccess.Repository.IRepository;
using Marco.Pms.Model.Activities;
using Marco.Pms.Model.Dtos.Project;
using Marco.Pms.Model.Employees;
@ -9,6 +7,8 @@ using Marco.Pms.Model.Mapper;
using Marco.Pms.Model.Projects;
using Marco.Pms.Model.Utilities;
using Marco.Pms.Model.ViewModels;
using Marco.Pms.Model.ViewModels.Employee;
using MarcoBMS.Services.Helpers;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
@ -21,19 +21,21 @@ namespace MarcoBMS.Services.Controllers
[Authorize]
public class ProjectController : ControllerBase
{
private readonly IUnitOfWork _unitOfWork;
//private readonly IUnitOfWork _unitOfWork;
private readonly ApplicationDbContext _context;
private ApplicationUser _applicationUser;
private readonly IProjectRepository _projectrepo;
// private readonly IProjectRepository _projectrepo;
private readonly UserManager<IdentityUser> _userManager;
private readonly UserHelper _userHelper;
public ProjectController(UserManager<IdentityUser> userManager, IProjectRepository projectrepo, IUnitOfWork unitOfWork, ApplicationDbContext context)
public ProjectController(UserManager<IdentityUser> userManager, ApplicationDbContext context, UserHelper userHelper)
{
_unitOfWork = unitOfWork;
//_unitOfWork = unitOfWork;
_context = context;
_projectrepo = projectrepo;
//_projectrepo = projectrepo;
_userManager = userManager;
_userHelper = userHelper;
}
[HttpGet("list")]
public async Task<IActionResult> GetAll()
@ -42,8 +44,7 @@ namespace MarcoBMS.Services.Controllers
{
return BadRequest(ModelState);
}
List<Project> project = await _projectrepo.GetAllAsync();
// var commentDto = comments.Select(x => x.ToCommentDto());
List<Project> project = await _context.Projects.Where(c=>c.TenantId == _userHelper.GetTenantId()).ToListAsync();
return Ok(project);
}
@ -56,9 +57,7 @@ namespace MarcoBMS.Services.Controllers
return BadRequest(ModelState);
}
var project = _projectrepo.Get(c => c.Id == id); //_context.Stock.FindAsync(id);
// List<Project> project = await _projectrepo.GetAsync(id);
var project = await _context.Projects.Where(c => c.TenantId == _userHelper.GetTenantId() && c.Id == id).SingleOrDefaultAsync();
return Ok(project);
}
@ -73,19 +72,17 @@ namespace MarcoBMS.Services.Controllers
return BadRequest(ModelState);
}
var projects = await _projectrepo.GetAsync((c => c.Id == id), includeProperties: "ProjectStatus,Tenant"); //_context.Stock.FindAsync(id);
var project = await _context.Projects.Where(c => c.TenantId == _userHelper.GetTenantId() && c.Id == id).Include(c=> c.ProjectStatus).SingleOrDefaultAsync(); // includeProperties: "ProjectStatus,Tenant"); //_context.Stock.FindAsync(id);
if (projects == null)
if (project == null)
{
//vm.project = new Project();
//vm.buildings = new List<Building>();
//vm.floors = new List<Floor>();
//vm.workAreas = new List<WorkArea>();
return Ok(new ProjectVM());
}
else
{
var project = projects.Where(c => c.Id == id).SingleOrDefault();
ProjectDetailsVM vm = GetProjectViewModel(id, project);
//var project = projects.Where(c => c.Id == id).SingleOrDefault();
ProjectDetailsVM vm = await GetProjectViewModel(id, project);
ProjectVM projectVM = new ProjectVM();
projectVM.Id = vm.project.Id;
@ -132,25 +129,26 @@ namespace MarcoBMS.Services.Controllers
return Ok(projectVM);
}
return Ok(new ProjectVM());
}
private ProjectDetailsVM GetProjectViewModel(int? id, Project project)
private async Task<ProjectDetailsVM> GetProjectViewModel(int? id, Project project)
{
ProjectDetailsVM vm = new ProjectDetailsVM();
// List<Building> buildings = _unitOfWork.Building.GetAll(c => c.ProjectId == id).ToList();
List<Building> buildings = _context.Buildings.Where(c => c.ProjectId == id).ToList();
List<Building> buildings = await _context.Buildings.Where(c => c.ProjectId == id).ToListAsync();
List<int> idList = buildings.Select(o => o.Id).ToList();
// List<Floor> floors = _unitOfWork.Floor.GetAll(c => idList.Contains(c.Id)).ToList();
List<Floor> floors = _context.Floor.Where(c => idList.Contains(c.BuildingId)).ToList();
List<Floor> floors = await _context.Floor.Where(c => idList.Contains(c.BuildingId)).ToListAsync();
idList = floors.Select(o => o.Id).ToList();
//List<WorkArea> workAreas = _unitOfWork.WorkArea.GetAll(c => idList.Contains(c.Id), includeProperties: "WorkItems,WorkItems.ActivityMaster").ToList();
List<WorkArea> workAreas = _context.WorkAreas.Where(c => idList.Contains(c.FloorId)).ToList();
List<WorkArea> workAreas = await _context.WorkAreas.Where(c => idList.Contains(c.FloorId)).ToListAsync();
idList = floors.Select(o => o.Id).ToList();
List<WorkItem> workItems = _unitOfWork.WorkItem.GetAll(c => idList.Contains(c.WorkAreaId), includeProperties: "ActivityMaster").ToList();
List<WorkItem> workItems = await _context.WorkItems.Where(c => idList.Contains(c.WorkAreaId)).Include(c=>c.ActivityMaster).ToListAsync();
// List <WorkItem> workItems = _unitOfWork.WorkItem.GetAll(c => idList.Contains(c.WorkAreaId), includeProperties: "ActivityMaster").ToList();
vm.project = project;
vm.buildings = buildings;
@ -163,8 +161,9 @@ namespace MarcoBMS.Services.Controllers
private int GetTenantId()
{
var tenant = User.FindFirst("TenantId")?.Value;
return (tenant != null ? Convert.ToInt32(tenant) : 1);
return _userHelper.GetTenantId();
//var tenant = User.FindFirst("TenantId")?.Value;
//return (tenant != null ? Convert.ToInt32(tenant) : 1);
}
[HttpPost]
@ -176,26 +175,13 @@ namespace MarcoBMS.Services.Controllers
}
int TenantId = GetTenantId();
var projectModel = projectDto.ToProjectFromCreateProjectDto(TenantId);
var project = projectDto.ToProjectFromCreateProjectDto(TenantId);
var result = await _projectrepo.CreateAsync(projectModel);
_context.Projects.Add(project);
return Ok(result);
await _context.SaveChangesAsync();
}
[HttpGet("get-allocation/{projectId:int}")]
public async Task<IActionResult> GetAllocation([FromRoute] int projectId)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
List<ProjectAllocation> allocations = await _unitOfWork.ProjectAllocation.GetAsync(c => c.ProjectId == projectId);
allocations = allocations.Where(c => c.ProjectId == projectId).ToList();
return Ok(allocations);
return Ok(ApiResponse<object>.SuccessResponse(project.ToProjectDto(), "Success.", 200));
}
[HttpPut]
@ -210,13 +196,14 @@ namespace MarcoBMS.Services.Controllers
{
int TenantId = GetTenantId();
updateProjectDto.TenantId = TenantId;
var projectModel = await _projectrepo.UpdateAsync(id, updateProjectDto);
if (projectModel == null)
{
return NotFound("Project not found");
}
return Ok(projectModel.ToProjectDto());
Project project = updateProjectDto.ToProjectFromUpdateProjectDto(TenantId);
_context.Projects.Update(project);
await _context.SaveChangesAsync();
return Ok(ApiResponse<object>.SuccessResponse(project.ToProjectDto(), "Success.", 200));
}
catch (Exception ex)
{
@ -225,49 +212,96 @@ namespace MarcoBMS.Services.Controllers
}
[HttpPost("assign-employee")]
public async Task<IActionResult> AssignEmployee(int? allocationid, int employeeId, int projectId)
//[HttpPost("assign-employee")]
//public async Task<IActionResult> AssignEmployee(int? allocationid, int employeeId, int projectId)
//{
// var employee = await _context.Employees.FindAsync(employeeId);
// var project = _projectrepo.Get(c => c.Id == projectId);
// if (employee == null || project == null)
// {
// return NotFound();
// }
// // Logic to add the product to a new table (e.g., selected products)
// if (allocationid == null)
// {
// // Add allocation
// ProjectAllocation allocation = new ProjectAllocation()
// {
// EmployeeId = employeeId,
// ProjectId = project.Id,
// AllocationDate = DateTime.UtcNow,
// //EmployeeRole = employee.Rol
// TenantId = project.TenantId
// };
// _unitOfWork.ProjectAllocation.CreateAsync(allocation);
// }
// else
// {
// //remove allocation
// var allocation = await _context.ProjectAllocations.FindAsync(allocationid);
// if (allocation != null)
// {
// allocation.ReAllocationDate = DateTime.UtcNow;
// _unitOfWork.ProjectAllocation.UpdateAsync(allocation.Id, allocation);
// }
// else
// {
// return NotFound();
// }
// }
// return Ok();
//}
[HttpGet]
[Route("employees/get/{projectid?}/{includeInactive?}")]
public async Task<IActionResult> GetEmployeeByProjectID(int? projectid, bool? includeInactive = false)
{
var employee = await _context.Employees.FindAsync(employeeId);
var project = _projectrepo.Get(c => c.Id == projectId);
if (employee == null || project == null)
if (!ModelState.IsValid)
{
return NotFound();
return BadRequest(ModelState);
}
int TenantId = GetTenantId();
// Logic to add the product to a new table (e.g., selected products)
if (allocationid == null)
if (projectid != null)
{
// Add allocation
ProjectAllocation allocation = new ProjectAllocation()
{
EmployeeId = employeeId,
ProjectId = project.Id,
AllocationDate = DateTime.UtcNow,
//EmployeeRole = employee.Rol
TenantId = project.TenantId
};
// Fetch assigned project
List<Employee> result = new List<Employee>();
_unitOfWork.ProjectAllocation.CreateAsync(allocation);
if ((bool)includeInactive)
{
result = await (from rpm in _context.Employees.Include(c => c.JobRole)
join fp in _context.ProjectAllocations.Where(c => c.TenantId == TenantId && c.ProjectId == projectid)
on rpm.Id equals fp.EmployeeId
select rpm).ToListAsync();
}else
{
result = await (from rpm in _context.Employees.Include(c => c.JobRole)
join fp in _context.ProjectAllocations.Where(c => c.TenantId == TenantId && c.ProjectId == projectid && c.IsActive == true)
on rpm.Id equals fp.EmployeeId
select rpm).ToListAsync();
}
List<EmployeeVM> resultVM = new List<EmployeeVM>();
foreach (Employee employee in result)
{
EmployeeVM vm = employee.ToEmployeeVMFromEmployee();
resultVM.Add(vm);
}
return Ok(ApiResponse<object>.SuccessResponse(resultVM, "Success.", 200));
}
else
{
//remove allocation
var allocation = await _context.ProjectAllocations.FindAsync(allocationid);
if (allocation != null)
{
allocation.ReAllocationDate = DateTime.UtcNow;
_unitOfWork.ProjectAllocation.UpdateAsync(allocation.Id, allocation);
}
else
{
return NotFound();
}
return Ok(ApiResponse<object>.ErrorResponse("Invalid Input Parameter", 422));
}
return Ok();
}
[HttpGet]
@ -280,25 +314,25 @@ namespace MarcoBMS.Services.Controllers
}
int TenantId = GetTenantId();
var employees = await _context.ProjectAllocations.Where(c => c.TenantId == TenantId && c.ProjectId == projectId ).Include(e => e.Employee).Select(e=> new
var employees = await _context.ProjectAllocations.Where(c => c.TenantId == TenantId && c.ProjectId == projectId).Include(e => e.Employee).Include(e => e.Employee.JobRole).Select(e => new
{
ID = e.Id,
EmployeeId = e.EmployeeId,
ProjectId = e.ProjectId,
RoleID = e.EmployeeRoleId,
AllocationDate = e.AllocationDate,
ReAllocationDate = e.ReAllocationDate,
FirstName = e.Employee.FirstName,
LastName = e.Employee.LastName,
MiddleName = e.Employee.MiddleName,
IsActive = e.IsActive
IsActive = e.IsActive,
JobRoleId = (e.JobRoleId != null ? e.JobRoleId : e.Employee.JobRoleId)
}).ToListAsync();
return Ok(ApiResponse<object>.SuccessResponse(employees, "Success.", 200));
}
[HttpPost("allocation")]
[HttpPost("allocation")]
public async Task<IActionResult> ManageAllocation(List<ProjectAllocationDot> projectAllocationDot)
{
if (projectAllocationDot != null)
@ -310,7 +344,7 @@ namespace MarcoBMS.Services.Controllers
try
{
ProjectAllocation projectAllocation = item.ToProjectAllocationFromProjectAllocationDto(TenentID);
ProjectAllocation projectAllocationFromDb =await _context.ProjectAllocations.Where(c => c.EmployeeId == projectAllocation.EmployeeId
ProjectAllocation projectAllocationFromDb = await _context.ProjectAllocations.Where(c => c.EmployeeId == projectAllocation.EmployeeId
&& c.ProjectId == projectAllocation.ProjectId
&& c.ReAllocationDate == null
&& c.TenantId == TenentID).SingleOrDefaultAsync();
@ -321,11 +355,10 @@ namespace MarcoBMS.Services.Controllers
if (item.Status)
{
projectAllocationFromDb.EmployeeRoleId = projectAllocation.EmployeeRoleId; ;
projectAllocationFromDb.JobRoleId = projectAllocation.JobRoleId; ;
projectAllocationFromDb.IsActive = true;
_context.Entry(projectAllocationFromDb).Property(e => e.EmployeeRoleId).IsModified = true;
_context.Entry(projectAllocationFromDb).Property(e => e.JobRoleId).IsModified = true;
_context.Entry(projectAllocationFromDb).Property(e => e.IsActive).IsModified = true;
}
else
{
@ -333,7 +366,6 @@ namespace MarcoBMS.Services.Controllers
projectAllocationFromDb.IsActive = false;
_context.Entry(projectAllocationFromDb).Property(e => e.ReAllocationDate).IsModified = true;
_context.Entry(projectAllocationFromDb).Property(e => e.IsActive).IsModified = true;
}
await _context.SaveChangesAsync();
@ -371,20 +403,15 @@ namespace MarcoBMS.Services.Controllers
if (item.Id > 0)
{
//update
_unitOfWork.WorkItem.Update(workItem);
_context.WorkItems.Update(workItem);
await _context.SaveChangesAsync();
}
else
{
//create
_unitOfWork.WorkItem.Add(workItem);
_context.WorkItems.Add(workItem);
await _context.SaveChangesAsync();
}
_unitOfWork.Save();
}
return Ok(ApiResponse<object>.SuccessResponse(null, "Data saved successfully.", 200));
@ -410,15 +437,15 @@ namespace MarcoBMS.Services.Controllers
if (item.Building.Id == 0)
{
//create
_unitOfWork.Building.Add(building);
_context.Buildings.Add(building);
await _context.SaveChangesAsync();
}
else
{
//update
_unitOfWork.Building.Update(building);
_context.Buildings.Update(building);
await _context.SaveChangesAsync();
}
_unitOfWork.Save();
}
if (item.Floor != null)
{
@ -428,16 +455,15 @@ namespace MarcoBMS.Services.Controllers
if (item.Floor.Id == 0)
{
//create
_unitOfWork.Floor.Add(floor);
_context.Floor.Add(floor);
await _context.SaveChangesAsync();
}
else
{
//update
_unitOfWork.Floor.Update(floor);
_context.Floor.Update(floor);
await _context.SaveChangesAsync();
}
_unitOfWork.Save();
}
if (item.WorkArea != null)
{
@ -447,15 +473,15 @@ namespace MarcoBMS.Services.Controllers
if (item.WorkArea.Id == 0)
{
//create
_unitOfWork.WorkArea.Add(workArea);
_context.WorkAreas.Add(workArea);
await _context.SaveChangesAsync();
}
else
{
//update
_unitOfWork.WorkArea.Update(workArea);
_context.WorkAreas.Update(workArea);
await _context.SaveChangesAsync();
}
_unitOfWork.Save();
}
}
}

View File

@ -1,9 +1,11 @@
using Marco.Pms.DataAccess.Data;
using Azure;
using Marco.Pms.DataAccess.Data;
using Marco.Pms.Model.Dtos.Roles;
using Marco.Pms.Model.Entitlements;
using Marco.Pms.Model.Mapper;
using Marco.Pms.Model.Utilities;
using Marco.Pms.Model.ViewModels;
using MarcoBMS.Services.Helpers;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
@ -18,13 +20,16 @@ namespace MarcoBMS.Services.Controllers
public class RolesController : ControllerBase
{
private readonly ApplicationDbContext _context;
private readonly RolesHelper _rolesHelper;
private readonly UserManager<IdentityUser> _userManager;
public RolesController(UserManager<IdentityUser> userManager, ApplicationDbContext context)
public RolesController(UserManager<IdentityUser> userManager, ApplicationDbContext context, RolesHelper rolesHelper)
{
_context = context;
_userManager = userManager;
_rolesHelper = rolesHelper;
}
@ -154,8 +159,7 @@ namespace MarcoBMS.Services.Controllers
}
return Ok(applicationRoles);
return Ok(ApiResponse<object>.SuccessResponse(applicationRoles, "Roles list fetched successfully.", 200));
}
@ -214,21 +218,34 @@ namespace MarcoBMS.Services.Controllers
return NotFound("Project not found");
}
bool modified = false;
foreach (var permission in updateRoleDto.FeaturesPermission)
{
var item = new RolePermissionMappings() { ApplicationRoleId = role.Id, FeaturePermissionId = permission.Id };
bool assigned = _context.RolePermissionMappings.Any(c => c.ApplicationRoleId == role.Id && c.FeaturePermissionId == permission.Id);
if (permission.IsEnabled && !assigned)
_context.RolePermissionMappings.Add(item);
else
if (permission.IsEnabled == false && assigned == true)
{
_context.RolePermissionMappings.Remove(item);
modified = true;
}
else if (permission.IsEnabled && !assigned)
{
_context.RolePermissionMappings.Add(item);
modified = true;
}
}
return Ok(role.ToRoleVMFromApplicationRole());
if (modified)
await _context.SaveChangesAsync();
ApplicationRolesVM response = role.ToRoleVMFromApplicationRole();
List<FeaturePermission> permissions = await _rolesHelper.GetFeaturePermissionByRoleID(response.Id);
response.FeaturePermission = permissions.Select(c => c.ToFeaturePermissionVMFromFeaturePermission()).ToList();
return Ok(ApiResponse<object>.SuccessResponse(response, "Roles perimssions updated.", 200));
}
catch (Exception ex)
{
return Ok(null);
return Ok(ApiResponse<object>.ErrorResponse( "RUnable to update roles perimssions.", 200));
}
}
@ -269,7 +286,8 @@ namespace MarcoBMS.Services.Controllers
FeaturePermission = featurePermissions
};
return Ok(vm);
return Ok(ApiResponse<object>.SuccessResponse(vm, "Roles Perimssions fetched successfully.", 200));
}
}
}

View File

@ -1,8 +1,6 @@
using Marco.Pms.DataAccess.Data;
using Marco.Pms.DataAccess.Repository.IRepository;
using Marco.Pms.Model.Entitlements;
using MarcoBMS.Services.Helpers;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
@ -13,32 +11,23 @@ namespace MarcoBMS.Services.Controllers
[ApiController]
public class TaskController : ControllerBase
{
private readonly IUnitOfWork _unitOfWork;
private readonly ApplicationDbContext _context;
private ApplicationUser _applicationUser;
private readonly IActivityMasterRepository _activityRepo;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly UserHelper _userHelper;
public TaskController(IActivityMasterRepository activityRepo, IUnitOfWork unitOfWork, ApplicationDbContext context, IHttpContextAccessor httpContextAccessor)
public TaskController(ApplicationDbContext context, UserHelper userHelper)
{
_unitOfWork = unitOfWork;
_context = context;
_activityRepo = activityRepo;
_httpContextAccessor = httpContextAccessor;
_userHelper = userHelper;
}
[HttpGet]
[Route("activities")]
public async Task<IActionResult> GetActivities()
{
var tenantId = _httpContextAccessor.HttpContext?.Items["TenantId"]?.ToString();
var activities = await _activityRepo.GetAllAsync(c=>c.TenantId == Convert.ToInt32( tenantId));
var activities = await _context.ActivityMasters.Where(c => c.TenantId == _userHelper.GetTenantId()).ToListAsync();
return Ok(activities);
}
}
}

View File

@ -0,0 +1,68 @@
using Marco.Pms.Model.Employees;
using Marco.Pms.Model.Entitlements;
using Marco.Pms.Model.Mapper;
using Marco.Pms.Model.Projects;
using Marco.Pms.Model.ViewModels.Employee;
using MarcoBMS.Services.Helpers;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace MarcoBMS.Services.Controllers
{
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class UserController : ControllerBase
{
private readonly UserHelper _userHelper;
private readonly EmployeeHelper _employeeHelper;
private readonly ProjectsHelper _projectsHelper;
private readonly RolesHelper _rolesHelper;
public UserController(EmployeeHelper employeeHelper, ProjectsHelper projectsHelper, UserHelper userHelper, RolesHelper rolesHelper)
{
_userHelper = userHelper;
_employeeHelper = employeeHelper;
_projectsHelper = projectsHelper;
_rolesHelper = rolesHelper;
}
[HttpGet("profile")]
public async Task<IActionResult> GetUserProfileFromJwt()
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var user = await _userHelper.GetCurrentUserAsync();
Employee emp = await _employeeHelper.GetEmployeeByApplicationUserID(user.Id);
List<FeaturePermission> featurePermission = await _rolesHelper.GetFeaturePermissionByEmployeeID(emp.Id);
string[] projectsId = [];
if (featurePermission != null && featurePermission.Exists(c => c.FeatureId.ToString() == "53176ebf-c75d-42e5-839f-4508ffac3def")) {
List<Project> projects = await _projectsHelper.GetAllProjectByTanentID(emp.TenantId);
projectsId = projects.Select(c=>c.Id.ToString()).ToArray();
}
else
{
List<ProjectAllocation> allocation = await _projectsHelper.GetProjectByEmployeeID(emp.Id);
projectsId = allocation.Select(c => c.ProjectId.ToString()).ToArray();
}
EmployeeVM employeeVM = EmployeeMapper.ToEmployeeVMFromEmployee(emp);
EmployeeProfile profile = new EmployeeProfile()
{
EmployeeInfo = employeeVM,
Projects = projectsId,
FeaturePermissions = featurePermission.Select(c => c.FeatureId.ToString()).ToArray(),
};
return Ok(profile);
}
}
}

View File

@ -0,0 +1,565 @@

<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional //EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
<head>
<!--[if gte mso 9]>
<xml>
<o:OfficeDocumentSettings>
<o:AllowPNG/>
<o:PixelsPerInch>96</o:PixelsPerInch>
</o:OfficeDocumentSettings>
</xml>
<![endif]-->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="x-apple-disable-message-reformatting">
<!--[if !mso]><!-->
<meta http-equiv="X-UA-Compatible" content="IE=edge"><!--<![endif]-->
<title></title>
<style type="text/css">
@media only screen and (min-width: 620px) {
.u-row {
width: 600px !important;
}
.u-row .u-col {
vertical-align: top;
}
.u-row .u-col-50 {
width: 300px !important;
}
.u-row .u-col-100 {
width: 600px !important;
}
}
@media only screen and (max-width: 620px) {
.u-row-container {
max-width: 100% !important;
padding-left: 0px !important;
padding-right: 0px !important;
}
.u-row {
width: 100% !important;
}
.u-row .u-col {
display: block !important;
width: 100% !important;
min-width: 320px !important;
max-width: 100% !important;
}
.u-row .u-col > div {
margin: 0 auto;
}
.u-row .u-col img {
max-width: 100% !important;
}
}
body {
margin: 0;
padding: 0
}
table, td, tr {
border-collapse: collapse;
vertical-align: top
}
p {
margin: 0
}
.ie-container table, .mso-container table {
table-layout: fixed
}
* {
line-height: inherit
}
a[x-apple-data-detectors=true] {
color: inherit !important;
text-decoration: none !important
}
table, td {
color: #000000;
}
#u_body a {
color: #e93f32;
text-decoration: underline;
}
</style>
<!--[if !mso]><!-->
<link href="https://fonts.googleapis.com/css?family=Lato:400,700" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Lato:400,700" rel="stylesheet" type="text/css"><!--<![endif]-->
</head>
<body class="clean-body u_body" style="margin: 0;padding: 0;-webkit-text-size-adjust: 100%;background-color: #f9f9f9;color: #000000">
<!--[if IE]><div class="ie-container"><![endif]-->
<!--[if mso]><div class="mso-container"><![endif]-->
<table id="u_body" style="border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;min-width: 320px;Margin: 0 auto;background-color: #f9f9f9;width:100%" cellpadding="0" cellspacing="0">
<tbody>
<tr style="vertical-align: top">
<td style="word-break: break-word;border-collapse: collapse !important;vertical-align: top">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td align="center" style="background-color: #f9f9f9;"><![endif]-->
<!--<div>Top Spacing</div>-->
<div class="u-row-container" style="padding: 0px;background-color: #f9f9f9">
<div class="u-row" style="margin: 0 auto;min-width: 320px;max-width: 600px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: #f9f9f9;">
<div style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: #f9f9f9;" align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:600px;"><tr style="background-color: #f9f9f9;"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="600" style="width: 600px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;" valign="top"><![endif]-->
<div class="u-col u-col-100" style="max-width: 320px;min-width: 600px;display: table-cell;vertical-align: top;">
<div style="height: 100%;width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;">
<!--<![endif]-->
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:15px;font-family:'Lato',sans-serif;" align="left">
<table height="0px" align="center" border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;border-top: 1px solid #f9f9f9;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%">
<tbody>
<tr style="vertical-align: top">
<td style="word-break: break-word;border-collapse: collapse !important;vertical-align: top;font-size: 0px;line-height: 0px;mso-line-height-rule: exactly;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%">
Sita
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<!--[if (!mso)&(!IE)]><!-->
</div><!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<!--<div>Logo Block</div>-->
<div class="u-row-container" style="padding: 0px;background-color: transparent">
<div class="u-row" style="margin: 0 auto;min-width: 320px;max-width: 600px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: #ffffff;">
<div style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: transparent;" align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:600px;"><tr style="background-color: #ffffff;"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="600" style="width: 600px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;" valign="top"><![endif]-->
<div class="u-col u-col-100" style="max-width: 320px;min-width: 600px;display: table-cell;vertical-align: top;">
<div style="height: 100%;width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;">
<!--<![endif]-->
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:25px 10px;font-family:'Lato',sans-serif;" align="left">
<table width="100%" cellpadding="0" cellspacing="0" border="0">
<tr>
<td style="padding-right: 0px;padding-left: 0px;" align="center">
<img align="center" border="0" src="http://localhost:5032/logos/marco-aiot-tech-logo.jpg" alt="Image" title="Image" style="outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;clear: both;display: inline-block !important;border: none;height: auto;float: none;width: 29%;max-width: 168.2px;" width="168.2" />
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
<!--[if (!mso)&(!IE)]><!-->
</div><!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<!--<div>Title Block</div>-->
<div class="u-row-container" style="padding: 0px;background-color: transparent">
<div class="u-row" style="margin: 0 auto; min-width: 320px; max-width: 600px; overflow-wrap: break-word; word-wrap: break-word; word-break: break-word; background-color: #f46b61;">
<div style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: transparent;" align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:600px;"><tr style="background-color: #e93f32;"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="600" style="width: 600px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;" valign="top"><![endif]-->
<div class="u-col u-col-100" style="max-width: 320px;min-width: 600px;display: table-cell;vertical-align: top;">
<div style="height: 100%;width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;">
<!--<![endif]-->
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:35px 10px 10px;font-family:'Lato',sans-serif;" align="left">
<table width="100%" cellpadding="0" cellspacing="0" border="0">
<tr>
<td style="padding-right: 0px;padding-left: 0px;" align="center">
<img align="center" border="0" src="https://cdn.templates.unlayer.com/assets/1593141680866-reset.png" alt="Image" title="Image" style="outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;clear: both;display: inline-block !important;border: none;height: auto;float: none;width: 10%;max-width: 58px;" width="58" />
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:0px 10px 30px;font-family:'Lato',sans-serif;" align="left">
<div style="font-size: 14px; line-height: 140%; text-align: left; word-wrap: break-word;">
<p style="font-size: 14px; line-height: 140%; text-align: center;"><span style="font-size: 28px; line-height: 39.2px; color: #ffffff; font-family: Lato, sans-serif;">{{MAIL_TITLE}} </span></p>
</div>
</td>
</tr>
</tbody>
</table>
<!--[if (!mso)&(!IE)]><!-->
</div><!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<!--<div>Mail Body</div>-->
<div class="u-row-container" style="padding: 0px;background-color: transparent">
<div class="u-row" style="margin: 0 auto;min-width: 320px;max-width: 600px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: #ffffff;">
<div style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: transparent;" align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:600px;"><tr style="background-color: #ffffff;"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="600" style="width: 600px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;" valign="top"><![endif]-->
<div class="u-col u-col-100" style="max-width: 320px;min-width: 600px;display: table-cell;vertical-align: top;">
<div style="height: 100%;width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;">
<!--<![endif]-->
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:40px 40px 30px;font-family:'Lato',sans-serif;" align="left">
<div style="font-size: 14px; line-height: 140%; text-align: left; word-wrap: break-word;">
<p style="font-size: 14px; line-height: 140%;"><span style="font-size: 14px; line-height: 25.2px; color: #666666;">Hello,</span></p>
<p style="font-size: 14px; line-height: 140%;">&nbsp;</p>
<p style="font-size: 14px; line-height: 140%;"><span style="font-size: 14px; line-height: 25.2px; color: #666666;">We have sent you this email in response to your request to reset your password on MarcoPMS.</span></p>
<p style="font-size: 14px; line-height: 140%;">&nbsp;</p>
<p style="font-size: 14px; line-height: 140%;"><span style="font-size: 14px; line-height: 25.2px; color: #666666;">To reset your password, please follow the link below: </span></p>
</div>
</td>
</tr>
</tbody>
</table>
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:0px 40px;font-family:'Lato',sans-serif;" align="left">
<!--[if mso]><style>.v-button {background: transparent !important;}</style><![endif]-->
<div align="left">
<!--[if mso]><v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="" style="height:51px; v-text-anchor:middle; width:205px;" arcsize="2%" stroke="f" fillcolor="#e93f32"><w:anchorlock/><center style="color:#FFFFFF;"><![endif]-->
<a href="{{RESET_PWD_URL}}" target="_blank" class="v-button" style="box-sizing: border-box;display: inline-block;text-decoration: none;-webkit-text-size-adjust: none;text-align: center;color: #FFFFFF; background-color: #e93f32; border-radius: 1px;-webkit-border-radius: 1px; -moz-border-radius: 1px; width:auto; max-width:100%; overflow-wrap: break-word; word-break: break-word; word-wrap:break-word; mso-border-alt: none;font-size: 14px;">
<span style="display:block;padding:15px 40px;line-height:120%;"><span style="font-size: 18px; line-height: 21.6px;">Reset Password</span></span>
</a>
<!--[if mso]></center></v:roundrect><![endif]-->
</div>
</td>
</tr>
</tbody>
</table>
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:40px 40px 30px;font-family:'Lato',sans-serif;" align="left">
<div style="font-size: 14px; line-height: 140%; text-align: left; word-wrap: break-word;">
<p style="font-size: 14px; line-height: 140%;"><span style="color: #888888; font-size: 14px; line-height: 19.6px;"><em><span style="font-size: 14px; line-height: 22.4px;">Please ignore this email if you did not request a password change.</span></em></span><br /><span style="color: #888888; font-size: 14px; line-height: 19.6px;"><em><span style="font-size: 16px; line-height: 22.4px;">&nbsp;</span></em></span></p>
</div>
</td>
</tr>
</tbody>
</table>
<!--[if (!mso)&(!IE)]><!-->
</div><!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<!--<div>Contact</div>-->
<div class="u-row-container" style="padding: 0px;background-color: transparent">
<div class="u-row" style="margin: 0 auto;min-width: 320px;max-width: 600px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: #e93f32;">
<div style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: transparent;" align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:600px;"><tr style="background-color: #e93f32;"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="300" style="width: 300px;padding: 20px 20px 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;" valign="top"><![endif]-->
<div class="u-col u-col-50" style="max-width: 320px;min-width: 300px;display: table-cell;vertical-align: top;">
<div style="height: 100%;width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="box-sizing: border-box; height: 100%; padding: 20px 20px 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;">
<!--<![endif]-->
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:10px;font-family:'Lato',sans-serif;" align="left">
<div style="font-size: 14px; line-height: 140%; text-align: left; word-wrap: break-word;">
<p style="font-size: 14px; line-height: 140%;"><span style="font-size: 16px; line-height: 22.4px; color: #ecf0f1;">Contact</span></p>
<p style="font-size: 14px; line-height: 140%;"><span style="font-size: 14px; line-height: 19.6px; color: #ecf0f1;">1912 &nbsp;Mcwhorter Road, FL 11223</span></p>
<p style="font-size: 14px; line-height: 140%;"><span style="font-size: 14px; line-height: 19.6px; color: #ecf0f1;">+111 222 333 | info [@] marcoaiot.com</span></p>
</div>
</td>
</tr>
</tbody>
</table>
<!--[if (!mso)&(!IE)]><!-->
</div><!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="300" style="width: 300px;padding: 0px 0px 0px 20px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;" valign="top"><![endif]-->
<div class="u-col u-col-50" style="max-width: 320px;min-width: 300px;display: table-cell;vertical-align: top;">
<div style="height: 100%;width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="box-sizing: border-box; height: 100%; padding: 0px 0px 0px 20px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;">
<!--<![endif]-->
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:25px 10px 10px;font-family:'Lato',sans-serif;" align="left">
<div align="left" style="direction: ltr;">
<div style="display: table; max-width:187px;">
<!--[if (mso)|(IE)]><table width="187" cellpadding="0" cellspacing="0" border="0"><tr><td style="border-collapse:collapse;" align="left"><table width="100%" cellpadding="0" cellspacing="0" border="0" style="border-collapse:collapse; mso-table-lspace: 0pt;mso-table-rspace: 0pt; width:187px;"><tr><![endif]-->
<!--[if (mso)|(IE)]><td width="32" style="width:32px; padding-right: 15px;" valign="top"><![endif]-->
<table border="0" cellspacing="0" cellpadding="0" width="32" height="32" style="width: 32px !important;height: 32px !important;display: inline-block;border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;margin-right: 15px">
<tbody>
<tr style="vertical-align: top">
<td valign="middle" style="word-break: break-word;border-collapse: collapse !important;vertical-align: top">
<a href=" " title="Facebook" target="_blank">
<img src="https://cdn.tools.unlayer.com/social/icons/circle-white/facebook.png" alt="Facebook" title="Facebook" width="32" style="outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;clear: both;display: block !important;border: none;height: auto;float: none;max-width: 32px !important">
</a>
</td>
</tr>
</tbody>
</table>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]><td width="32" style="width:32px; padding-right: 15px;" valign="top"><![endif]-->
<table border="0" cellspacing="0" cellpadding="0" width="32" height="32" style="width: 32px !important;height: 32px !important;display: inline-block;border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;margin-right: 15px">
<tbody>
<tr style="vertical-align: top">
<td valign="middle" style="word-break: break-word;border-collapse: collapse !important;vertical-align: top">
<a href=" " title="Twitter" target="_blank">
<img src="https://cdn.tools.unlayer.com/social/icons/circle-white/twitter.png" alt="Twitter" title="Twitter" width="32" style="outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;clear: both;display: block !important;border: none;height: auto;float: none;max-width: 32px !important">
</a>
</td>
</tr>
</tbody>
</table>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]><td width="32" style="width:32px; padding-right: 15px;" valign="top"><![endif]-->
<table border="0" cellspacing="0" cellpadding="0" width="32" height="32" style="width: 32px !important;height: 32px !important;display: inline-block;border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;margin-right: 15px">
<tbody>
<tr style="vertical-align: top">
<td valign="middle" style="word-break: break-word;border-collapse: collapse !important;vertical-align: top">
<a href=" " title="Instagram" target="_blank">
<img src="https://cdn.tools.unlayer.com/social/icons/circle-white/instagram.png" alt="Instagram" title="Instagram" width="32" style="outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;clear: both;display: block !important;border: none;height: auto;float: none;max-width: 32px !important">
</a>
</td>
</tr>
</tbody>
</table>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]><td width="32" style="width:32px; padding-right: 0px;" valign="top"><![endif]-->
<table border="0" cellspacing="0" cellpadding="0" width="32" height="32" style="width: 32px !important;height: 32px !important;display: inline-block;border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;margin-right: 0px">
<tbody>
<tr style="vertical-align: top">
<td valign="middle" style="word-break: break-word;border-collapse: collapse !important;vertical-align: top">
<a href=" " title="LinkedIn" target="_blank">
<img src="https://cdn.tools.unlayer.com/social/icons/circle-white/linkedin.png" alt="LinkedIn" title="LinkedIn" width="32" style="outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;clear: both;display: block !important;border: none;height: auto;float: none;max-width: 32px !important">
</a>
</td>
</tr>
</tbody>
</table>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
</div>
</div>
</td>
</tr>
</tbody>
</table>
<!--<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:5px 10px 10px;font-family:'Lato',sans-serif;" align="left">
<div style="font-size: 14px; line-height: 140%; text-align: left; word-wrap: break-word;">
<p style="line-height: 140%; font-size: 14px;"><span style="font-size: 14px; line-height: 19.6px;"><span style="color: #ecf0f1; font-size: 14px; line-height: 19.6px;"><span style="line-height: 19.6px; font-size: 14px;">Marco AIoT Technologies Pvt. Ltd. &copy;&nbsp; All Rights Reserved</span></span></span></p>
</div>
</td>
</tr>
</tbody>
</table>-->
<!--[if (!mso)&(!IE)]><!-->
</div><!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<!--<div>Bottom Spacing - light red</div>-->
<div class="u-row-container" style="padding: 0px;background-color: #f9f9f9">
<div class="u-row" style="margin: 0 auto; min-width: 320px; max-width: 600px; overflow-wrap: break-word; word-wrap: break-word; word-break: break-word; background-color: #f46b61;">
<div style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: #f9f9f9;" align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:600px;"><tr style="background-color: #e93f32;"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="600" style="width: 600px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;" valign="top"><![endif]-->
<div class="u-col u-col-100" style="max-width: 320px;min-width: 600px;display: table-cell;vertical-align: top;">
<div style="height: 100%;width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;">
<!--<![endif]-->
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:15px;font-family:'Lato',sans-serif;" align="center">
<p style="line-height: 140%; font-size: 14px;"><span style="font-size: 14px; line-height: 19.6px;"><span style="color: #ecf0f1; font-size: 14px; line-height: 19.6px;"><span style="line-height: 19.6px; font-size: 14px;">Marco AIoT Technologies Pvt. Ltd. &copy;&nbsp; All Rights Reserved</span></span></span></p>
<!--<table align="center" border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;border-top: 1px solid #e93f32;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%">
<tbody>
<tr style="vertical-align: top">
<td style="word-break: break-word;border-collapse: collapse !important;vertical-align: top;mso-line-height-rule: exactly;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%">
</td>
</tr>
</tbody>
</table>-->
</td>
</tr>
</tbody>
</table>
<!--[if (!mso)&(!IE)]><!-->
</div><!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<div class="u-row-container" style="padding: 0px;background-color: transparent">
<div class="u-row" style="margin: 0 auto;min-width: 320px;max-width: 600px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: #f9f9f9;">
<div style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: transparent;" align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:600px;"><tr style="background-color: #f9f9f9;"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="600" style="width: 600px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;" valign="top"><![endif]-->
<div class="u-col u-col-100" style="max-width: 320px;min-width: 600px;display: table-cell;vertical-align: top;">
<div style="height: 100%;width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;">
<!--<![endif]-->
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:0px 40px 30px 20px;font-family:'Lato',sans-serif;" align="left">
<div style="font-size: 14px; line-height: 140%; text-align: left; word-wrap: break-word;">
<small style="color: #a5a3a3;"> You're receiving this email because you have a MarcoPMS account. This email is not a marketing or promotional email. That is why this email does not contain an unsubscribe link. You will receive this email even if you have unsubscribed from MarcoPMS's marketing emails</small>
</div>
</td>
</tr>
</tbody>
</table>
<!--[if (!mso)&(!IE)]><!-->
</div><!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<!--[if (mso)|(IE)]></td></tr></table><![endif]-->
</td>
</tr>
</tbody>
</table>
<!--[if mso]></div><![endif]-->
<!--[if IE]></div><![endif]-->
</body>
</html>

View File

@ -0,0 +1,565 @@

<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional //EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
<head>
<!--[if gte mso 9]>
<xml>
<o:OfficeDocumentSettings>
<o:AllowPNG/>
<o:PixelsPerInch>96</o:PixelsPerInch>
</o:OfficeDocumentSettings>
</xml>
<![endif]-->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="x-apple-disable-message-reformatting">
<!--[if !mso]><!-->
<meta http-equiv="X-UA-Compatible" content="IE=edge"><!--<![endif]-->
<title></title>
<style type="text/css">
@media only screen and (min-width: 620px) {
.u-row {
width: 600px !important;
}
.u-row .u-col {
vertical-align: top;
}
.u-row .u-col-50 {
width: 300px !important;
}
.u-row .u-col-100 {
width: 600px !important;
}
}
@media only screen and (max-width: 620px) {
.u-row-container {
max-width: 100% !important;
padding-left: 0px !important;
padding-right: 0px !important;
}
.u-row {
width: 100% !important;
}
.u-row .u-col {
display: block !important;
width: 100% !important;
min-width: 320px !important;
max-width: 100% !important;
}
.u-row .u-col > div {
margin: 0 auto;
}
.u-row .u-col img {
max-width: 100% !important;
}
}
body {
margin: 0;
padding: 0
}
table, td, tr {
border-collapse: collapse;
vertical-align: top
}
p {
margin: 0
}
.ie-container table, .mso-container table {
table-layout: fixed
}
* {
line-height: inherit
}
a[x-apple-data-detectors=true] {
color: inherit !important;
text-decoration: none !important
}
table, td {
color: #000000;
}
#u_body a {
color: #e93f32;
text-decoration: underline;
}
</style>
<!--[if !mso]><!-->
<link href="https://fonts.googleapis.com/css?family=Lato:400,700" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Lato:400,700" rel="stylesheet" type="text/css"><!--<![endif]-->
</head>
<body class="clean-body u_body" style="margin: 0;padding: 0;-webkit-text-size-adjust: 100%;background-color: #f9f9f9;color: #000000">
<!--[if IE]><div class="ie-container"><![endif]-->
<!--[if mso]><div class="mso-container"><![endif]-->
<table id="u_body" style="border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;min-width: 320px;Margin: 0 auto;background-color: #f9f9f9;width:100%" cellpadding="0" cellspacing="0">
<tbody>
<tr style="vertical-align: top">
<td style="word-break: break-word;border-collapse: collapse !important;vertical-align: top">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td align="center" style="background-color: #f9f9f9;"><![endif]-->
<!--<div>Top Spacing</div>-->
<div class="u-row-container" style="padding: 0px;background-color: #f9f9f9">
<div class="u-row" style="margin: 0 auto;min-width: 320px;max-width: 600px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: #f9f9f9;">
<div style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: #f9f9f9;" align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:600px;"><tr style="background-color: #f9f9f9;"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="600" style="width: 600px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;" valign="top"><![endif]-->
<div class="u-col u-col-100" style="max-width: 320px;min-width: 600px;display: table-cell;vertical-align: top;">
<div style="height: 100%;width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;">
<!--<![endif]-->
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:15px;font-family:'Lato',sans-serif;" align="left">
<table height="0px" align="center" border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;border-top: 1px solid #f9f9f9;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%">
<tbody>
<tr style="vertical-align: top">
<td style="word-break: break-word;border-collapse: collapse !important;vertical-align: top;font-size: 0px;line-height: 0px;mso-line-height-rule: exactly;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%">
Sita
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<!--[if (!mso)&(!IE)]><!-->
</div><!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<!--<div>Logo Block</div>-->
<div class="u-row-container" style="padding: 0px;background-color: transparent">
<div class="u-row" style="margin: 0 auto;min-width: 320px;max-width: 600px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: #ffffff;">
<div style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: transparent;" align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:600px;"><tr style="background-color: #ffffff;"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="600" style="width: 600px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;" valign="top"><![endif]-->
<div class="u-col u-col-100" style="max-width: 320px;min-width: 600px;display: table-cell;vertical-align: top;">
<div style="height: 100%;width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;">
<!--<![endif]-->
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:25px 10px;font-family:'Lato',sans-serif;" align="left">
<table width="100%" cellpadding="0" cellspacing="0" border="0">
<tr>
<td style="padding-right: 0px;padding-left: 0px;" align="center">
<img align="center" border="0" src="https://cdn.templates.unlayer.com/assets/1593141459339-Untitled-1.jpg" alt="Image" title="Image" style="outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;clear: both;display: inline-block !important;border: none;height: auto;float: none;width: 29%;max-width: 168.2px;" width="168.2" />
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
<!--[if (!mso)&(!IE)]><!-->
</div><!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<!--<div>Title Block</div>-->
<div class="u-row-container" style="padding: 0px;background-color: transparent">
<div class="u-row" style="margin: 0 auto; min-width: 320px; max-width: 600px; overflow-wrap: break-word; word-wrap: break-word; word-break: break-word; background-color: #f46b61;">
<div style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: transparent;" align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:600px;"><tr style="background-color: #e93f32;"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="600" style="width: 600px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;" valign="top"><![endif]-->
<div class="u-col u-col-100" style="max-width: 320px;min-width: 600px;display: table-cell;vertical-align: top;">
<div style="height: 100%;width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;">
<!--<![endif]-->
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:35px 10px 10px;font-family:'Lato',sans-serif;" align="left">
<table width="100%" cellpadding="0" cellspacing="0" border="0">
<tr>
<td style="padding-right: 0px;padding-left: 0px;" align="center">
<img align="center" border="0" src="https://cdn.templates.unlayer.com/assets/1593141680866-reset.png" alt="Image" title="Image" style="outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;clear: both;display: inline-block !important;border: none;height: auto;float: none;width: 10%;max-width: 58px;" width="58" />
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:0px 10px 30px;font-family:'Lato',sans-serif;" align="left">
<div style="font-size: 14px; line-height: 140%; text-align: left; word-wrap: break-word;">
<p style="font-size: 14px; line-height: 140%; text-align: center;"><span style="font-size: 28px; line-height: 39.2px; color: #ffffff; font-family: Lato, sans-serif;">Please reset your password </span></p>
</div>
</td>
</tr>
</tbody>
</table>
<!--[if (!mso)&(!IE)]><!-->
</div><!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<!--<div>Mail Body</div>-->
<div class="u-row-container" style="padding: 0px;background-color: transparent">
<div class="u-row" style="margin: 0 auto;min-width: 320px;max-width: 600px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: #ffffff;">
<div style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: transparent;" align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:600px;"><tr style="background-color: #ffffff;"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="600" style="width: 600px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;" valign="top"><![endif]-->
<div class="u-col u-col-100" style="max-width: 320px;min-width: 600px;display: table-cell;vertical-align: top;">
<div style="height: 100%;width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;">
<!--<![endif]-->
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:40px 40px 30px;font-family:'Lato',sans-serif;" align="left">
<div style="font-size: 14px; line-height: 140%; text-align: left; word-wrap: break-word;">
<p style="font-size: 14px; line-height: 140%;"><span style="font-size: 18px; line-height: 25.2px; color: #666666;">Hello,</span></p>
<p style="font-size: 14px; line-height: 140%;">&nbsp;</p>
<p style="font-size: 14px; line-height: 140%;"><span style="font-size: 18px; line-height: 25.2px; color: #666666;">We have sent you this email in response to your request to reset your password on MarcoPMS.</span></p>
<p style="font-size: 14px; line-height: 140%;">&nbsp;</p>
<p style="font-size: 14px; line-height: 140%;"><span style="font-size: 18px; line-height: 25.2px; color: #666666;">To reset your password, please follow the link below: </span></p>
</div>
</td>
</tr>
</tbody>
</table>
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:0px 40px;font-family:'Lato',sans-serif;" align="left">
<!--[if mso]><style>.v-button {background: transparent !important;}</style><![endif]-->
<div align="left">
<!--[if mso]><v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="" style="height:51px; v-text-anchor:middle; width:205px;" arcsize="2%" stroke="f" fillcolor="#e93f32"><w:anchorlock/><center style="color:#FFFFFF;"><![endif]-->
<a href="" target="_blank" class="v-button" style="box-sizing: border-box;display: inline-block;text-decoration: none;-webkit-text-size-adjust: none;text-align: center;color: #FFFFFF; background-color: #e93f32; border-radius: 1px;-webkit-border-radius: 1px; -moz-border-radius: 1px; width:auto; max-width:100%; overflow-wrap: break-word; word-break: break-word; word-wrap:break-word; mso-border-alt: none;font-size: 14px;">
<span style="display:block;padding:15px 40px;line-height:120%;"><span style="font-size: 18px; line-height: 21.6px;">Reset Password</span></span>
</a>
<!--[if mso]></center></v:roundrect><![endif]-->
</div>
</td>
</tr>
</tbody>
</table>
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:40px 40px 30px;font-family:'Lato',sans-serif;" align="left">
<div style="font-size: 14px; line-height: 140%; text-align: left; word-wrap: break-word;">
<p style="font-size: 14px; line-height: 140%;"><span style="color: #888888; font-size: 14px; line-height: 19.6px;"><em><span style="font-size: 16px; line-height: 22.4px;">Please ignore this email if you did not request a password change.</span></em></span><br /><span style="color: #888888; font-size: 14px; line-height: 19.6px;"><em><span style="font-size: 16px; line-height: 22.4px;">&nbsp;</span></em></span></p>
</div>
</td>
</tr>
</tbody>
</table>
<!--[if (!mso)&(!IE)]><!-->
</div><!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<!--<div>Contact</div>-->
<div class="u-row-container" style="padding: 0px;background-color: transparent">
<div class="u-row" style="margin: 0 auto;min-width: 320px;max-width: 600px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: #e93f32;">
<div style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: transparent;" align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:600px;"><tr style="background-color: #e93f32;"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="300" style="width: 300px;padding: 20px 20px 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;" valign="top"><![endif]-->
<div class="u-col u-col-50" style="max-width: 320px;min-width: 300px;display: table-cell;vertical-align: top;">
<div style="height: 100%;width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="box-sizing: border-box; height: 100%; padding: 20px 20px 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;">
<!--<![endif]-->
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:10px;font-family:'Lato',sans-serif;" align="left">
<div style="font-size: 14px; line-height: 140%; text-align: left; word-wrap: break-word;">
<p style="font-size: 14px; line-height: 140%;"><span style="font-size: 16px; line-height: 22.4px; color: #ecf0f1;">Contact</span></p>
<p style="font-size: 14px; line-height: 140%;"><span style="font-size: 14px; line-height: 19.6px; color: #ecf0f1;">1912 &nbsp;Mcwhorter Road, FL 11223</span></p>
<p style="font-size: 14px; line-height: 140%;"><span style="font-size: 14px; line-height: 19.6px; color: #ecf0f1;">+111 222 333 | info [@] marcoaiot.com</span></p>
</div>
</td>
</tr>
</tbody>
</table>
<!--[if (!mso)&(!IE)]><!-->
</div><!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="300" style="width: 300px;padding: 0px 0px 0px 20px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;" valign="top"><![endif]-->
<div class="u-col u-col-50" style="max-width: 320px;min-width: 300px;display: table-cell;vertical-align: top;">
<div style="height: 100%;width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="box-sizing: border-box; height: 100%; padding: 0px 0px 0px 20px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;">
<!--<![endif]-->
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:25px 10px 10px;font-family:'Lato',sans-serif;" align="left">
<div align="left" style="direction: ltr;">
<div style="display: table; max-width:187px;">
<!--[if (mso)|(IE)]><table width="187" cellpadding="0" cellspacing="0" border="0"><tr><td style="border-collapse:collapse;" align="left"><table width="100%" cellpadding="0" cellspacing="0" border="0" style="border-collapse:collapse; mso-table-lspace: 0pt;mso-table-rspace: 0pt; width:187px;"><tr><![endif]-->
<!--[if (mso)|(IE)]><td width="32" style="width:32px; padding-right: 15px;" valign="top"><![endif]-->
<table border="0" cellspacing="0" cellpadding="0" width="32" height="32" style="width: 32px !important;height: 32px !important;display: inline-block;border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;margin-right: 15px">
<tbody>
<tr style="vertical-align: top">
<td valign="middle" style="word-break: break-word;border-collapse: collapse !important;vertical-align: top">
<a href=" " title="Facebook" target="_blank">
<img src="https://cdn.tools.unlayer.com/social/icons/circle-white/facebook.png" alt="Facebook" title="Facebook" width="32" style="outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;clear: both;display: block !important;border: none;height: auto;float: none;max-width: 32px !important">
</a>
</td>
</tr>
</tbody>
</table>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]><td width="32" style="width:32px; padding-right: 15px;" valign="top"><![endif]-->
<table border="0" cellspacing="0" cellpadding="0" width="32" height="32" style="width: 32px !important;height: 32px !important;display: inline-block;border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;margin-right: 15px">
<tbody>
<tr style="vertical-align: top">
<td valign="middle" style="word-break: break-word;border-collapse: collapse !important;vertical-align: top">
<a href=" " title="Twitter" target="_blank">
<img src="https://cdn.tools.unlayer.com/social/icons/circle-white/twitter.png" alt="Twitter" title="Twitter" width="32" style="outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;clear: both;display: block !important;border: none;height: auto;float: none;max-width: 32px !important">
</a>
</td>
</tr>
</tbody>
</table>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]><td width="32" style="width:32px; padding-right: 15px;" valign="top"><![endif]-->
<table border="0" cellspacing="0" cellpadding="0" width="32" height="32" style="width: 32px !important;height: 32px !important;display: inline-block;border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;margin-right: 15px">
<tbody>
<tr style="vertical-align: top">
<td valign="middle" style="word-break: break-word;border-collapse: collapse !important;vertical-align: top">
<a href=" " title="Instagram" target="_blank">
<img src="https://cdn.tools.unlayer.com/social/icons/circle-white/instagram.png" alt="Instagram" title="Instagram" width="32" style="outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;clear: both;display: block !important;border: none;height: auto;float: none;max-width: 32px !important">
</a>
</td>
</tr>
</tbody>
</table>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]><td width="32" style="width:32px; padding-right: 0px;" valign="top"><![endif]-->
<table border="0" cellspacing="0" cellpadding="0" width="32" height="32" style="width: 32px !important;height: 32px !important;display: inline-block;border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;margin-right: 0px">
<tbody>
<tr style="vertical-align: top">
<td valign="middle" style="word-break: break-word;border-collapse: collapse !important;vertical-align: top">
<a href=" " title="LinkedIn" target="_blank">
<img src="https://cdn.tools.unlayer.com/social/icons/circle-white/linkedin.png" alt="LinkedIn" title="LinkedIn" width="32" style="outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;clear: both;display: block !important;border: none;height: auto;float: none;max-width: 32px !important">
</a>
</td>
</tr>
</tbody>
</table>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
</div>
</div>
</td>
</tr>
</tbody>
</table>
<!--<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:5px 10px 10px;font-family:'Lato',sans-serif;" align="left">
<div style="font-size: 14px; line-height: 140%; text-align: left; word-wrap: break-word;">
<p style="line-height: 140%; font-size: 14px;"><span style="font-size: 14px; line-height: 19.6px;"><span style="color: #ecf0f1; font-size: 14px; line-height: 19.6px;"><span style="line-height: 19.6px; font-size: 14px;">Marco AIoT Technologies Pvt. Ltd. &copy;&nbsp; All Rights Reserved</span></span></span></p>
</div>
</td>
</tr>
</tbody>
</table>-->
<!--[if (!mso)&(!IE)]><!-->
</div><!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<!--<div>Bottom Spacing - light red</div>-->
<div class="u-row-container" style="padding: 0px;background-color: #f9f9f9">
<div class="u-row" style="margin: 0 auto; min-width: 320px; max-width: 600px; overflow-wrap: break-word; word-wrap: break-word; word-break: break-word; background-color: #f46b61;">
<div style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: #f9f9f9;" align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:600px;"><tr style="background-color: #e93f32;"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="600" style="width: 600px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;" valign="top"><![endif]-->
<div class="u-col u-col-100" style="max-width: 320px;min-width: 600px;display: table-cell;vertical-align: top;">
<div style="height: 100%;width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;">
<!--<![endif]-->
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:15px;font-family:'Lato',sans-serif;" align="center">
<p style="line-height: 140%; font-size: 14px;"><span style="font-size: 14px; line-height: 19.6px;"><span style="color: #ecf0f1; font-size: 14px; line-height: 19.6px;"><span style="line-height: 19.6px; font-size: 14px;">Marco AIoT Technologies Pvt. Ltd. &copy;&nbsp; All Rights Reserved</span></span></span></p>
<!--<table align="center" border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;border-top: 1px solid #e93f32;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%">
<tbody>
<tr style="vertical-align: top">
<td style="word-break: break-word;border-collapse: collapse !important;vertical-align: top;mso-line-height-rule: exactly;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%">
</td>
</tr>
</tbody>
</table>-->
</td>
</tr>
</tbody>
</table>
<!--[if (!mso)&(!IE)]><!-->
</div><!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<div class="u-row-container" style="padding: 0px;background-color: transparent">
<div class="u-row" style="margin: 0 auto;min-width: 320px;max-width: 600px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: #f9f9f9;">
<div style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: transparent;" align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:600px;"><tr style="background-color: #f9f9f9;"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="600" style="width: 600px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;" valign="top"><![endif]-->
<div class="u-col u-col-100" style="max-width: 320px;min-width: 600px;display: table-cell;vertical-align: top;">
<div style="height: 100%;width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;">
<!--<![endif]-->
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:0px 40px 30px 20px;font-family:'Lato',sans-serif;" align="left">
<div style="font-size: 14px; line-height: 140%; text-align: left; word-wrap: break-word;">
<small style="color: #a5a3a3;"> You're receiving this email because you have a MarcoPMS account. This email is not a marketing or promotional email. That is why this email does not contain an unsubscribe link. You will receive this email even if you have unsubscribed from MarcoPMS's marketing emails</small>
</div>
</td>
</tr>
</tbody>
</table>
<!--[if (!mso)&(!IE)]><!-->
</div><!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<!--[if (mso)|(IE)]></td></tr></table><![endif]-->
</td>
</tr>
</tbody>
</table>
<!--[if mso]></div><![endif]-->
<!--[if IE]></div><![endif]-->
</body>
</html>

View File

@ -0,0 +1,564 @@

<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional //EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
<head>
<!--[if gte mso 9]>
<xml>
<o:OfficeDocumentSettings>
<o:AllowPNG/>
<o:PixelsPerInch>96</o:PixelsPerInch>
</o:OfficeDocumentSettings>
</xml>
<![endif]-->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="x-apple-disable-message-reformatting" />
<!--[if !mso]><!-->
<meta http-equiv="X-UA-Compatible" content="IE=edge" /><!--<![endif]-->
<title></title>
<style type="text/css">
@media only screen and (min-width: 620px) {
.u-row {
width: 600px !important;
}
.u-row .u-col {
vertical-align: top;
}
.u-row .u-col-50 {
width: 300px !important;
}
.u-row .u-col-100 {
width: 600px !important;
}
}
@media only screen and (max-width: 620px) {
.u-row-container {
max-width: 100% !important;
padding-left: 0px !important;
padding-right: 0px !important;
}
.u-row {
width: 100% !important;
}
.u-row .u-col {
display: block !important;
width: 100% !important;
min-width: 320px !important;
max-width: 100% !important;
}
.u-row .u-col > div {
margin: 0 auto;
}
.u-row .u-col img {
max-width: 100% !important;
}
}
body {
margin: 0;
padding: 0
}
table, td, tr {
border-collapse: collapse;
vertical-align: top
}
p {
margin: 0
}
.ie-container table, .mso-container table {
table-layout: fixed
}
* {
line-height: inherit
}
a[x-apple-data-detectors=true] {
color: inherit !important;
text-decoration: none !important
}
table, td {
color: #000000;
}
#u_body a {
color: #e93f32;
text-decoration: underline;
}
</style>
<!--[if !mso]><!-->
<link href="https://fonts.googleapis.com/css?family=Lato:400,700" rel="stylesheet" type="text/css" />
<link href="https://fonts.googleapis.com/css?family=Lato:400,700" rel="stylesheet" type="text/css" /><!--<![endif]-->
</head>
<body class="clean-body u_body" style="margin: 0;padding: 0;-webkit-text-size-adjust: 100%;background-color: #f9f9f9;color: #000000">
<!--[if IE]><div class="ie-container"><![endif]-->
<!--[if mso]><div class="mso-container"><![endif]-->
<table id="u_body" style="border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;min-width: 320px;Margin: 0 auto;background-color: #f9f9f9;width:100%" cellpadding="0" cellspacing="0">
<tbody>
<tr style="vertical-align: top">
<td style="word-break: break-word;border-collapse: collapse !important;vertical-align: top">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td align="center" style="background-color: #f9f9f9;"><![endif]-->
<!--<div>Top Spacing</div>-->
<div class="u-row-container" style="padding: 0px;background-color: #f9f9f9">
<div class="u-row" style="margin: 0 auto;min-width: 320px;max-width: 600px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: #f9f9f9;">
<div style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: #f9f9f9;" align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:600px;"><tr style="background-color: #f9f9f9;"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="600" style="width: 600px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;" valign="top"><![endif]-->
<div class="u-col u-col-100" style="max-width: 320px;min-width: 600px;display: table-cell;vertical-align: top;">
<div style="height: 100%;width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;">
<!--<![endif]-->
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:15px;font-family:'Lato',sans-serif;" align="left">
<table height="0px" align="center" border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;border-top: 1px solid #f9f9f9;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%">
<tbody>
<tr style="vertical-align: top">
<td style="word-break: break-word;border-collapse: collapse !important;vertical-align: top;font-size: 0px;line-height: 0px;mso-line-height-rule: exactly;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%">
Sita
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<!--[if (!mso)&(!IE)]><!-->
</div><!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<!--<div>Logo Block</div>-->
<div class="u-row-container" style="padding: 0px;background-color: transparent">
<div class="u-row" style="margin: 0 auto;min-width: 320px;max-width: 600px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: #ffffff;">
<div style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: transparent;" align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:600px;"><tr style="background-color: #ffffff;"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="600" style="width: 600px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;" valign="top"><![endif]-->
<div class="u-col u-col-100" style="max-width: 320px;min-width: 600px;display: table-cell;vertical-align: top;">
<div style="height: 100%;width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;">
<!--<![endif]-->
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:25px 10px;font-family:'Lato',sans-serif;" align="left">
<table width="100%" cellpadding="0" cellspacing="0" border="0">
<tr>
<td style="padding-right: 0px;padding-left: 0px;" align="center">
<img align="center" border="0" src="http://localhost:5032/logos/marco-aiot-tech-logo.jpg" alt="Image" title="Image" style="outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;clear: both;display: inline-block !important;border: none;height: auto;float: none;width: 29%;max-width: 168.2px;" width="168.2" />
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
<!--[if (!mso)&(!IE)]><!-->
</div><!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<!--<div>Title Block</div>-->
<div class="u-row-container" style="padding: 0px;background-color: transparent">
<div class="u-row" style="margin: 0 auto; min-width: 320px; max-width: 600px; overflow-wrap: break-word; word-wrap: break-word; word-break: break-word; background-color: #f46b61;">
<div style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: transparent;" align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:600px;"><tr style="background-color: #e93f32;"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="600" style="width: 600px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;" valign="top"><![endif]-->
<div class="u-col u-col-100" style="max-width: 320px;min-width: 600px;display: table-cell;vertical-align: top;">
<div style="height: 100%;width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;">
<!--<![endif]-->
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:35px 10px 10px;font-family:'Lato',sans-serif;" align="left">
<table width="100%" cellpadding="0" cellspacing="0" border="0">
<tr>
<td style="padding-right: 0px;padding-left: 0px;" align="center">
<img align="center" border="0" src="https://cdn.templates.unlayer.com/assets/1593141680866-reset.png" alt="Image" title="Image" style="outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;clear: both;display: inline-block !important;border: none;height: auto;float: none;width: 10%;max-width: 58px;" width="58" />
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:0px 10px 30px;font-family:'Lato',sans-serif;" align="left">
<div style="font-size: 14px; line-height: 140%; text-align: left; word-wrap: break-word;">
<p style="font-size: 14px; line-height: 140%; text-align: center;"><span style="font-size: 28px; line-height: 39.2px; color: #ffffff; font-family: Lato, sans-serif;">{{MAIL_TITLE}} </span></p>
</div>
</td>
</tr>
</tbody>
</table>
<!--[if (!mso)&(!IE)]><!-->
</div><!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<!--<div>Mail Body</div>-->
<div class="u-row-container" style="padding: 0px;background-color: transparent">
<div class="u-row" style="margin: 0 auto;min-width: 320px;max-width: 600px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: #ffffff;">
<div style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: transparent;" align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:600px;"><tr style="background-color: #ffffff;"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="600" style="width: 600px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;" valign="top"><![endif]-->
<div class="u-col u-col-100" style="max-width: 320px;min-width: 600px;display: table-cell;vertical-align: top;">
<div style="height: 100%;width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;">
<!--<![endif]-->
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:40px 40px 30px;font-family:'Lato',sans-serif;" align="left">
<div style="font-size: 14px; line-height: 140%; text-align: left; word-wrap: break-word;">
<p style="font-size: 14px; line-height: 140%;"><span style="font-size: 14px; line-height: 25.2px; color: #666666;">Hello {{RECEIVER_NAME}},</span></p>
<p style="font-size: 14px; line-height: 140%;">&nbsp;</p>
<p style="font-size: 14px; line-height: 140%;"><span style="font-size: 14px; line-height: 25.2px; color: #666666;">Welcome, You've joined your teammates on MarcoPMS. We have sent you this email to set your password on MarcoPMS.</span></p>
<p style="font-size: 14px; line-height: 140%;">&nbsp;</p>
<p style="font-size: 14px; line-height: 140%;"><span style="font-size: 14px; line-height: 25.2px; color: #666666;">To set your password, please follow the link below: </span></p>
</div>
</td>
</tr>
</tbody>
</table>
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:0px 40px;font-family:'Lato',sans-serif;" align="left">
<!--[if mso]><style>.v-button {background: transparent !important;}</style><![endif]-->
<div align="left">
<!--[if mso]><v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="" style="height:51px; v-text-anchor:middle; width:205px;" arcsize="2%" stroke="f" fillcolor="#e93f32"><w:anchorlock/><center style="color:#FFFFFF;"><![endif]-->
<a href="{{RESET_PWD_URL}}" target="_blank" class="v-button" style="box-sizing: border-box;display: inline-block;text-decoration: none;-webkit-text-size-adjust: none;text-align: center;color: #FFFFFF; background-color: #e93f32; border-radius: 1px;-webkit-border-radius: 1px; -moz-border-radius: 1px; width:auto; max-width:100%; overflow-wrap: break-word; word-break: break-word; word-wrap:break-word; mso-border-alt: none;font-size: 14px;">
<span style="display:block;padding:15px 40px;line-height:120%;"><span style="font-size: 18px; line-height: 21.6px;">Set Password</span></span>
</a>
<!--[if mso]></center></v:roundrect><![endif]-->
</div>
</td>
</tr>
</tbody>
</table>
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:40px 40px 30px;font-family:'Lato',sans-serif;" align="left">
<div style="font-size: 14px; line-height: 140%; text-align: left; word-wrap: break-word;">
<p style="font-size: 14px; line-height: 140%;"><span style="color: #888888; font-size: 14px; line-height: 19.6px;"><em><span style="font-size: 14px; line-height: 22.4px;">Please ignore this email if you did not request a password change.</span></em></span><br /><span style="color: #888888; font-size: 14px; line-height: 19.6px;"><em><span style="font-size: 16px; line-height: 22.4px;">&nbsp;</span></em></span></p>
</div>
</td>
</tr>
</tbody>
</table>
<!--[if (!mso)&(!IE)]><!-->
</div><!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<!--<div>Contact</div>-->
<div class="u-row-container" style="padding: 0px;background-color: transparent">
<div class="u-row" style="margin: 0 auto;min-width: 320px;max-width: 600px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: #e93f32;">
<div style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: transparent;" align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:600px;"><tr style="background-color: #e93f32;"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="300" style="width: 300px;padding: 20px 20px 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;" valign="top"><![endif]-->
<div class="u-col u-col-50" style="max-width: 320px;min-width: 300px;display: table-cell;vertical-align: top;">
<div style="height: 100%;width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="box-sizing: border-box; height: 100%; padding: 20px 20px 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;">
<!--<![endif]-->
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:10px;font-family:'Lato',sans-serif;" align="left">
<div style="font-size: 14px; line-height: 140%; text-align: left; word-wrap: break-word;">
<p style="font-size: 14px; line-height: 140%;"><span style="font-size: 16px; line-height: 22.4px; color: #ecf0f1;">Contact</span></p>
<p style="font-size: 14px; line-height: 140%;"><span style="font-size: 14px; line-height: 19.6px; color: #ecf0f1;">1912 &nbsp;Mcwhorter Road, FL 11223</span></p>
<p style="font-size: 14px; line-height: 140%;"><span style="font-size: 14px; line-height: 19.6px; color: #ecf0f1;">+111 222 333 | info [@] marcoaiot.com</span></p>
</div>
</td>
</tr>
</tbody>
</table>
<!--[if (!mso)&(!IE)]><!-->
</div><!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="300" style="width: 300px;padding: 0px 0px 0px 20px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;" valign="top"><![endif]-->
<div class="u-col u-col-50" style="max-width: 320px;min-width: 300px;display: table-cell;vertical-align: top;">
<div style="height: 100%;width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="box-sizing: border-box; height: 100%; padding: 0px 0px 0px 20px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;">
<!--<![endif]-->
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:25px 10px 10px;font-family:'Lato',sans-serif;" align="left">
<div align="left" style="direction: ltr;">
<div style="display: table; max-width:187px;">
<!--[if (mso)|(IE)]><table width="187" cellpadding="0" cellspacing="0" border="0"><tr><td style="border-collapse:collapse;" align="left"><table width="100%" cellpadding="0" cellspacing="0" border="0" style="border-collapse:collapse; mso-table-lspace: 0pt;mso-table-rspace: 0pt; width:187px;"><tr><![endif]-->
<!--[if (mso)|(IE)]><td width="32" style="width:32px; padding-right: 15px;" valign="top"><![endif]-->
<table border="0" cellspacing="0" cellpadding="0" width="32" height="32" style="width: 32px !important;height: 32px !important;display: inline-block;border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;margin-right: 15px">
<tbody>
<tr style="vertical-align: top">
<td valign="middle" style="word-break: break-word;border-collapse: collapse !important;vertical-align: top">
<a href=" " title="Facebook" target="_blank">
<img src="https://cdn.tools.unlayer.com/social/icons/circle-white/facebook.png" alt="Facebook" title="Facebook" width="32" style="outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;clear: both;display: block !important;border: none;height: auto;float: none;max-width: 32px !important" />
</a>
</td>
</tr>
</tbody>
</table>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]><td width="32" style="width:32px; padding-right: 15px;" valign="top"><![endif]-->
<table border="0" cellspacing="0" cellpadding="0" width="32" height="32" style="width: 32px !important;height: 32px !important;display: inline-block;border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;margin-right: 15px">
<tbody>
<tr style="vertical-align: top">
<td valign="middle" style="word-break: break-word;border-collapse: collapse !important;vertical-align: top">
<a href=" " title="Twitter" target="_blank">
<img src="https://cdn.tools.unlayer.com/social/icons/circle-white/twitter.png" alt="Twitter" title="Twitter" width="32" style="outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;clear: both;display: block !important;border: none;height: auto;float: none;max-width: 32px !important" />
</a>
</td>
</tr>
</tbody>
</table>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]><td width="32" style="width:32px; padding-right: 15px;" valign="top"><![endif]-->
<table border="0" cellspacing="0" cellpadding="0" width="32" height="32" style="width: 32px !important;height: 32px !important;display: inline-block;border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;margin-right: 15px">
<tbody>
<tr style="vertical-align: top">
<td valign="middle" style="word-break: break-word;border-collapse: collapse !important;vertical-align: top">
<a href=" " title="Instagram" target="_blank">
<img src="https://cdn.tools.unlayer.com/social/icons/circle-white/instagram.png" alt="Instagram" title="Instagram" width="32" style="outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;clear: both;display: block !important;border: none;height: auto;float: none;max-width: 32px !important" />
</a>
</td>
</tr>
</tbody>
</table>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]><td width="32" style="width:32px; padding-right: 0px;" valign="top"><![endif]-->
<table border="0" cellspacing="0" cellpadding="0" width="32" height="32" style="width: 32px !important;height: 32px !important;display: inline-block;border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;margin-right: 0px">
<tbody>
<tr style="vertical-align: top">
<td valign="middle" style="word-break: break-word;border-collapse: collapse !important;vertical-align: top">
<a href=" " title="LinkedIn" target="_blank">
<img src="https://cdn.tools.unlayer.com/social/icons/circle-white/linkedin.png" alt="LinkedIn" title="LinkedIn" width="32" style="outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;clear: both;display: block !important;border: none;height: auto;float: none;max-width: 32px !important" />
</a>
</td>
</tr>
</tbody>
</table>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
</div>
</div>
</td>
</tr>
</tbody>
</table>
<!--<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:5px 10px 10px;font-family:'Lato',sans-serif;" align="left">
<div style="font-size: 14px; line-height: 140%; text-align: left; word-wrap: break-word;">
<p style="line-height: 140%; font-size: 14px;"><span style="font-size: 14px; line-height: 19.6px;"><span style="color: #ecf0f1; font-size: 14px; line-height: 19.6px;"><span style="line-height: 19.6px; font-size: 14px;">Marco AIoT Technologies Pvt. Ltd. &copy;&nbsp; All Rights Reserved</span></span></span></p>
</div>
</td>
</tr>
</tbody>
</table>-->
<!--[if (!mso)&(!IE)]><!-->
</div><!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<!--<div>Bottom Spacing - light red</div>-->
<div class="u-row-container" style="padding: 0px;background-color: #f9f9f9">
<div class="u-row" style="margin: 0 auto; min-width: 320px; max-width: 600px; overflow-wrap: break-word; word-wrap: break-word; word-break: break-word; background-color: #f46b61;">
<div style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: #f9f9f9;" align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:600px;"><tr style="background-color: #e93f32;"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="600" style="width: 600px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;" valign="top"><![endif]-->
<div class="u-col u-col-100" style="max-width: 320px;min-width: 600px;display: table-cell;vertical-align: top;">
<div style="height: 100%;width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;">
<!--<![endif]-->
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:15px;font-family:'Lato',sans-serif;" align="center">
<p style="line-height: 140%; font-size: 14px;"><span style="font-size: 14px; line-height: 19.6px;"><span style="color: #ecf0f1; font-size: 14px; line-height: 19.6px;"><span style="line-height: 19.6px; font-size: 14px;">Marco AIoT Technologies Pvt. Ltd. &copy;&nbsp; All Rights Reserved</span></span></span></p>
<!--<table align="center" border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;border-top: 1px solid #e93f32;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%">
<tbody>
<tr style="vertical-align: top">
<td style="word-break: break-word;border-collapse: collapse !important;vertical-align: top;mso-line-height-rule: exactly;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%">
</td>
</tr>
</tbody>
</table>-->
</td>
</tr>
</tbody>
</table>
<!--[if (!mso)&(!IE)]><!-->
</div><!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<div class="u-row-container" style="padding: 0px;background-color: transparent">
<div class="u-row" style="margin: 0 auto;min-width: 320px;max-width: 600px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: #f9f9f9;">
<div style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding: 0px;background-color: transparent;" align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:600px;"><tr style="background-color: #f9f9f9;"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="600" style="width: 600px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;" valign="top"><![endif]-->
<div class="u-col u-col-100" style="max-width: 320px;min-width: 600px;display: table-cell;vertical-align: top;">
<div style="height: 100%;width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;">
<!--<![endif]-->
<table style="font-family:'Lato',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:0px 40px 30px 20px;font-family:'Lato',sans-serif;" align="left">
<div style="font-size: 14px; line-height: 140%; text-align: left; word-wrap: break-word;">
<small style="color: #a5a3a3;"> You're receiving this email because you have a MarcoPMS account. This email is not a marketing or promotional email. That is why this email does not contain an unsubscribe link. You will receive this email even if you have unsubscribed from MarcoPMS's marketing emails</small>
</div>
</td>
</tr>
</tbody>
</table>
<!--[if (!mso)&(!IE)]><!-->
</div><!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td><![endif]-->
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<!--[if (mso)|(IE)]></td></tr></table><![endif]-->
</td>
</tr>
</tbody>
</table>
<!--[if mso]></div><![endif]-->
<!--[if IE]></div><![endif]-->
</body>
</html>

View File

@ -1,20 +1,101 @@
using Marco.Pms.DataAccess.Data;

using Marco.Pms.DataAccess.Data;
using Marco.Pms.Model.Employees;
using Marco.Pms.Model.Mapper;
using Marco.Pms.Model.ViewModels.Employee;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Runtime.Intrinsics.Arm;
namespace MarcoBMS.Services.Helpers
{
public class EmployeeHelper
{
private readonly ApplicationDbContext _context;
public EmployeeHelper(ApplicationDbContext context) {
public EmployeeHelper(ApplicationDbContext context)
{
_context = context;
}
public async Task<Employee> GetEmployeeByID(int EmployeeID)
{
return await _context.Employees.FindAsync(EmployeeID);
}
public async Task<Employee> GetEmployeeByApplicationUserID(string ApplicationUserID)
{
try
{
var result = await _context.Employees.Where(c => c.ApplicationUserId == ApplicationUserID).ToListAsync();
return await _context.Employees.Where(c => c.ApplicationUserId == ApplicationUserID).SingleOrDefaultAsync();
}
catch (Exception ex)
{
return null;
}
}
public async Task<List<EmployeeVM>> SearchEmployeeByProjectId(int TenentId, string searchString, int? ProjectId)
{
try
{
List<EmployeeVM> result = new List<EmployeeVM>();
if (ProjectId != null)
{
result = await (from pa in _context.ProjectAllocations.Where(c => c.ProjectId == ProjectId)
join em in _context.Employees.Where(c => c.TenantId == TenentId).Include(fp => fp.JobRole) // Include Feature
on pa.EmployeeId equals em.Id
where em.FirstName.ToLower().Contains(searchString.ToLower()) || em.LastName.ToLower().Contains(searchString.ToLower())
select em.ToEmployeeVMFromEmployee()
)
.ToListAsync();
}
else
{
result = await _context.Employees.Where(c => c.TenantId == TenentId &&
(c.FirstName.ToLower().Contains(searchString.ToLower()) || c.LastName.ToLower().Contains(searchString.ToLower()))).Include(fp => fp.JobRole)
.Select(c => c.ToEmployeeVMFromEmployee()).ToListAsync();
}
return result;
}
catch (Exception ex)
{
return new List<EmployeeVM>();
}
}
public async Task<List<EmployeeVM>> GetEmployeeByProjectId(int TenentId, int? ProjectId)
{
try
{
List<EmployeeVM> result = new List<EmployeeVM>();
if (ProjectId != null)
{
result = await (from pa in _context.ProjectAllocations.Where(c => c.ProjectId == ProjectId)
join em in _context.Employees.Where(c => c.TenantId == TenentId).Include(fp => fp.JobRole) // Include Feature
on pa.EmployeeId equals em.Id
select em.ToEmployeeVMFromEmployee()
)
.ToListAsync();
}
else
{
result = await _context.Employees.Where(c => c.TenantId == TenentId).Include(fp => fp.JobRole)
.Select(c => c.ToEmployeeVMFromEmployee()).ToListAsync();
}
return result;
}
catch (Exception ex)
{
return new List<EmployeeVM>();
}
}
}
}

View File

@ -4,7 +4,7 @@ using Microsoft.CodeAnalysis;
using Microsoft.EntityFrameworkCore;
namespace MarcoBMS.Services.Helpers
namespace ModelServices.Helpers
{
public class ProjectHelper
{

View File

@ -0,0 +1,48 @@
using Marco.Pms.DataAccess.Data;
using Marco.Pms.Model.Projects;
using Microsoft.EntityFrameworkCore;
namespace MarcoBMS.Services.Helpers
{
public class ProjectsHelper
{
private readonly ApplicationDbContext _context;
public ProjectsHelper(ApplicationDbContext context)
{
_context = context;
}
public async Task<List<Project>> GetAllProjectByTanentID(int tanentID)
{
List<Project> alloc = await _context.Projects.Where(c => c.TenantId == tanentID).ToListAsync();
return alloc;
}
public async Task<List<ProjectAllocation>> GetProjectByEmployeeID(int employeeID)
{
List<ProjectAllocation> alloc = await _context.ProjectAllocations.Where(c => c.EmployeeId ==employeeID && c.IsActive == true).Include(c=>c.Project).ToListAsync();
return alloc;
}
public async Task<List<ProjectAllocation>> GetTeamByProject(int TenantId, int ProjectId, bool IncludeInactive)
{
if (IncludeInactive)
{
var employees = await _context.ProjectAllocations.Where(c => c.TenantId == TenantId && c.ProjectId == ProjectId).Include(e => e.Employee).ToListAsync();
return employees;
}
else
{
var employees = await _context.ProjectAllocations.Where(c => c.TenantId == TenantId && c.ProjectId == ProjectId && c.IsActive == true).Include(e => e.Employee).ToListAsync();
return employees;
}
}
}
}

View File

@ -0,0 +1,53 @@

using Marco.Pms.DataAccess.Data;
using Marco.Pms.Model.Entitlements;
using Microsoft.EntityFrameworkCore;
namespace MarcoBMS.Services.Helpers
{
public class RolesHelper
{
private readonly ApplicationDbContext _context;
public RolesHelper(ApplicationDbContext context)
{
_context = context;
}
public async Task<List<FeaturePermission>> GetFeaturePermissionByEmployeeID(int EmployeeID)
{
List<Guid> roleMappings = await _context.EmployeeRoleMappings.Where(c => c.EmployeeId ==EmployeeID && c.IsEnabled == true).Select(c=>c.RoleId).ToListAsync();
// _context.RolePermissionMappings
var result = await (from rpm in _context.RolePermissionMappings
join fp in _context.FeaturePermissions.Where(c=>c.IsEnabled == true).Include(fp => fp.Feature) // Include Feature
on rpm.FeaturePermissionId equals fp.Id
where roleMappings.Contains(rpm.ApplicationRoleId)
select fp)
.ToListAsync();
return result;
// return null;
}
public async Task<List<FeaturePermission>> GetFeaturePermissionByRoleID(Guid roleId)
{
List<Guid> roleMappings = await _context.RolePermissionMappings.Where(c => c.ApplicationRoleId == roleId ).Select(c => c.ApplicationRoleId).ToListAsync();
// _context.RolePermissionMappings
var result = await (from rpm in _context.RolePermissionMappings.Where(c=>c.ApplicationRoleId == roleId)
join fp in _context.FeaturePermissions.Where(c => c.IsEnabled == true).Include(fp => fp.Feature) // Include Feature
on rpm.FeaturePermissionId equals fp.Id
select fp)
.ToListAsync();
return result;
// return null;
}
}
}

View File

@ -0,0 +1,63 @@
using Marco.Pms.Model.Dtos.Employees;
using Marco.Pms.Model.Entitlements;
using Microsoft.AspNetCore.Identity;
using System.Security.Claims;
namespace MarcoBMS.Services.Helpers
{
public class UserHelper
{
private readonly UserManager<IdentityUser> _userManager;
private readonly IHttpContextAccessor _httpContextAccessor;
public UserHelper(UserManager<IdentityUser> userManager, IHttpContextAccessor httpContextAccessor)
{
_userManager = userManager;
_httpContextAccessor = httpContextAccessor;
}
public int GetTenantId()
{
var tenant = _httpContextAccessor.HttpContext?.User.FindFirst("TenantId")?.Value;
return (tenant != null ? Convert.ToInt32(tenant) : 1);
}
public async Task<IdentityUser?> GetCurrentUserAsync()
{
var userId = _httpContextAccessor.HttpContext?.User.FindFirstValue(ClaimTypes.NameIdentifier);
if (string.IsNullOrEmpty(userId))
return null;
var user = await _userManager.FindByEmailAsync(userId);
return user; //await _userManager.FindByIdAsync(userId);
}
public async Task<object?> GetCurrentUserProfileAsync()
{
var user = await GetCurrentUserAsync();
return user == null ? null : new
{
user.Id,
user.UserName,
user.Email,
user.PhoneNumber
};
}
public async Task<IdentityUser?> GetRegisteredUser(string email)
{
//IdentityUser? user = await _userManager.Users
// .FirstOrDefaultAsync(u => u.Email == model.Email || u.PhoneNumber == model.PhoneNumber);
IdentityUser? user = await _userManager.FindByEmailAsync(email);
//if (user == null)
//{
// user = await _userManager.Find(model.Email);
//}
return user;
}
}
}

View File

@ -29,6 +29,9 @@
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="9.0.0" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.2" />
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
<PackageReference Include="Serilog.Sinks.Async" Version="2.1.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
<PackageReference Include="Serilog.Sinks.MongoDB" Version="7.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
</ItemGroup>

View File

@ -0,0 +1,64 @@
using MarcoBMS.Services.Helpers;
using MarcoBMS.Services.Service;
using Serilog.Context;
using System.Diagnostics;
namespace MarcoBMS.Services.Middleware
{
public class LoggingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<LoggingMiddleware> _logger;
private readonly ILoggingService _loggingService;
//private readonly UserHelper _userHelper;
public LoggingMiddleware(RequestDelegate next, ILogger<LoggingMiddleware> logger, ILoggingService loggingService)
{
_next = next;
_logger = logger;
//_userHelper = userHelper;
_loggingService = loggingService;
}
public async Task Invoke(HttpContext context)
{
var stopwatch = Stopwatch.StartNew();
var response = context.Response;
var request = context.Request;
var tenant = context.User.FindFirst("TenantId")?.Value;
int tenantId = (tenant != null ? Convert.ToInt32(tenant) : 1);
using (LogContext.PushProperty("TenantId", tenantId))
using (LogContext.PushProperty("TraceId", context.TraceIdentifier))
using (LogContext.PushProperty("UserAgent", request.Headers["User-Agent"].ToString()))
using (LogContext.PushProperty("HttpMethod", request.Method))
using (LogContext.PushProperty("Timestamp", DateTime.UtcNow))
using (LogContext.PushProperty("IpAddress", context.Connection.RemoteIpAddress?.ToString()))
using (LogContext.PushProperty("RequestPath", request.Path))
try
{
await _next(context);
stopwatch.Stop();
using (LogContext.PushProperty("StatusCode", response.StatusCode.ToString()))
using (LogContext.PushProperty("ResponseTimeMs", stopwatch.ElapsedMilliseconds))
using (LogContext.PushProperty("LogLevel", "Information"))
_logger.LogInformation("HTTP {method} {path} responded {statusCode} in {timeTaken} ms", request.Method,request.Path, response.StatusCode.ToString(),stopwatch.ElapsedMilliseconds);
}
catch (Exception ex)
{
stopwatch.Stop();
using (LogContext.PushProperty("Error", ex))
using (LogContext.PushProperty("StatusCode", "500"))
using (LogContext.PushProperty("ResponseTimeMs", stopwatch.ElapsedMilliseconds))
using (LogContext.PushProperty("LogLevel", "Error"))
_logger.LogError("API Error{error}", ex.Message);
throw;
}
}
}
}

View File

@ -1,7 +1,4 @@
using BulkyBook.DataAccess.Repository;
using Marco.Pms.DataAccess.Data;
using Marco.Pms.DataAccess.Repository;
using Marco.Pms.DataAccess.Repository.IRepository;
using Marco.Pms.Model.Authentication;
using Marco.Pms.Model.Utilities;
using MarcoBMS.Services.Helpers;
@ -22,10 +19,10 @@ var builder = WebApplication.CreateBuilder(args);
// Add Serilog Configuration
builder.Host.UseSerilog((context, config) =>
{
config
.WriteTo.Console(); // Optional: Log to console
// .WriteTo.MongoDB("mongodb://localhost:27017/logs", collectionName: "api_logs");
});
config.ReadFrom.Configuration(context.Configuration); // Taking all configuration from appsetting.json
})
;
// Add services
builder.Services.AddCors(options =>
@ -98,21 +95,23 @@ builder.Services.AddDbContext<ApplicationDbContext>(options =>
builder.Services.AddMemoryCache();
builder.Services.AddScoped<IUnitOfWork, UnitOfWork>();
builder.Services.AddScoped<IProjectRepository, ProjectRepository>();
builder.Services.AddScoped<IEmployeeRepository, EmployeeRepository>();
builder.Services.AddScoped<IActivityMasterRepository, ActivityMasterRepository>();
builder.Services.AddScoped<IAttendenceRepository, AttendenceRepository>();
builder.Services.AddScoped<EmployeeHelper>();
builder.Services.AddScoped<ProjectHelper>();
builder.Services.AddScoped<IProjectAllocationRepository, ProjectAllocationRepository>();
//builder.Services.AddScoped<IUnitOfWork, UnitOfWork>();
//builder.Services.AddScoped<IProjectRepository, ProjectRepository>();
//builder.Services.AddScoped<IEmployeeRepository, EmployeeRepository>();
//builder.Services.AddScoped<IActivityMasterRepository, ActivityMasterRepository>();
//builder.Services.AddScoped<IAttendenceRepository, AttendenceRepository>();
//builder.Services.AddScoped<IProjectAllocationRepository, ProjectAllocationRepository>();
builder.Services.AddScoped<RefreshTokenService>();
builder.Services.AddScoped<UserHelper>();
builder.Services.AddScoped<RolesHelper>();
builder.Services.AddScoped<EmployeeHelper>();
builder.Services.AddScoped<ProjectsHelper>();
builder.Services.AddSingleton<ILoggingService, LoggingService>();
builder.Services.AddHttpContextAccessor();
var jwtSettings = builder.Configuration.GetSection("Jwt").Get<JwtSettings>();
builder.Services.AddAuthentication(options =>
@ -150,10 +149,14 @@ if (app.Environment.IsDevelopment())
app.UseCors("DevCorsPolicy");
}
app.UseStaticFiles(); // Enables serving static files
app.UseSerilogRequestLogging(); // Log HTTP requests
app.UseHttpsRedirection();
app.UseMiddleware<ExceptionHandlingMiddleware>();
app.UseMiddleware<TenantMiddleware>();
app.UseMiddleware<LoggingMiddleware>();
app.UseAuthorization();

View File

@ -5,13 +5,61 @@ using MimeKit;
namespace MarcoBMS.Services.Service
{ public class EmailSender : IEmailSender
{
public class EmailSender : IEmailSender
{
private readonly SmtpSettings _smtpSettings;
private readonly IConfiguration _configuration;
public EmailSender(IOptions<SmtpSettings> emailSettings)
public EmailSender(IOptions<SmtpSettings> emailSettings, IConfiguration configuration)
{
_smtpSettings = emailSettings.Value;
_configuration = configuration;
}
public async Task<string> GetEmailTemplate(string templateName, Dictionary<string, string> replacements)
{
string path = Path.Combine(Directory.GetCurrentDirectory(), "EmailTemplates", $"{templateName}.html");
if (!File.Exists(path))
throw new FileNotFoundException("Template file not found");
string content = await File.ReadAllTextAsync(path);
foreach (var item in replacements)
{
content = content.Replace($"{{{{{item.Key}}}}}", item.Value);
}
return content;
}
public async Task SendResetPasswordEmailOnRegister(string toEmail, string toName, string resetLink)
{
var replacements = new Dictionary<string, string>
{
{ "MAIL_TITLE", "New registration,Reset Your Password" },
{ "RESET_PWD_URL", resetLink },
{ "RECEIVER_NAME", toName }
};
string emailBody = await GetEmailTemplate("new-user-email", replacements);
await SendEmailAsync(toEmail, "New user registration, Reset Your Password", emailBody);
}
public async Task SendResetPasswordEmail(string toEmail, string userName, string resetLink)
{
var replacements = new Dictionary<string, string>
{
{ "MAIL_TITLE", "Reset Your Password" },
{ "RESET_PWD_URL", resetLink }
};
string emailBody = await GetEmailTemplate("forgot-password", replacements);
await SendEmailAsync(toEmail, "Reset Your Password", emailBody);
}
public async Task SendEmailAsync(string toEmail, string subject, string body)

View File

@ -2,6 +2,9 @@
{
public interface IEmailSender
{
Task SendResetPasswordEmail(string toEmail, string userName, string resetLink);
Task SendResetPasswordEmailOnRegister(string toEmail, string toName, string resetLink);
Task SendEmailAsync(string toEmail, string subject, string body);
}
}

View File

@ -0,0 +1,15 @@
using Serilog.Context;
namespace MarcoBMS.Services.Service
{
public interface ILoggingService
{
void LogInfo(string? message, params object[]? args);
void LogWarning(string? message, params object[]? args);
void LogError(Exception? ex, string? message, params object[]? args);
}
}

View File

@ -0,0 +1,35 @@
using Serilog.Context;
namespace MarcoBMS.Services.Service
{
public class LoggingService : ILoggingService
{
private readonly ILogger<LoggingService> _logger;
public LoggingService(ILogger<LoggingService> logger)
{
_logger = logger;
}
public void LogError(Exception? ex, string? message, params object[]? args)
{
using (LogContext.PushProperty("Error", ex))
using (LogContext.PushProperty("LogLevel", "Error"))
_logger.LogError(message, args);
}
public void LogInfo(string? message, params object[]? args)
{
using (LogContext.PushProperty("LogLevel", "Information"))
_logger.LogInformation(message, args);
}
public void LogWarning(string? message, params object[]? args)
{
using (LogContext.PushProperty("LogLevel", "Warning"))
_logger.LogWarning(message,args);
}
}
}

View File

@ -1,14 +1,75 @@
{
"Logging": {
"LogLevel": {
"Serilog": {
"Using": [
"Serilog.Sinks.Console",
"Serilog.Sinks.MongoDB",
"Serilog.Sinks.Async"
],
"MinimumLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
"Override": {
"Microsoft": "Warning",
"Microsoft.EntityFrameworkCore.Database.Command": "Warning",
"Microsoft.AspNetCore.Mvc.Infrastructure": "Warning",
"Serilog.AspNetCore.RequestLoggingMiddleware": "Warning"
}
},
"WriteTo": [
{
"Name": "Async",
"Args": {
"configure": [
{
"Name": "MongoDB",
"Args": {
"databaseUrl": "mongodb://localhost:27017/DotNetLogs",
//"databaseUrl": "mongodb://devuser:xxxxx@147.93.98.152:27017/MarcoPMS?authSource=admin",
"collectionName": "application_logs",
"batchPostingLimit": 50,
"cappedMaxSizeMb": "1024",
"cappedMaxDocuments": "1000",
"rollingInterval": "Day"
//"outputTemplate": "[{Timestamp:yyyy/MM/dd HH:mm} {Level:u3}] {SourceContext}:{NewLine} {Message:lj}{Exception}{NewLine}"
}
},
{
"Name": "File",
"Args": {
"path": "logs/myapp-.log",
"rollingInterval": "Day",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {Message:lj}{NewLine}{Exception}",
"fileSizeLimitBytes": 1073741824, // 1 GB
"retainedFileCountLimit": 100, // Retain 100 files
"buffered": true, // use async logging
"flushToDiskInterval": "00:00:30" // flush every 30 seconds
}
},
{
"Name": "Console",
"Args": {
"outputTemplate": "[{Timestamp:yyyy/MM/dd HH:mm} {Level:u3}] {SourceContext}:{NewLine} {Message:lj}{NewLine}{Properties:j}{Exception}{NewLine}"
}
}
]
}
}
],
"Enrich": [
"FromLogContext",
"WithMachineName",
"WithThreadId"
]
},
"ConnectionStrings": {
// "DefaultConnectionString": "Server=103.50.160.45;User ID=marcowvh_admin;Password=Marcoemp@123;Database=marcowvh_empattendanceci",
//"DefaultConnectionString": "Server=localhost;port=3333;User ID=root;Password=root;Database=MarcoBMS1",
"DefaultConnectionString": "Server=147.93.98.152;User ID=root;Password=MySqlUser@123$;Database=MarcoBMS1"
"DefaultConnectionString": "Server=localhost;port=3333;User ID=root;Password=root;Database=MarcoBMS1",
// "DefaultConnectionString": "Server=147.93.98.152;User ID=devuser;Password=AppUser@123$;Database=MarcoBMS1"
},
"AppSettings": {
"WebFrontendUrl": "http://localhost:5173",
"ImagesBaseUrl": "http://localhost:5173"
},
"AllowedHosts": "*",
"Jwt": {

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -5,7 +5,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MarcoBMS.Utility
namespace Marco.Pms.Utility
{
public static class ParentToChildClassMapper
{

View File

@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Identity.UI.Services;
namespace MarcoBMS.Utility
namespace Marco.Pms.Utility
{
public class EmailSender : IEmailSender
{

View File

@ -6,7 +6,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MarcoBMS.Utility
namespace Marco.Pms.Utility
{
public class SessionUtil
{

View File

@ -5,7 +5,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MarcoBMS.Utility
namespace Marco.Pms.Utility
{
public enum APP_ROLES
{