using KarleyLibrary.Erweiterungen;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WK5.Core.Basis.Filter;
using WK5.Core.Models;
using WK5.Core.Models.Bestellungen;
using WK5.Core.PageModels.Einkauf.Bestellungen;

namespace WK5.Core.Services
{
    public class BestellService
    {
        /// <summary>
        /// Lädt alle offenen Aufträge die komplett durch eine Bestellung geliefert werden können
        /// </summary>
        /// <param name="bestellnummer"></param>
        /// <param name="fbController"></param>
        /// <returns></returns>
        public async IAsyncEnumerable<Auftrag> GetOffeneAufträgeDieKomplettDurchBestellungLieferbarSind(int bestellnummer, FbController2 fbController)
        {
            string sql = @"SELECT BELE_A_TYP, BELE_N_NR FROM BELEGE
WHERE BELE_A_TYP = 'AU'
AND BELE_L_ERLEDIGT = 'N'
AND BELE_L_STORNO = 'N'
AND (
    SELECT COUNT(*) FROM BELEGPOS 
    WHERE BPOS_A_TYP = BELE_A_TYP 
    AND BPOS_N_NR = BELE_N_NR 
    AND (BPOS_N_MENGE-BPOS_N_MENGEGELIEF) > 0
    AND (
        SELECT SUMME FROM (
            SELECT SUM(BEPO_N_MENGE-BEPO_N_LIEFERMENGE) AS SUMME, BEPO_A_ARTIKELNR 
            FROM BESTELLUNGEN_POS 
            WHERE BEPO_N_BESTNR = @BESTELLNR
            AND BEPO_L_ERLEDIGT = 'N'
            GROUP BY BEPO_A_ARTIKELNR
        )
        WHERE BEPO_A_ARTIKELNR = BPOS_A_ARTIKELNR 
    ) >= (BPOS_N_MENGE-BPOS_N_MENGEGELIEF)    
) = (SELECT COUNT(*) FROM BELEGPOS WHERE BPOS_A_TYP = BELE_A_TYP AND BPOS_N_NR = BELE_N_NR )
AND (SELECT COUNT(*) FROM BELEGPOS WHERE BPOS_A_TYP = BELE_A_TYP AND BPOS_N_NR = BELE_N_NR ) > 0";

            BelegService belegService = new BelegService();

            fbController.AddParameter("@BESTELLNR", bestellnummer);            

            DataTable data = await fbController.SelectDataAsync(sql);
            foreach(DataRow row in data.Rows)
            {
                yield return (await Auftrag.GetAuftragAsync(row.Field<int>("BELE_N_NR"), fbController))!;                
            }
        }

        /// <summary>
        /// Lädt Alle offenen Aufträge die noch offene Positionen enthalten die in der Bestellung vorhanden sind
        /// </summary>
        /// <param name="bestellnummer"></param>
        /// <param name="fbController"></param>
        /// <returns></returns>
        public async IAsyncEnumerable<Auftrag> GetOffeneAufträgeDieArtikelDerBestellungEnthalten(int bestellnummer, FbController2 fbController)
        {
            string sql = @"SELECT BELE_A_TYP, BELE_N_NR FROM BELEGE
WHERE BELE_A_TYP = 'AU'
AND BELE_L_ERLEDIGT = 'N'
AND BELE_L_STORNO = 'N'
AND (
    SELECT COUNT(*) FROM BELEGPOS 
    WHERE BPOS_A_TYP = BELE_A_TYP 
    AND BPOS_N_NR = BELE_N_NR 
    AND (BPOS_N_MENGE-BPOS_N_MENGEGELIEF) > 0
    AND BPOS_A_ARTIKELNR IN 
    (
        SELECT DISTINCT(BEPO_A_ARTIKELNR) 
        FROM BESTELLUNGEN_POS 
        WHERE BEPO_N_BESTNR = @BESTELLNR 
        AND (BEPO_N_MENGE-BEPO_N_LIEFERMENGE) > 0               
        AND BEPO_L_ERLEDIGT = 'N'
    )         
) > 0";
            fbController.AddParameter("@BESTELLNR", bestellnummer);

            DataTable data = await fbController.SelectDataAsync(sql);
            foreach (DataRow row in data.Rows)
            {
                yield return (await Auftrag.GetAuftragAsync(row.Field<int>("BELE_N_NR"), fbController))!;
            }

        }

