public async Task <IActionResult> CalculateBonus([FromBody] CalculateBonusDto request)
        {
            if (request == null || request.SelectedEmployeeId == 0)
            {
                return(ErrorResponse());
            }

            var employee = await _employeeService.GetEmployee(request.SelectedEmployeeId);

            if (employee == null)
            {
                return(ErrorResponse());
            }

            var totalSalary     = _employeeService.GetTotalSalary();
            var bonusAllocation = _bonusPoolService.Calculate(request.TotalBonusPoolAmount, totalSalary, employee.Salary);

            var result = new BonusPoolCalculatorResultDto
            {
                Employee = new EmployeeDto(employee),
                Amount   = bonusAllocation
            };

            return(Ok(result));
        }
        public async Task CalculateAsync_Should_Return_Correct_Result()
        {
            // Arrange
            var employeeServiceMock      = new Mock <IEmployeeService>();
            var mappingServiceMock       = new Mock <IMappingService>();
            var calculationServiceMock   = new Mock <ICalculationService>();
            int bonusPoolAmount          = 10000;
            int selectedEmployeeId       = 1;
            int totalCompanySalaryBudget = 100000;
            var employee   = new Employee(1, "Amanda Woods", "Product Owner", 50000, 1);
            var department = new DepartmentDto()
            {
                Title       = "IT",
                Description = "The software development department for the company"
            };
            var mappedEmployee = new EmployeeDto
            {
                Id         = 1,
                Fullname   = "Amanda Woods",
                JobTitle   = "Product Owner",
                Salary     = 60000,
                Department = department
            };

            decimal expectedEmployeeBonusPercentage = (decimal)employee.Salary / (decimal)totalCompanySalaryBudget;
            int     expectedBonusAmount             = (int)(expectedEmployeeBonusPercentage * bonusPoolAmount);
            var     mappedBonusPoolCalculatorResult = new BonusPoolCalculatorResultDto
            {
                Employee = mappedEmployee,
                Amount   = expectedBonusAmount
            };

            calculationServiceMock
            .Setup(x => x.CalculateTotalSalaryBudgetForCompany())
            .ReturnsAsync(totalCompanySalaryBudget);
            employeeServiceMock.Setup(x => x.GetEmployeeByIdAsync(It.IsAny <int>())).ReturnsAsync(employee);
            calculationServiceMock
            .Setup(x => x.CalculateEmployeeBonusAllocation(It.IsAny <decimal>(), It.IsAny <decimal>()))
            .Returns(expectedEmployeeBonusPercentage);
            calculationServiceMock
            .Setup(x => x.CalculateEmployeeBonus(It.IsAny <decimal>(), It.IsAny <int>()))
            .Returns(expectedBonusAmount);
            mappingServiceMock
            .Setup(x => x.MapBonusPoolCalculatorResultToDto(It.IsAny <Employee>(), It.IsAny <int>()))
            .Returns(mappedBonusPoolCalculatorResult);
            var service = new BonusPoolService(employeeServiceMock.Object,
                                               calculationServiceMock.Object,
                                               mappingServiceMock.Object);

            // Act
            var result = await service.CalculateAsync(bonusPoolAmount, selectedEmployeeId);

            // Assert
            Assert.IsNotNull(result);
            Assert.IsInstanceOfType(result, typeof(BonusPoolCalculatorResultDto));
            Assert.AreEqual(mappedBonusPoolCalculatorResult, result);
            Assert.AreEqual(expectedBonusAmount, result.Amount);
            Assert.AreEqual(mappedEmployee, result.Employee);
        }
        public async Task CalculateBonus_Should_Return_Correct_Results()
        {
            // Arrange
            var bonusPoolServiceMock     = new Mock <IBonusPoolService>();
            int selectedEmployeeId       = 1;
            int totalCompanySalaryBudget = 100000;
            int bonusPoolAmount          = 10000;

            var request = new CalculateBonusDto
            {
                SelectedEmployeeId   = selectedEmployeeId,
                TotalBonusPoolAmount = totalCompanySalaryBudget
            };

            var employee   = new Employee(1, "Amanda Woods", "Product Owner", 60000, 1);
            var department = new DepartmentDto()
            {
                Title       = "IT",
                Description = "The software development department for the company"
            };
            var mappedEmployee = new EmployeeDto()
            {
                Id         = 1,
                Fullname   = "Amanda Woods",
                JobTitle   = "Product Owner",
                Salary     = 60000,
                Department = department
            };
            decimal expectedEmployeeBonusPercentage = (decimal)employee.Salary / (decimal)totalCompanySalaryBudget;
            int     expectedBonusAmount             = (int)(expectedEmployeeBonusPercentage * bonusPoolAmount);
            var     mappedBonusPoolCalculatorResult = new BonusPoolCalculatorResultDto
            {
                Employee = mappedEmployee,
                Amount   = expectedBonusAmount
            };

            bonusPoolServiceMock
            .Setup(x => x.CalculateAsync(It.IsAny <int>(), It.IsAny <int>()))
            .ReturnsAsync(mappedBonusPoolCalculatorResult);
            var controller = new BonusPoolController(bonusPoolServiceMock.Object);

            // Act
            var result = await controller.CalculateBonus(request);

            var objectResult       = result as ObjectResult;
            var expectedStatusCode = StatusCodes.Status200OK;

            // Assert
            Assert.IsNotNull(result);
            Assert.IsInstanceOfType(result, typeof(IActionResult));
            Assert.AreEqual(expectedStatusCode, objectResult.StatusCode);
            Assert.AreEqual(mappedBonusPoolCalculatorResult, objectResult.Value);
        }