using GB5Shared.DTO.Framework.AutoNumber; using GB5Shared.DTO.Framework.Criteria; using GB5Shared.DTO.Framework.Login; using GB5Shared.GenerateAutoNumber; using GB5Shared.Resource.Response; using GB5Shared.Validation; using PayrollDAL.DTO.AdditionDeduction; using PayRollDAL.CustomeCode.AdditionDeduction; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Threading.Tasks; namespace PayRollBLL.AdditionDeduction { public class AdditionDeductionBLL : IAdditionDeductionBLL { private readonly IAdditionDeductionDAL _additionDeductionDAL; private readonly AutoNumber _autoNumber; private readonly IValidation _validation; public AdditionDeductionBLL( IAdditionDeductionDAL additionDeductionDAL, AutoNumber autoNumber, IValidation validation) { _additionDeductionDAL = additionDeductionDAL; _autoNumber = autoNumber; _validation = validation; } public async Task GetAdditionDeductionListAsync( int firstNumber, int maxResult, CriteriaDTO criteriaDTO, LoginDTO loginDTO, bool isCount = false) { try { ValidateRequest(firstNumber, maxResult, criteriaDTO, loginDTO); (int validatedFirstNumber, int validatedMaxResult) = ValidatePagination(firstNumber, maxResult); return await _additionDeductionDAL.GetAdditionDeductionListAsync( validatedFirstNumber, validatedMaxResult, criteriaDTO, loginDTO, isCount ); } catch (Exception ex) { throw new Exception($"Error in GetAdditionDeductionListAsync BLL: {ex.Message}", ex); } } public async Task GetSelectListAdditionDeduction( int firstNumber, int maxResult, CriteriaDTO criteriaDTO, LoginDTO loginDTO, bool isCount = false) { try { if (firstNumber == 0 && maxResult == 0) { firstNumber = 0; maxResult = 10; } return await _additionDeductionDAL.GetSelectListAdditionDeduction( firstNumber, maxResult, criteriaDTO, loginDTO, isCount ); } catch (Exception ex) { throw new Exception($"Error in GetSelectListAdditionDeduction BLL: {ex.Message}", ex); } } public async Task GetAdditionDeduction(int additionDeductionId, LoginDTO loginDTO) { try { return await _additionDeductionDAL.GetAdditionDeduction(additionDeductionId, loginDTO); } catch (Exception) { throw; } } public async Task SaveAdditionDeduction(AdditionDeductionDTO additionDeductionDTO, LoginDTO loginDTO) { if (additionDeductionDTO == null) throw new ArgumentNullException(nameof(additionDeductionDTO)); AutoNumberDTO? autoNumberDTO = null; try { await _validation.NotEmpty(additionDeductionDTO.AdditionDeductionCode, nameof(additionDeductionDTO.AdditionDeductionCode)); additionDeductionDTO.AdditionDeductionModifiedOn = DateTime.UtcNow; additionDeductionDTO.AdditionDeductionModifiedById = loginDTO.UserId; if (additionDeductionDTO.AdditionDeductionId == 0) { autoNumberDTO = await _autoNumber.GetAutoNumber(1, "AdditionDeduction", loginDTO); additionDeductionDTO.AdditionDeductionId = autoNumberDTO.StartNumber; additionDeductionDTO.AdditionDeductionCreatedById = loginDTO.UserId; additionDeductionDTO.AdditionDeductionCreatedOn = DateTime.UtcNow; await _additionDeductionDAL.SaveAdditionDeduction(additionDeductionDTO, loginDTO); return $"{SuccessResponse.SaveSuccessMessage} {additionDeductionDTO.AdditionDeductionId}"; } else { await _additionDeductionDAL.UpdateAdditionDeduction(additionDeductionDTO, loginDTO); return $"{SuccessResponse.UpdateSuccessMessage} {additionDeductionDTO.AdditionDeductionId}"; } } catch (ValidationException vex) { throw new Exception(vex.Message); } catch (Exception) { if (autoNumberDTO != null && additionDeductionDTO.AdditionDeductionId > 0) { await _autoNumber.RollbackAutoNumber("AdditionDeduction", additionDeductionDTO.AdditionDeductionId, loginDTO); } throw; } } public async Task DeleteAdditionDeduction(int additionDeductionId, LoginDTO loginDTO) { try { return await _additionDeductionDAL.DeleteAdditionDeduction(additionDeductionId, loginDTO); } catch (Exception) { throw; } } private void ValidateRequest(int firstNumber, int maxResult, CriteriaDTO criteriaDTO, LoginDTO loginDTO) { if (criteriaDTO == null) throw new ArgumentNullException(nameof(criteriaDTO), "CriteriaDTO cannot be null"); if (loginDTO == null) throw new ArgumentNullException(nameof(loginDTO), "LoginDTO cannot be null"); if (firstNumber < -1) throw new ArgumentException("FirstNumber cannot be less than -1", nameof(firstNumber)); if (maxResult < -1) throw new ArgumentException("MaxResult cannot be less than -1", nameof(maxResult)); bool hasNature = false; bool hasApplicableType = false; if (criteriaDTO.SectionCriteriaList != null) { foreach (var section in criteriaDTO.SectionCriteriaList) { if (section.AttributesCriteriaList != null) { foreach (var attr in section.AttributesCriteriaList) { if (string.Equals(attr.FieldName, "Nature", StringComparison.OrdinalIgnoreCase)) hasNature = true; else if (string.Equals(attr.FieldName, "ApplicableType", StringComparison.OrdinalIgnoreCase)) hasApplicableType = true; } } } } if (!hasNature || !hasApplicableType) throw new ArgumentException("Criteria must contain both Nature and ApplicableType"); } private (int FirstNumber, int MaxResult) ValidatePagination(int firstNumber, int maxResult) { if (firstNumber == -1 && maxResult == -1) return (firstNumber, maxResult); int validatedFirstNumber = firstNumber < -1 ? -1 : firstNumber; int validatedMaxResult = maxResult < -1 ? -1 : maxResult; const int MAX_RECORDS = 1000; if (validatedMaxResult > MAX_RECORDS) validatedMaxResult = MAX_RECORDS; return (validatedFirstNumber, validatedMaxResult); } public async Task> GetAdditionDeductionFields(CriteriaDTO criteriaDTO, LoginDTO loginDTO) { try { return await _additionDeductionDAL.GetAdditionDeductionFields(criteriaDTO, loginDTO); } catch (Exception) { throw; } } } }