Skip to content

Commit 8afe816

Browse files
author
CIS Guru
committed
Added Aquiis.Professional project
1 parent b053f80 commit 8afe816

509 files changed

Lines changed: 223639 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
using Microsoft.Extensions.Options;
2+
using Aquiis.Professional.Core.Entities;
3+
using Aquiis.Professional.Core.Constants;
4+
5+
namespace Aquiis.Professional.Application.Services
6+
{
7+
public class ApplicationService
8+
{
9+
private readonly ApplicationSettings _settings;
10+
private readonly PaymentService _paymentService;
11+
private readonly LeaseService _leaseService;
12+
13+
public bool SoftDeleteEnabled { get; }
14+
15+
public ApplicationService(
16+
IOptions<ApplicationSettings> settings,
17+
PaymentService paymentService,
18+
LeaseService leaseService)
19+
{
20+
_settings = settings.Value;
21+
_paymentService = paymentService;
22+
_leaseService = leaseService;
23+
SoftDeleteEnabled = _settings.SoftDeleteEnabled;
24+
}
25+
26+
public string GetAppInfo()
27+
{
28+
return $"{_settings.AppName} - {_settings.Version}";
29+
}
30+
31+
/// <summary>
32+
/// Gets the total payments received for a specific date
33+
/// </summary>
34+
public async Task<decimal> GetDailyPaymentTotalAsync(DateTime date)
35+
{
36+
var payments = await _paymentService.GetAllAsync();
37+
return payments
38+
.Where(p => p.PaidOn.Date == date.Date && !p.IsDeleted)
39+
.Sum(p => p.Amount);
40+
}
41+
42+
/// <summary>
43+
/// Gets the total payments received for today
44+
/// </summary>
45+
public async Task<decimal> GetTodayPaymentTotalAsync()
46+
{
47+
return await GetDailyPaymentTotalAsync(DateTime.Today);
48+
}
49+
50+
/// <summary>
51+
/// Gets the total payments received for a date range
52+
/// </summary>
53+
public async Task<decimal> GetPaymentTotalForRangeAsync(DateTime startDate, DateTime endDate)
54+
{
55+
var payments = await _paymentService.GetAllAsync();
56+
return payments
57+
.Where(p => p.PaidOn.Date >= startDate.Date &&
58+
p.PaidOn.Date <= endDate.Date &&
59+
!p.IsDeleted)
60+
.Sum(p => p.Amount);
61+
}
62+
63+
/// <summary>
64+
/// Gets payment statistics for a specific period
65+
/// </summary>
66+
public async Task<PaymentStatistics> GetPaymentStatisticsAsync(DateTime startDate, DateTime endDate)
67+
{
68+
var payments = await _paymentService.GetAllAsync();
69+
var periodPayments = payments
70+
.Where(p => p.PaidOn.Date >= startDate.Date &&
71+
p.PaidOn.Date <= endDate.Date &&
72+
!p.IsDeleted)
73+
.ToList();
74+
75+
return new PaymentStatistics
76+
{
77+
StartDate = startDate,
78+
EndDate = endDate,
79+
TotalAmount = periodPayments.Sum(p => p.Amount),
80+
PaymentCount = periodPayments.Count,
81+
AveragePayment = periodPayments.Any() ? periodPayments.Average(p => p.Amount) : 0,
82+
PaymentsByMethod = periodPayments
83+
.GroupBy(p => p.PaymentMethod)
84+
.ToDictionary(g => g.Key, g => g.Sum(p => p.Amount))
85+
};
86+
}
87+
88+
/// <summary>
89+
/// Gets leases expiring within the specified number of days
90+
/// </summary>
91+
public async Task<int> GetLeasesExpiringCountAsync(int daysAhead)
92+
{
93+
var leases = await _leaseService.GetAllAsync();
94+
return leases
95+
.Where(l => l.EndDate >= DateTime.Today &&
96+
l.EndDate <= DateTime.Today.AddDays(daysAhead) &&
97+
!l.IsDeleted)
98+
.Count();
99+
}
100+
}
101+
102+
public class PaymentStatistics
103+
{
104+
public DateTime StartDate { get; set; }
105+
public DateTime EndDate { get; set; }
106+
public decimal TotalAmount { get; set; }
107+
public int PaymentCount { get; set; }
108+
public decimal AveragePayment { get; set; }
109+
public Dictionary<string, decimal> PaymentsByMethod { get; set; } = new();
110+
}
111+
}
Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
using Microsoft.EntityFrameworkCore;
2+
using Aquiis.Professional.Infrastructure.Data;
3+
using Aquiis.Professional.Core.Entities;
4+
using Aquiis.Professional.Core.Interfaces;
5+
using Aquiis.Professional.Shared.Services;
6+
7+
namespace Aquiis.Professional.Application.Services
8+
{
9+
/// <summary>
10+
/// Service for managing calendar events and synchronizing with schedulable entities
11+
/// </summary>
12+
public class CalendarEventService : ICalendarEventService
13+
{
14+
private readonly ApplicationDbContext _context;
15+
private readonly CalendarSettingsService _settingsService;
16+
private readonly UserContextService _userContextService;
17+
18+
public CalendarEventService(ApplicationDbContext context, CalendarSettingsService settingsService, UserContextService userContext)
19+
{
20+
_context = context;
21+
_settingsService = settingsService;
22+
_userContextService = userContext;
23+
}
24+
25+
/// <summary>
26+
/// Create or update a calendar event from a schedulable entity
27+
/// </summary>
28+
public async Task<CalendarEvent?> CreateOrUpdateEventAsync<T>(T entity)
29+
where T : BaseModel, ISchedulableEntity
30+
{
31+
var entityType = entity.GetEventType();
32+
33+
// Check if auto-creation is enabled for this entity type
34+
var isEnabled = await _settingsService.IsAutoCreateEnabledAsync(
35+
entity.OrganizationId,
36+
entityType
37+
);
38+
39+
if (!isEnabled)
40+
{
41+
// If disabled and event exists, delete it
42+
if (entity.CalendarEventId.HasValue)
43+
{
44+
await DeleteEventAsync(entity.CalendarEventId);
45+
entity.CalendarEventId = null;
46+
await _context.SaveChangesAsync();
47+
}
48+
return null;
49+
}
50+
51+
CalendarEvent? calendarEvent;
52+
53+
if (entity.CalendarEventId.HasValue)
54+
{
55+
// Update existing event
56+
calendarEvent = await _context.CalendarEvents
57+
.FindAsync(entity.CalendarEventId.Value);
58+
59+
if (calendarEvent != null)
60+
{
61+
UpdateEventFromEntity(calendarEvent, entity);
62+
}
63+
else
64+
{
65+
// Event was deleted, create new one
66+
calendarEvent = CreateEventFromEntity(entity);
67+
_context.CalendarEvents.Add(calendarEvent);
68+
}
69+
}
70+
else
71+
{
72+
// Create new event
73+
calendarEvent = CreateEventFromEntity(entity);
74+
_context.CalendarEvents.Add(calendarEvent);
75+
}
76+
77+
await _context.SaveChangesAsync();
78+
79+
// Link back to entity if not already linked
80+
if (!entity.CalendarEventId.HasValue)
81+
{
82+
entity.CalendarEventId = calendarEvent.Id;
83+
await _context.SaveChangesAsync();
84+
}
85+
86+
return calendarEvent;
87+
}
88+
89+
/// <summary>
90+
/// Delete a calendar event
91+
/// </summary>
92+
public async Task DeleteEventAsync(Guid? calendarEventId)
93+
{
94+
if (!calendarEventId.HasValue) return;
95+
96+
var evt = await _context.CalendarEvents.FindAsync(calendarEventId.Value);
97+
if (evt != null)
98+
{
99+
_context.CalendarEvents.Remove(evt);
100+
await _context.SaveChangesAsync();
101+
}
102+
}
103+
104+
/// <summary>
105+
/// Get calendar events for a date range with optional filtering
106+
/// </summary>
107+
public async Task<List<CalendarEvent>> GetEventsAsync(
108+
DateTime startDate,
109+
DateTime endDate,
110+
List<string>? eventTypes = null)
111+
{
112+
var organizationId = await _userContextService.GetActiveOrganizationIdAsync();
113+
var query = _context.CalendarEvents
114+
.Include(e => e.Property)
115+
.Where(e => e.OrganizationId == organizationId
116+
&& e.StartOn >= startDate
117+
&& e.StartOn <= endDate
118+
&& !e.IsDeleted);
119+
120+
if (eventTypes?.Any() == true)
121+
{
122+
query = query.Where(e => eventTypes.Contains(e.EventType));
123+
}
124+
125+
return await query.OrderBy(e => e.StartOn).ToListAsync();
126+
}
127+
128+
/// <summary>
129+
/// Get a specific calendar event by ID
130+
/// </summary>
131+
public async Task<CalendarEvent?> GetEventByIdAsync(Guid eventId)
132+
{
133+
var organizationId = await _userContextService.GetActiveOrganizationIdAsync();
134+
return await _context.CalendarEvents
135+
.Include(e => e.Property)
136+
.FirstOrDefaultAsync(e => e.Id == eventId
137+
&& e.OrganizationId == organizationId
138+
&& !e.IsDeleted);
139+
}
140+
141+
/// <summary>
142+
/// Create a custom calendar event (not linked to a domain entity)
143+
/// </summary>
144+
public async Task<CalendarEvent> CreateCustomEventAsync(CalendarEvent calendarEvent)
145+
{
146+
calendarEvent.EventType = CalendarEventTypes.Custom;
147+
calendarEvent.SourceEntityId = null;
148+
calendarEvent.SourceEntityType = null;
149+
calendarEvent.Color = CalendarEventTypes.GetColor(CalendarEventTypes.Custom);
150+
calendarEvent.Icon = CalendarEventTypes.GetIcon(CalendarEventTypes.Custom);
151+
calendarEvent.CreatedOn = DateTime.UtcNow;
152+
153+
_context.CalendarEvents.Add(calendarEvent);
154+
await _context.SaveChangesAsync();
155+
156+
return calendarEvent;
157+
}
158+
159+
/// <summary>
160+
/// Update a custom calendar event
161+
/// </summary>
162+
public async Task<CalendarEvent?> UpdateCustomEventAsync(CalendarEvent calendarEvent)
163+
{
164+
var existing = await _context.CalendarEvents
165+
.FirstOrDefaultAsync(e => e.Id == calendarEvent.Id
166+
&& e.OrganizationId == calendarEvent.OrganizationId
167+
&& e.SourceEntityType == null
168+
&& !e.IsDeleted);
169+
170+
if (existing == null) return null;
171+
172+
existing.Title = calendarEvent.Title;
173+
existing.StartOn = calendarEvent.StartOn;
174+
existing.EndOn = calendarEvent.EndOn;
175+
existing.DurationMinutes = calendarEvent.DurationMinutes;
176+
existing.Description = calendarEvent.Description;
177+
existing.PropertyId = calendarEvent.PropertyId;
178+
existing.Location = calendarEvent.Location;
179+
existing.Status = calendarEvent.Status;
180+
existing.LastModifiedBy = calendarEvent.LastModifiedBy;
181+
existing.LastModifiedOn = calendarEvent.LastModifiedOn;
182+
183+
await _context.SaveChangesAsync();
184+
185+
return existing;
186+
}
187+
188+
/// <summary>
189+
/// Get all calendar events for a specific property
190+
/// </summary>
191+
public async Task<List<CalendarEvent>> GetEventsByPropertyIdAsync(Guid propertyId)
192+
{
193+
var organizationId = await _userContextService.GetActiveOrganizationIdAsync();
194+
return await _context.CalendarEvents
195+
.Include(e => e.Property)
196+
.Where(e => e.PropertyId == propertyId
197+
&& e.OrganizationId == organizationId
198+
&& !e.IsDeleted)
199+
.OrderByDescending(e => e.StartOn)
200+
.ToListAsync();
201+
}
202+
203+
/// <summary>
204+
/// Get upcoming events for the next N days
205+
/// </summary>
206+
public async Task<List<CalendarEvent>> GetUpcomingEventsAsync(
207+
int days = 7,
208+
List<string>? eventTypes = null)
209+
{
210+
var startDate = DateTime.Today;
211+
var endDate = DateTime.Today.AddDays(days);
212+
return await GetEventsAsync(startDate, endDate, eventTypes);
213+
}
214+
215+
/// <summary>
216+
/// Create a CalendarEvent from a schedulable entity
217+
/// </summary>
218+
private CalendarEvent CreateEventFromEntity<T>(T entity)
219+
where T : BaseModel, ISchedulableEntity
220+
{
221+
var eventType = entity.GetEventType();
222+
223+
return new CalendarEvent
224+
{
225+
Id = Guid.NewGuid(),
226+
Title = entity.GetEventTitle(),
227+
StartOn = entity.GetEventStart(),
228+
DurationMinutes = entity.GetEventDuration(),
229+
EventType = eventType,
230+
Status = entity.GetEventStatus(),
231+
Description = entity.GetEventDescription(),
232+
PropertyId = entity.GetPropertyId(),
233+
Color = CalendarEventTypes.GetColor(eventType),
234+
Icon = CalendarEventTypes.GetIcon(eventType),
235+
SourceEntityId = entity.Id,
236+
SourceEntityType = typeof(T).Name,
237+
OrganizationId = entity.OrganizationId,
238+
CreatedBy = entity.CreatedBy,
239+
CreatedOn = DateTime.UtcNow
240+
};
241+
}
242+
243+
/// <summary>
244+
/// Update a CalendarEvent from a schedulable entity
245+
/// </summary>
246+
private void UpdateEventFromEntity<T>(CalendarEvent evt, T entity)
247+
where T : ISchedulableEntity
248+
{
249+
evt.Title = entity.GetEventTitle();
250+
evt.StartOn = entity.GetEventStart();
251+
evt.DurationMinutes = entity.GetEventDuration();
252+
evt.EventType = entity.GetEventType();
253+
evt.Status = entity.GetEventStatus();
254+
evt.Description = entity.GetEventDescription();
255+
evt.PropertyId = entity.GetPropertyId();
256+
evt.Color = CalendarEventTypes.GetColor(entity.GetEventType());
257+
evt.Icon = CalendarEventTypes.GetIcon(entity.GetEventType());
258+
}
259+
}
260+
}

0 commit comments

Comments
 (0)