1. Work Order Creation Flow
public async Task<WorkOrderFormResponse?> WorkOrderSaveAsDraft(WorkOrderCreateRequest workOrderCreateRequest)
{
using var transaction = await _dbContext.Database.BeginTransactionAsync();
try
{
// 1. Validate registration data
await _workOrderValidationService.ValidateRegistrationRequest(workOrderCreateRequest.RegistrationCreateRequest);
// 2. Create work order entity
var workOrder = await _workOrderMapperService.MapperWorkOrder(workOrderCreateRequest.RegistrationCreateRequest);
_dbContext.WorkOrder.Add(workOrder);
await _dbContext.SaveChangesAsync();
// 3. Create related entities (Location, Payers, Utilization, etc.)
// ... complex entity creation logic
await _dbContext.SaveChangesAsync();
await transaction.CommitAsync();
return await GetWorkOrderForm(workOrderID);
}
catch (Exception)
{
await transaction.RollbackAsync();
throw;
}
}
Key Technical Aspects:
• Transactional Integrity: Uses database transactions to ensure data consistency
• Complex Object Mapping: Multiple related entities created in sequence
• Validation Pipeline: Multi-layer validation before persistence
• Error Handling: Automatic rollback on failures
2. External System Integration
Scenario: Sending work order data to external grid company systems via SOAP/XML.
public async Task<WorkOrderFormResponse?> TransmitWorkOrder(WorkOrderFormResponse workOrderForm)
{
try
{
var content = JsonContent.Create(workOrderForm);
var httpClient = _httpClientFactory.CreateClient("integrationserviceapi");
var response = await httpClient.PostAsync("api/SendWorkOrderForm", content);
if (!response.IsSuccessStatusCode)
{
var errorDetails = await response.Content.ReadAsStringAsync();
throw new NotFoundException($"Error: {response.StatusCode}, Details: {errorDetails}");
}
// Update work order status
var workOrder = await _dbContext.WorkOrder.FindAsync(workOrderForm.ID);
workOrder.WorkOrderStatusID = (int)Enums.WorkOrderStatus.RegistrationSent;
await _dbContext.SaveChangesAsync();
return workOrderForm;
}
catch (Exception ex)
{
throw new NotFoundException($"Error: {ex.Message}, WorkOrderFormID: {workOrderForm.ID}");
}
}
Key Technical Aspects:
• Service-to-Service Communication: HTTP client communication between microservices
• Status Management: Automatic status updates based on integration success
• Error Propagation: Detailed error information for troubleshooting
3. PDF Generation and Email Delivery
Scenario: Generating PDF documents and sending via email for charging station work orders.
public async Task<WorkOrderFormResponse?> SendEmailToSonwin(WorkOrderFormResponse workOrder)
{
// 1. Build email model with localized data
EmailModel emailModel = new EmailModel
{
Tilmelding = new Registration
{
WorkOrderNumber = workOrder.WorkOrderNumber,
GridCompanyName = workOrder.GridCompany.Name,
// ... additional mapping
},
// ... other sections
};
// 2. Generate PDF using QuestPDF
var pdf = Generate(emailModel, title: $"Blanket – {workOrder.WorkOrderNumber}");
// 3. Send email with PDF attachment
var sendmail = await _emailService.SendEmailAsync(email, subject, body, pdf, fileName);
if (sendmail)
{
// Update work order status
workOrder.WorkOrderStatusID = (int)Enums.WorkOrderStatus.RegistrationSent;
await _dbContext.SaveChangesAsync();
}
return workOrder;
}
Key Technical Aspects:
• Dynamic PDF Generation: QuestPDF for complex document layouts
• Internationalization: Localized content in generated documents
• Email Integration: SendGrid for reliable email delivery
• File Management: Temporary file handling for attachments
4. Complex Query Optimization
Scenario: Retrieving work orders with extensive related data for display.
public async Task<IEnumerable<WorkOrderExtendedResponse>> GetWorkOrders()
{
var consumptionCategories = await _dbContext.ConsumptionCategory
.ToDictionaryAsync(cc => cc.ID, cc => cc.Name ?? "");
return await _dbContext.WorkOrder
.Select(wo => new WorkOrderExtendedResponse
{
ID = wo.ID,
WorkOrderNumber = wo.WorkOrderNumber,
LocationAddress = FormatLocationAddress(wo.Location),
ConsumptionCategoryName = _dbContext.InstallationCategory
.Where(ic => ic.WorkOrderID == wo.ID)
.Select(ic => ic.ConsumptionCategoryID != null &&
consumptionCategories.ContainsKey(ic.ConsumptionCategoryID.Value)
? consumptionCategories[ic.ConsumptionCategoryID.Value] : "")
.FirstOrDefault(),
// ... complex projections
}).ToListAsync();
}
Key Technical Aspects:
• Query Optimization: Dictionary lookup to reduce database queries
• Complex Projections: Direct projection to response models
• Performance: AsNoTracking for read-only scenarios
5. Multi-Language Utilization Management
Scenario: Dynamic form rendering based on utilization item types with validation.
Key Technical Aspects:
• Dynamic UI: Conditional rendering based on enum values
• Validation: FluentValidation with localized error messages
• State Management: Complex form state in Blazor components
6. Azure Blob Storage Integration
Scenario: File upload handling with size limits and validation.
public async Task<FileUploadResponse> UploadFileAsync(IFormFile file, string containerName)
{
// Validation
if (file.Length > 52_428_800) // 50MB
throw new InvalidOperationException("File too large");
// Upload to Azure Blob Storage
var blobClient = _blobServiceClient.GetBlobContainerClient(containerName);
await blobClient.CreateIfNotExistsAsync(PublicAccessType.Blob);
var blob = blobClient.GetBlobClient(fileName);
await blob.UploadAsync(file.OpenReadStream(), true);
return new FileUploadResponse { Url = blob.Uri.ToString() };
}
Key Technical Aspects:
• File Size Validation: Configurable limits for uploads
• Container Management: Dynamic container creation
• Stream Handling: Efficient file streaming to Azure