using System; using System.IO; using System.Linq; using System.Threading.Tasks; using System.Collections.Generic; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using DigitalData.Modules.Interfaces; using DigitalData.Modules.Logging; using static DigitalData.Modules.Interfaces.Exceptions; using static DigitalData.Modules.Interfaces.ZUGFeRDInterface; namespace ZUGFeRDRESTService.Controllers { [Route("api/[controller]")] [ApiController] public class ValidationController : ControllerBase { public static string RESPONSE_OK = "OK"; public static string RESPONSE_ERROR = "ERROR"; private readonly ZUGFeRDInterface _zugferd; private readonly IDatabase _database; private readonly DigitalData.Modules.Logging.LogConfig _logConfig; private readonly DigitalData.Modules.Logging.Logger _logger; private readonly PropertyValues _props; private readonly Dictionary _propertyMap; public class ValidationResponse { public string status; public string message; public List errors; public ValidationResponse() { status = RESPONSE_OK; message = string.Empty; errors = new List(); } public ValidationResponse(string Status, string Message) { status = Status; message = Message; errors = new List(); } public ValidationResponse(string Status, string Message, List Errors) { status = Status; message = Message; errors = Errors; } } public ValidationController(ILogging logging, IDatabase database) { _logConfig = logging.LogConfig; _logger = _logConfig.GetLogger(); _logger.Debug("Validation Controller initializing"); _database = database; var oGDPictureKey = database.GetGDPictureKey(); var oPropertyMap = database.GetPropertyMap(); _propertyMap = oPropertyMap; _zugferd = new ZUGFeRDInterface(_logConfig, oGDPictureKey); _props = new PropertyValues(_logConfig); _logger.Debug("Validation Controller initialized!"); } /// /// POST: /api/validation /// /// This parameter's name needs to correspond to the html form's file-input name [HttpPost] public async Task Post(IFormFile file, string user_id) { _logger.Debug("Start processing request to ValidationController"); CrossIndustryDocumentType oDocument; PropertyValues.CheckPropertyValuesResult oResult = new PropertyValues.CheckPropertyValuesResult(); try { using Stream oStream = file.OpenReadStream(); { _logger.Debug("Extracting ZUGFeRD Data from file [{0}]", file.FileName); oDocument = _zugferd.ExtractZUGFeRDFileWithGDPicture(oStream); _logger.Debug("Checking ZUGFeRD Data against the database"); oResult = _props.CheckPropertyValues(oDocument, _propertyMap, "MESSAGEID"); var oRequiredProperties = _propertyMap. Where(prop => {return prop.Value.IsRequired == true;}). Select(prop => { return prop.Value.Description; }) .ToList(); _logger.Debug("Found [{0}] required properties", oRequiredProperties.Count); _logger.Debug(String.Join(",", oRequiredProperties.ToArray())); _logger.Debug("Result of checking against the database: {0} valid properties, {1} missing properties", oResult.ValidProperties.Count, oResult.MissingProperties.Count); if (oResult.MissingProperties.Count > 0) { throw new ZUGFeRDExecption(ZUGFeRDInterface.ErrorType.MissingProperties, "Die hochgeladene Datei ist eine gültige ZUGFeRD-Rechnung, allerdings fehlen benötigte Daten."); } string oMessage = "Die hochgeladene Datei ist eine gültige-ZUGFeRD Rechnung"; _logger.Debug($"Replying with: [{oMessage}]"); return new ValidationResponse() { status = RESPONSE_OK, message = oMessage }; }; } catch (ZUGFeRDExecption ex) { _logger.Error(ex); // Determine which message should be sent in the response string oMessage = ex.ErrorType switch { ErrorType.NoValidFile => "Die hochgeladene Datei ist keine gültige Datei.", ErrorType.NoZugferd => "Die hochgeladene Datei ist keine ZUGFeRD-Rechnung.", ErrorType.NoValidZugferd => "Die hochgeladene Datei ist keine gültige ZUGFeRD-Rechnung.", ErrorType.MissingProperties => "Die hochgeladene Datei ist keine gültige ZUGFeRD-Rechnung, es fehlen einige Metadaten", _ => "Die hochgeladene Datei kann nicht validiert werden.", }; // Determine if any errors should be sent in the response List oErrors = ex.ErrorType switch { // Errors contains the list of missing fields ErrorType.MissingProperties => oResult.MissingProperties, _ => new List() }; _logger.Debug($"Replying with: [{oMessage}]"); return new ValidationResponse() { status = RESPONSE_ERROR, message = oMessage, errors = oErrors }; } catch (Exception ex) { _logger.Error(ex); string oMessage = "Die hochgeladene Datei kann nicht validiert werden, weil ein unbekannter Fehler aufgetreten ist."; _logger.Debug($"Replying with: [{oMessage}]"); return new ValidationResponse() { status = RESPONSE_ERROR, message = oMessage }; } } } }