/// <summary>
        /// Saves a new Ausgangsrechnung within the database
        /// </summary>
        /// <param name="projektID">The connected ProjektID</param>
        /// <param name="unpaidBalance">The amount of money which the Ausgangsrechnung shall include</param>
        /// <param name="rechnungstitelString">The title of the Ausgangsrechnung</param>
        public void CreateAusgangsrechnung(int projektID, double unpaidBalance, string rechnungstitelString)
        {
            // create business objects for Ausgangsrechnung, Ausgangsbuchung & Buchungszeilen
            AusgangsrechnungTable rechnung = new AusgangsrechnungTable();
            AusgangsbuchungTable buchung = new AusgangsbuchungTable();
            BuchungszeilenTable zeile = new BuchungszeilenTable();

            // fill with values and validate
            rechnung.ProjektID = projektID;
            rechnung.Rechnungsdatum = DateTime.Now.ToShortDateString();
            rechnung.Bezeichnung = rechnungstitelString;

            zeile.BetragNetto = unpaidBalance;
            zeile.Bezeichnung = rechnungstitelString;
            zeile.Buchungsdatum = rechnung.Rechnungsdatum;

            // initialise Rule objects
            PositiveIntValidator piv = new PositiveIntValidator();
            PositiveDoubleValidator pdv = new PositiveDoubleValidator();
            LettersNumbersHyphenSpaceValidator lnhsv = new LettersNumbersHyphenSpaceValidator();
            StringLength150Validator slv = new StringLength150Validator();

            // evaluate ProjektID
            piv.Eval(rechnung.ProjektID);

            if (piv.HasErrors)
            { throw new InvalidInputException("ProjektID ungültig!"); }

            // evaluate Bezeichnung
            lnhsv.Eval(rechnung.Bezeichnung);
            slv.Eval(rechnung.Bezeichnung);

            if (lnhsv.HasErrors || slv.HasErrors)
            { throw new InvalidInputException("Bezeichnung ungültig!"); }

            // evaluate Betrag
            pdv.Eval(zeile.BetragNetto);

            if (pdv.HasErrors)
            { throw new InvalidInputException("Betrag ungültig"); }

            // SAVE Ausgangsrechnung, Buchungszeile and Ausgangsbuchung
            try
            {
                buchung.AusgangsrechnungsID = DALFactory.GetDAL().SaveAusgangsrechnung(rechnung);
                buchung.BuchungszeilenID = DALFactory.GetDAL().SaveBuchungszeile(zeile);

                // create Ausgangsbuchung with ID values which just returned from database
                DALFactory.GetDAL().SaveAusgangsbuchung(buchung);
            }
            catch (SQLiteException e)
            {
                this.logger.Log(Logger.Level.Info, "A database exception occured while saving a new Ausgangsrechnung, Buchungszeile or Ausgangsbuchung.");
                throw new DataBaseException(e.Message, e);
            }
        }
        /// <summary>
        /// Creates a new Ausgangsrechnung with the provided parameters
        /// </summary>
        /// <param name="sender">The sending button</param>
        /// <param name="e">The EventArgs</param>
        private void CreateAusgangsrechnung(object sender, EventArgs e)
        {
            // reset message label
            this.ausgangsrechnungMsgLabel.Visible = false;
            this.ausgangsrechnungMsgLabel.Text = string.Empty;

            // check if a projekt is selected
            if (this.projekteComboBox.SelectedIndex < 1)
            {
                this.ausgangsrechnungMsgLabel.Visible = true;
                this.ausgangsrechnungMsgLabel.Text = "Kein Projekt ausgewählt";
                this.ausgangsrechnungMsgLabel.ForeColor = Color.Red;
                return;
            }

            AusgangsrechnungTable table = new AusgangsrechnungTable();

            // Get values
            int projektID = GlobalActions.GetIdFromCombobox(this.projekteComboBox.SelectedValue.ToString(), this.ausgangsrechnungMsgLabel);
            string unpaidBalanceString = this.unpaidBalanceTextBox.Text;
            string rechnungstitelString = this.rechnungstitelTextBox.Text;

            double unpaidBalance;

            // Validate values
            IRule posintval = new PositiveIntValidator();
            IRule posdoubval = new PositiveDoubleValidator();
            IRule lnhsv = new LettersNumbersHyphenSpaceValidator();
            IRule slv = new StringLength150Validator();

            DataBindingFramework.BindFromInt(projektID.ToString(), "ProjektID", this.ausgangsrechnungMsgLabel, false, posintval);
            unpaidBalance = DataBindingFramework.BindFromDouble(unpaidBalanceString, "Offener Betrag", this.ausgangsrechnungMsgLabel, false, posdoubval);
            DataBindingFramework.BindFromString(rechnungstitelString, "Rechnungstitel", this.ausgangsrechnungMsgLabel, false, lnhsv, slv);

            // return if errors occured
            if (this.ausgangsrechnungMsgLabel.Visible)
            {
                return;
            }

            // no errors, send values to business layer
            RechnungsManager saver = new RechnungsManager();

            try
            {
                saver.CreateAusgangsrechnung(projektID, unpaidBalance, rechnungstitelString);
            }
            catch (InvalidInputException)
            {
                this.logger.Log(Logger.Level.Error, "The business layer returned the provided values for saving a new Ausgangsrechnung with an error.");
            }
            catch (DataBaseException ex)
            {
                this.logger.Log(Logger.Level.Error, "A serious problem with the database occured while trying to save a new Ausgangsrechnung.");
                this.logger.Log(Logger.Level.Error, ex.Message);
                this.ausgangsrechnungMsgLabel.Text = ex.Message;
                this.ausgangsrechnungMsgLabel.ForeColor = Color.Red;
                this.ausgangsrechnungMsgLabel.Show();
            }

            // show success message label (only if saving has been successful)
            if (!this.ausgangsrechnungMsgLabel.Visible)
            {
                GlobalActions.ShowSuccessLabel(this.ausgangsrechnungMsgLabel);
            }
        }
        /// <summary>
        /// Saves a new Ausgangsrechnung
        /// </summary>
        /// <param name="table">The Ausgangsrechnung table</param>
        /// <returns>The ID of the just inserted Ausgangsrechnung</returns>
        public int SaveAusgangsrechnung(AusgangsrechnungTable table)
        {
            string sql = "INSERT INTO Ausgangsrechnung (ProjektID, Rechnungsdatum, Bezeichnung) VALUES (?, ?, ?)";

            int insertedID;

            try
            {
                insertedID = this.InsertAndReturnID(sql, "Ausgangsrechnung", table.ProjektID, table.Rechnungsdatum, table.Bezeichnung);
            }
            catch (SQLiteException)
            {
                throw;
            }

            return insertedID;
        }
        /// <summary>
        /// Saves a new Ausgangsrechnung
        /// </summary>
        /// <param name="table">The Ausgangsrechnung table</param>
        /// <returns>The ID of the just inserted Ausgangsrechnung</returns>
        public int SaveAusgangsrechnung(AusgangsrechnungTable table)
        {
            table.ID = MockDataBaseManager.AusgangsrechnungsID;
            MockDataBaseManager.savedAusgangsrechnungen.Add(table);

            return table.ID;
        }