using System; using System.IO; using System.Linq; using System.Collections.Generic; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using DigitalData.Modules.Interfaces; using static DigitalData.Modules.Interfaces.Exceptions; using static DigitalData.Modules.Interfaces.ZUGFeRDInterface; using static DigitalData.Modules.Interfaces.PropertyValues; using System.Data.SqlClient; using DigitalData.Modules.Database; namespace ZUGFeRDRESTService.Controllers { [Route("api/[controller]")] [ApiController] public class ValidationController : ControllerBase { public const string RESPONSE_OK = "OK"; public const 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 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 ValidationResponse Post(IFormFile file, string user_id) { _logger.Debug("Start processing request to ValidationController"); object 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(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 }; } } private Tuple ValidateBuyerOrderReference(Dictionary pPropertyMap, List pProperties) { foreach (var oItem in pProperties) { var oResult = InsertPropertyMap(oItem); if (oResult == false) { _logger.Warn("Error while inserting the Property [{0}] into the Database!", oItem.Description); } } // TODO: Execute the Procedure. // _database.MSSQL.ExecuteNonQuery(""); // TODO: Return a Status value which will be returned to the caller. return new Tuple(true, ""); } public bool InsertPropertyMap(ValidProperty pProperty) { try { var oCreator = "ZUGFeRD REST Service"; var oDomain = "test.wisag.de"; var oMessageId = $"{Guid.NewGuid()}@{oDomain}"; var oSql = $"INSERT INTO {pProperty.TableName} " + "(REFERENCE_GUID, ITEM_DESCRIPTION, ITEM_VALUE, CREATEDWHO, SPEC_NAME, GROUP_COUNTER, IS_REQUIRED) VALUES " + "(@REFERENCE_GUID, @ITEM_DESCRIPTION, @ITEM_VALUE, @CREATEDWHO, @SPEC_NAME, @GROUP_COUNTER, @IS_REQUIRED)"; var oParams = new SqlParameter[] { new SqlParameter("@REFERENCE_GUID", oMessageId), new SqlParameter("@ITEM_DESCRIPTION", pProperty.Description), new SqlParameter("@ITEM_VALUE", pProperty.Value), new SqlParameter("@CREATEDWHO", oCreator), new SqlParameter("@GROUP_COUNTER", pProperty.GroupCounter), new SqlParameter("@SPEC_NAME", pProperty.TableColumn), new SqlParameter("@IS_REQUIRED", pProperty.ISRequired) }; var oCommand = new SqlCommand(oSql); oCommand.Parameters.AddRange(oParams); return _database.MSSQL.ExecuteNonQuery(oCommand); } catch (Exception ex) { _logger.Error(ex); return false; } } } }