#define CREATE_PREVIEW_HTML
using iText.Html2pdf;
using KarleyLibrary.Erweiterungen;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WK5.Core.Basis.Erweiterungen;
using WK5.Core.Models;

namespace WK5.Core.Drucken.Gutschriften
{
    public class PrintGutschrift : PrintBase
    {
        private readonly Gutschrift _gutschrift;
        private readonly PrintGutschriftRegelsatz _regeln;
        private readonly OptionCollection _optionen;
        private readonly List<Lieferbedingung> _lieferbedingungen;
        private readonly ZahlungsbedingungCollection _zahlungsbedingungen;
        private readonly Mehrwertsteuer _versandMehrwertsteuer;
        private readonly TemplateTextCollection _textCollection;

        public bool IsEnglisch { get; }
        private PrintGutschrift(Gutschrift gutschrift, PrintGutschriftRegelsatz regeln, OptionCollection optionen, List<Lieferbedingung> lieferbedingungen, ZahlungsbedingungCollection zahlungsbedingungen, Mehrwertsteuer versandMehrwertsteuer, TemplateTextCollection textCollection)
        {
            _gutschrift = gutschrift;
            IsEnglisch = !GlobalConfig.DachLächer.Contains(_gutschrift.Land);
            _regeln = regeln;
            _optionen = optionen;
            _lieferbedingungen = lieferbedingungen;
            _zahlungsbedingungen = zahlungsbedingungen;
            _versandMehrwertsteuer = versandMehrwertsteuer;
            _textCollection = textCollection;
            _layoutFile = IsEnglisch ? "GutschriftEnglisch.html" : "Gutschrift.html";
            _template = String.Empty;
        }
        public static async Task<PrintGutschrift> CreateAsync(Gutschrift gutschrift, PrintGutschriftRegelsatz regeln, FbController2 fbController)
        {
            var myClass = new PrintGutschrift
            (
                gutschrift,
                regeln,
                await Option.GetOptionenAsync(fbController),
                await Lieferbedingung.GetLieferbedingungenAsync().ToListAsync(),
                await Zahlungsbedingung.GetZahlungsbedingungenAsync(fbController),
                await Mehrwertsteuer.GetVersandMehrwertsteuerAsync(fbController) ?? throw new ArgumentNullException(nameof(_versandMehrwertsteuer)),
                await TemplateText.GetTemplateTexteAsync(GlobalConfig.IDENTIFIER_RECHNUNGEN, fbController) // 27.05.2021 - MK: Ist soweit korrekt. Die Texte sind mit der von Rechnungen identisch
            );
            await myClass.InitializeAsync();
            return myClass;
        }
        public override string Print(string speicherpfad)
        {
            string filename = $"GU_{_gutschrift.Belegnummer}.pdf";

#if CREATE_PREVIEW_HTML
            File.WriteAllText(Path.Combine(speicherpfad, $"GU_{ _gutschrift.Belegnummer}.html"), _template);
#endif
            byte[] byteArray = Encoding.UTF8.GetBytes(_template);
            MemoryStream stream = new MemoryStream(byteArray);
            ConverterProperties converterProperties = new ConverterProperties()
                .SetBaseUri(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, LAYOUT_PATH));

            string fullPath = Path.Combine(speicherpfad, filename);
            if (File.Exists(fullPath))
            {
                File.Delete(fullPath);
            }

            HtmlConverter.ConvertToPdf(stream, new FileStream(fullPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None), converterProperties);

            return fullPath;
        }

        protected override string GenerateDisplayCss()
        {
            StringBuilder cssBuilder = new StringBuilder();
            cssBuilder.AppendLine("<style>");



            if (!_regeln.ShowFooter)
            {
                cssBuilder.AppendLine("\t#footer {");
                //cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t\tvisibility: hidden;");
                cssBuilder.AppendLine("\t\topacity: 0;");
                cssBuilder.AppendLine("\t\tcolor: rgba(0,0,0,0);");
                cssBuilder.AppendLine("\t\ttransform: scale(0);");
                cssBuilder.AppendLine("\t}");
            }

            if (!_regeln.ShowHeader)
            {
                cssBuilder.AppendLine("\t.karley-header {");
                //cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t\tvisibility: hidden;");
                cssBuilder.AppendLine("\t\topacity: 0;");
                cssBuilder.AppendLine("\t\tcolor: rgba(0,0,0,0);");
                cssBuilder.AppendLine("\t\ttransform: scale(0);");
                cssBuilder.AppendLine("\t}");
            }

            if (!_regeln.ShowBestelltDurch)
            {
                cssBuilder.AppendLine("\t.display-bestellt-durch{");
                cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t}");
            }

