erp-platform/api/src/Kurs.Platform.Application/Intranet/IntranetAppService.cs

345 lines
13 KiB
C#
Raw Normal View History

2025-10-28 18:03:15 +00:00
using System;
using System.Collections.Generic;
2025-10-29 10:20:21 +00:00
using System.IO;
2025-10-28 18:03:15 +00:00
using System.Linq;
using System.Threading.Tasks;
2025-10-29 10:20:21 +00:00
using Kurs.Platform.BlobStoring;
2025-10-28 18:03:15 +00:00
using Kurs.Platform.Entities;
2025-10-29 10:20:21 +00:00
using Kurs.Platform.FileManagement;
using Kurs.Platform.Intranet;
2025-10-28 18:03:15 +00:00
using Microsoft.AspNetCore.Authorization;
2025-10-29 10:20:21 +00:00
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
2025-10-28 18:03:15 +00:00
using Volo.Abp.Domain.Repositories;
2025-10-29 10:20:21 +00:00
using Volo.Abp.MultiTenancy;
2025-10-28 18:03:15 +00:00
namespace Kurs.Platform.Public;
[Authorize]
public class IntranetAppService : PlatformAppService, IIntranetAppService
{
2025-10-29 10:20:21 +00:00
private readonly ICurrentTenant _currentTenant;
private readonly BlobManager _blobContainer;
private readonly IConfiguration _configuration;
2025-10-28 18:03:15 +00:00
private readonly IRepository<Event, Guid> _eventRepository;
private readonly IRepository<Employee, Guid> _employeeRepository;
2025-10-29 10:20:21 +00:00
private readonly IRepository<Visitor, Guid> _visitorRepository;
private readonly IRepository<Reservation, Guid> _reservationRepository;
private readonly IRepository<Training, Guid> _trainingRepository;
private readonly IRepository<Expense, Guid> _expenseRepository;
2025-10-29 11:57:08 +00:00
private readonly IRepository<Announcement, Guid> _announcementRepository;
private readonly IRepository<Department, Guid> _departmentRepository;
2025-10-28 18:03:15 +00:00
public IntranetAppService(
2025-10-29 10:20:21 +00:00
ICurrentTenant currentTenant,
BlobManager blobContainer,
IConfiguration configuration,
2025-10-28 18:03:15 +00:00
IRepository<Event, Guid> eventRepository,
2025-10-29 10:20:21 +00:00
IRepository<Employee, Guid> employeeRepository,
IRepository<Visitor, Guid> visitorRepository,
IRepository<Reservation, Guid> reservationRepository,
IRepository<Training, Guid> trainingRepository,
2025-10-29 11:57:08 +00:00
IRepository<Expense, Guid> expenseRepository,
IRepository<Announcement, Guid> announcementRepository,
IRepository<Department, Guid> departmentRepository
)
2025-10-28 18:03:15 +00:00
{
2025-10-29 10:20:21 +00:00
_currentTenant = currentTenant;
_blobContainer = blobContainer;
_configuration = configuration;
2025-10-28 18:03:15 +00:00
_eventRepository = eventRepository;
_employeeRepository = employeeRepository;
2025-10-29 10:20:21 +00:00
_visitorRepository = visitorRepository;
_reservationRepository = reservationRepository;
_trainingRepository = trainingRepository;
_expenseRepository = expenseRepository;
2025-10-29 11:57:08 +00:00
_announcementRepository = announcementRepository;
_departmentRepository = departmentRepository;
2025-10-28 18:03:15 +00:00
}
public async Task<IntranetDashboardDto> GetIntranetDashboardAsync()
{
return new IntranetDashboardDto
{
2025-10-29 10:20:21 +00:00
Events = await GetUpcomingEventsAsync(),
Birthdays = await GetBirthdaysAsync(),
Visitors = await GetVisitorsAsync(),
Reservations = await GetReservationsAsync(),
Trainings = await GetTrainingsAsync(),
Expenses = await GetExpensesAsync(),
2025-10-29 11:57:08 +00:00
Documents = await GetIntranetDocumentsAsync(BlobContainerNames.Intranet),
Announcements = await GetAnnouncementsAsync()
2025-10-29 10:20:21 +00:00
};
}
2025-10-29 11:57:08 +00:00
private async Task<List<AnnouncementDto>> GetAnnouncementsAsync()
2025-10-29 10:20:21 +00:00
{
2025-10-29 11:57:08 +00:00
var announcements = await _announcementRepository
.WithDetailsAsync(e => e.Employee)
.ContinueWith(t => t.Result.ToList());
2025-10-29 10:20:21 +00:00
2025-10-29 11:57:08 +00:00
var announcementDtos = new List<AnnouncementDto>();
2025-10-29 10:20:21 +00:00
2025-10-29 11:57:08 +00:00
// Tüm departmanları bir kez çek (performans için)
var allDepartments = await _departmentRepository.GetListAsync();
2025-10-29 10:20:21 +00:00
2025-10-29 11:57:08 +00:00
foreach (var announcement in announcements)
2025-10-29 10:20:21 +00:00
{
2025-10-29 11:57:08 +00:00
var dto = ObjectMapper.Map<Announcement, AnnouncementDto>(announcement);
2025-10-29 10:20:21 +00:00
2025-10-29 11:57:08 +00:00
// Departments string'ini array'e çevir (pipe ile ayrılmış ID'ler)
if (!string.IsNullOrEmpty(announcement.Departments))
{
var departmentIds = announcement.Departments
.Split('|', StringSplitOptions.RemoveEmptyEntries)
.Select(d => d.Trim())
.ToArray();
// ID'leri Department Name'lere çevir
var departmentNames = new List<string>();
foreach (var deptId in departmentIds)
{
if (Guid.TryParse(deptId, out var guid))
{
var department = allDepartments.FirstOrDefault(d => d.Id == guid);
if (department != null)
{
departmentNames.Add(department.Name);
}
}
}
2025-10-29 10:20:21 +00:00
2025-10-29 11:57:08 +00:00
dto.Departments = departmentNames.ToArray();
}
else
2025-10-29 10:20:21 +00:00
{
2025-10-29 11:57:08 +00:00
dto.Departments = [];
}
announcementDtos.Add(dto);
2025-10-29 10:20:21 +00:00
}
2025-10-29 11:57:08 +00:00
return announcementDtos;
2025-10-29 10:20:21 +00:00
}
private async Task<ExpensesDto> GetExpensesAsync()
{
var queryable = await _expenseRepository.GetQueryableAsync();
var today = DateTime.Today;
var oneMonthAgo = today.AddMonths(-1);
// Son 1 ay içerisindeki kayıtlar
var lastMonthExpenses = queryable
.Where(a => a.RequestDate >= oneMonthAgo && a.RequestDate <= today);
// Son 1 aydaki toplam talep miktarı
var totalRequested = lastMonthExpenses.Sum(a => a.Amount);
// Son 1 aydaki onaylanan harcamaların toplamı
var totalApproved = lastMonthExpenses
.Where(a => a.Status == "approved")
.Sum(a => a.Amount);
// Son 5 kayıt
var last5Expenses = queryable
.OrderByDescending(a => a.RequestDate)
.Take(5)
.ToList();
// Map işlemleri
var last5Dtos = ObjectMapper.Map<List<Expense>, List<ExpenseDto>>(last5Expenses);
// Dönüş DTO'su
return new ExpensesDto
{
TotalRequested = totalRequested,
TotalApproved = totalApproved,
Last5Expenses = last5Dtos
2025-10-28 18:03:15 +00:00
};
}
2025-10-29 10:20:21 +00:00
private async Task<List<TrainingDto>> GetTrainingsAsync()
{
var trainings = await _trainingRepository.GetListAsync(a => a.StartDate >= DateTime.Today);
return ObjectMapper.Map<List<Training>, List<TrainingDto>>(trainings);
}
private async Task<List<ReservationDto>> GetReservationsAsync()
{
var reservations = await _reservationRepository.GetListAsync(a => a.StartDate >= DateTime.Today);
return ObjectMapper.Map<List<Reservation>, List<ReservationDto>>(reservations);
}
private async Task<List<VisitorDto>> GetVisitorsAsync()
{
var visitors = await _visitorRepository.GetListAsync(a => a.VisitDate >= DateTime.Today);
return ObjectMapper.Map<List<Visitor>, List<VisitorDto>>(visitors);
}
private async Task<List<EmployeeDto>> GetBirthdaysAsync()
{
var today = DateTime.Now;
var employees = await _employeeRepository
.WithDetailsAsync(e => e.EmploymentType, e => e.JobPosition, e => e.Department)
.ContinueWith(t => t.Result
.Where(e => e.BirthDate.Day == today.Day && e.BirthDate.Month == today.Month)
.ToList());
return ObjectMapper.Map<List<Employee>, List<EmployeeDto>>(employees);
}
2025-10-28 18:03:15 +00:00
private async Task<List<EventDto>> GetUpcomingEventsAsync()
{
var events = await _eventRepository
.WithDetailsAsync(e => e.Category, e => e.Type, e => e.Category, e => e.Photos, e => e.Comments)
2025-10-28 18:03:15 +00:00
.ContinueWith(t => t.Result.ToList().Where(e => e.isPublished).OrderByDescending(e => e.CreationTime));
var result = new List<EventDto>();
foreach (var evt in events)
{
var employee = await _employeeRepository
.WithDetailsAsync(e => e.JobPosition)
2025-10-28 18:59:07 +00:00
.ContinueWith(t => t.Result.FirstOrDefault(e => e.Id == evt.EmployeeId));
2025-10-28 18:03:15 +00:00
if (employee != null)
{
var calendarEvent = new EventDto
{
Id = evt.Id.ToString(),
Name = evt.Name,
2025-10-28 18:03:15 +00:00
Description = evt.Description,
TypeName = evt.Type?.Name,
CategoryName = evt.Category?.Name,
Date = evt.Date,
Place = evt.Place,
2025-10-28 18:03:15 +00:00
Organizer = new EventOrganizerDto
{
Id = employee.Id,
Name = employee.FullName,
Position = employee.JobPosition.Name,
Avatar = employee.Avatar
},
Participants = evt.ParticipantsCount,
2025-10-29 10:20:21 +00:00
Photos = [],
2025-10-28 18:03:15 +00:00
Comments = [],
Likes = evt.Likes,
IsPublished = evt.isPublished
};
// Comment'lerin author bilgilerini doldur
if (evt.Comments != null && evt.Comments.Any())
{
foreach (var comment in evt.Comments)
{
var commentAuthor = await _employeeRepository
.WithDetailsAsync(e => e.JobPosition)
2025-10-28 18:59:07 +00:00
.ContinueWith(t => t.Result.FirstOrDefault(e => e.Id == comment.EmployeeId));
2025-10-28 18:03:15 +00:00
if (commentAuthor != null)
{
calendarEvent.Comments.Add(new EventCommentDto
{
Id = comment.Id.ToString(),
Author = new EventOrganizerDto
{
Id = commentAuthor.Id,
Name = commentAuthor.FullName,
Position = commentAuthor.JobPosition.Name,
Avatar = commentAuthor.Avatar
},
2025-10-28 18:59:07 +00:00
Content = comment.Content,
2025-10-28 18:03:15 +00:00
CreationTime = comment.CreationTime,
Likes = comment.Likes
});
}
}
}
result.Add(calendarEvent);
}
}
return result;
}
2025-10-29 11:57:08 +00:00
public async Task<List<FileItemDto>> GetIntranetDocumentsAsync(string folderPath)
{
var items = new List<FileItemDto>();
var cdnBasePath = _configuration["App:CdnPath"];
if (string.IsNullOrEmpty(cdnBasePath))
{
Logger.LogWarning("CDN path is not configured");
return items;
}
var tenantId = _currentTenant.Id?.ToString() ?? "host";
var fullPath = Path.Combine(cdnBasePath, tenantId);
if (!string.IsNullOrEmpty(folderPath))
{
fullPath = Path.Combine(fullPath, folderPath);
}
if (!Directory.Exists(fullPath))
{
Logger.LogWarning($"Directory not found: {fullPath}");
return items;
}
var files = Directory.GetFiles(fullPath);
foreach (var file in files)
{
var fileInfo = new FileInfo(file);
var relativePath = string.IsNullOrEmpty(folderPath) ? fileInfo.Name : $"{folderPath}/{fileInfo.Name}";
items.Add(new FileItemDto
{
Id = Guid.NewGuid().ToString(),
Name = fileInfo.Name,
Type = "file",
Size = fileInfo.Length,
Extension = fileInfo.Extension,
MimeType = GetMimeType(fileInfo.Extension),
CreatedAt = fileInfo.CreationTime,
ModifiedAt = fileInfo.LastWriteTime,
Path = relativePath,
ParentId = string.Empty,
IsReadOnly = false,
ChildCount = 0
});
}
return items.OrderBy(x => x.Name).ToList();
}
private string GetMimeType(string extension)
{
return extension.ToLowerInvariant() switch
{
".pdf" => "application/pdf",
".doc" => "application/msword",
".docx" => "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
".xls" => "application/vnd.ms-excel",
".xlsx" => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
".ppt" => "application/vnd.ms-powerpoint",
".pptx" => "application/vnd.openxmlformats-officedocument.presentationml.presentation",
".jpg" or ".jpeg" => "image/jpeg",
".png" => "image/png",
".gif" => "image/gif",
".txt" => "text/plain",
".zip" => "application/zip",
".rar" => "application/x-rar-compressed",
_ => "application/octet-stream"
};
}
2025-10-28 18:03:15 +00:00
}