| using Diligent.WebAPI.Data.Entities; | using Diligent.WebAPI.Data.Entities; | ||||
| using Diligent.WebAPI.Data.HelperModels; | |||||
| namespace Diligent.WebAPI.Business.Interfaces | namespace Diligent.WebAPI.Business.Interfaces | ||||
| { | { | ||||
| public interface IRoomRepository : IBaseRepository<Room> | public interface IRoomRepository : IBaseRepository<Room> | ||||
| { | { | ||||
| Task<bool> AddCustomerToRoom(string customerId, string roomId); | |||||
| Task<bool> AddMessage(string roomId, Message message); | |||||
| Task<List<Message>> GetMessagesForSpecificRoom(string roomId); | |||||
| Task<bool> LeaveChatRoom(string roomId, string userId); | |||||
| Task AddCustomerToRoom(Room room, string customerId); | |||||
| Task AddMessage(Room room, Message message); | |||||
| Task LeaveChatRoom(Room room, CustomerDTO userConnection); | |||||
| Task<List<Room>> GetRoomsWhichSupportCreated(string supportId); | Task<List<Room>> GetRoomsWhichSupportCreated(string supportId); | ||||
| Task<List<Room>?> GetRoomsWithFilteredMessages(string customerId); | |||||
| } | } | ||||
| } | } |
| using MongoDB.Driver; | using MongoDB.Driver; | ||||
| using System; | using System; | ||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| using System.Diagnostics.CodeAnalysis; | |||||
| using System.Linq; | using System.Linq; | ||||
| using System.Text; | using System.Text; | ||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| namespace Diligent.WebAPI.Business.Services | namespace Diligent.WebAPI.Business.Services | ||||
| { | { | ||||
| [ExcludeFromCodeCoverage] | |||||
| public class RequestRepository : BaseRepository<Request>, IRequestRepository | public class RequestRepository : BaseRepository<Request>, IRequestRepository | ||||
| { | { | ||||
| protected new IMongoCollection<Request> _dbCollection; | protected new IMongoCollection<Request> _dbCollection; |
| using Diligent.WebAPI.Business.Interfaces; | using Diligent.WebAPI.Business.Interfaces; | ||||
| using Diligent.WebAPI.Data; | using Diligent.WebAPI.Data; | ||||
| using Diligent.WebAPI.Data.Entities; | using Diligent.WebAPI.Data.Entities; | ||||
| using Diligent.WebAPI.Data.HelperModels; | |||||
| using MongoDB.Driver; | using MongoDB.Driver; | ||||
| namespace Diligent.WebAPI.Business.Services | namespace Diligent.WebAPI.Business.Services | ||||
| { | { | ||||
| public class RoomRepository : BaseRepository<Room>, IRoomRepository | public class RoomRepository : BaseRepository<Room>, IRoomRepository | ||||
| { | { | ||||
| protected new IMongoCollection<Request> _dbCollection; | |||||
| protected new IMongoCollection<Room> _dbCollection; | |||||
| public RoomRepository(IMongoDBContext context) : base(context) | public RoomRepository(IMongoDBContext context) : base(context) | ||||
| { | { | ||||
| _dbCollection = _mongoContext.GetCollection<Request>(typeof(Request).Name); | |||||
| _dbCollection = _mongoContext.GetCollection<Room>(typeof(Room).Name); | |||||
| } | } | ||||
| public Task<bool> AddCustomerToRoom(string customerId, string roomId) | |||||
| public async Task AddCustomerToRoom(Room room, string customerId) | |||||
| { | { | ||||
| throw new NotImplementedException(); | |||||
| } | |||||
| room.Customers.Add(new CustomerDTO { CustomerId = customerId, DateOfEnteringRoom = DateTime.Now }); | |||||
| public Task<bool> AddMessage(string roomId, Message message) | |||||
| { | |||||
| throw new NotImplementedException(); | |||||
| await _dbCollection.ReplaceOneAsync(x => x.Id == room.Id, room); | |||||
| } | } | ||||
| public Task<List<Message>> GetMessagesForSpecificRoom(string roomId) | |||||
| public async Task AddMessage(Room room, Message message) | |||||
| { | { | ||||
| throw new NotImplementedException(); | |||||
| room.Messages.Add(message); | |||||
| await _dbCollection.ReplaceOneAsync(x => x.Id == room.Id, room); | |||||
| } | } | ||||
| public Task<List<Room>> GetRoomsWhichSupportCreated(string supportId) | |||||
| { | |||||
| throw new NotImplementedException(); | |||||
| } | |||||
| public async Task<List<Room>> GetRoomsWhichSupportCreated(string supportId) => | |||||
| await _dbCollection.Find(k => k.CreatedBy == supportId).ToListAsync(); | |||||
| public Task<List<Room>?> GetRoomsWithFilteredMessages(string customerId) | |||||
| public async Task LeaveChatRoom(Room room, CustomerDTO userConnection) | |||||
| { | { | ||||
| throw new NotImplementedException(); | |||||
| } | |||||
| room.Customers.Remove(userConnection); | |||||
| public Task<bool> LeaveChatRoom(string roomId, string userId) | |||||
| { | |||||
| throw new NotImplementedException(); | |||||
| await _dbCollection.ReplaceOneAsync(x => x.Id == room.Id, room); | |||||
| } | } | ||||
| } | } | ||||
| } | } |
| using Diligent.WebAPI.Business.MongoServices; | |||||
| using Diligent.WebAPI.Data; | |||||
| using Diligent.WebAPI.Data.Entities; | |||||
| using Diligent.WebAPI.Data.HelperModels; | |||||
| using Microsoft.Extensions.Options; | |||||
| using MongoDB.Driver; | |||||
| namespace Diligent.WebAPI.Business.Services | |||||
| { | |||||
| public class RoomService : BaseMongo<Room> | |||||
| { | |||||
| public RoomService(IOptions<WebApiDatabaseSettings> webApiDatabaseSettings) : | |||||
| base(webApiDatabaseSettings, "Room") | |||||
| { } | |||||
| public async Task<List<Room>> GetRoomsAsync() => | |||||
| await _mongoCollection.Find(_ => true).ToListAsync(); | |||||
| public async Task CreateRoomAsync(Room room) => | |||||
| await _mongoCollection.InsertOneAsync(room); | |||||
| public async Task<bool> AddCustomerToRoom(string customerId,string roomId) | |||||
| { | |||||
| var room = await _mongoCollection.Find(k => k.Id == roomId).FirstOrDefaultAsync(); | |||||
| if (room is null) | |||||
| return false; | |||||
| room.Customers.Add(new CustomerDTO { CustomerId = customerId, DateOfEnteringRoom = DateTime.Now}); | |||||
| await _mongoCollection.ReplaceOneAsync(x => x.Id == roomId, room); | |||||
| return true; | |||||
| } | |||||
| public async Task<Room> GetRoomAsync(string roomId) => | |||||
| await _mongoCollection.Find(r => r.Id == roomId).FirstOrDefaultAsync(); | |||||
| public async Task<bool> AddMessage(string roomId,Message message) | |||||
| { | |||||
| var room = await GetRoomAsync(roomId); | |||||
| if (room is null) | |||||
| return false; | |||||
| room.Messages.Add(message); | |||||
| await _mongoCollection.ReplaceOneAsync(x => x.Id == roomId, room); | |||||
| return true; | |||||
| } | |||||
| public async Task<List<Message>> GetMessagesForSpecificRoom(string roomId) | |||||
| { | |||||
| var room = await _mongoCollection.Find(r => r.Id == roomId).FirstOrDefaultAsync(); | |||||
| if (room is null) return new List<Message>(); | |||||
| return room.Messages; | |||||
| } | |||||
| public async Task<List<Room>> GetRoomsForSupport(string supportId) => | |||||
| await _mongoCollection.Find(k => k.CreatedBy == supportId).ToListAsync(); | |||||
| public async Task<bool> LeaveChatRoom(string roomId, string userId) | |||||
| { | |||||
| var room = await GetRoomAsync(roomId); | |||||
| if (room == null) | |||||
| { | |||||
| return false; | |||||
| } | |||||
| var userConnection = room.Customers.Where(x => x.CustomerId == userId).FirstOrDefault(); | |||||
| if (userConnection == null) | |||||
| { | |||||
| return false; | |||||
| } | |||||
| room.Customers.Remove(userConnection); | |||||
| await _mongoCollection.ReplaceOneAsync(x => x.Id == roomId, room); | |||||
| return true; | |||||
| } | |||||
| public async Task<List<Room>> GetRoomsWhichSupportCreated(string supportId) => | |||||
| await _mongoCollection.Find(k => k.CreatedBy == supportId).ToListAsync(); | |||||
| public async Task<List<Room>?> GetRoomsWithFilteredMessages(string customerId) | |||||
| { | |||||
| var rooms = await GetRoomsAsync(); | |||||
| foreach (var room in rooms) | |||||
| { | |||||
| List<Message> msg = new(); | |||||
| var customer = room.Customers.Where(c => c.CustomerId == customerId).FirstOrDefault(); | |||||
| if (customer is not null) | |||||
| { | |||||
| foreach (var message in room.Messages) | |||||
| { | |||||
| if (message.CreatedAtUtc >= customer.DateOfEnteringRoom) | |||||
| msg.Add(message); | |||||
| } | |||||
| room.Messages = msg; | |||||
| } | |||||
| else | |||||
| { | |||||
| room.Messages = new List<Message>(); | |||||
| } | |||||
| } | |||||
| return rooms; | |||||
| } | |||||
| } | |||||
| } |
| public async Task<ActionResult<List<CustomerRequestRoomReadDTO>>> GetCustomersForSpecificRequestRoom(string id) => | public async Task<ActionResult<List<CustomerRequestRoomReadDTO>>> GetCustomersForSpecificRequestRoom(string id) => | ||||
| await _mediator.Send(new GetSendersForSpecificRequestRoomQuery(id)); | await _mediator.Send(new GetSendersForSpecificRequestRoomQuery(id)); | ||||
| //public async Task<ActionResult> AcceptCustomerRequest(AcceptCustomerRequestCommand request) | |||||
| [HttpPost("accept-request")] | [HttpPost("accept-request")] | ||||
| public async Task<ActionResult> AcceptCustomerRequest(AcceptCustomerDTO acceptCustomerDTO) | public async Task<ActionResult> AcceptCustomerRequest(AcceptCustomerDTO acceptCustomerDTO) | ||||
| { | { | ||||
| //var id = await _mediator.Send(request); | |||||
| var id = await _mediator.Send(new AcceptCustomerRequestCommand(acceptCustomerDTO.customerId, acceptCustomerDTO.roomId)); | var id = await _mediator.Send(new AcceptCustomerRequestCommand(acceptCustomerDTO.customerId, acceptCustomerDTO.roomId)); | ||||
| return Ok(id); | return Ok(id); | ||||
| } | } |
| builder.Services.AddScoped<IAuthenticationService, AuthenticationService>(); | builder.Services.AddScoped<IAuthenticationService, AuthenticationService>(); | ||||
| builder.Services.AddScoped<ICustomerService, CustomerService>(); | builder.Services.AddScoped<ICustomerService, CustomerService>(); | ||||
| builder.Services.AddSingleton<RoomService>(); | |||||
| builder.Services.AddSingleton<AuthorizationService>(); | builder.Services.AddSingleton<AuthorizationService>(); | ||||
| builder.Services.AddMediatR(Assembly.GetExecutingAssembly()); | builder.Services.AddMediatR(Assembly.GetExecutingAssembly()); |
| using Diligent.WebAPI.Business.Services; | |||||
| using Diligent.WebAPI.Business.Interfaces; | |||||
| using Diligent.WebAPI.Business.Services; | |||||
| using Diligent.WebAPI.Data.Entities; | using Diligent.WebAPI.Data.Entities; | ||||
| using Diligent.WebAPI.Host.Exceptions; | using Diligent.WebAPI.Host.Exceptions; | ||||
| using Diligent.WebAPI.Host.Mediator.Messages.Commands; | using Diligent.WebAPI.Host.Mediator.Messages.Commands; | ||||
| { | { | ||||
| public class AddMessageHandler : IRequestHandler<AddMessageCommand, Unit> | public class AddMessageHandler : IRequestHandler<AddMessageCommand, Unit> | ||||
| { | { | ||||
| private readonly RoomService _roomService; | |||||
| private readonly IRoomRepository _roomRepository; | |||||
| public AddMessageHandler(RoomService roomService) | |||||
| public AddMessageHandler(IRoomRepository roomRepository) | |||||
| { | { | ||||
| _roomService = roomService; | |||||
| _roomRepository = roomRepository; | |||||
| } | } | ||||
| public async Task<Unit> Handle(AddMessageCommand request, CancellationToken cancellationToken) | public async Task<Unit> Handle(AddMessageCommand request, CancellationToken cancellationToken) | ||||
| { | { | ||||
| var result = await _roomService.AddMessage(request.roomId,request.message); | |||||
| var room = await _roomRepository.GetByIdAsync(request.roomId); | |||||
| if (!result) | |||||
| throw new NotFoundException("Room id doesn't exist"); | |||||
| if(room == null) | |||||
| { | |||||
| throw new NotFoundException("Room is not found"); | |||||
| } | |||||
| await _roomRepository.AddMessage(room, request.message); | |||||
| return new Unit(); | return new Unit(); | ||||
| } | } |
| { | { | ||||
| Request = request; | Request = request; | ||||
| } | } | ||||
| //public string SenderId { get; set; } | |||||
| //public string SenderUsername { get; set; } | |||||
| //public string RoomId { get; set; } | |||||
| //public string RoomName { get; set; } | |||||
| } | } | ||||
| } | } |
| public class AcceptCustomerRequestHandler : IRequestHandler<AcceptCustomerRequestCommand, string?> | public class AcceptCustomerRequestHandler : IRequestHandler<AcceptCustomerRequestCommand, string?> | ||||
| { | { | ||||
| private readonly IRequestRepository _requestRepository; | private readonly IRequestRepository _requestRepository; | ||||
| private readonly RoomService _roomService; | |||||
| private readonly IRoomRepository _roomRepository; | |||||
| public AcceptCustomerRequestHandler(RoomService roomService, IRequestRepository requestRepository) | |||||
| public AcceptCustomerRequestHandler(IRequestRepository requestRepository, IRoomRepository roomRepository) | |||||
| { | { | ||||
| _roomService = roomService; | |||||
| _requestRepository = requestRepository; | _requestRepository = requestRepository; | ||||
| _roomRepository = roomRepository; | |||||
| } | } | ||||
| public async Task<string?> Handle(AcceptCustomerRequestCommand request, CancellationToken cancellationToken) | public async Task<string?> Handle(AcceptCustomerRequestCommand request, CancellationToken cancellationToken) | ||||
| { | { | ||||
| var result1 = await _roomService.AddCustomerToRoom(request.CustomerId, request.RoomId); | |||||
| var room = await _roomRepository.GetByIdAsync(request.RoomId); | |||||
| if (!result1) | |||||
| throw new NotFoundException($"Room with id={request.RoomId} doesn't exist"); | |||||
| if(room == null) | |||||
| { | |||||
| throw new NotFoundException("Room are not found"); | |||||
| } | |||||
| await _roomRepository.AddCustomerToRoom(room, request.CustomerId); | |||||
| var req = await _requestRepository.FindRequestAsync(request.CustomerId, request.RoomId); | var req = await _requestRepository.FindRequestAsync(request.CustomerId, request.RoomId); | ||||
| if (req == null) | if (req == null) | ||||
| throw new BadHttpRequestException("Resource object cannot be null."); | throw new BadHttpRequestException("Resource object cannot be null."); | ||||
| var createdRequest = _mapper.Map<Data.Entities.Request>(req); | var createdRequest = _mapper.Map<Data.Entities.Request>(req); | ||||
| await _requestService.CreateAsync(createdRequest); | await _requestService.CreateAsync(createdRequest); | ||||
| using AutoMapper; | using AutoMapper; | ||||
| using Diligent.WebAPI.Business.Interfaces; | using Diligent.WebAPI.Business.Interfaces; | ||||
| using Diligent.WebAPI.Business.Services; | |||||
| using Diligent.WebAPI.Data.Entities; | using Diligent.WebAPI.Data.Entities; | ||||
| using Diligent.WebAPI.Host.DTOs.Request; | using Diligent.WebAPI.Host.DTOs.Request; | ||||
| using Diligent.WebAPI.Host.Mediator.Request.Queries; | using Diligent.WebAPI.Host.Mediator.Request.Queries; | ||||
| public class GetRoomsForWhichRequestExistHandler : IRequestHandler<GetRoomsForWhichRequestExistQuery, List<RequestRoomReadDTO>> | public class GetRoomsForWhichRequestExistHandler : IRequestHandler<GetRoomsForWhichRequestExistQuery, List<RequestRoomReadDTO>> | ||||
| { | { | ||||
| private readonly IRequestRepository _requestService; | private readonly IRequestRepository _requestService; | ||||
| private readonly RoomService _roomService; | |||||
| private readonly IRoomRepository _roomRepository; | |||||
| private readonly IMapper _mapper; | private readonly IMapper _mapper; | ||||
| public GetRoomsForWhichRequestExistHandler(IRequestRepository requestService,RoomService roomService,IMapper mapper) | |||||
| public GetRoomsForWhichRequestExistHandler(IRequestRepository requestService, IMapper mapper, IRoomRepository roomRepository) | |||||
| { | { | ||||
| _requestService = requestService; | _requestService = requestService; | ||||
| _roomService = roomService; | |||||
| _mapper = mapper; | _mapper = mapper; | ||||
| _roomRepository = roomRepository; | |||||
| } | } | ||||
| public async Task<List<RequestRoomReadDTO>> Handle(GetRoomsForWhichRequestExistQuery request, CancellationToken cancellationToken) | public async Task<List<RequestRoomReadDTO>> Handle(GetRoomsForWhichRequestExistQuery request, CancellationToken cancellationToken) | ||||
| { | { | ||||
| var requests = await _requestService.GetAsync(); | var requests = await _requestService.GetAsync(); | ||||
| var rooms = await _roomService.GetRoomsAsync(); | |||||
| var rooms = await _roomRepository.GetAsync(); | |||||
| List<Room> temp = new(); | List<Room> temp = new(); | ||||
| foreach (var req in requests) | foreach (var req in requests) | ||||
| { | { |
| using Diligent.WebAPI.Business.Services; | |||||
| using Diligent.WebAPI.Business.Interfaces; | |||||
| using Diligent.WebAPI.Business.Services; | |||||
| using Diligent.WebAPI.Data.Entities; | using Diligent.WebAPI.Data.Entities; | ||||
| using Diligent.WebAPI.Host.Mediator.Rooms.Queries; | using Diligent.WebAPI.Host.Mediator.Rooms.Queries; | ||||
| using MediatR; | using MediatR; | ||||
| { | { | ||||
| public class GetAllRoomsWithFilteredMessagesHandler : IRequestHandler<GetAllRoomsWithFilteredMessagesQuery, List<Room>> | public class GetAllRoomsWithFilteredMessagesHandler : IRequestHandler<GetAllRoomsWithFilteredMessagesQuery, List<Room>> | ||||
| { | { | ||||
| private readonly RoomService _roomService; | |||||
| private readonly IRoomRepository _roomRepository; | |||||
| public GetAllRoomsWithFilteredMessagesHandler(RoomService roomService) | |||||
| public GetAllRoomsWithFilteredMessagesHandler(IRoomRepository roomRepository) | |||||
| { | { | ||||
| _roomService = roomService; | |||||
| _roomRepository = roomRepository; | |||||
| } | } | ||||
| public async Task<List<Room>> Handle(GetAllRoomsWithFilteredMessagesQuery request, CancellationToken cancellationToken) | public async Task<List<Room>> Handle(GetAllRoomsWithFilteredMessagesQuery request, CancellationToken cancellationToken) | ||||
| { | { | ||||
| var rooms = await _roomService.GetRoomsWithFilteredMessages(request.CustomerId); | |||||
| var rooms = await _roomRepository.GetAsync(); | |||||
| //if (rooms == null) | |||||
| // throw new BadHttpRequestException("Please send a valid customer id"); | |||||
| foreach (var room in rooms) | |||||
| { | |||||
| return rooms; | |||||
| List<Message> msg = new(); | |||||
| var customer = room.Customers.Where(c => c.CustomerId == request.CustomerId).FirstOrDefault(); | |||||
| if (customer is not null) | |||||
| { | |||||
| foreach (var message in room.Messages) | |||||
| { | |||||
| if (message.CreatedAtUtc >= customer.DateOfEnteringRoom) | |||||
| msg.Add(message); | |||||
| } | |||||
| room.Messages = msg; | |||||
| } | |||||
| else | |||||
| { | |||||
| room.Messages = new List<Message>(); | |||||
| } | |||||
| } | |||||
| return rooms; | |||||
| } | } | ||||
| } | } | ||||
| } | } |
| using Diligent.WebAPI.Business.Services; | |||||
| using Diligent.WebAPI.Business.Interfaces; | |||||
| using Diligent.WebAPI.Business.Services; | |||||
| using Diligent.WebAPI.Data.Entities; | using Diligent.WebAPI.Data.Entities; | ||||
| using Diligent.WebAPI.Host.Mediator.Rooms.Queries; | using Diligent.WebAPI.Host.Mediator.Rooms.Queries; | ||||
| using MediatR; | using MediatR; | ||||
| { | { | ||||
| public class GetRoomsWhichSupportCreatedHandler : IRequestHandler<GetRoomsWhichSupportCreatedQuery, List<Room>> | public class GetRoomsWhichSupportCreatedHandler : IRequestHandler<GetRoomsWhichSupportCreatedQuery, List<Room>> | ||||
| { | { | ||||
| private readonly RoomService _roomService; | |||||
| private readonly IRoomRepository _roomRepository; | |||||
| public GetRoomsWhichSupportCreatedHandler(RoomService roomService) | |||||
| public GetRoomsWhichSupportCreatedHandler(IRoomRepository roomRepository) | |||||
| { | { | ||||
| _roomService = roomService; | |||||
| _roomRepository = roomRepository; | |||||
| } | } | ||||
| public async Task<List<Room>> Handle(GetRoomsWhichSupportCreatedQuery request, CancellationToken cancellationToken) => | public async Task<List<Room>> Handle(GetRoomsWhichSupportCreatedQuery request, CancellationToken cancellationToken) => | ||||
| await _roomService.GetRoomsWhichSupportCreated(request.SupportId); | |||||
| await _roomRepository.GetRoomsWhichSupportCreated(request.SupportId); | |||||
| } | } | ||||
| } | } |
| using Diligent.WebAPI.Business.Services; | |||||
| using Diligent.WebAPI.Business.Interfaces; | |||||
| using Diligent.WebAPI.Business.Services; | |||||
| using Diligent.WebAPI.Host.Exceptions; | |||||
| using Diligent.WebAPI.Host.Mediator.Rooms.Commands; | using Diligent.WebAPI.Host.Mediator.Rooms.Commands; | ||||
| using MediatR; | using MediatR; | ||||
| { | { | ||||
| public class RemoveUserFromGroupHandler : IRequestHandler<RemoveUserFromGroupCommand, Unit> | public class RemoveUserFromGroupHandler : IRequestHandler<RemoveUserFromGroupCommand, Unit> | ||||
| { | { | ||||
| private readonly RoomService _roomService; | |||||
| private readonly IRoomRepository _roomRepository; | |||||
| public RemoveUserFromGroupHandler(RoomService roomService) | |||||
| public RemoveUserFromGroupHandler(IRoomRepository roomRepository) | |||||
| { | { | ||||
| _roomService = roomService; | |||||
| _roomRepository = roomRepository; | |||||
| } | } | ||||
| public async Task<Unit> Handle(RemoveUserFromGroupCommand request, CancellationToken cancellationToken) | public async Task<Unit> Handle(RemoveUserFromGroupCommand request, CancellationToken cancellationToken) | ||||
| { | { | ||||
| if (request == null) | |||||
| var room = await _roomRepository.GetByIdAsync(request.RoomId); | |||||
| if(room == null) | |||||
| { | { | ||||
| throw new BadHttpRequestException("Object cannot be null"); | |||||
| throw new NotFoundException("Room is not found"); | |||||
| } | } | ||||
| var result = await _roomService.LeaveChatRoom(request.RoomId, request.UserId); | |||||
| var userConnection = room.Customers.Where(x => x.CustomerId == request.UserId).FirstOrDefault(); | |||||
| if (!result) | |||||
| if(userConnection == null) | |||||
| { | { | ||||
| throw new Exception("Problem with deleting user from group"); | |||||
| throw new NotFoundException("User connection is not found"); | |||||
| } | } | ||||
| await _roomRepository.LeaveChatRoom(room, userConnection); | |||||
| return new Unit(); | return new Unit(); | ||||
| } | } | ||||
| } | } |