            if (!_regeln.ShowBestelltAm)
            {
                cssBuilder.AppendLine("\t.display-bestellt-am{");
                cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t}");
            }

            if (!_regeln.ShowRechnungsanschrift)
            {
                cssBuilder.AppendLine("\t.display-rechnungsanschrift{");
                cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t}");
            }

            if (!_regeln.ShowLieferanschrift)
            {
                cssBuilder.AppendLine("\t.display-lieferanschrift{");
                cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t}");
            }

            if (!_regeln.ShowLieferzeit)
            {
                cssBuilder.AppendLine("\t.display-lieferzeit{");
                cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t}");
            }

            if (!_regeln.ShowMwstUndBrutto)
            {
                cssBuilder.AppendLine("\t.display-mwst, .display-endbetrag-brutto{");
                cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t}");
            }

            if (!_regeln.ShowZwischensumme)
            {
                cssBuilder.AppendLine("\t.display-zwischensumme{");
                cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t}");
            }

            if (!_regeln.ShowRabatt)
            {
                cssBuilder.AppendLine("\t.display-rabatt{");
                cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t}");
            }

            if (!_regeln.ShowBestellnummer)
            {
                cssBuilder.AppendLine("\t.display-bestellnummer{");
                cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t}");
            }

            if (!_regeln.ShowVerpackungskosten)
            {
                cssBuilder.AppendLine("\t.display-verpackungskosten{");
                cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t}");
            }

            if (!_regeln.ShowVersicherungskosten)
            {
                cssBuilder.AppendLine("\t.display-versicherungskosten{");
                cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t}");
            }

            if (!_regeln.ShowVersandkosten)
            {
                cssBuilder.AppendLine("\t.display-versandkosten{");
                cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t}");
            }



            if (!_regeln.ShowAdresszeileLand)
            {
                cssBuilder.AppendLine("\t.display-empfaenger-land{");
                cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t}");
            }

            if (!_regeln.ShowAdresszeile2)
            {
                cssBuilder.AppendLine("\t.display-addresszeile2{");
                cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t}");
            }

            if (!_regeln.ShowAdresszeile3)
            {
                cssBuilder.AppendLine("\t.display-addresszeile3{");
                cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t}");
            }

            if (!_regeln.ShowAdresszeile4)
            {
                cssBuilder.AppendLine("\t.display-addresszeile4{");
                cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t}");
            }


            if (!_regeln.ShowRechnungsnummer)
            {
                cssBuilder.AppendLine("\t.display-rechnungsnummer{");
                cssBuilder.AppendLine("\t\tdisplay: none;");
                cssBuilder.AppendLine("\t}");
            }



            cssBuilder.AppendLine("</style>");

            return cssBuilder.ToString();
        }

        protected override async Task InitializeAsync()
        {
            string layoutPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, LAYOUT_PATH, _layoutFile);
            _template = await File.ReadAllTextAsync(layoutPath);
            SetRegeln();
            _template = await SetTemplateVariables();
        }

        protected override Task InitializeAsync(FbController2 fbController)
        {
            throw new NotImplementedException();
        }

        protected override void SetRegeln()
        {
            _regeln.ShowLieferzeit = !_gutschrift.Lieferzeit.Equals(String.Empty);
            _regeln.ShowMwstUndBrutto = _gutschrift.MwstBerechnen;
            _regeln.ShowRabatt = _gutschrift.Positionen.Where(x => x.GetRabatt1() > 0 || x.GetRabatt2() > 0).Any();
            _regeln.ShowBestelltDurch = !String.IsNullOrWhiteSpace(_gutschrift.BestelltDurch);
            _regeln.ShowBestelltAm = _gutschrift.BestelltAm != default;
            _regeln.ShowLieferanschrift = _gutschrift.LieferanschriftId > 0;
            _regeln.ShowRechnungsanschrift = _gutschrift.RechnungsanschriftId > 0;
            _regeln.ShowBestellnummer = !String.IsNullOrWhiteSpace(_gutschrift.Bestellnummer);
            _regeln.ShowVerpackungskosten = _gutschrift.Verpackungskosten > 0;
            _regeln.ShowVersandkosten = _gutschrift.Frachtkosten > 0;
            _regeln.ShowVersicherungskosten = _gutschrift.Versicherungskosten > 0;
            _regeln.ShowZwischensumme = _regeln.ShowVersicherungskosten || _regeln.ShowVersandkosten || _regeln.ShowVerpackungskosten || _regeln.ShowRabatt;
            _regeln.ShowAdresszeileLand = _gutschrift.Land != "DE";
            _regeln.ShowAdresszeile2 = !String.IsNullOrWhiteSpace(_gutschrift.Name2);
            _regeln.ShowAdresszeile3 = !String.IsNullOrWhiteSpace(_gutschrift.Name3);
            _regeln.ShowAdresszeile4 = !String.IsNullOrWhiteSpace(_gutschrift.Ansprechpartner);
            _regeln.ShowRechnungsnummer = _gutschrift.RechnungsnummerVerknüpfung > 0;
        }

        protected override async Task<string> SetTemplateVariables()
        {
            Ansprechpartner? partner = null;
            if (!String.IsNullOrWhiteSpace(_gutschrift.Ansprechpartner))
            {
                partner = await Ansprechpartner.GetAnsprechpartnerByNameAsync(_gutschrift.Kundennummer, _gutschrift.Ansprechpartner);
            }

            Lieferanschrift? lieferanschrift = null;
            Rechnungsanschrift? rechnungsanschrift = null;
            Lieferbedingung? lieferbedingung = _lieferbedingungen.Where(x => x.LIBD_N_NR == _gutschrift.LieferbedingungId).FirstOrDefault();
            Zahlungsbedingung zahlungsbedingung = _zahlungsbedingungen.Where(x => x.ZABD_N_NR == _gutschrift.ZahlungsbedingungId).FirstOrDefault() ?? throw new ArgumentNullException(nameof(zahlungsbedingung));
            if (_gutschrift.LieferanschriftId > 0)
            {
                lieferanschrift = await Lieferanschrift.GetLieferanschriftAsync(_gutschrift.Kundennummer, _gutschrift.LieferanschriftId);
            }

            if (_gutschrift.RechnungsanschriftId > 0)
            {
                rechnungsanschrift = await Rechnungsanschrift.GetRechnungsanschriftAsync(_gutschrift.Kundennummer, _gutschrift.RechnungsanschriftId);
                _regeln.ShowAdresszeile2 = !String.IsNullOrWhiteSpace(rechnungsanschrift.KURE_A_NAME2);
                _regeln.ShowAdresszeile3 = !String.IsNullOrWhiteSpace(rechnungsanschrift.KURE_A_NAME3);
                _regeln.ShowAdresszeile4 = false;
                _regeln.ShowAdresszeileLand = rechnungsanschrift.KURE_A_LAND != "DE";
            }

            using FbController2 fbController = new FbController2();


            Land land = rechnungsanschrift is not null
                ? await Land.GetLandAsync(rechnungsanschrift.KURE_A_LAND, fbController) ?? throw new ArgumentNullException(nameof(land))
                : await Land.GetLandAsync(_gutschrift.Land, fbController) ?? throw new ArgumentNullException(nameof(land));

            StringBuilder posBuilder = new StringBuilder();
            decimal netto = 0;
            decimal rabatt = 0;
            decimal mwst = 0;
            int zähler = 1;
            foreach (var pos in _gutschrift.Positionen.OrderBy(x => x.PosNr))
            {
                if (pos.PosOhneDruck)
                {
                    continue;
                }

                bool istText = pos.Artikelnummer.Equals("TEXT", StringComparison.OrdinalIgnoreCase);

                Option? sucheOption = _optionen.Where(x => x.OPTI_A_NR.Equals(pos.Option)).FirstOrDefault();

                posBuilder.AppendLine("<tr class=\"pos\">");
                posBuilder.AppendLine("\t<td class=\"nowrap\">");
                if (!istText)
                {
                    posBuilder.AppendLine($"\t\t{zähler}");
                    zähler++;
                }
                posBuilder.AppendLine("\t</td>");
                // Spalte Artikelnummer
                posBuilder.AppendLine("\t<td class=\"\">");
                if (!istText)
                {
                    posBuilder.AppendLine("\t\t<span class=\"font-weight-bold\">");
                    if (!String.IsNullOrWhiteSpace(pos.Kundensachnummer))
                    {
                        posBuilder.AppendLine($"\t\t\t{pos.Artikelnummer} ({pos.Kundensachnummer})");
                    }
                    else
                    {
                        posBuilder.AppendLine($"\t\t\t{pos.Artikelnummer}");
                    }
                    posBuilder.AppendLine("\t\t</span>");
                }

                if (pos.ARTI_L_MIETE && pos.BPOS_D_MIETE_START != default && pos.BPOS_D_MIETE_ENDE != default)
                {
                    if (IsEnglisch)
                    {
                        posBuilder.AppendLine($"\t\t<span class=\"d-block font-weight-bold\">Period: {pos.BPOS_D_MIETE_START.ToShortDateString()} - {pos.BPOS_D_MIETE_ENDE.ToShortDateString()}</span>");
                    }
                    else
                    {
                        posBuilder.AppendLine($"\t\t<span class=\"d-block font-weight-bold\">Zeitraum: {pos.BPOS_D_MIETE_START.ToShortDateString()} - {pos.BPOS_D_MIETE_ENDE.ToShortDateString()}</span>");
                    }
                }

                posBuilder.AppendLine($"\t\t<div class=\"position-bezeichnung\">");
                posBuilder.AppendLine($"\t\t\t{pos.GetBezeichnung()}");
                posBuilder.AppendLine($"\t\t</div>");

                foreach (Seriennummer seriennummer in pos.Seriennummern)
                {
                    posBuilder.AppendLine($"\t\t<span class=\"d-block font-weight-bold\">SN: {seriennummer.Nummer}{(!String.IsNullOrWhiteSpace(seriennummer.Kunde) ? $", {seriennummer.Kunde}" : String.Empty)}</span>");
                }

                if (!land.WK5_LAND_L_ISTEULAND)
                {
                    Zolltarif? zolltarif = await Zolltarif.GetZolltarifAsync(pos.Artikelnummer, fbController);

                    if (zolltarif is not null)
                    {
                        if (!String.IsNullOrWhiteSpace(pos.ARTI_A_URSPRUNGSLAND))
                        {
                            if (IsEnglisch)
                            {
                                posBuilder.AppendLine($"\t\t<span class=\"d-block font-weight-bold\">TARIC: {zolltarif.ZOTA_A_ZOLLTARIFNR}, Origin country: {pos.ARTI_A_URSPRUNGSLAND}</span>");
                            }
                            else
                            {
                                posBuilder.AppendLine($"\t\t<span class=\"d-block font-weight-bold\">TARIC: {zolltarif.ZOTA_A_ZOLLTARIFNR}, Ursprungsland: {pos.ARTI_A_URSPRUNGSLAND}</span>");
                            }

                        }
                        else
                        {
                            posBuilder.AppendLine($"\t\t<span class=\"d-block font-weight-bold\">TARIC: {zolltarif.ZOTA_A_ZOLLTARIFNR}</span>");
                        }

                    }
                }


                posBuilder.AppendLine("\t</td>");

                // Spalte Menge
                posBuilder.AppendLine("\t<td class=\"nowrap text-right\">");
                if (pos.Menge > 0)
                {
                    posBuilder.AppendLine($"\t\t{pos.Menge:0.00} {pos.BPOS_A_MASSEINHEIT}");
                }
                else
                {
                    posBuilder.AppendLine($"\t\t");
                }

                // Spalte VK-Preis
                posBuilder.AppendLine("\t<td class=\"nowrap text-right\">");
                if (!istText)
                {
                    if (pos.Menge > 10000)
                    {
                        posBuilder.AppendLine($"\t\t{pos.Preis:0.0000}");
                    }
                    else
                    {
                        posBuilder.AppendLine($"\t\t{pos.Preis:0.00}");
                    }

                }
                posBuilder.AppendLine("\t</td>");

                // Spalte Rabatt
                posBuilder.AppendLine("\t<td class=\"nowrap text-right\">");
                if (pos.Rabatt1 > 0 && pos.Rabatt2 > 0)
                {
                    if (!String.IsNullOrWhiteSpace(pos.Rabattbezeichnung))
                    {
                        if (IsEnglisch)
                        {
                            // Bei Englisch gibt es keine Rabattbezeichnung, da die nur auf deutsch vorhanden ist.
                            posBuilder.AppendLine($"\t\t{pos.Rabatt1:0.00}<br />+ {pos.Rabatt2}<br />Special discount");
                        }
                        else
                        {
                            posBuilder.AppendLine($"\t\t{pos.Rabatt1:0.00}<br />{pos.Rabattbezeichnung}<br />+ {pos.Rabatt2:0.00}<br />Sonderrabatt");
                        }

                    }
                    else
                    {
                        if (IsEnglisch)
                        {
                            posBuilder.AppendLine($"\t\t{pos.Rabatt1:0.00}<br />+ {pos.Rabatt2:0.00}<br />Special discount");
                        }
                        else
                        {
                            posBuilder.AppendLine($"\t\t{pos.Rabatt1:0.00}<br />+ {pos.Rabatt2:0.00}<br />Sonderrabatt");
                        }
                    }

                }
                else if (pos.Rabatt1 > 0)
                {

                    if (!String.IsNullOrWhiteSpace(pos.Rabattbezeichnung))
                    {
                        posBuilder.AppendLine($"\t\t{pos.Rabatt1:0.00}<br />");
                        posBuilder.AppendLine($"\t\t{pos.Rabattbezeichnung}");
                    }
                    else
                    {
                        posBuilder.AppendLine($"\t\t{pos.Rabatt1:0.00}");
                    }
                }
                else if (pos.Rabatt2 > 0)
                {
                    posBuilder.AppendLine($"\t\t{pos.Rabatt2:0.00}<br />");
                    if (IsEnglisch)
                    {
                        posBuilder.AppendLine("\t\tSpecial discount");
                    }
                    else
                    {
                        posBuilder.AppendLine("\t\tSonderrabatt");
                    }
                }
                posBuilder.AppendLine("\t</td>");

                // Spalte Preis
                posBuilder.AppendLine("\t<td class=\"nowrap text-right\">");
                if (pos.PreisMitRabatt is > 0 or < 0 || pos.Rabatt > 0)
                {
                    posBuilder.AppendLine($"\t\t{pos.PreisMitRabatt:0.00}");
                }
                posBuilder.AppendLine("\t</td>");

                // Spalte Gesamt
                posBuilder.AppendLine("\t<td class=\"nowrap text-right\">");
                if (!istText)
                {
                    if (sucheOption is not null && !sucheOption.OPTI_L_BERECHNEN)
                    {
                        posBuilder.AppendLine($"\t\t{pos.GetGesamtNetto():0.00}<br /><span class=\"font-weight-bold\">{sucheOption.OPTI_A_BEZEICH}<br />nicht in Summe</span>");
                    }
                    else
                    {
                        posBuilder.AppendLine($"\t\t{(pos.GetGesamtNetto() - pos.Rabatt):0.00}");
                    }
                }
                posBuilder.AppendLine("\t</td>");



                posBuilder.AppendLine("\t</td>");
                posBuilder.AppendLine("</tr>");

                if (!String.IsNullOrWhiteSpace(pos.Langtext))
                {
                    posBuilder.AppendLine("<tr>");
                    posBuilder.AppendLine("\t<td></td>");
                    posBuilder.AppendLine("\t<td colspan=\"5\">");
                    posBuilder.AppendLine($"\t\t<div class=\"position-bezeichnung\">");
                    if (pos.LangtextDrucken)
                    {
                        posBuilder.AppendLine($"\t\t\t\t{pos.Langtext.HtmlToDruckHtml()}");
                    }
                    posBuilder.AppendLine($"\t\t</div>");
                    posBuilder.AppendLine("\t</td>");
                    posBuilder.AppendLine("\t<td></td>");
                    posBuilder.AppendLine("</tr>");
                }

                if ((sucheOption is not null && sucheOption.OPTI_L_BERECHNEN) || sucheOption is null)
                {
                    if (_gutschrift.MwstBerechnen)
                    {
                        mwst += pos.GetMwstSumme();
                    }
                    rabatt += pos.GetRabatt1();
                    rabatt += pos.GetRabatt2();
                    netto += pos.GetGesamtNetto();
                }
            }

            if (_gutschrift.MwstBerechnen)
            {
                mwst += _gutschrift.Zusatzkosten * _versandMehrwertsteuer.MWST_N_PROZENT / 100;
            }

            if (_regeln.ShowZwischensumme)
            {
                posBuilder.AppendLine("<tr class=\"total display-zwischensumme border-top\">");
            }
            else
            {
                posBuilder.AppendLine("<tr class=\"total display-zwischensumme\">");
            }

            posBuilder.AppendLine("\t<td colspan=\"6\" class=\"text-right\">");
            if (IsEnglisch)
            {
                posBuilder.AppendLine($"\t\tSubtotal:");
            }
            else
            {
                posBuilder.AppendLine($"\t\tZwischensumme:");
            }
            posBuilder.AppendLine("\t</td>");
            posBuilder.AppendLine("\t<td class=\"text-right\">");
            posBuilder.AppendLine($"\t\t{(netto - rabatt):0.00}");
            posBuilder.AppendLine("\t</td>");
            posBuilder.AppendLine("</tr>");

            posBuilder.AppendLine("<tr class=\"total display-versandkosten\">");
            posBuilder.AppendLine("\t<td colspan=\"6\" class=\"text-right\">");
            if (IsEnglisch)
            {
                posBuilder.AppendLine($"\t\tShipping costs:");
            }
            else
            {
                posBuilder.AppendLine($"\t\tVersandkosten:");
            }
            posBuilder.AppendLine("\t</td>");
            posBuilder.AppendLine("\t<td class=\"text-right\">");
            posBuilder.AppendLine($"\t\t{_gutschrift.Frachtkosten:0.00}");
            posBuilder.AppendLine("\t</td>");
            posBuilder.AppendLine("</tr>");

            posBuilder.AppendLine("<tr class=\"total display-verpackungskosten\">");
            posBuilder.AppendLine("\t<td colspan=\"6\" class=\"text-right\">");
            if (IsEnglisch)
            {
                posBuilder.AppendLine($"\t\tPacking costs:");
            }
            else
            {
                posBuilder.AppendLine($"\t\tVerpackungskosten:");
            }
            posBuilder.AppendLine("\t</td>");
            posBuilder.AppendLine("\t<td class=\"text-right\">");
            posBuilder.AppendLine($"\t\t{_gutschrift.Verpackungskosten:0.00}");
            posBuilder.AppendLine("\t</td>");
            posBuilder.AppendLine("</tr>");

            posBuilder.AppendLine("<tr class=\"total display-versicherungskosten\">");
            posBuilder.AppendLine("\t<td colspan=\"6\" class=\"text-right\">");
            if (IsEnglisch)
            {
                posBuilder.AppendLine($"\t\tInsurance costs:");
            }
            else
            {
                posBuilder.AppendLine($"\t\tVersicherungskosten:");
            }
            posBuilder.AppendLine("\t</td>");
            posBuilder.AppendLine("\t<td class=\"text-right\">");
            posBuilder.AppendLine($"\t\t{_gutschrift.Versicherungskosten:0.00}");
            posBuilder.AppendLine("\t</td>");
            posBuilder.AppendLine("</tr>");



            if (_regeln.ShowZwischensumme)
            {
                posBuilder.AppendLine("<tr class=\"total font-weight-bold\">");
            }
            else
            {
                posBuilder.AppendLine("<tr class=\"total border-top font-weight-bold\">");
            }

            posBuilder.AppendLine("\t<td colspan=\"6\" class=\"text-right\">");
            if (IsEnglisch)
            {
                posBuilder.AppendLine($"\t\tTotal EUR without VAT.:");
            }
            else
            {
                posBuilder.AppendLine($"\t\tTotal EUR ohne Mwst.:");
            }
            posBuilder.AppendLine("\t</td>");
            posBuilder.AppendLine("\t<td class=\"text-right\">");
            posBuilder.AppendLine($"\t\t{netto + _gutschrift.Zusatzkosten - rabatt:0.00}");
            posBuilder.AppendLine("\t</td>");
            posBuilder.AppendLine("</tr>");

            posBuilder.AppendLine("<tr class=\"total display-mwst\">");
            posBuilder.AppendLine("\t<td colspan=\"6\" class=\"text-right\">");
            posBuilder.AppendLine($"\t\tzzgl. {_gutschrift.BELE_N_MWST_SATZ1}% MwSt:");
            posBuilder.AppendLine("\t</td>");
            posBuilder.AppendLine("\t<td class=\"text-right\">");
            posBuilder.AppendLine($"\t\t{mwst:0.00}");
            posBuilder.AppendLine("\t</td>");
            posBuilder.AppendLine("</tr>");

            posBuilder.AppendLine("<tr class=\"total display-endbetrag-brutto font-weight-bold\">");
            posBuilder.AppendLine("\t<td colspan=\"6\" class=\"text-right\">");
            if (IsEnglisch)
            {
                posBuilder.AppendLine($"\t\tTotal EUR incl. VAT.");
            }
            else
            {
                posBuilder.AppendLine($"\t\tTotal EUR inkl. Mwst.:");
            }
            posBuilder.AppendLine("\t</td>");
            posBuilder.AppendLine("\t<td class=\"text-right\">");
            posBuilder.AppendLine($"\t\t{netto + _gutschrift.Zusatzkosten - rabatt + mwst:0.00}");
            posBuilder.AppendLine("\t</td>");
            posBuilder.AppendLine("</tr>");

            posBuilder.AppendLine("<tr class=\"total display-rabatt\">");
            posBuilder.AppendLine("\t<td colspan=\"6\" class=\"text-right\">");
            if (IsEnglisch)
            {
                posBuilder.AppendLine($"\t\t(Discount:");
            }
            else
            {
                posBuilder.AppendLine($"\t\t(eingerechneter Rabatt:");
            }
            posBuilder.AppendLine("\t</td>");
            posBuilder.AppendLine("\t<td class=\"text-right\">");
            posBuilder.AppendLine($"\t\t-{rabatt:0.00})");
            posBuilder.AppendLine("\t</td>");
            posBuilder.AppendLine("</tr>");



            string zusatztext = String.Empty;

            if (land.LAND_A_ID.Equals("DE", StringComparison.OrdinalIgnoreCase))
            {
                zusatztext = _textCollection.Where(x => x.TEXT_A_IDENTIFIER == GlobalConfig.IDENTIFIER_KEY_RECHNUNGEN_DE).FirstOrDefault()?.TEXT_B_TEXT ?? String.Empty;
            }
            else if (land.WK5_LAND_L_ISTEULAND && _gutschrift.MwstBerechnen)
            {
                if (IsEnglisch)
                {
                    zusatztext = _textCollection.Where(x => x.TEXT_A_IDENTIFIER == GlobalConfig.IDENTIFIER_KEY_RECHNUNGEN_EU_MIT_MWST_EN).FirstOrDefault()?.TEXT_B_TEXT ?? String.Empty;
                }
                else
                {
                    zusatztext = _textCollection.Where(x => x.TEXT_A_IDENTIFIER == GlobalConfig.IDENTIFIER_KEY_RECHNUNGEN_EU_MIT_MWST).FirstOrDefault()?.TEXT_B_TEXT ?? String.Empty;
                }

            }
            else if (land.WK5_LAND_L_ISTEULAND && !_gutschrift.MwstBerechnen)
            {
                Kunde kunde = await Kunde.GetKundeAsync(_gutschrift.Kundennummer) ?? throw new ArgumentNullException(nameof(kunde));
                if (IsEnglisch)
                {
                    zusatztext = _textCollection.Where(x => x.TEXT_A_IDENTIFIER == GlobalConfig.IDENTIFIER_KEY_RECHNUNGEN_EU_OHNE_MWST_EN).FirstOrDefault()?.TEXT_B_TEXT ?? String.Empty;
                }
                else
                {
                    zusatztext = _textCollection.Where(x => x.TEXT_A_IDENTIFIER == GlobalConfig.IDENTIFIER_KEY_RECHNUNGEN_EU_OHNE_MWST).FirstOrDefault()?.TEXT_B_TEXT ?? String.Empty;
                }


                zusatztext = zusatztext.Replace("{{ USTID }}", kunde.KUND_A_USTIDNR ?? String.Empty);
                zusatztext = zusatztext.Replace("{{ USTID_GEPRUEFT }}", kunde.UstIdLastPrüfung.ToShortDateString());
            }
            else if (!land.WK5_LAND_L_ISTEULAND)
            {
                if (IsEnglisch)
                {
                    zusatztext = _textCollection.Where(x => x.TEXT_A_IDENTIFIER == GlobalConfig.IDENTIFIER_KEY_RECHNUNGEN_DRITTLAND_EN).FirstOrDefault()?.TEXT_B_TEXT ?? String.Empty;
                }
                else
                {
                    zusatztext = _textCollection.Where(x => x.TEXT_A_IDENTIFIER == GlobalConfig.IDENTIFIER_KEY_RECHNUNGEN_DRITTLAND).FirstOrDefault()?.TEXT_B_TEXT ?? String.Empty;
                }
            }

            string zahlungsbedinungText = IsEnglisch
                ? zahlungsbedingung.ZABD_A_TEXT2 ?? String.Empty
                : zahlungsbedingung.ZABD_A_TEXT1 ?? String.Empty;

            if (zahlungsbedingung.ZABD_L_VORKASSE && _gutschrift.BELE_L_BEZAHLT)
            {
                zahlungsbedinungText = IsEnglisch
                    ? $"{zahlungsbedinungText} (Your payment has been booked)"
                    : $"{zahlungsbedinungText} (Ihre Zahlung wurde verbucht)";
            }

            DateTime zahlungsziel = _gutschrift.BELE_D_DATE.AddDays(zahlungsbedingung.ZABD_N_NETTOTAGE);
            string gesamtfälligkeitText = IsEnglisch
                ? $"<span class=\"font-weight-bold\">{_gutschrift.GetBruttoBetrag(_optionen, _versandMehrwertsteuer):0.00}€ until</span> {zahlungsziel.ToShortDateString()}"
                : $"<span class=\"font-weight-bold\">{_gutschrift.GetBruttoBetrag(_optionen, _versandMehrwertsteuer):0.00}€ bis</span> {zahlungsziel.ToShortDateString()}";

            if (zahlungsbedingung.ZABD_N_SKONTO1TAGE > 0 && zahlungsbedingung.ZABD_N_SKONTO1TAGE > 0)
            {
                DateTime zahlungszielSkonto = _gutschrift.BELE_D_DATE.AddDays(zahlungsbedingung.ZABD_N_SKONTO1TAGE);

                if (zahlungsziel != zahlungszielSkonto)
                {
                    gesamtfälligkeitText = IsEnglisch
                    ? $"{gesamtfälligkeitText}<br /><span class=\"font-weight-bold\">With cashback {zahlungsbedingung.ZABD_N_SKONTO1PROZ}% {MathExtensions.BerechnePreis(_gutschrift.GetBruttoBetrag(_optionen, _versandMehrwertsteuer), zahlungsbedingung.ZABD_N_SKONTO1PROZ):0.00}€ until</span>{zahlungszielSkonto.ToShortDateString()}"
                    : $"{gesamtfälligkeitText}<br /><span class=\"font-weight-bold\">Mit Skonto {zahlungsbedingung.ZABD_N_SKONTO1PROZ}% {MathExtensions.BerechnePreis(_gutschrift.GetBruttoBetrag(_optionen, _versandMehrwertsteuer), zahlungsbedingung.ZABD_N_SKONTO1PROZ):0.00}€ bis </span>{zahlungszielSkonto.ToShortDateString()}";
                }
            }

            // 19.05.2021 MK- Vertrieb möchte keinen Ansprechpartner in der Rechnunganschrift sehen, daher hier fix ausgeblendet
            _regeln.ShowAdresszeile4 = false;

            if (rabatt is 0)
            {
                _regeln.ShowRabatt = false;
            }

            _template = _template
                .Replace("{{ DISPLAY_CSS }}", GenerateDisplayCss())
                .Replace("{{ IMPRESSUM }}", GlobalConfig.Configuration.FirmenDaten.ImpressumHtmlDruckformulare())
                .Replace("{{ ABS_FIRMA }}", GlobalConfig.Configuration.FirmenDaten.Firmenname)
                .Replace("{{ ABS_STRASSE }}", GlobalConfig.Configuration.FirmenDaten.Firmenanschrift.Strasse)
                .Replace("{{ ABS_LAND }}", GlobalConfig.Configuration.FirmenDaten.Firmenanschrift.Land)
                .Replace("{{ ABS_PLZ }}", GlobalConfig.Configuration.FirmenDaten.Firmenanschrift.Postleitzahl)
                .Replace("{{ ABS_ORT }}", GlobalConfig.Configuration.FirmenDaten.Firmenanschrift.Ort)
                .Replace("{{ ADDRESSZEILE1 }}", rechnungsanschrift is not null ? rechnungsanschrift.KURE_A_NAME1 ?? String.Empty : _gutschrift.Name1)
                .Replace("{{ ADDRESSZEILE2 }}", rechnungsanschrift is not null ? rechnungsanschrift.KURE_A_NAME2 ?? String.Empty : _gutschrift.Name2)
                .Replace("{{ ADDRESSZEILE3 }}", rechnungsanschrift is not null ? rechnungsanschrift.KURE_A_NAME3 ?? String.Empty : _gutschrift.Name3)
                .Replace("{{ ADDRESSZEILE4 }}", rechnungsanschrift is not null ? String.Empty : partner is not null ? partner.GetName() : _gutschrift.Ansprechpartner)
                .Replace("{{ EMP_STRASSE }}", rechnungsanschrift is not null ? rechnungsanschrift.KURE_A_STRASSE ?? String.Empty : _gutschrift.Strasse)
                .Replace("{{ EMP_LAND }}", rechnungsanschrift is not null ? rechnungsanschrift.KURE_A_LAND ?? String.Empty : land.LAND_A_NAME)
                .Replace("{{ EMP_PLZ }}", rechnungsanschrift is not null ? rechnungsanschrift.KURE_A_PLZ : _gutschrift.Postleitzahl)
                .Replace("{{ EMP_ORT }}", rechnungsanschrift is not null ? rechnungsanschrift.KURE_A_ORT : _gutschrift.Ort)
                .Replace("{{ DATUM }}", _gutschrift.BELE_D_DATE.ToShortDateString())
                .Replace("{{ KUNDENNUMMER }}", _gutschrift.Kundennummer)
                .Replace("{{ BESTELLT_DURCH }}", _gutschrift.BestelltDurch)
                .Replace("{{ BESTELLT_AM }}", _gutschrift.BestelltAm.ToShortDateString())
                .Replace("{{ KOPFTEXT }}", _gutschrift.Kopftext)
                .Replace("{{ FUSSTEXT }}", _gutschrift.Fußtext)
                .Replace("{{ POSITIONEN }}", posBuilder.ToString())
                .Replace("{{ GUTSCHRIFTNUMMER }}", _gutschrift.Belegnummer.ToString())
                .Replace("{{ BESTELLNUMMER }}", _gutschrift.Bestellnummer ?? String.Empty)
                .Replace("{{ RECHNUNGSNUMMER }}", _gutschrift.RechnungsnummerVerknüpfung.ToString())
                .Replace("{{ ZUSATZTEXT }}", zusatztext)
                ;

            return await Task.FromResult(_template);
        }
    }
}