        public async Task<int> CreateBestellungAsync(Bestellung bestellung, int userId, FbController2 fbController)
        {
            if (bestellung.Bestellnummer > 0)
            {
                return 0;
            }

            int neueBestellnummer = Convert.ToInt32(await fbController.FetchObjectAsync("SELECT NR_NEW FROM BESTELLUNG_NEW"));

            decimal netto = bestellung.Positionen.Sum(x => x.PreisMitRabatt * x.BEPO_N_MENGE);
            decimal brutto = bestellung.Positionen.Sum(x => x.PreisMitRabatt * x.BEPO_N_MENGE * (1 + (x.BEPO_N_MWSTPROZ / 100)));
            decimal mwst = bestellung.Positionen.Sum(x => x.PreisMitRabatt * x.BEPO_N_MENGE * x.BEPO_N_MWSTPROZ / 100);

            #region Parameter
            fbController.AddParameter("@BEST_N_NR", neueBestellnummer);
            fbController.AddParameter("@BEST_N_LIEFNR", bestellung.LieferantenId);
            fbController.AddParameter("@BEST_A_PARTNER", bestellung.BEST_A_PARTNER);
            fbController.AddParameter("@BEST_D_LIEFTERMIN", bestellung.BEST_D_LIEFTERMIN);
            fbController.AddParameter("@BEST_N_ZAHLUNG", bestellung.BEST_N_ZAHLUNG);
            fbController.AddParameter("@BEST_N_LIEFERUNG", bestellung.LieferbedingungId);
            fbController.AddParameter("@BEST_A_WAEHRUNG", bestellung.Währung);
            fbController.AddParameter("@BEST_N_NETTO", netto);
            fbController.AddParameter("@BEST_N_AB_NR", bestellung.BEST_N_AB_NR);
            fbController.AddParameter("@BEST_N_MWST", mwst);
            fbController.AddParameter("@BEST_N_BRUTTO", brutto);
            fbController.AddParameter("@BEST_A_LIEFERKUNDE", bestellung.BEST_A_LIEFERKUNDE);
            fbController.AddParameter("@BEST_A_LIEFERKUNDELA", bestellung.BEST_A_LIEFERKUNDELA);
            fbController.AddParameter("@BEST_A_FORMULAR", "Beleg_Bestellung.lst");
            fbController.AddParameter("@BEST_L_ERLEDIGT", "N");
            fbController.AddParameter("@BEST_N_ANLAGEUSER", userId);
            fbController.AddParameter("@BEST_N_LASTUSER", userId);
            fbController.AddParameter("@BEST_N_ZUSATZKOST", bestellung.BEST_N_ZUSATZKOST);
            fbController.AddParameter("@BEST_N_FRACHT", bestellung.Versandkosten);
            fbController.AddParameter("@BEST_N_VERPACKUNG", bestellung.Verpackungskosten);
            fbController.AddParameter("@BEST_N_VERSICHERUNG", bestellung.Versicherungskosten);
            fbController.AddParameter("@BEST_A_ANGEBOTNR", bestellung.BEST_A_ANGEBOTNR);
            fbController.AddParameter("@BEST_A_BESTAET_NR_LIEF", bestellung.BEST_A_BESTAET_NR_LIEF);
            fbController.AddParameter("@BEST_B_FUSSTEXT", bestellung.BEST_B_FUSSTEXT);
            fbController.AddParameter("@BEST_B_KOPFTEXT", bestellung.BEST_B_KOPFTEXT);
            fbController.AddParameter("@BEST_B_NOTIZ", bestellung.BEST_B_NOTIZ);
            fbController.AddParameter("@BEST_D_ANGEBOTVOM", bestellung.BEST_D_ANGEBOTVOM);
            fbController.AddParameter("@BEST_D_BESTAETIGT", bestellung.BEST_D_BESTAETIGT);
            fbController.AddParameter("@BEST_D_ERLEDIGTAM", bestellung.BEST_D_ERLEDIGTAM);
            fbController.AddParameter("@BEST_D_VERSENDET", bestellung.BEST_D_VERSENDET);
            fbController.AddParameter("@BEST_L_BESTAETIGT", bestellung.BEST_L_BESTAETIGT);
            fbController.AddParameter("@BEST_L_VERSENDET", bestellung.BEST_L_VERSENDET);
            fbController.AddParameter("@BEST_L_ABRUF", bestellung.IstAbrufbestellung);
            fbController.AddParameter("@BEST_L_FRACHTFREI", bestellung.BEST_L_FRACHTFREI);
            #endregion

            #region Bestellung einfügen
            await fbController.QueryAsync(@"INSERT INTO BESTELLUNGEN
(
BEST_N_NR, 
BEST_N_LIEFNR, 
BEST_A_PARTNER, 
BEST_D_DATE, 
BEST_D_LIEFTERMIN,
BEST_N_ZAHLUNG, 
BEST_N_LIEFERUNG, 
BEST_N_KURS, 
BEST_A_WAEHRUNG, 
BEST_N_NETTO, 
BEST_N_AB_NR, 
BEST_L_ABRUF,
BEST_N_ZUSATZKOST, 
BEST_N_FRACHT, 
BEST_N_VERPACKUNG, 
BEST_N_VERSICHERUNG,
BEST_N_RABATT, 
BEST_N_MWST, 
BEST_N_BRUTTO, 
BEST_A_LIEFERKUNDE, 
BEST_A_LIEFERKUNDELA,
BEST_A_ANGEBOTNR, 
BEST_A_BESTAET_NR_LIEF, 
BEST_B_FUSSTEXT, 
BEST_B_KOPFTEXT, 
BEST_B_NOTIZ,
BEST_D_ANGEBOTVOM, 
BEST_D_BESTAETIGT, 
BEST_D_ERLEDIGTAM, 
BEST_D_VERSENDET,
BEST_L_BESTAETIGT, 
BEST_L_VERSENDET,
BEST_A_FORMULAR, 
BEST_L_ERLEDIGT, 
BEST_L_FRACHTFREI,
BEST_N_ANLAGEUSER, 
BEST_N_LASTUSER, 
BEST_TIMESTAMP
)
VALUES
(
@BEST_N_NR, 
@BEST_N_LIEFNR, 
@BEST_A_PARTNER, 
CURRENT_DATE, 
@BEST_D_LIEFTERMIN,
@BEST_N_ZAHLUNG, 
@BEST_N_LIEFERUNG, 
(SELECT WAEH_N_KURS FROM WAEHRUNG WHERE WAEH_A_ZEICHEN = @BEST_A_WAEHRUNG), 
@BEST_A_WAEHRUNG, 
@BEST_N_NETTO, 
@BEST_N_AB_NR, 
@BEST_L_ABRUF, 
@BEST_N_ZUSATZKOST, 
@BEST_N_FRACHT, 
@BEST_N_VERPACKUNG, 
@BEST_N_VERSICHERUNG,
0,
@BEST_N_MWST, 
@BEST_N_BRUTTO, 
@BEST_A_LIEFERKUNDE, 
@BEST_A_LIEFERKUNDELA,
@BEST_A_ANGEBOTNR, 
@BEST_A_BESTAET_NR_LIEF, 
@BEST_B_FUSSTEXT, 
@BEST_B_KOPFTEXT, 
@BEST_B_NOTIZ,
@BEST_D_ANGEBOTVOM, 
@BEST_D_BESTAETIGT, 
@BEST_D_ERLEDIGTAM, 
@BEST_D_VERSENDET,
@BEST_L_BESTAETIGT, 
@BEST_L_VERSENDET,
@BEST_A_FORMULAR, 
@BEST_L_ERLEDIGT, 
@BEST_L_FRACHTFREI,
@BEST_N_ANLAGEUSER, 
@BEST_N_LASTUSER, 
CURRENT_TIMESTAMP
)");
            #endregion

            #region Positionen
            foreach (var pos in bestellung.Positionen)
            {
                pos.BEPO_N_BESTNR = neueBestellnummer;
                pos.BEPO_N_LASTUSER = userId;
                pos.BEPO_N_POSID = Convert.ToInt32(await InsertPosition(fbController, pos));

            }
            #endregion


            await InsertAngelegtHistorie(neueBestellnummer, userId, fbController);

            return neueBestellnummer;
        }

        private Task<bool> InsertAngelegtHistorie(int bestellnummer, int userId, FbController2 fbController)
        {
            return BelegChange.InsertBelegChangeAsync(fbController, new BelegChange
            {
                BCNG_A_BELEGTYP = "BE",
                BCNG_N_ART = 100, // Beleg angelegt,
                BCNG_N_USER = userId,
                BCNG_N_BELEGNR = bestellnummer.ToString()
            });
        }

        public async Task UpdateBestellungAsync(Bestellung bestellung, Lieferant lieferant, int userId, FbController2 fbController, BelegChange? change = null)
        {
            if (bestellung.Bestellnummer <= 0)
            {
                return;
            }



            Mehrwertsteuer? versandMehrwertsteuer = await Mehrwertsteuer.GetVersandMehrwertsteuerAsync();

            decimal netto = bestellung.Positionen.Sum(x => x.BEPO_N_PREIS * x.BEPO_N_MENGE);
            decimal mwst = bestellung.Positionen.Sum(x => x.PreisMitRabatt * x.BEPO_N_MENGE * x.BEPO_N_MWSTPROZ / 100);

            if (versandMehrwertsteuer is not null && lieferant.LIEF_L_MWST)
            {
                mwst += bestellung.Zusatzkosten * versandMehrwertsteuer.MWST_N_PROZENT / 100;
            }

            decimal rabatt = netto - bestellung.Positionen.Sum(x => x.PreisMitRabatt * x.BEPO_N_MENGE);
            decimal brutto = netto - rabatt + mwst + bestellung.Zusatzkosten;
            #region Parameter
            fbController.AddParameter("@BEST_N_LIEFNR", bestellung.LieferantenId);
            fbController.AddParameter("@BEST_A_PARTNER", bestellung.BEST_A_PARTNER);
            fbController.AddParameter("@BEST_D_LIEFTERMIN", bestellung.BEST_D_LIEFTERMIN);

            fbController.AddParameter("@BEST_N_ZAHLUNG", bestellung.BEST_N_ZAHLUNG);
            fbController.AddParameter("@BEST_N_LIEFERUNG", bestellung.LieferbedingungId);
            fbController.AddParameter("@BEST_A_WAEHRUNG", bestellung.Währung);
            fbController.AddParameter("@BEST_L_ABRUF", bestellung.IstAbrufbestellung);

            fbController.AddParameter("@BEST_N_NETTO", netto);
            fbController.AddParameter("@BEST_N_MWST", mwst);
            fbController.AddParameter("@BEST_N_BRUTTO", brutto);
            fbController.AddParameter("@BEST_N_RABATT", rabatt);

            fbController.AddParameter("@BEST_N_FRACHT", bestellung.Versandkosten);
            fbController.AddParameter("@BEST_N_VERPACKUNG", bestellung.Verpackungskosten);
            fbController.AddParameter("@BEST_N_VERSICHERUNG", bestellung.Versicherungskosten);

            fbController.AddParameter("@BEST_N_AB_NR", bestellung.BEST_N_AB_NR);
            fbController.AddParameter("@BEST_A_LIEFERKUNDE", bestellung.BEST_A_LIEFERKUNDE);
            fbController.AddParameter("@BEST_A_LIEFERKUNDELA", bestellung.BEST_A_LIEFERKUNDELA);

            fbController.AddParameter("@BEST_L_BESTAETIGT", bestellung.BEST_L_BESTAETIGT);
            fbController.AddParameter("@BEST_D_BESTAETIGT", bestellung.BEST_D_BESTAETIGT);
            fbController.AddParameter("@BEST_A_BESTAET_NR_LIEF", bestellung.BEST_A_BESTAET_NR_LIEF);

            fbController.AddParameter("@BEST_A_ANGEBOTNR", bestellung.BEST_A_ANGEBOTNR);
            fbController.AddParameter("@BEST_D_ANGEBOTVOM", bestellung.BEST_D_ANGEBOTVOM);

            fbController.AddParameter("@BEST_B_FUSSTEXT", StringErweiterung.RtfToString(bestellung.BEST_B_FUSSTEXT));
            fbController.AddParameter("@BEST_B_KOPFTEXT", StringErweiterung.RtfToString(bestellung.BEST_B_KOPFTEXT));
            fbController.AddParameter("@BEST_B_NOTIZ", StringErweiterung.RtfToString(bestellung.BEST_B_NOTIZ));

            fbController.AddParameter("@BEST_L_VERSENDET", bestellung.BEST_L_VERSENDET);
            fbController.AddParameter("@BEST_D_VERSENDET", bestellung.BEST_D_VERSENDET);

            fbController.AddParameter("@BEST_L_ERLEDIGT", bestellung.BEST_L_ERLEDIGT);
            fbController.AddParameter("@BEST_D_ERLEDIGTAM", bestellung.BEST_D_ERLEDIGTAM);
            fbController.AddParameter("@BEST_L_FRACHTFREI", bestellung.BEST_L_FRACHTFREI);

            fbController.AddParameter("@BEST_N_LASTUSER", userId);

            fbController.AddParameter("@BEST_N_NR", bestellung.Bestellnummer);
            #endregion

            #region Bestellung updaten
            await fbController.QueryAsync(@"UPDATE BESTELLUNGEN SET 
BEST_N_LIEFNR = @BEST_N_LIEFNR, 
BEST_A_PARTNER = @BEST_A_PARTNER, 
BEST_D_LIEFTERMIN = @BEST_D_LIEFTERMIN,
BEST_N_ZAHLUNG = @BEST_N_ZAHLUNG, 
BEST_N_LIEFERUNG = @BEST_N_LIEFERUNG, 
BEST_A_WAEHRUNG = @BEST_A_WAEHRUNG, 
BEST_L_ABRUF = @BEST_L_ABRUF,
BEST_N_NETTO = @BEST_N_NETTO,
BEST_N_MWST = @BEST_N_MWST, 
BEST_N_BRUTTO = @BEST_N_BRUTTO,
BEST_N_RABATT = @BEST_N_RABATT,
BEST_N_FRACHT = @BEST_N_FRACHT, 
BEST_N_VERPACKUNG = @BEST_N_VERPACKUNG, 
BEST_N_VERSICHERUNG = @BEST_N_VERSICHERUNG,
BEST_N_AB_NR = @BEST_N_AB_NR, 
BEST_A_LIEFERKUNDE = @BEST_A_LIEFERKUNDE, 
BEST_A_LIEFERKUNDELA = @BEST_A_LIEFERKUNDELA,
BEST_L_BESTAETIGT = @BEST_L_BESTAETIGT, 
BEST_D_BESTAETIGT = @BEST_D_BESTAETIGT, 
BEST_A_BESTAET_NR_LIEF = @BEST_A_BESTAET_NR_LIEF,
BEST_A_ANGEBOTNR = @BEST_A_ANGEBOTNR, 
BEST_D_ANGEBOTVOM = @BEST_D_ANGEBOTVOM, 
BEST_B_FUSSTEXT = @BEST_B_FUSSTEXT, 
BEST_B_KOPFTEXT = @BEST_B_KOPFTEXT, 
BEST_B_NOTIZ = @BEST_B_NOTIZ,
BEST_L_VERSENDET = @BEST_L_VERSENDET, 
BEST_D_VERSENDET = @BEST_D_VERSENDET,
BEST_L_ERLEDIGT = @BEST_L_ERLEDIGT, 
BEST_D_ERLEDIGTAM = @BEST_D_ERLEDIGTAM,
BEST_L_FRACHTFREI = @BEST_L_FRACHTFREI,
BEST_N_LASTUSER = @BEST_N_LASTUSER, 
BEST_TIMESTAMP = CURRENT_TIMESTAMP
WHERE BEST_N_NR = @BEST_N_NR");
            #endregion

            #region Positionen
            var posIds = bestellung.Positionen.Where(x => x.BEPO_N_POSID >= 0).Select(x => x.BEPO_N_POSID);
            string deletePosCommand = "DELETE FROM BESTELLUNGEN_POS WHERE BEPO_N_BESTNR = @BEPO_N_BESTNR AND BEPO_N_LIEFERMENGE = 0";
            if (posIds.Any())
            {
                deletePosCommand += $" AND BEPO_N_POSID NOT IN({String.Join(',', posIds)})";
            }
            fbController.AddParameter("@BEPO_N_BESTNR", bestellung.Bestellnummer);
            await fbController.QueryAsync(deletePosCommand);

            fbController.AddParameter("@BEPO_N_BESTNR", bestellung.Bestellnummer);
            await fbController.QueryAsync("UPDATE BESTELLUNGEN_POS SET BEPO_N_POS = BEPO_N_POS + 1000 WHERE BEPO_N_BESTNR = @BEPO_N_BESTNR");

            foreach (var pos in bestellung.Positionen)
            {
                pos.BEPO_N_BESTNR = bestellung.Bestellnummer;
                pos.BEPO_N_LASTUSER = userId;
                if (pos.BEPO_N_POSID is 0)
                {
                    pos.BEPO_N_POSID = Convert.ToInt32(await InsertPosition(fbController, pos));
                }
                else
                {
                    await UpdatePosition(fbController, pos);
                }
            }
            #endregion

            if (change is not null)
            {
                await BelegChange.InsertBelegChangeAsync(fbController, change);
            }


        }

        private Task UpdatePosition(FbController2 fbController, Bestellposition pos)
        {
            fbController.AddParameter("@BEPO_N_POS", pos.BEPO_N_POS);
            fbController.AddParameter("@BEPO_A_ARTIKELNR", pos.BEPO_A_ARTIKELNR);
            fbController.AddParameter("@BEPO_A_BESTELLNUMMER", pos.BEPO_A_BESTELLNUMMER);
            fbController.AddParameter("@BEPO_A_BEZ1", StringErweiterung.ConvertEncoding(pos.BEPO_A_BEZ1, Encoding.UTF8, Encoding.GetEncoding("ISO-8859-1")));
            fbController.AddParameter("@BEPO_A_BEZ2", StringErweiterung.ConvertEncoding(pos.BEPO_A_BEZ2, Encoding.UTF8, Encoding.GetEncoding("ISO-8859-1")));
            fbController.AddParameter("@BEPO_A_BEZ3", StringErweiterung.ConvertEncoding(pos.BEPO_A_BEZ3, Encoding.UTF8, Encoding.GetEncoding("ISO-8859-1")));
            fbController.AddParameter("@BEPO_A_BEZ4", StringErweiterung.ConvertEncoding(pos.BEPO_A_BEZ4, Encoding.UTF8, Encoding.GetEncoding("ISO-8859-1")));
            fbController.AddParameter("@BEPO_A_BEZ5", StringErweiterung.ConvertEncoding(pos.BEPO_A_BEZ5, Encoding.UTF8, Encoding.GetEncoding("ISO-8859-1")));
            fbController.AddParameter("@BEPO_N_MENGE", pos.BEPO_N_MENGE);
            fbController.AddParameter("@BEPO_N_PREIS", pos.BEPO_N_PREIS);
            fbController.AddParameter("@BEPO_N_RABATTPROZ", pos.BEPO_N_RABATTPROZ);
            fbController.AddParameter("@BEPO_N_RABATTPROZ2", pos.BEPO_N_RABATTPROZ2);
            fbController.AddParameter("@BEPO_D_LIEFERDAT", pos.BEPO_D_LIEFERDAT);
            fbController.AddParameter("@BEPO_L_ERLEDIGT", pos.BEPO_L_ERLEDIGT);
            fbController.AddParameter("@BEPO_A_NOTIZ", StringErweiterung.ConvertEncoding(StringErweiterung.RtfToString(pos.BEPO_A_NOTIZ), Encoding.UTF8, Encoding.GetEncoding("ISO-8859-1")));
            fbController.AddParameter("@BEPO_N_LASTUSER", pos.BEPO_N_LASTUSER);
            fbController.AddParameter("@BEPO_N_POSID", pos.BEPO_N_POSID);

            return fbController.QueryAsync(@"UPDATE BESTELLUNGEN_POS SET
BEPO_N_POS = @BEPO_N_POS, BEPO_A_ARTIKELNR = @BEPO_A_ARTIKELNR, BEPO_A_BESTELLNUMMER = @BEPO_A_BESTELLNUMMER,
BEPO_A_BEZ1 = @BEPO_A_BEZ1, BEPO_A_BEZ2 = @BEPO_A_BEZ2, BEPO_A_BEZ3 = @BEPO_A_BEZ3, BEPO_A_BEZ4 = @BEPO_A_BEZ4, BEPO_A_BEZ5 = @BEPO_A_BEZ5,
BEPO_N_MENGE = @BEPO_N_MENGE, BEPO_N_PREIS = @BEPO_N_PREIS,
BEPO_N_RABATTPROZ = @BEPO_N_RABATTPROZ, BEPO_N_RABATTPROZ2 = @BEPO_N_RABATTPROZ2, BEPO_D_LIEFERDAT = @BEPO_D_LIEFERDAT,
BEPO_L_ERLEDIGT = @BEPO_L_ERLEDIGT, BEPO_A_NOTIZ = @BEPO_A_NOTIZ, 
BEPO_N_LASTUSER = @BEPO_N_LASTUSER, BEPO_TIMESTAMP = CURRENT_TIMESTAMP
WHERE BEPO_N_POSID = @BEPO_N_POSID");
        }

        private Task<object?> InsertPosition(FbController2 fbController, Bestellposition pos)
        {
            if(pos.BEPO_N_POS <= 0)
            {
                throw new ArgumentOutOfRangeException("Bitte geben Sie für die Position eine eindeutige PosNr an.");
            }

            fbController.AddParameter("@BEPO_N_BESTNR", pos.BEPO_N_BESTNR);
            fbController.AddParameter("@BEPO_N_POS", pos.BEPO_N_POS);
            fbController.AddParameter("@BEPO_A_ARTIKELNR", pos.BEPO_A_ARTIKELNR);
            fbController.AddParameter("@BEPO_A_BESTELLNUMMER", pos.BEPO_A_BESTELLNUMMER);
            fbController.AddParameter("@BEPO_A_BEZ1", StringErweiterung.ConvertEncoding(pos.BEPO_A_BEZ1, Encoding.UTF8, Encoding.GetEncoding("ISO-8859-1")));
            fbController.AddParameter("@BEPO_A_BEZ2", StringErweiterung.ConvertEncoding(pos.BEPO_A_BEZ2, Encoding.UTF8, Encoding.GetEncoding("ISO-8859-1")));
            fbController.AddParameter("@BEPO_A_BEZ3", StringErweiterung.ConvertEncoding(pos.BEPO_A_BEZ3, Encoding.UTF8, Encoding.GetEncoding("ISO-8859-1")));
            fbController.AddParameter("@BEPO_A_BEZ4", StringErweiterung.ConvertEncoding(pos.BEPO_A_BEZ4, Encoding.UTF8, Encoding.GetEncoding("ISO-8859-1")));
            fbController.AddParameter("@BEPO_A_BEZ5", StringErweiterung.ConvertEncoding(pos.BEPO_A_BEZ5, Encoding.UTF8, Encoding.GetEncoding("ISO-8859-1")));
            fbController.AddParameter("@BEPO_N_MENGE", pos.BEPO_N_MENGE);
            fbController.AddParameter("@BEPO_N_LIEFERMENGE", 0);
            fbController.AddParameter("@BEPO_N_PREIS", pos.BEPO_N_PREIS);
            fbController.AddParameter("@BEPO_N_MWSTPROZ", pos.BEPO_N_MWSTPROZ);
            fbController.AddParameter("@BEPO_N_RABATTPROZ", pos.BEPO_N_RABATTPROZ);
            fbController.AddParameter("@BEPO_N_RABATTPROZ2", pos.BEPO_N_RABATTPROZ2);
            fbController.AddParameter("@BEPO_D_LIEFERDAT", pos.BEPO_D_LIEFERDAT);
            fbController.AddParameter("@BEPO_L_ERLEDIGT", "N");
            fbController.AddParameter("@BEPO_A_NOTIZ", StringErweiterung.ConvertEncoding(StringErweiterung.RtfToString(pos.BEPO_A_NOTIZ), Encoding.UTF8, Encoding.GetEncoding("ISO-8859-1")));
            fbController.AddParameter("@BEPO_N_LASTUSER", pos.BEPO_N_LASTUSER);

            return fbController.FetchObjectAsync(@$"INSERT INTO BESTELLUNGEN_POS
(
BEPO_N_BESTNR, BEPO_N_POS, BEPO_A_ARTIKELNR, BEPO_A_BESTELLNUMMER,
BEPO_A_BEZ1, BEPO_A_BEZ2, BEPO_A_BEZ3, BEPO_A_BEZ4, BEPO_A_BEZ5,
BEPO_N_MENGE, BEPO_N_MENGENFAKTOR, BEPO_N_LIEFERMENGE, BEPO_N_PREIS,
BEPO_N_MWSTPROZ, BEPO_N_RABATTPROZ, BEPO_N_RABATTPROZ2, BEPO_D_LIEFERDAT,
BEPO_L_ERLEDIGT, BEPO_A_NOTIZ, BEPO_TIMESTAMP, BEPO_N_LASTUSER
)
VALUES
(
@BEPO_N_BESTNR, @BEPO_N_POS, @BEPO_A_ARTIKELNR, @BEPO_A_BESTELLNUMMER,
@BEPO_A_BEZ1, @BEPO_A_BEZ2, @BEPO_A_BEZ3, @BEPO_A_BEZ4, @BEPO_A_BEZ5,
@BEPO_N_MENGE, 1, @BEPO_N_LIEFERMENGE, @BEPO_N_PREIS,
@BEPO_N_MWSTPROZ, @BEPO_N_RABATTPROZ, @BEPO_N_RABATTPROZ2, @BEPO_D_LIEFERDAT,
@BEPO_L_ERLEDIGT, @BEPO_A_NOTIZ, CURRENT_TIMESTAMP, @BEPO_N_LASTUSER
)
RETURNING BEPO_N_POSID");
        }

        /// <summary>
        /// Erstellt eine neue Bestellung für einen mit dem ShopImport importieren Auftrag.
        /// </summary>
        /// <param name="bestellung"></param>
        public async Task<int> CreateBestellungAsync(FbController2 fbController, AuftragBestellenBestellung bestellung, Auftrag auftrag, int userId)
        {


            // Wir brauchen noch Netto, Brutto und Mwst. Brutto und Mwst lassen sich mithilfe von Netto berechnen.
            decimal netto = bestellung.Positionen.Sum(x => x.PreisMitRabatt * x.Menge);
            decimal brutto = netto * (decimal)GlobalConfig.MwSt;
            decimal mwst = netto * ((decimal)GlobalConfig.MwSt - 1);

            int neueBestellnummer = Convert.ToInt32(await fbController.FetchObjectAsync("SELECT NR_NEW FROM BESTELLUNG_NEW"));
            
            // TODO: Frachtfrei berechnen
            fbController.AddParameter("@BEST_N_NR", neueBestellnummer);
            fbController.AddParameter("@BEST_N_LIEFNR", bestellung.LieferantId);
            fbController.AddParameter("@BEST_A_PARTNER", bestellung.Ansprechpartner);
            fbController.AddParameter("@BEST_D_LIEFTERMIN", bestellung.Positionen.Select(x => x.Lieferdatum).Max());
            fbController.AddParameter("@BEST_N_ZAHLUNG", bestellung.Zahlungsbedingung);
            fbController.AddParameter("@BEST_N_LIEFERUNG", bestellung.Lieferbedingung);
            fbController.AddParameter("@BEST_A_WAEHRUNG", bestellung.Währung);
            fbController.AddParameter("@BEST_N_NETTO", netto);
            fbController.AddParameter("@BEST_N_AB_NR", auftrag.Belegnummer);
            fbController.AddParameter("@BEST_N_MWST", mwst);
            fbController.AddParameter("@BEST_N_BRUTTO", brutto);
            fbController.AddParameter("@BEST_A_LIEFERKUNDE", bestellung.Direktlieferung ? auftrag.Kundennummer : null);
            fbController.AddParameter("@BEST_A_LIEFERKUNDELA", bestellung.Direktlieferung ? auftrag.LieferanschriftId : 0);
            fbController.AddParameter("@BEST_A_FORMULAR", "Beleg_Bestellung.lst");
            fbController.AddParameter("@BEST_L_ERLEDIGT", "N");
            fbController.AddParameter("@BEST_N_ANLAGEUSER", userId);
            fbController.AddParameter("@BEST_L_FRACHTFREI", false);
            fbController.AddParameter("@BEST_N_LASTUSER", userId);
            fbController.AddParameter("@BEST_L_ABRUF", bestellung.Abrufbestellung);




            await fbController.QueryAsync(@"INSERT INTO BESTELLUNGEN
(
BEST_N_NR, 
BEST_N_LIEFNR, 
BEST_A_PARTNER, 
BEST_D_DATE, 
BEST_D_LIEFTERMIN,
BEST_N_ZAHLUNG, 
BEST_N_LIEFERUNG, 
BEST_N_KURS, 
BEST_A_WAEHRUNG, 
BEST_A_ZEICHEN,
BEST_N_NETTO, 
BEST_N_AB_NR, 
BEST_N_PROJEKT_NR, 
BEST_A_KOMMISSION,
BEST_N_ZUSATZKOST, 
BEST_N_FRACHT, 
BEST_N_VERPACKUNG, 
BEST_N_VERSICHERUNG,
BEST_N_RABATT, 
BEST_N_MWST, 
BEST_N_BRUTTO, 
BEST_A_LIEFERKUNDE, 
BEST_A_LIEFERKUNDELA,
BEST_A_FORMULAR, 
BEST_L_ERLEDIGT, 
BEST_N_ANLAGEUSER, 
BEST_L_FRACHTFREI,
BEST_L_ABRUF,
BEST_N_LASTUSER, 
BEST_TIMESTAMP
)
VALUES
(
@BEST_N_NR, 
@BEST_N_LIEFNR, 
@BEST_A_PARTNER, 
CURRENT_DATE, 
@BEST_D_LIEFTERMIN,
@BEST_N_ZAHLUNG, 
@BEST_N_LIEFERUNG, 
(SELECT WAEH_N_KURS FROM WAEHRUNG WHERE WAEH_A_ZEICHEN = @BEST_A_WAEHRUNG), @BEST_A_WAEHRUNG, 'Vertrieb',
@BEST_N_NETTO, 
@BEST_N_AB_NR, 
0, 
'',
0, 
0,
0, 
0,
0, 
@BEST_N_MWST, 
@BEST_N_BRUTTO, 
@BEST_A_LIEFERKUNDE, 
@BEST_A_LIEFERKUNDELA,
@BEST_A_FORMULAR, 
@BEST_L_ERLEDIGT, 
@BEST_N_ANLAGEUSER, 
@BEST_L_FRACHTFREI,
@BEST_L_ABRUF,
@BEST_N_LASTUSER, 
CURRENT_TIMESTAMP
)");

          

            await InsertAngelegtHistorie(neueBestellnummer, userId, fbController);

            foreach (var pos in bestellung.Positionen)
            {
                fbController.AddParameter("@BEPO_N_BESTNR", neueBestellnummer);
                fbController.AddParameter("@BEPO_A_ARTIKELNR", pos.Artikelnummer);
                fbController.AddParameter("@BEPO_A_BESTELLNUMMER", pos.Bestellnummer);
                fbController.AddParameter("@BEPO_A_BEZ1", StringErweiterung.ConvertEncoding(pos.Bezeichnung1, Encoding.UTF8, Encoding.GetEncoding("ISO-8859-1")));
                fbController.AddParameter("@BEPO_A_BEZ2", StringErweiterung.ConvertEncoding(pos.Bezeichnung2, Encoding.UTF8, Encoding.GetEncoding("ISO-8859-1")));
                fbController.AddParameter("@BEPO_A_BEZ3", StringErweiterung.ConvertEncoding(pos.Bezeichnung3, Encoding.UTF8, Encoding.GetEncoding("ISO-8859-1")));
                fbController.AddParameter("@BEPO_A_BEZ4", StringErweiterung.ConvertEncoding(pos.Bezeichnung4, Encoding.UTF8, Encoding.GetEncoding("ISO-8859-1")));
                fbController.AddParameter("@BEPO_A_BEZ5", StringErweiterung.ConvertEncoding(pos.Bezeichnung5, Encoding.UTF8, Encoding.GetEncoding("ISO-8859-1")));
                fbController.AddParameter("@BEPO_N_MENGE", pos.Menge);
                fbController.AddParameter("@BEPO_N_LIEFERMENGE", 0);
                fbController.AddParameter("@BEPO_N_PREIS", pos.Preis);
                fbController.AddParameter("@BEPO_N_MWSTPROZ", (GlobalConfig.MwSt * 100) - 100);
                fbController.AddParameter("@BEPO_N_RABATTPROZ", pos.Rabatt1);
                fbController.AddParameter("@BEPO_N_RABATTPROZ2", pos.Rabatt2);
                fbController.AddParameter("@BEPO_D_LIEFERDAT", pos.Lieferdatum);
                fbController.AddParameter("@BEPO_L_ERLEDIGT",  "N");
                fbController.AddParameter("@BEPO_A_NOTIZ", pos.DruckLangtext
                    ? StringErweiterung.ConvertEncoding(pos.Langtext, Encoding.UTF8, Encoding.GetEncoding("ISO-8859-1"))
                        .Replace("<b>", "<span class=\"font-weight-bold\">")
                        .Replace("</b>", "</span>")
                        .Replace("<strong>", "<span class=\"font-weight-bold\">")
                        .Replace("</strong>", "</span>")
                    : null
                );
                fbController.AddParameter("@BEPO_N_LASTUSER", userId);

                int BEPO_N_POS = Convert.ToInt32(await fbController.FetchObjectAsync(@$"INSERT INTO BESTELLUNGEN_POS
(
BEPO_N_BESTNR, BEPO_N_POS, BEPO_A_ARTIKELNR, BEPO_A_BESTELLNUMMER,
BEPO_A_BEZ1, BEPO_A_BEZ2, BEPO_A_BEZ3, BEPO_A_BEZ4, BEPO_A_BEZ5,
BEPO_N_MENGE, BEPO_N_MENGENFAKTOR, BEPO_N_LIEFERMENGE, BEPO_N_PREIS,
BEPO_N_MWSTPROZ, BEPO_N_RABATTPROZ, BEPO_N_RABATTPROZ2, BEPO_D_LIEFERDAT,
BEPO_L_ERLEDIGT, BEPO_A_NOTIZ, BEPO_TIMESTAMP, BEPO_N_LASTUSER
)
VALUES
(
@BEPO_N_BESTNR, (SELECT NEW_POS FROM BESTELLUNG_NEWPOS(@BEPO_N_BESTNR)), @BEPO_A_ARTIKELNR, @BEPO_A_BESTELLNUMMER,
@BEPO_A_BEZ1, @BEPO_A_BEZ2, @BEPO_A_BEZ3, @BEPO_A_BEZ4, @BEPO_A_BEZ5,
@BEPO_N_MENGE, 1, @BEPO_N_LIEFERMENGE, @BEPO_N_PREIS,
@BEPO_N_MWSTPROZ, @BEPO_N_RABATTPROZ, @BEPO_N_RABATTPROZ2, @BEPO_D_LIEFERDAT,
@BEPO_L_ERLEDIGT, @BEPO_A_NOTIZ, CURRENT_TIMESTAMP, @BEPO_N_LASTUSER
)
RETURNING BEPO_N_POS"));



                


            }

            return neueBestellnummer;
        }

        /// <summary>
        /// Prüft, ob ein Artikel bereits in einer Abrufbestellung enthalten ist
        /// </summary>
        /// <param name="artikelnummer"></param>
        /// <returns>Liefert die Bestellnummer für die Abrufbestellung zurück, sofern eine gefunden wurde, ansonsten 0.</returns>
        public async Task<int> GetAbrufbestellungFürArtikelAsync(string artikelnummer, decimal menge, int lieferantennummer)
        {
            using FbController2 fbController = new FbController2();
            fbController.AddParameter("@BEPO_A_ARTIKELNR", artikelnummer);
            fbController.AddParameter("@MENGE", menge);
            fbController.AddParameter("@BEST_N_LIEFNR", lieferantennummer);
            int bestellnummer = Convert.ToInt32(await fbController.FetchObjectAsync("SELECT FIRST 1 BEST_N_NR FROM BESTELLUNGEN_POS BP INNER JOIN BESTELLUNGEN BE ON BE.BEST_N_NR = BP.BEPO_N_BESTNR WHERE BE.BEST_N_PROJEKT_NR = 1 AND BEST_L_ERLEDIGT = 'N' AND BEPO_A_ARTIKELNR = @BEPO_A_ARTIKELNR AND (BEPO_N_MENGE - BEPO_N_LIEFERMENGE) >= @MENGE AND BEST_N_LIEFNR = @BEST_N_LIEFNR"));
            return bestellnummer;

        }

        public async IAsyncEnumerable<int> GetOffeneBestellungenFürArtikelAsync(string artikelnummer)
        {
            using FbController2 fbController = new FbController2();
            fbController.AddParameter("@BEPO_A_ARTIKELNR", artikelnummer);
            DataTable data = await fbController.SelectDataAsync(@"SELECT DISTINCT BEST_N_NR FROM BESTELLUNGEN_POS BP
INNER JOIN BESTELLUNGEN BE ON BE.BEST_N_NR = BP.BEPO_N_BESTNR 
AND BEST_L_ERLEDIGT = 'N' 
AND BEPO_A_ARTIKELNR = @BEPO_A_ARTIKELNR
AND BEPO_N_MENGE > BEPO_N_LIEFERMENGE");

            foreach (DataRow row in data.Rows)
            {
                int nr = row.Field<int>("BEST_N_NR");

                yield return nr;
            }
        }

        public async Task<int> GetMindestbestellmenge(string artikelnummer, int lieferantenId)
        {
            using FbController2 fbController = new FbController2();
            fbController.AddParameter("@ARLI_A_ARTIKELNR", artikelnummer);
            fbController.AddParameter("ARLI_N_LIEFNR", lieferantenId);
            var obj = await fbController.FetchObjectAsync("SELECT ARLI_N_MINDESTABNAHME FROM LIEFERANTENARTIKEL WHERE ARLI_A_ARTIKELNR = @ARLI_A_ARTIKELNR AND ARLI_N_LIEFNR = @ARLI_N_LIEFNR");

            return obj is int mindestbestellMenge ? mindestbestellMenge : 0;
        }

        public Task SetGeprüftAsync(BestellungPrüfenInput input, FbController2 fbController)
        {
            fbController.AddParameter("@BEST_N_NR", input.Bestellnummer);
            fbController.AddParameter("@BEST_D_LIEFTERMIN", input.Liefertermin);
            fbController.AddParameter("@BEST_A_BESTAET_NR_LIEF", input.Auftragsbestätigungsnummer);
            fbController.AddParameter("@BEST_N_FRACHT", input.Frachtkosten);
            fbController.AddParameter("@BEST_N_MINDERMENGENZUSCHLAG", input.Mindermengenzuschlag);
            fbController.AddParameter("@BEST_N_VERPACKUNG", input.Verpackungskosten);
            fbController.AddParameter("@BEST_N_VERSICHERUNG", input.Versicherungskosten);
            return fbController.QueryAsync(@"UPDATE BESTELLUNGEN SET 
BEST_L_BESTAETIGT = 'Y', 
BEST_D_LIEFTERMIN = @BEST_D_LIEFTERMIN, 
BEST_D_BESTAETIGT = CURRENT_TIMESTAMP, 
BEST_A_BESTAET_NR_LIEF = @BEST_A_BESTAET_NR_LIEF,
BEST_N_FRACHT = @BEST_N_FRACHT,
BEST_N_MINDERMENGENZUSCHLAG = @BEST_N_MINDERMENGENZUSCHLAG,
BEST_N_VERPACKUNG = @BEST_N_VERPACKUNG,
BEST_N_VERSICHERUNG = @BEST_N_VERSICHERUNG
WHERE BEST_N_NR = @BEST_N_NR");
        }

        public async Task<int> GetAnzahlBestellungenAsync(BestellungFilter filter, FbController2 fbController, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            object? anzahlObj = await fbController.FetchObjectAsync(filter.ToCountQuery(fbController), cancellationToken);
            return Convert.ToInt32(anzahlObj);
        }
        public async IAsyncEnumerable<Bestellung> GetBestellungenAsync(BestellungFilter filter, FbController2 fbController, [EnumeratorCancellation] CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();


            DataTable bestellungen = await fbController.SelectDataAsync(filter.ToSqlQuery(fbController), cancellationToken);

            if (bestellungen is not null && bestellungen.Rows.Count > 0)
            {
                int[] bestellnummern = bestellungen.AsEnumerable().Select(s => s.Field<int>("BEST_N_NR"))
                    .Distinct()
                    .ToArray();

                DataTable positionenData = await fbController.SelectDataAsync(@$"SELECT * FROM BESTELLUNGEN_POS WHERE BEPO_N_BESTNR IN ({string.Join(',', bestellnummern)})", cancellationToken);

                foreach (DataRow bestellungRow in bestellungen.Rows)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    if (cancellationToken.IsCancellationRequested)
                    {
                        break;
                    }
                    var bestellung = ObjectErweiterung.DataRowZuObjekt(new Bestellung(), bestellungRow);
                    // Positionen laden
                    var posData = positionenData.AsEnumerable()
                    .Where(x => x.Field<int>("BEPO_N_BESTNR") == bestellung.Bestellnummer);

                    foreach (DataRow posRow in posData)
                    {
                        bestellung.Positionen.Add(ObjectErweiterung.DataRowZuObjekt(new Bestellposition(), posRow));
                    }
                    yield return bestellung;
                }
            }

        }


        public async IAsyncEnumerable<Bestelldisposition> GetBestelldispositionAsync(BestelldispositionFilter filter, [EnumeratorCancellation] CancellationToken cancellationToken)
        {
            using FbController2 fbController = new FbController2();

            var data = await fbController.SelectDataAsync(filter.ToSqlQuery(fbController), cancellationToken);


            foreach (DataRow row in data.Rows)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    break;
                }
                yield return ObjectErweiterung.DataRowZuObjekt(new Bestelldisposition(), row);
            }

        }

        public async Task BestellungStornierenAsync(int bestellnummer, FbController2 fbController)
        {
            fbController.AddParameter("@BEST_N_NR", bestellnummer);
            await fbController.QueryAsync("UPDATE BESTELLUNGEN SET BEST_L_ERLEDIGT = 'Y', BEST_D_ERLEDIGTAM = CURRENT_DATE WHERE BEST_N_NR = @BEST_N_NR");

            fbController.AddParameter("@BEST_N_NR", bestellnummer);
            await fbController.QueryAsync("UPDATE BESTELLUNGEN_POS SET BEPO_L_ERLEDIGT = 'Y' WHERE BEPO_N_BESTNR = @BEST_N_NR");
        }

        public async IAsyncEnumerable<int> GetZugangsnummernFürBestellungAsync(int bestellnummer, FbController2 fbController, [EnumeratorCancellation] CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();
            fbController.AddParameter("@CHAR_N_BESTNR", bestellnummer);
            DataTable data = await fbController.SelectDataAsync("SELECT DISTINCT CHAR_N_STAPELNR FROM CHARGEN WHERE CHAR_N_BESTNR = @CHAR_N_BESTNR ORDER BY CHAR_N_NR DESC", cancellationToken);

            foreach (DataRow row in data.Rows)
            {
                cancellationToken.ThrowIfCancellationRequested();
                yield return row.Field<int>("CHAR_N_STAPELNR");
            }



        }

        public async Task<Artikelbewegung?> GetLetzterBewegungZugangAsync(string artikelnummer, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();


            using FbController2 fbController = new FbController2();

            fbController.AddParameter("@ARBE_A_ARTINR", artikelnummer);
            DataRow? row = await fbController.SelectRowAsync("SELECT FIRST 1 SKIP 0 * FROM ARTIKELBEWEGUNG AB WHERE AB.ARBE_A_ARTINR = @ARBE_A_ARTINR AND AB.ARBE_A_ART = 'ZUGA' ORDER BY AB.ARBE_TIMESTAMP DESC", cancellationToken);

            return row is null ? null : ObjectErweiterung.DataRowZuObjekt(new Artikelbewegung(), row);

        }

        public async Task CreateAbrufAsync(BestellungAbruf abruf, FbController2 fbController)
        {
            abruf.MitarbeiterId = fbController.UserId;
            abruf.Anlagedatum = DateTime.Now;
            fbController.AddParameter("@BEAB_N_BESTNR", abruf.Bestellnummer);
            fbController.AddParameter("@BEAB_D_ANLAGEDATUM", abruf.Anlagedatum);
            fbController.AddParameter("@BEAB_N_LASTUSER", abruf.MitarbeiterId);

            abruf.Id = Convert.ToInt32(await fbController.FetchObjectAsync(@"INSERT INTO BESTELLUNGEN_ABRUF
(
BEAB_N_BESTNR,
BEAB_D_ANLAGEDATUM,
BEAB_N_LASTUSER
)
VALUES
(
@BEAB_N_BESTNR,
@BEAB_D_ANLAGEDATUM,
@BEAB_N_LASTUSER
)
RETURNING BEAB_N_NR"));

            foreach (var pos in abruf.Positionen)
            {
                pos.AbrufId = abruf.Id;
                fbController.AddParameter("@BABP_N_ABRUFNR", pos.AbrufId);
                fbController.AddParameter("@BABP_N_POSID", pos.PosId);
                fbController.AddParameter("@BABP_N_MENGE", pos.Menge);
                await fbController.QueryAsync(@"INSERT INTO BESTELLUNGEN_ABRUF_POS
(
BABP_N_ABRUFNR,
BABP_N_POSID,
BABP_N_MENGE
)
VALUES
(
@BABP_N_ABRUFNR,
@BABP_N_POSID,
@BABP_N_MENGE
)");
            }
        }

        public async IAsyncEnumerable<BestellungAbruf> GetAbrufeAsync(int bestellnummer, FbController2 fbController)
        {
            List<BestellungAbruf> abrufe = await fbController.SelectDataAsync<BestellungAbruf>("SELECT * FROM BESTELLUNGEN_ABRUF WHERE BEAB_N_BESTNR = @BEAB_N_BESTNR ORDER BY BEAB_N_NR DESC", new { BEAB_N_BESTNR = bestellnummer });
            if (abrufe.Any())
            {
                int[] abrufIds = abrufe.Select(x => x.Id).ToArray();
                List<BestellungAbrufPos> positionen = await fbController.SelectDataAsync<BestellungAbrufPos>(@$"SELECT BAP.*, BEPO_A_ARTIKELNR AS ARTIKELNUMMER FROM BESTELLUNGEN_ABRUF_POS BAP 
LEFT JOIN BESTELLUNGEN_POS BP ON BEPO_N_POSID = BABP_N_POSID
WHERE BABP_N_ABRUFNR IN ({String.Join(",", abrufIds)})");
                foreach (var abruf in abrufe)
                {
                    abruf.Positionen = positionen.Where(x => x.AbrufId == abruf.Id).ToList();
                    yield return abruf;
                }
            }


        }

    }
}
