using BeWo.Data.Access; using BeWo.Data.Entities; using BeWo.Data.Models.XRechnung; using BeWo.Service.Core; using BeWo.Service.DCEntityMapper; using BeWo.Service.ServiceImplementations; using BeWo.Service.ServiceProxy; using BeWo.Service.ServiceUtils; using BS.Shared; using BS.Shared.Core; using BS.Shared.DataContracts; using BS.Shared.DataContracts.MikePHPContracts; using BS.Shared.Interface; using DevExpress.Export; using DevExpress.Utils.Filtering.Internal; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; namespace BeWo.Service.Plugins { public class XRechnungService : AbstractIDSpecificDefaultClass { private readonly LocalTenantFileStorageDAO _storage; private readonly GenericDAO _genericDAO; private readonly FileLogger _logger; public XRechnungService() { // Hole Storage var lStoragePath = MergedConfig.GetSetting(WebConfigSetting.StoredTenantFilesFolderPath); _storage = DAOFactory.GetLocalTenantFileStorage(lStoragePath); _genericDAO = DAOFactory.GenericDAO; _logger = ServiceHelper.CoreLogger; } public ApiResponse> GetXRechnung(long invoice_base_oid, int report_type, string report_url) { var invoice_base = _genericDAO.LoadByID(invoice_base_oid); var stored_file = invoice_base.XRechnungStoredFile; // Falls Lokal vorhanden, gebe lokale Version zurück if (stored_file?.FileName is string lFileName && tryGetXRechnungLocal(_storage, lFileName, out var bytes)) { var stored_file_dc = MapperFactory.StoredFile.MapToNewDC(stored_file); return ApiResponse>.SuccessResponse(new Tuple(stored_file_dc, bytes)); } // Lokal nicht vorhanden, berechne XRechnung var str = //ServiceConfigReader.GetInvoiceTestJsonString(); calculate(invoice_base); str = str.Replace("19.0", "19"); str = str.Replace("76.0", "76"); // Erstelle Url ohne weitere Authentifizierung var token_url = GetTokenUrl(report_url); return requestXRechnung(_storage, invoice_base, str, token_url); } private ApiResponse> requestXRechnung(LocalTenantFileStorageDAO pStorage, InvoiceBase invoice_base, object obj, string token_url) { var response = ServiceFacade.XRechnung.Create(obj, token_url); var final_response = new ApiResponse>(); ApiResponse.CopyTo(response, final_response); var lFileName = pStorage.GetXRechnungFileName(invoice_base.Oid.Value); if (response.Success) { try { var bytes = response.Data; StoredFile stored_file = null; using (MemoryStream ms = new MemoryStream(bytes)) { stored_file = pStorage.SaveHybridFile(BWPFeature.XRechnung, lFileName, "application/pdf", ms, TableID.InvoiceBase, invoice_base.Oid.Value); invoice_base.XRechnungStoredFile = stored_file; _genericDAO.Update(invoice_base); } var stored_file_dc = MapperFactory.StoredFile.MapToNewDC(stored_file); final_response.Data = new Tuple(stored_file_dc, bytes); } catch (Exception ex) { try { _logger.LogError(ex, nameof(GetXRechnung)); } catch (Exception ex2) { response.ErrorStrings.Add("AccountingEnhancedServiceImp - CoreLogger: " + ex2.ToString()); } response.ErrorStrings.Add("AccountingEnhancedServiceImp: " + ex.ToString()); } } return final_response; } private string GetTokenUrl(string report_url) { string download_url; if (report_url.IndexOf("localhost") < 0) download_url = report_url + "&mode=pdf"; else download_url = "https://app5.bewoplaner.de/service/ApiStreamService.svc/GetPdf"; return new DownloadServiceImp().CreateTemporaryUrl(download_url, false); } private bool tryGetXRechnungLocal(LocalTenantFileStorageDAO pStorage, string pFileName, out byte[] bytes) { bytes = null; // Hole StoredFile aus DB var lFile = pStorage.GetStoredFile(BWPFeature.XRechnung, pFileName); if (lFile is null) return false; using (Stream file_stream = pStorage.GetFileContent(lFile)) { if (file_stream is null) return false; using (MemoryStream ms = new MemoryStream()) { file_stream.CopyTo(ms); bytes = ms.ToArray(); } } return true; } private string calculate(InvoiceBase invoice) { var undefinded = "??undefinded??"; var undefinded_num = -1; var undefinded_num2 = 1001; var undefinded_num3 = 58; XRechnung xRechnung = new XRechnung(); xRechnung.Invoice.Type = (invoice.InvoiceTypeText?.StartsWith("storno", StringComparison.OrdinalIgnoreCase) ?? false) ? "384" : "380"; xRechnung.Invoice.Number = invoice.InvoiceNumber; xRechnung.Invoice.Date = invoice.InvoiceDate?.ToString("yyyyMMdd") ?? undefinded; xRechnung.Invoice.Currency = "EUR"; xRechnung.Invoice.Notice = invoice.Notice; xRechnung.Invoice.CancellationNumber = ""; xRechnung.Invoice.Period.Start = invoice.AccountingPeriodStart?.ToString("yyyyMMdd") ?? undefinded; xRechnung.Invoice.Period.End = invoice.AccountingPeriodEnd?.ToString("yyyyMMdd") ?? undefinded; xRechnung.Invoice.Period.Description = String.Format("Leistungszeitraum {0:dd.MM.yyyy} bis {1:dd.MM.yyyy}", invoice.AccountingPeriodStart, invoice.AccountingPeriodEnd); xRechnung.Invoice.Payment.Type = undefinded_num3; xRechnung.Invoice.Payment.Term = "Zahlbar innerhalb 14 Tagen netto"; xRechnung.Invoice.Payment.DueDate = invoice.InvoiceDate?.AddDays(14).ToString("yyyyMMdd") ?? undefinded; xRechnung.Seller.Name = "Muster GmbH"; xRechnung.Seller.ID = null; xRechnung.Seller.TaxID = null; xRechnung.Seller.VatID = "DE123456789"; xRechnung.Seller.Street = "Musterstr. 1-3"; xRechnung.Seller.ZipCode = "30674"; xRechnung.Seller.City = "Frankfurt"; xRechnung.Seller.EMail = "rechnungen@musterfirma.de"; xRechnung.Seller.CountryCode = "DE"; xRechnung.Seller.Contact.Name = "Peter Musterfrau"; xRechnung.Seller.Contact.Department = "Buchhaltung"; xRechnung.Seller.Contact.Phone = "+49211171717"; xRechnung.Seller.Contact.EMail = "pm@muster.de"; xRechnung.Seller.BankAccount.IBAN = "DE38370501980147522957"; xRechnung.Seller.BankAccount.BIC = "SSKMDEMMXXX"; xRechnung.Seller.BankAccount.Owner = "Muster GmbH"; xRechnung.Seller.BankAccount.Reference = "z.B. Rechnungnummer"; xRechnung.Seller.BankAccount.ReferenceID = "GläubigerID"; Address rechnungsAdresse = null; if (invoice.RecipientOrganisationOid.HasValue) { var org = DAOFactory.GenericDAO.LoadByID(invoice.RecipientOrganisationOid.Value); rechnungsAdresse = org.InvoiceAddress ?? org.Address; } else if (invoice.RecipientCustomerOid.HasValue) { var customer = DAOFactory.GenericDAO.LoadByID(invoice.RecipientCustomerOid.Value); rechnungsAdresse = customer.Person.InvoiceAddress ?? customer.Person.Address; } xRechnung.Buyer.ID = null; if (rechnungsAdresse != null) { xRechnung.Buyer.Street = rechnungsAdresse.Street; xRechnung.Buyer.ZipCode = rechnungsAdresse.PostalCode; xRechnung.Buyer.City = rechnungsAdresse.Town; xRechnung.Buyer.CountryCode = "DE"; } xRechnung.Buyer.EMail = "rechnungen@kunde.de"; xRechnung.Buyer.Reference = "PO-Nummer oder andere Referenz, die Kunde haben will"; xRechnung.Buyer.BankAccount.IBAN = "DE38370501980147522957"; xRechnung.Buyer.BankAccount.BIC = "SSKMDEMMXXX"; xRechnung.Buyer.BankAccount.Owner = "Muster GmbH"; xRechnung.Buyer.BankAccount.MandateID = "Mandatsreferenznummer"; foreach (var item in invoice.GetInvoiceItems()) { var position = new XRPosition(); position.Quantity = item.UnitCount ?? 0; position.QuantityType = "H87"; position.Text = item.ItemDescription; position.Net = item.AmountPerUnit ?? 0; position.NetTotal = item.AmountTotal ?? 0; position.Tax = 0; position.TaxSum = 0; position.TaxType = "S"; xRechnung.Position.Add(position); } return JsonConvert.SerializeObject(xRechnung); } } }