2025-11-11 19:49:52 +00:00
|
|
|
|
using System;
|
2025-10-28 18:03:15 +00:00
|
|
|
|
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 13:11:03 +00:00
|
|
|
|
using ClosedXML;
|
2025-11-11 19:49:52 +00:00
|
|
|
|
using Erp.Platform.BlobStoring;
|
|
|
|
|
|
using Erp.Platform.Entities;
|
|
|
|
|
|
using Erp.Platform.FileManagement;
|
|
|
|
|
|
using Erp.Platform.Intranet;
|
2025-10-28 18:03:15 +00:00
|
|
|
|
using Microsoft.AspNetCore.Authorization;
|
2025-10-29 19:24:40 +00:00
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
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
|
|
|
|
|
2025-11-11 19:49:52 +00:00
|
|
|
|
namespace Erp.Platform.Public;
|
2025-10-28 18:03:15 +00:00
|
|
|
|
|
|
|
|
|
|
[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-29 13:11:03 +00:00
|
|
|
|
private readonly IRepository<ShuttleRoute, Guid> _shuttleRouteRepository;
|
|
|
|
|
|
private readonly IRepository<Meal, Guid> _mealRepository;
|
2025-10-29 13:45:58 +00:00
|
|
|
|
private readonly IRepository<Leave, Guid> _leaveRepository;
|
|
|
|
|
|
private readonly IRepository<Overtime, Guid> _overtimeRepository;
|
2025-10-29 19:24:40 +00:00
|
|
|
|
private readonly IRepository<Survey, Guid> _surveyRepository;
|
|
|
|
|
|
private readonly IRepository<SocialPost, Guid> _socialPostRepository;
|
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,
|
2025-10-29 13:11:03 +00:00
|
|
|
|
IRepository<Department, Guid> departmentRepository,
|
|
|
|
|
|
IRepository<ShuttleRoute, Guid> shuttleRouteRepository,
|
2025-10-29 13:45:58 +00:00
|
|
|
|
IRepository<Meal, Guid> mealRepository,
|
|
|
|
|
|
IRepository<Leave, Guid> leaveRepository,
|
2025-10-29 19:24:40 +00:00
|
|
|
|
IRepository<Overtime, Guid> overtimeRepository,
|
|
|
|
|
|
IRepository<Survey, Guid> surveyRepository,
|
|
|
|
|
|
IRepository<SocialPost, Guid> socialPostRepository
|
2025-10-29 11:57:08 +00:00
|
|
|
|
)
|
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-29 13:11:03 +00:00
|
|
|
|
_shuttleRouteRepository = shuttleRouteRepository;
|
|
|
|
|
|
_mealRepository = mealRepository;
|
2025-10-29 13:45:58 +00:00
|
|
|
|
_leaveRepository = leaveRepository;
|
|
|
|
|
|
_overtimeRepository = overtimeRepository;
|
2025-10-29 19:24:40 +00:00
|
|
|
|
_surveyRepository = surveyRepository;
|
|
|
|
|
|
_socialPostRepository = socialPostRepository;
|
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),
|
2025-10-29 13:11:03 +00:00
|
|
|
|
Announcements = await GetAnnouncementsAsync(),
|
|
|
|
|
|
ShuttleRoutes = await GetShuttleRoutesAsync(),
|
2025-10-29 13:45:58 +00:00
|
|
|
|
Meals = await GetMealsAsync(),
|
|
|
|
|
|
Leaves = await GetLeavesAsync(),
|
2025-10-29 19:24:40 +00:00
|
|
|
|
Overtimes = await GetOvertimesAsync(),
|
|
|
|
|
|
Surveys = await GetSurveysAsync(),
|
|
|
|
|
|
SocialPosts = await GetSocialPostsAsync()
|
2025-10-29 10:20:21 +00:00
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-29 19:24:40 +00:00
|
|
|
|
private async Task<List<SocialPostDto>> GetSocialPostsAsync()
|
|
|
|
|
|
{
|
|
|
|
|
|
var socialPosts = await _socialPostRepository
|
|
|
|
|
|
.WithDetailsAsync(e => e.Employee, e => e.Location, e => e.Media, e => e.Comments, e => e.Likes)
|
|
|
|
|
|
.ContinueWith(t => t.Result.ToList());
|
|
|
|
|
|
|
|
|
|
|
|
return ObjectMapper.Map<List<SocialPost>, List<SocialPostDto>>(socialPosts);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async Task<List<SurveyDto>> GetSurveysAsync()
|
|
|
|
|
|
{
|
|
|
|
|
|
var queryable = await _surveyRepository.GetQueryableAsync();
|
|
|
|
|
|
|
|
|
|
|
|
var surveys = queryable
|
|
|
|
|
|
.Where(s => s.Status == "active")
|
|
|
|
|
|
.Include(s => s.Questions)
|
|
|
|
|
|
.ThenInclude(q => q.Options)
|
|
|
|
|
|
.ToList();
|
|
|
|
|
|
|
|
|
|
|
|
return ObjectMapper.Map<List<Survey>, List<SurveyDto>>(surveys);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-29 13:45:58 +00:00
|
|
|
|
private async Task<List<OvertimeDto>> GetOvertimesAsync()
|
|
|
|
|
|
{
|
|
|
|
|
|
var today = DateTime.Now;
|
|
|
|
|
|
|
|
|
|
|
|
var overtimes = await _overtimeRepository
|
|
|
|
|
|
.WithDetailsAsync(e => e.Employee)
|
|
|
|
|
|
.ContinueWith(t => t.Result.ToList());
|
|
|
|
|
|
|
|
|
|
|
|
return ObjectMapper.Map<List<Overtime>, List<OvertimeDto>>(overtimes);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async Task<List<LeaveDto>> GetLeavesAsync()
|
|
|
|
|
|
{
|
|
|
|
|
|
var today = DateTime.Now;
|
|
|
|
|
|
|
|
|
|
|
|
var leaves = await _leaveRepository
|
|
|
|
|
|
.WithDetailsAsync(e => e.Employee)
|
|
|
|
|
|
.ContinueWith(t => t.Result.ToList());
|
|
|
|
|
|
|
|
|
|
|
|
return ObjectMapper.Map<List<Leave>, List<LeaveDto>>(leaves);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-29 13:11:03 +00:00
|
|
|
|
private async Task<List<MealDto>> GetMealsAsync()
|
|
|
|
|
|
{
|
2025-11-11 19:49:52 +00:00
|
|
|
|
// Bu haftanın başlangıç ve bitiş tarihlerini hesapla
|
2025-10-29 13:11:03 +00:00
|
|
|
|
var today = DateTime.Now.Date;
|
|
|
|
|
|
var dayOfWeek = (int)today.DayOfWeek;
|
2025-11-11 19:49:52 +00:00
|
|
|
|
// Pazartesi'yi haftanın başı olarak kabul ediyoruz (ISO 8601)
|
2025-10-29 13:11:03 +00:00
|
|
|
|
var weekStart = today.AddDays(-(dayOfWeek == 0 ? 6 : dayOfWeek - 1));
|
|
|
|
|
|
var weekEnd = weekStart.AddDays(6);
|
|
|
|
|
|
|
2025-11-11 19:49:52 +00:00
|
|
|
|
// Sadece bu haftanın yemeklerini getir
|
2025-10-29 13:45:58 +00:00
|
|
|
|
var meals = await _mealRepository.GetListAsync(m =>
|
2025-10-29 13:11:03 +00:00
|
|
|
|
m.Date >= weekStart && m.Date <= weekEnd);
|
|
|
|
|
|
|
|
|
|
|
|
var mealDtos = new List<MealDto>();
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var meal in meals)
|
|
|
|
|
|
{
|
|
|
|
|
|
var dto = ObjectMapper.Map<Meal, MealDto>(meal);
|
|
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrEmpty(meal.Materials))
|
|
|
|
|
|
{
|
|
|
|
|
|
dto.Materials = meal.Materials
|
|
|
|
|
|
.Split('|', StringSplitOptions.RemoveEmptyEntries)
|
|
|
|
|
|
.Select(r => r.Trim())
|
|
|
|
|
|
.ToArray();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
dto.Materials = [];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
mealDtos.Add(dto);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return mealDtos;
|
|
|
|
|
|
}
|
2025-10-29 13:45:58 +00:00
|
|
|
|
|
2025-10-29 13:11:03 +00:00
|
|
|
|
private async Task<List<ShuttleRouteDto>> GetShuttleRoutesAsync()
|
|
|
|
|
|
{
|
|
|
|
|
|
var shuttleRoutes = await _shuttleRouteRepository.GetListAsync();
|
|
|
|
|
|
|
|
|
|
|
|
var shuttleRouteDtos = new List<ShuttleRouteDto>();
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var shuttleRoute in shuttleRoutes)
|
|
|
|
|
|
{
|
|
|
|
|
|
var dto = ObjectMapper.Map<ShuttleRoute, ShuttleRouteDto>(shuttleRoute);
|
|
|
|
|
|
|
2025-11-11 19:49:52 +00:00
|
|
|
|
// Route string'ini array'e çevir (pipe ile ayrılmış)
|
2025-10-29 13:11:03 +00:00
|
|
|
|
if (!string.IsNullOrEmpty(shuttleRoute.Route))
|
|
|
|
|
|
{
|
|
|
|
|
|
dto.Route = shuttleRoute.Route
|
|
|
|
|
|
.Split('|', StringSplitOptions.RemoveEmptyEntries)
|
|
|
|
|
|
.Select(r => r.Trim())
|
|
|
|
|
|
.ToArray();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
dto.Route = [];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
shuttleRouteDtos.Add(dto);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return shuttleRouteDtos;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
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-11-11 19:49:52 +00:00
|
|
|
|
// Tüm departmanları bir kez çek (performans için)
|
2025-10-29 11:57:08 +00:00
|
|
|
|
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-11-11 19:49:52 +00:00
|
|
|
|
// Departments string'ini array'e çevir (pipe ile ayrılmış ID'ler)
|
2025-10-29 11:57:08 +00:00
|
|
|
|
if (!string.IsNullOrEmpty(announcement.Departments))
|
|
|
|
|
|
{
|
|
|
|
|
|
var departmentIds = announcement.Departments
|
|
|
|
|
|
.Split('|', StringSplitOptions.RemoveEmptyEntries)
|
|
|
|
|
|
.Select(d => d.Trim())
|
|
|
|
|
|
.ToArray();
|
|
|
|
|
|
|
2025-11-11 19:49:52 +00:00
|
|
|
|
// ID'leri Department Name'lere çevir
|
2025-10-29 11:57:08 +00:00
|
|
|
|
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);
|
|
|
|
|
|
|
2025-11-11 19:49:52 +00:00
|
|
|
|
// Son 1 ay içerisindeki kayıtlar
|
2025-10-29 10:20:21 +00:00
|
|
|
|
var lastMonthExpenses = queryable
|
|
|
|
|
|
.Where(a => a.RequestDate >= oneMonthAgo && a.RequestDate <= today);
|
|
|
|
|
|
|
2025-11-11 19:49:52 +00:00
|
|
|
|
// Son 1 aydaki toplam talep miktarı
|
2025-10-29 10:20:21 +00:00
|
|
|
|
var totalRequested = lastMonthExpenses.Sum(a => a.Amount);
|
|
|
|
|
|
|
2025-11-11 19:49:52 +00:00
|
|
|
|
// Son 1 aydaki onaylanan harcamaların toplamı
|
2025-10-29 10:20:21 +00:00
|
|
|
|
var totalApproved = lastMonthExpenses
|
|
|
|
|
|
.Where(a => a.Status == "approved")
|
|
|
|
|
|
.Sum(a => a.Amount);
|
|
|
|
|
|
|
2025-11-11 19:49:52 +00:00
|
|
|
|
// Son 5 kayıt
|
2025-10-29 10:20:21 +00:00
|
|
|
|
var last5Expenses = queryable
|
|
|
|
|
|
.OrderByDescending(a => a.RequestDate)
|
|
|
|
|
|
.Take(5)
|
|
|
|
|
|
.ToList();
|
|
|
|
|
|
|
2025-11-11 19:49:52 +00:00
|
|
|
|
// Map iÅŸlemleri
|
2025-10-29 10:20:21 +00:00
|
|
|
|
var last5Dtos = ObjectMapper.Map<List<Expense>, List<ExpenseDto>>(last5Expenses);
|
|
|
|
|
|
|
2025-11-11 19:49:52 +00:00
|
|
|
|
// Dönüş DTO'su
|
2025-10-29 10:20:21 +00:00
|
|
|
|
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
|
2025-10-28 20:12:06 +00:00
|
|
|
|
.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(),
|
2025-10-28 20:12:06 +00:00
|
|
|
|
Name = evt.Name,
|
2025-10-28 18:03:15 +00:00
|
|
|
|
Description = evt.Description,
|
2025-10-28 20:12:06 +00:00
|
|
|
|
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(),
|
2025-11-04 12:29:56 +00:00
|
|
|
|
Employee = new EventOrganizerDto
|
2025-10-28 18:03:15 +00:00
|
|
|
|
{
|
|
|
|
|
|
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
|
|
|
|
}
|
2025-11-11 19:49:52 +00:00
|
|
|
|
|