diff --git a/Marco.Pms.Services/Service/ExpensesService.cs b/Marco.Pms.Services/Service/ExpensesService.cs index 71dfe33..9411443 100644 --- a/Marco.Pms.Services/Service/ExpensesService.cs +++ b/Marco.Pms.Services/Service/ExpensesService.cs @@ -250,8 +250,6 @@ namespace Marco.Pms.Services.Service public async Task> CreateExpenseAsync(CreateExpensesDto dto, Employee loggedInEmployee, Guid tenantId) { _logger.LogDebug("Starting CreateExpense for Project {ProjectId}", dto.ProjectId); - // The entire operation is wrapped in a transaction to ensure data consistency. - await using var transaction = await _context.Database.BeginTransactionAsync(); try { @@ -301,7 +299,7 @@ namespace Marco.Pms.Services.Service .Include(s => s.Status) .Include(s => s.NextStatus) .AsNoTracking() - .FirstOrDefaultAsync(es => es.StatusId == Draft && es.Status != null); + .Where(es => es.StatusId == Draft && es.Status != null).ToListAsync(); }); @@ -329,11 +327,10 @@ namespace Marco.Pms.Services.Service if (paidBy == null) validationErrors.Add("Paid by employee not found"); if (expenseType == null) validationErrors.Add("Expense Type not found."); if (paymentMode == null) validationErrors.Add("Payment Mode not found."); - if (statusMapping == null) validationErrors.Add("Default status 'Draft' not found."); + if (!statusMapping.Any()) validationErrors.Add("Default status 'Draft' not found."); if (validationErrors.Any()) { - await transaction.RollbackAsync(); var errorMessage = string.Join(" ", validationErrors); _logger.LogWarning("Expense creation failed due to validation errors: {ValidationErrors}", errorMessage); return ApiResponse.ErrorResponse("Invalid input data.", errorMessage, 400); @@ -358,14 +355,13 @@ namespace Marco.Pms.Services.Service // 5. Database Commit await _context.SaveChangesAsync(); - // 6. Transaction Commit - await transaction.CommitAsync(); - + var status = statusMapping.Select(sm => sm.Status).FirstOrDefault(); + var nextStatus = statusMapping.Select(sm => sm.NextStatus).ToList(); var response = _mapper.Map(expense); response.PaidBy = _mapper.Map(paidBy); response.Project = _mapper.Map(project); - response.Status = _mapper.Map(statusMapping!.Status); - response.NextStatus = _mapper.Map>(statusMapping!.NextStatus); + response.Status = _mapper.Map(status); + response.NextStatus = _mapper.Map>(nextStatus); response.PaymentMode = _mapper.Map(paymentMode); response.ExpensesType = _mapper.Map(expenseType); @@ -374,7 +370,6 @@ namespace Marco.Pms.Services.Service } catch (ArgumentException ex) // Catches bad Base64 from attachment pre-validation { - await transaction.RollbackAsync(); _logger.LogError(ex, "Invalid argument during expense creation for project {ProjectId}.", dto.ProjectId); return ApiResponse.ErrorResponse("Invalid Request Data.", new { @@ -391,7 +386,6 @@ namespace Marco.Pms.Services.Service } catch (Exception ex) // General-purpose catch for unexpected errors (e.g., S3 or DB connection failure) { - await transaction.RollbackAsync(); _logger.LogError(ex, "An unhandled exception occurred while creating an expense for project {ProjectId}.", dto.ProjectId); return ApiResponse.ErrorResponse("An internal server error occurred.", new { diff --git a/Marco.Pms.Services/appsettings.Production.json b/Marco.Pms.Services/appsettings.Production.json index 0abe3f1..f164fdf 100644 --- a/Marco.Pms.Services/appsettings.Production.json +++ b/Marco.Pms.Services/appsettings.Production.json @@ -1,46 +1,47 @@ { - "Cors": { - "AllowedOrigins": "https://app.marcoaiot.com", - "AllowedMethods": "*", - "AllowedHeaders": "*" - }, - "Environment": { - "Name": "Production", - "Title": "" - }, - "ConnectionStrings": { - "DefaultConnectionString": "Server=147.93.98.152;User ID=devuser;Password=AppUser@123$;Database=MarcoBMS1" - }, - "SmtpSettings": { - "SmtpServer": "smtp.gmail.com", - "Port": 587, - "SenderName": "MarcoAIOT", - "SenderEmail": "marcoioitsoft@gmail.com", - "Password": "qrtq wfuj hwpp fhqr" - }, - "AppSettings": { - "WebFrontendUrl": "https://app.marcoaiot.com", - "ImagesBaseUrl": "https://app.marcoaiot.com" - }, - "Jwt": { - "Issuer": "https://app.marcoaiot.com", - "Audience": "https://app.marcoaiot.com", - "Key": "sworffishhkjfa9dnfdndfu33infnajfj", - "ExpiresInMinutes": 60, - "RefreshTokenExpiresInDays": 7 - }, - "MailingList": { - "RequestDemoReceivers": "ashutosh.nehete@marcoaiot.com;vikas@marcoaiot.com;umesh@marcoait.com", - "ProjectStatisticsReceivers": "ashutosh.nehete@marcoaiot.com;vikas@marcoaiot.com;umesh@marcoait.com" - }, - "AWS": { - "AccessKey": "AKIARZDBH3VDMSUUY2FX", - "SecretKey": "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", - "Region": "us-east-1", - "BucketName": "testenv-marco-pms-documents" - }, - "MongoDB": { - "SerilogDatabaseUrl": "mongodb://localhost:27017/DotNetLogs", - "ConnectionString": "mongodb://localhost:27017/MarcoBMS_Caches" - } + "Cors": { + "AllowedOrigins": "https://app.marcoaiot.com", + "AllowedMethods": "*", + "AllowedHeaders": "*" + }, + "Environment": { + "Name": "Production", + "Title": "" + }, + "ConnectionStrings": { + "DefaultConnectionString": "Server=147.93.98.152;User ID=devuser;Password=AppUser@123$;Database=MarcoBMS1" + }, + "SmtpSettings": { + "SmtpServer": "smtp.gmail.com", + "Port": 587, + "SenderName": "MarcoAIOT", + "SenderEmail": "marcoioitsoft@gmail.com", + "Password": "qrtq wfuj hwpp fhqr" + }, + "AppSettings": { + "WebFrontendUrl": "https://app.marcoaiot.com", + "ImagesBaseUrl": "https://app.marcoaiot.com" + }, + "Jwt": { + "Issuer": "https://app.marcoaiot.com", + "Audience": "https://app.marcoaiot.com", + "Key": "sworffishhkjfa9dnfdndfu33infnajfj", + "ExpiresInMinutes": 60, + "RefreshTokenExpiresInDays": 7 + }, + "MailingList": { + "RequestDemoReceivers": "ashutosh.nehete@marcoaiot.com;vikas@marcoaiot.com;umesh@marcoait.com", + "ProjectStatisticsReceivers": "ashutosh.nehete@marcoaiot.com;vikas@marcoaiot.com;umesh@marcoait.com" + }, + "AWS": { + "AccessKey": "AKIARZDBH3VDMSUUY2FX", + "SecretKey": "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", + "Region": "us-east-1", + "BucketName": "testenv-marco-pms-documents" + }, + "MongoDB": { + "SerilogDatabaseUrl": "mongodb://localhost:27017/DotNetLogs", + "ConnectionString": "mongodb://localhost:27017/MarcoBMS_Caches", + "ModificationConnectionString": "mongodb://localhost:27017/ModificationLog?authSource=admin&socketTimeoutMS=500&serverSelectionTimeoutMS=500&connectTimeoutMS=500" + } } \ No newline at end of file