From 3b621227cf25fc3a4cff87f9cb9508a416445702 Mon Sep 17 00:00:00 2001 From: jojo aquino Date: Mon, 24 Mar 2025 09:10:06 +0000 Subject: [PATCH] new ConferenceSheduleService --- .../Services/ConferenceSheduleService.cs | 163 ++++++++++++++++++ .../Services/IConferenceSheduleService.cs | 11 ++ 2 files changed, 174 insertions(+) create mode 100644 EnotaryoPH/EnotaryoPH.Web/Common/Services/ConferenceSheduleService.cs create mode 100644 EnotaryoPH/EnotaryoPH.Web/Common/Services/IConferenceSheduleService.cs diff --git a/EnotaryoPH/EnotaryoPH.Web/Common/Services/ConferenceSheduleService.cs b/EnotaryoPH/EnotaryoPH.Web/Common/Services/ConferenceSheduleService.cs new file mode 100644 index 0000000..c848c5c --- /dev/null +++ b/EnotaryoPH/EnotaryoPH.Web/Common/Services/ConferenceSheduleService.cs @@ -0,0 +1,163 @@ +using Azure; +using Azure.Communication; +using Azure.Communication.CallAutomation; +using Azure.Communication.Identity; +using Azure.Communication.Rooms; +using EnotaryoPH.Data; +using EnotaryoPH.Data.Entities; + +namespace EnotaryoPH.Web.Common.Services +{ + public class ConferenceSheduleService : IConferenceSheduleService + { + private readonly NotaryoDBContext _dbContext; + private readonly CommunicationIdentityClient _communicationIdentityClient; + private readonly RoomsClient _roomsClient; + private readonly CallAutomationClient _callAutomationClient; + + public ConferenceSheduleService(NotaryoDBContext dbContext, CommunicationIdentityClient communicationIdentityClient, RoomsClient roomsClient, CallAutomationClient callAutomationClient) + { + _dbContext = dbContext; + _communicationIdentityClient = communicationIdentityClient; + _roomsClient = roomsClient; + _callAutomationClient = callAutomationClient; + } + + public async Task GetOrCreateScheduleIDAsync(Guid transaction_UID) + { + if (transaction_UID == Guid.Empty) + { + return Guid.Empty; + } + + var transactionEntity = _dbContext.Transactions + .Include(t => t.TransactionSignatories) + .FirstOrDefault(t => t.Transaction_UID == transaction_UID); + if (transactionEntity == null) + { + return Guid.Empty; + } + + var existingSchedule = _dbContext.LawyerVideoConferenceSchedules.FirstOrDefault(sched => sched.TransactionID == transactionEntity.TransactionID); + if (existingSchedule != null) + { + return existingSchedule.LawyerVideoConferenceSchedule_UID; + } + + var schedule_UID = Guid.Empty; + var isReadyForVideoCall = transactionEntity.TransactionSignatories.All(signatory => signatory.Status == nameof(SignatoryStatus.FaceMatch)); + var isAcceptedByLawyer = transactionEntity.Status == nameof(TransactionState.Accepted) && transactionEntity.LawyerID > 0; + if (isReadyForVideoCall && isAcceptedByLawyer) + { + var schedule = _dbContext.LawyerVideoConferenceSchedules.FirstOrDefault(sched => sched.TransactionID == transactionEntity.TransactionID); + if (schedule == null) + { + var participants = transactionEntity.TransactionSignatories.ConvertAll(signatory => new LawyerVideoConferenceParticipant + { + CreatedOn = DateTime.UtcNow, + Status = nameof(VideoConferenceStatus.New), + LawyerVideoConferenceParticipant_UID = Guid.CreateVersion7(DateTime.UtcNow), + ParticipantID = signatory.UserID, + }); + + participants.Add(new LawyerVideoConferenceParticipant + { + CreatedOn = DateTime.UtcNow, + Status = nameof(VideoConferenceStatus.New), + LawyerVideoConferenceParticipant_UID = Guid.CreateVersion7(DateTime.UtcNow), + ParticipantID = transactionEntity.PrincipalID, + }); + + schedule = new LawyerVideoConferenceSchedule + { + LawyerVideoConferenceSchedule_UID = Guid.CreateVersion7(DateTime.UtcNow), + CreatedOn = DateTime.UtcNow, + LawyerID = transactionEntity.LawyerID.GetValueOrDefault(), + TransactionID = transactionEntity.TransactionID, + MeetingDate = DateTime.UtcNow, + Status = nameof(VideoConferenceStatus.New), + }; + + var roomParticipants = new List(); + foreach (var participant in participants) + { + var attendee = await _communicationIdentityClient.CreateUserAsync(); + participant.MeetingRoomTokenID = await GetTokenResponseAsync(attendee); + participant.MeetingRoomUserID = attendee.Value.Id; + roomParticipants.Add(new RoomParticipant(attendee) { Role = ParticipantRole.Attendee }); + } + + var presenter = await _communicationIdentityClient.CreateUserAsync(); + schedule.MeetingRoomTokenID = await GetTokenResponseAsync(presenter); + schedule.MeetingRoomUserID = presenter.Value.Id; + roomParticipants.Add(new RoomParticipant(presenter) { Role = ParticipantRole.Presenter }); + + CommunicationRoom room = await _roomsClient.CreateRoomAsync(DateTime.Now, DateTime.Now.AddHours(2), roomParticipants); + schedule.MeetingRoomID = room.Id; + schedule.LawyerVideoConferenceParticipants = participants.ToList(); + + if (schedule.LawyerVideoConferenceScheduleID == 0) + { + _dbContext.Add(schedule); + } + else + { + _dbContext.Update(schedule); + } + _dbContext.SaveChanges(); + } + } + + return schedule_UID; + } + + public async Task StartRecordingAsync(Guid transaction_UID) + { + var transactionEntity = _dbContext.Transactions + .FirstOrDefault(t => t.Transaction_UID == transaction_UID) ?? throw new ArgumentException("Transaction not found."); + + var existingSchedule = _dbContext.LawyerVideoConferenceSchedules.FirstOrDefault(sched => sched.TransactionID == transactionEntity.TransactionID) ?? throw new ArgumentException("Schedule not found."); + if (string.IsNullOrEmpty(existingSchedule.ServerCallID)) + { + throw new ArgumentException("ServerCallID is not set for this transaction."); + } + + if (!string.IsNullOrEmpty(existingSchedule.RecordingID)) + { + return; + } + + CallLocator callLocator = new ServerCallLocator(existingSchedule.ServerCallID); + var recordingResult = await _callAutomationClient.GetCallRecording().StartAsync(new StartRecordingOptions(callLocator) { RecordingStorage = RecordingStorage.CreateAzureBlobContainerRecordingStorage(new Uri("")) }); + existingSchedule.RecordingID = recordingResult.Value.RecordingId; + _dbContext.Update(existingSchedule); + _dbContext.SaveChanges(); + } + + public async Task StopRecordingAsync(Guid transaction_UID) + { + var transactionEntity = _dbContext.Transactions + .FirstOrDefault(t => t.Transaction_UID == transaction_UID) ?? throw new ArgumentException("Transaction not found."); + + var existingSchedule = _dbContext.LawyerVideoConferenceSchedules.FirstOrDefault(sched => sched.TransactionID == transactionEntity.TransactionID) ?? throw new ArgumentException("Schedule not found."); + if (string.IsNullOrEmpty(existingSchedule.ServerCallID)) + { + throw new ArgumentException("ServerCallID is not set for this transaction."); + } + + if (string.IsNullOrEmpty(existingSchedule.RecordingID)) + { + throw new ArgumentException("Recording ID is not set for this transaction."); + } + + CallLocator callLocator = new ServerCallLocator(existingSchedule.ServerCallID); + await _callAutomationClient.GetCallRecording().StopAsync(existingSchedule.RecordingID); + } + + private async Task GetTokenResponseAsync(Response user) + { + var tokenResponse = await _communicationIdentityClient.GetTokenAsync(user, new[] { CommunicationTokenScope.VoIP }); + return tokenResponse.Value.Token; + } + } +} \ No newline at end of file diff --git a/EnotaryoPH/EnotaryoPH.Web/Common/Services/IConferenceSheduleService.cs b/EnotaryoPH/EnotaryoPH.Web/Common/Services/IConferenceSheduleService.cs new file mode 100644 index 0000000..ab3753c --- /dev/null +++ b/EnotaryoPH/EnotaryoPH.Web/Common/Services/IConferenceSheduleService.cs @@ -0,0 +1,11 @@ +namespace EnotaryoPH.Web.Common.Services +{ + public interface IConferenceSheduleService + { + Task GetOrCreateScheduleIDAsync(Guid transaction_UID); + + Task StartRecordingAsync(Guid transaction_UID); + + Task StopRecordingAsync(Guid transaction_UID); + } +} \ No newline at end of file