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




  • No labels