using GB5Shared.DTO.Framework.AutoNumber; using GB5Shared.DTO.Framework.Criteria; using GB5Shared.DTO.Framework.Login; using GB5Shared.GenerateAutoNumber; using PayRollDAL.CustomeCode.Declaration; using PayRollDAL.DTO.Declaration; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; namespace PayRollBLL.Declaration { public class DeclarationBLL : IDeclarationBLL { private readonly IDeclarationDAL _DeclarationDAL; private readonly AutoNumber _AutoNumber; public DeclarationBLL(IDeclarationDAL IDeclarationDAL, AutoNumber autoNumber) { _DeclarationDAL = IDeclarationDAL; _AutoNumber = autoNumber; } public async Task GetDeclaration(int DeclarationId, LoginDTO LoginDTO) { try { return await _DeclarationDAL.GetDeclaration(DeclarationId, LoginDTO); } catch (Exception) { throw; } } public async Task SaveDeclaration(DeclarationDTO declarationDTO, LoginDTO loginDTO) { if (declarationDTO == null) throw new ArgumentNullException(nameof(declarationDTO), "Declaration data is required and cannot be empty."); AutoNumberDTO? autoNumberDTO = null; try { declarationDTO.DeclarationModifiedById = loginDTO.UserId; declarationDTO.DeclarationModifiedOn = DateTime.UtcNow; bool isNew = declarationDTO.DeclarationId == 0; if (isNew) { int detailCount = declarationDTO.DeclarationDetailArray?.Count ?? 0; autoNumberDTO = await _AutoNumber.GetNumberAsync(1 + detailCount, "DECLARATION", loginDTO); int nextId = autoNumberDTO.StartNumber; declarationDTO.DeclarationId = nextId++; declarationDTO.DeclarationCreatedById = loginDTO.UserId; declarationDTO.DeclarationCreatedOn = DateTime.UtcNow; if (declarationDTO.DeclarationDetailArray?.Count > 0) { foreach (var detail in declarationDTO.DeclarationDetailArray) { detail.DeclarationDetailId = nextId++; detail.DeclarationId = declarationDTO.DeclarationId; } } await _DeclarationDAL.SaveDeclaration(declarationDTO, loginDTO); return "Declaration saved successfully."; } else { var newDetails = declarationDTO.DeclarationDetailArray? .Where(x => x.DeclarationDetailId == 0) .ToList(); if (newDetails != null && newDetails.Count > 0) { autoNumberDTO = await _AutoNumber.GetNumberAsync(newDetails.Count, "DECLARATION", loginDTO); int nextId = autoNumberDTO.StartNumber; foreach (var d in newDetails) { d.DeclarationDetailId = nextId++; d.DeclarationId = declarationDTO.DeclarationId; d.IsNewRecord = true; } } var existingDetails = declarationDTO.DeclarationDetailArray? .Where(x => x.DeclarationDetailId != 0); if (existingDetails != null) { foreach (var d in existingDetails) d.IsNewRecord = false; } await _DeclarationDAL.UpdateDeclaration(declarationDTO, loginDTO); return "Declaration updated successfully."; } } catch { if (autoNumberDTO != null) await _AutoNumber.RollbackAutoNumber("DECLARATION", autoNumberDTO.StartNumber, loginDTO); throw; } } public async Task DeleteDeclaration(int declarationId, LoginDTO loginDTO) { try { var detailsResult = await _DeclarationDAL.DeleteDeclarationDetail(declarationId, loginDTO); if (detailsResult <= 0) return ("Failed to delete Declaration Detail. Parent not deleted."); var declarationResult = await _DeclarationDAL.DeleteDeclaration(declarationId, loginDTO); if (declarationResult <= 0) return ("Detail deleted, but failed to delete Declaration."); return ("Declaration and DeclarationDetails deleted successfully."); } catch (Exception ex) { throw new Exception($"Error deleting DeclarationId {declarationId}", ex); } } public async Task DeleteDetailDeclaration(int DeclarationDetailId, LoginDTO LoginDTO) { try { return await _DeclarationDAL.DeleteDetailDeclaration(DeclarationDetailId, LoginDTO); } catch (Exception) { throw; } } public async Task GetSelectListDeclarationView(int FirstNumber, int MaxResult, CriteriaDTO CriteriaDTO, LoginDTO LoginDTO) { try { return await _DeclarationDAL.GetSelectListDeclarationView(FirstNumber, MaxResult, CriteriaDTO, LoginDTO); } catch (Exception) { throw; } } public async Task DeclarationBulkUpdate(List declarationList, LoginDTO loginDTO) { try { return await _DeclarationDAL.DeclarationBulkUpdate(declarationList, loginDTO); } catch (Exception) { throw; } } public async Task DeclarationDetailBulkUpdate(List declarationDetailList, LoginDTO loginDTO, CancellationToken ct) { try { return await _DeclarationDAL.DeclarationDetailBulkUpdate(declarationDetailList, loginDTO, ct); } catch (Exception) { throw; } } } }