using FrameworkDAL.CustomCode.CodeDefine; using FrameworkDAL.DTO.Code; using GB5Shared.DTO.Framework.AutoNumber; using GB5Shared.DTO.Framework.Criteria; using GB5Shared.DTO.Framework.Login; using GB5Shared.GenerateAutoNumber; using GB5Shared.Resource.Response; using GB5Shared.ResponseStandard; using GB5Shared.Validation; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FrameworkBLL.CodeDefine { public class CodeDefineBLL : ICodeDefineBLL { private readonly ICodeDefineDAL _CodeDefineDAL; private readonly AutoNumber _AutoNumber; private readonly IValidation _Validation; public CodeDefineBLL(ICodeDefineDAL CodeDefineDAL, AutoNumber autoNumber, IValidation Validation) { _CodeDefineDAL = CodeDefineDAL; _AutoNumber = autoNumber; _Validation = Validation; } public async Task GetCodeDefine(string EntityCode, string CategoryCode, LoginDTO LoginDTO) { try { return await _CodeDefineDAL.GetCodeDefine(EntityCode, CategoryCode, LoginDTO); } catch (Exception) { throw; } } public async Task SaveCodeDefine(CodeDefineDTO CodeDefineDTO, LoginDTO LoginDTO) { if (CodeDefineDTO == null) throw new ArgumentNullException(nameof(CodeDefineDTO)); AutoNumberDTO? autoNumberDTO = null; try { await _Validation.NotEmpty(CodeDefineDTO.CodeDefineCategoryCode, nameof(CodeDefineDTO.CodeDefineCategoryCode)); await _Validation.NotEmpty(CodeDefineDTO.CodeDefineCategoryName, nameof(CodeDefineDTO.CodeDefineCategoryName)); CodeDefineDTO.CodeDefineModifiedById = LoginDTO.UserId; CodeDefineDTO.CodeDefineModifiedOn = DateTime.UtcNow; bool isNew = CodeDefineDTO.CodeDefineId == 0; if (isNew) { int segmentCount = CodeDefineDTO.CodeDefineSegmentArray?.Count ?? 0; // Reserve IDs for header (1) + all segment rows in one batch autoNumberDTO = await _AutoNumber.GetAutoNumber(1 + segmentCount, "CodeDefine", LoginDTO); int nextId = autoNumberDTO.StartNumber; CodeDefineDTO.CodeDefineId = nextId++; CodeDefineDTO.CodeDefineCreatedById = LoginDTO.UserId; CodeDefineDTO.CodeDefineCreatedOn = DateTime.UtcNow; byte slno = 1; foreach (var seg in CodeDefineDTO.CodeDefineSegmentArray) { seg.CodeDefineSegmentId = nextId++; seg.CodeDefineId = CodeDefineDTO.CodeDefineId; seg.CodeDefineSegmentSlNo = slno++; seg.CodeDefineSegmentCreatedById = LoginDTO.UserId; seg.CodeDefineSegmentCreatedOn = DateTime.UtcNow; seg.CodeDefineSegmentModifiedById = LoginDTO.UserId; seg.CodeDefineSegmentModifiedOn = DateTime.UtcNow; } await _CodeDefineDAL.SaveCodeDefine(CodeDefineDTO, LoginDTO); return $"{SuccessResponse.SaveSuccessMessage} {CodeDefineDTO.CodeDefineId}"; } else { // For update: assign new segment IDs only for rows that are new (Id == 0) int newSegmentCount = CodeDefineDTO.CodeDefineSegmentArray?.Count(s => s.CodeDefineSegmentId == 0) ?? 0; if (newSegmentCount > 0) { autoNumberDTO = await _AutoNumber.GetAutoNumber(newSegmentCount, "CODEDEFINESEGMENT", LoginDTO); int nextId = autoNumberDTO.StartNumber; foreach (var seg in CodeDefineDTO.CodeDefineSegmentArray.Where(s => s.CodeDefineSegmentId == 0)) seg.CodeDefineSegmentId = nextId++; } byte slno = 1; foreach (var seg in CodeDefineDTO.CodeDefineSegmentArray) { seg.CodeDefineId = CodeDefineDTO.CodeDefineId; seg.CodeDefineSegmentSlNo = slno++; seg.CodeDefineSegmentModifiedById = LoginDTO.UserId; seg.CodeDefineSegmentModifiedOn = DateTime.UtcNow; } await _CodeDefineDAL.UpdateCodeDefine(CodeDefineDTO, LoginDTO); return $"{SuccessResponse.UpdateSuccessMessage} {CodeDefineDTO.CodeDefineId}"; } } catch (ValidationException vex) { throw new Exception(vex.Message); } catch (Exception) { if (autoNumberDTO != null && CodeDefineDTO.CodeDefineId > 0) await _AutoNumber.RollbackAutoNumber("CodeDefine", CodeDefineDTO.CodeDefineId, LoginDTO); throw; } } public async Task GetSelectListCodeDefine(int FirstNumber, int MaxResult, CriteriaDTO CriteriaDTO, LoginDTO LoginDTO) { try { return await _CodeDefineDAL.GetSelectListCodeDefine(FirstNumber, MaxResult, CriteriaDTO, LoginDTO); } catch (Exception) { throw; } } public async Task DeleteCodeDefine(int CodeDefineId, LoginDTO LoginDTO) { try { return await _CodeDefineDAL.DeleteCodeDefine(CodeDefineId, LoginDTO); } catch (Exception) { throw; } } } }