#pragma +
// Name:						ERechnung
// Programmtyp:			Hilfsroutine für
//								Fakturierprogramm
//	Programmiersprache:	C++ (AT&T Standard 3.0)
// Computersystem:		Commodore AMIGA
// Betriebssystem:		AMIGA OS3.0 oder höher
// Autor:					Manfred Tremmel
// © Copyright:			1997-2001 by MT Graphic & Design
// Version:					V1.08
//
//    Copyright (C) 1997-2001 Manfred Tremmel
//
//    This program is free software; you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation; either version 2 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program; if not, write to the Free Software
//    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA


// Includes:
#include <new.h>
#include <intuition/intuition.h>
#include <clib/dos_protos.h>
#include <iostream.h>
#include <stdio.h>

#include "MT-Rechnung.h"
#include "MTList.h"
#include "MTLocale.h"
#include "Datenbank.h"
#include "Adressen.h"
#include "Artikel.h"
#include "Laender.h"
#include "RechnungArtikel.h"
#include "Rechnung.h"
#include "ERechnung.h"
#include "Einstellungen.h"
#include "KontenPos.h"
#include "LocaleStrings.h"
#include "Allgemein.h"
#include "MTARexx.h"


extern Laender				*MyLaenderPTR;
extern Adress				*MyAdressPTR;
extern Lieferanten		*MyLieferantPTR;
extern Mitarbeiter		*MyMitarbeiterPTR;
extern Niederlassung		*MyNiederlassungPTR;
extern Artikel				*MyArtikelPTR;
extern RechnungArtikel	*MyERechnungArtikelPTR;
extern Prefs				*MyPrefsPTR;
extern OpenLocaleClass	*MyLocalePTR;
extern KontenPos			*MyKontenPosPTR;

extern FillAppStrings	*MyAppStringsPTR;

extern Allgemein			MyAllgemein;

extern APTR					surface;

// ARexx-Port Auswertung
extern MTARexx				MyARexx;

// Kostruktor
// Übergabe:	Dateiname		= Name des Files der Datenbank
//					Datenbankbez	= Bezeichnung der Datenbank
//					User				= Nummer des Benutzers (Key in der Mitarbeiter-DB
ERechnung::ERechnung(STRPTR Dateiname, STRPTR Datenbankbez, UWORD User ) : Rechnung( Dateiname, Datenbankbez, User, sizeof(ERechnungDaten), 448, MyERechnungArtikelPTR )
{
	// Pointer auf den Datenbereich setzen
	Daten					= (ERechnungDaten *)UserData;

	// Rechnungsstatuspointer setzen
	MyERechnungArtikelPTR->RStatus = &Daten->RStatus;

	// Felder für die Suchfunktion zuordnen
	Such_DB_Anzahl		= 31;
	Such_DB_Feld		= new void*[Such_DB_Anzahl];
	Such_DB_Typ			= new UBYTE[Such_DB_Anzahl];
	Such_DB_CS			= new STRPTR[Such_DB_Anzahl];

	Such_DB_Feld[0]	= NULL;
	Such_DB_Typ[0]		= 0;
	Such_DB_CS[0]		= NULL;
	Such_DB_Feld[1]	= (void *)&Daten->RStatus;
	Such_DB_Typ[1]		= 5;
	Such_DB_CS[1]		= AppStrings[MSG_ERechStatus];
	Such_DB_Feld[2]	= (void *)&Daten->BestDatum;
	Such_DB_Typ[2]		= 2;
	Such_DB_CS[2]		= NULL;
	Such_DB_Feld[3]	= (void *)&Daten->LDatum;
	Such_DB_Typ[3]		= 2;
	Such_DB_CS[3]		= NULL;
	Such_DB_Feld[4]	= (void *)&Daten->RDatum;
	Such_DB_Typ[4]		= 2;
	Such_DB_CS[4]		= NULL;
	Such_DB_Feld[5]	= (void *)&Daten->WDatum;
	Such_DB_Typ[5]		= 2;
	Such_DB_CS[5]		= NULL;
	Such_DB_Feld[6]	= (void *)&Daten->MahnDatum[0];
	Such_DB_Typ[6]		= 2;
	Such_DB_CS[6]		= NULL;
	Such_DB_Feld[7]	= (void *)&Daten->MahnDatum[1];
	Such_DB_Typ[7]		= 2;
	Such_DB_CS[7]		= NULL;
	Such_DB_Feld[8]	= (void *)&Daten->MahnDatum[2];
	Such_DB_Typ[8]		= 2;
	Such_DB_CS[8]		= NULL;
	Such_DB_Feld[9]	= (void *)&Daten->MahnDatum[3];
	Such_DB_Typ[9]		= 2;
	Such_DB_CS[9]		= NULL;
	Such_DB_Feld[10]	= (void *)&Daten->SDatum;
	Such_DB_Typ[10]	= 2;
	Such_DB_CS[10]		= NULL;
	Such_DB_Feld[11]	= (void *)&Daten->BDatum;
	Such_DB_Typ[11]	= 2;
	Such_DB_CS[11]		= NULL;
	Such_DB_Feld[12]	= (void *)&Daten->Niederlassung;
	Such_DB_Typ[12]	= 7;
	Such_DB_CS[12]		= NULL;
	Such_DB_Feld[13]	= (void *)&Daten->Bestellernummer;
	Such_DB_Typ[13]	= 7;
	Such_DB_CS[13]		= NULL;
	Such_DB_Feld[14]	= (void *)&Daten->LieferantenNr;
	Such_DB_Typ[14]	= 7;
	Such_DB_CS[14]		= NULL;
	Such_DB_Feld[15]	= (void *)Daten->LiefRechNr;
	Such_DB_Typ[15]	= 0;
	Such_DB_CS[15]		= NULL;
	Such_DB_Feld[16]	= (void *)&MyRechnungArtikel->Daten->Artikelnummer;
	Such_DB_Typ[16]	= 7;
	Such_DB_CS[16]		= NULL;
	Such_DB_Feld[17]	= (void *)&MyRechnungArtikel->Daten->Artikelanzahl;
	Such_DB_Typ[17]	= 11;
	Such_DB_CS[17]		= NULL;
	Such_DB_Feld[18]	= (void *)&MyRechnungArtikel->Daten->Artikelpreis;
	Such_DB_Typ[18]	= 11;
	Such_DB_CS[18]		= NULL;
	Such_DB_Feld[19]	= (void *)&Daten->Versandkosten;
	Such_DB_Typ[19]	= 11;
	Such_DB_CS[19]		= NULL;
	Such_DB_Feld[20]	= (void *)&Daten->Zusatzkosten;
	Such_DB_Typ[20]	= 11;
	Such_DB_CS[20]		= NULL;
	Such_DB_Feld[21]	= (void *)&Daten->SkoRab;
	Such_DB_Typ[21]	= 5;
	Such_DB_CS[21]		= AppStrings[MSG_SKORA];
	Such_DB_Feld[22]	= (void *)&Daten->Skonto;
	Such_DB_Typ[22]	= 11;
	Such_DB_CS[22]		= NULL;
	Such_DB_Feld[23]	= (void *)Daten->Bemerkung;
	Such_DB_Typ[23]	= 0;
	Such_DB_CS[23]		= NULL;
	Such_DB_Feld[24]	= (void *)&Daten->Waehrung_KZ;
	Such_DB_Typ[24]	= 5;
	Such_DB_CS[24]		= MyPrefsPTR->CycleWaehrung;
	Such_DB_Feld[25]	= (void *)&Daten->Preissystem;
	Such_DB_Typ[25]	= 5;
	Such_DB_CS[25]		= AppStrings[MSG_PreisSys];
	Such_DB_Feld[26]	= (void *)&Daten->Waehrung_KZ;
	Such_DB_Typ[26]	= 4;
	Such_DB_CS[26]		= NULL;
	Such_DB_Feld[27]	= (void *)&Daten->ZuAbNummer;
	Such_DB_Typ[27]	= 5;
	Such_DB_CS[27]		= MyPrefsPTR->CycleZuAb;
	Such_DB_Feld[28]	= (void *)&Daten->ZuAbTyp;
	Such_DB_Typ[28]	= 5;
	Such_DB_CS[28]		= AppStrings[MSG_ZuAbTyp];;
	Such_DB_Feld[29]	= (void *)&Daten->ZuAbWert;
	Such_DB_Typ[29]	= 11;
	Such_DB_CS[29]		= NULL;
	Such_DB_Feld[30]	= (void *)&Daten->Gebucht;
	Such_DB_Typ[30]	= 4;
	Such_DB_CS[30]		= NULL;

	Such_DB_Nr			= 7;

	Such_DB_Felder_Laenge = strlen( AppStrings[MSG_Such_Adr_Dummy] ) + 1 +
									strlen( AppStrings[MSG_Such_ERechnungA] ) +
									strlen( AppStrings[MSG_Such_ERechnungB] );
	Such_DB_Felder_String = new TEXT[Such_DB_Felder_Laenge];

	strcpy( Such_DB_Felder_String, AppStrings[MSG_Such_Adr_Dummy] );
	strcat( Such_DB_Felder_String, AppStrings[MSG_Such_ERechnungA] );
	strcat( Such_DB_Felder_String, AppStrings[MSG_Such_ERechnungB] );

	// Druckfelder für PostScript-Ausgabe
	// Feldbezeichnungen, Typ, Pointer, Länge und kennzeichen, ob
	// die Felder auch bei Kompaktausgabe verwendet werden sollen
	// Genaue Beschreibung der DruWert-Struktur in Datenbank.h
	struct DruWert ERechnungDruWert[] =
	{
		{"ERNiederlassungNr",	"(", NULL, 16, ")", TRUE},
		{"ERBestellerNr",			"(", NULL, 16, ")", TRUE},
		{"ERLieferNr",				"(", NULL, 16, ")", TRUE},
		{"ERRechnungsNr",			"(", NULL, 16, ")", TRUE},
		{"ERRechStatus",			"(", NULL, 32, ")", TRUE},
		{"ERBestellDatum",		"[", NULL, 80, "]", TRUE},
		{"ERLieferscheinDatum",	"[", NULL, 80, "]", TRUE},
		{"ERRechnungDatum",		"[", NULL, 80, "]", TRUE},
		{"ERWareneinDatum",		"[", NULL, 80, "]", TRUE},
		{"ERMahn1Datum",			"[", NULL, 80, "]", TRUE},
		{"ERMahn2Datum",			"[", NULL, 80, "]", TRUE},
		{"ERMahn3Datum",			"[", NULL, 80, "]", TRUE},
		{"ERMahnVerDatum",		"[", NULL, 80, "]", TRUE},
		{"ERStornoDatum",			"[", NULL, 80, "]", TRUE},
		{"ERBezahltDatum",		"[", NULL, 80, "]", TRUE},
		{"ERBemerkung",			"[", NULL, 240, "]", TRUE},
		{"ERWaehrung",				"", NULL, 4, "", TRUE},
		{"ERWaehrungSymbol",		"(", NULL, 8, ")", TRUE},
		{"ERVersandMWStSatz",	"(", NULL, 40, ")", TRUE},
		{"ERVersandkostenGef",	"", NULL, 8, "", TRUE},
		{"ERVersandWert",			"[", NULL, 120, "]", TRUE},
		{"ERZusatzkostenGef",	"", NULL, 8, "", TRUE},
		{"ERZusatzWert",			"[", NULL, 120, "]", TRUE},
		{"ERVersZusWert",			"[", NULL, 120, "]", TRUE},
		{"ERVersMWStWert",		"[", NULL, 80, "]", TRUE},
		{"ERZusMWStWert",			"[", NULL, 80, "]", TRUE},
		{"ERVersZusMWStWert",	"[", NULL, 80, "]", TRUE},
		{"ERSkontoGef",			"", NULL, 8, "", TRUE},
		{"ERSkontoSatz",			"(", NULL, 40, ")", TRUE},
		{"ERSkontoWert",			"[", NULL, 120, "]", TRUE},
		{"ERSkontoMWStWert",		"[", NULL, 80, "]", TRUE},
		{"ERGesamtWert",			"[", NULL, 120, "]", TRUE},
		{"ERGesamtminRabWert",	"[", NULL, 120, "]", TRUE},
		{"ERGesamtminRabSkonWert",	"[", NULL, 120, "]", TRUE},
		{"ERGesamtZusWert",		"[", NULL, 120, "]", TRUE},
		{"ERGesamtZusminRabWert",	"[", NULL, 120, "]", TRUE},
		{"ERGesamtZusminRabSkonWert",	"[", NULL, 120, "]", TRUE},
		{"ERMWStSatz",				"[", NULL, 400, "]", TRUE},
		{"ERMWStBel",				"[", NULL, 64, "]", TRUE},
		{"ERMWStGesWert",			"[", NULL, 800, "]", TRUE},
		{"ERMWStGesMinRabWert",	"[", NULL, 800, "]", TRUE},
		{"ERMWStGesMinRabSkoWert",	"[", NULL, 800, "]", TRUE},
		{"ERjeMWStWert",			"[", NULL, 1000, "]", TRUE},
		{"ERjeMWStMinRabWert",	"[", NULL, 1000, "]", TRUE},
		{"ERjeMWStMinRabSkoWert","[", NULL, 1000, "]", TRUE},
		{"ERMWStSummeWert",			"[", NULL, 120, "]", TRUE},
		{"ERMWStSummeMinRabWert",	"[", NULL, 120, "]", TRUE},
		{"ERMWStSummeMinRabSkoWert", "[", NULL, 120, "]", TRUE},
		{"ERZMWStGesWert",		"[", NULL, 800, "]", TRUE},
		{"ERZMWStGesMinRabWert","[", NULL, 800, "]", TRUE},
		{"ERZMWStGesMinRabSkoWert",	"[", NULL, 800, "]", TRUE},
		{"ERZjeMWStWert",			"[", NULL, 1000, "]", TRUE},
		{"ERZjeMWStMinRabWert",	"[", NULL, 1000, "]", TRUE},
		{"ERZjeMWStMinRabSkoWert","[", NULL, 1000, "]", TRUE},
		{"ERZMWStSummeWert",		"[", NULL, 120, "]", TRUE},
		{"ERZMWStSummeMinRabWert",	"[", NULL, 120, "]", TRUE},
		{"ERZMWStSummeMinRabSkoWert", "[", NULL, 120, "]", TRUE},
		{"ERZuAbNr",				"[", NULL, 16,  "]", TRUE},
		{"ERZuAbWert",				"[", NULL, 600, "]", TRUE},
		{"ERZuAbBezeich",			"[", NULL, 300, "]", TRUE},
		{"ERZuAbTyp",				"[", NULL, 16,  "]", TRUE},
		{"ERZuAbBetrag",			"[", NULL, 600, "]", TRUE},
		{"",							"",  NULL, 0, "", TRUE},
		{"ERBezahltWert",			"[", NULL, 120, "]", TRUE},
		{"ERRueckgabeWert",		"[", NULL, 120, "]", TRUE},
		{"ERBarbeleg",				"", NULL, 8, "", TRUE},
		{"",							"",  NULL, 0, "", FALSE}
	};

	// oben definierte Druckfelder initialisieren
	DruckWertInit( ERechnungDruWert );

	// Algemeine Felder die bei Ein- und Ausgangsrechnungen
	// gleichermassen verwendet werden können, auf Pointer
	// in die Rechnungsstruktur stellen
	MyRechnungArtikel->Artikel_KZ		= &MyPrefsPTR->Daten->ERechArt;
	MyRechnungArtikel->Waehrung_KZ	= &Daten->Waehrung_KZ;

	Status			= &Daten->Status;
	Skonto_Satz 	= &Daten->Skonto;
	MWSt				= Daten->MWSt;
	MWSt_Typ			= Daten->MWSt_Typ;
	SkoRab			= &Daten->SkoRab;
	VersMWSt			= &Daten->VersMWSt;
	ZusMWSt			= &Daten->ZusMWSt;
	Waehrung_KZ		= &Daten->Waehrung_KZ;
	DBVersandkosten= &Daten->Versandkosten;
	DBZusatzkosten	= &Daten->Zusatzkosten;
	ErsterArtikel	= &Daten->ErsterArtikel;
	MWStBefreit		= &Daten->MWStBefreit;
	Preissystem		= &Daten->Preissystem;
	Gebucht			= &Daten->Gebucht;
	ZuAbNummer		= Daten->ZuAbNummer;
	ZuAbTyp			= Daten->ZuAbTyp;
	ZuAbWert			= Daten->ZuAbWert;
	Bemerkung		= Daten->Bemerkung;
	Bezahlt			= &Daten->Bezahlt;
	Barbeleg			= &Daten->Barbeleg;

	// So lautet der Start einer jeden PostScript-Variable
	// bei der Druckaufbereitung
	Startstring[0]	= '/';
	Startstring[1]	= 'E';
	Startstring[2]	= 'R';
	Startstring[3]	= '\0';

	// So beginnen die ARexx-Variablen
	RexxStartstring[0]	= 'I';
	RexxStartstring[1]	= 'B';
	RexxStartstring[2]	= '.';
	RexxStartstring[3]	= '\0';

	// Adressfelder Initialisieren (Lieferant)
	MyLieferantPTR->Initialisiere( (STRPTR)&LiefLief );
	MyAdressPTR->Initialisiere( (STRPTR)&LiefAdress );
};

// Initialisierung der Datenbankstruktur
// Übergabe:	InitDaten		= String-Pointer auf die zu initialisierende DB-Struktur
void ERechnung::Initialisiere( STRPTR InitDaten )
{
	// allgemeines löschen
	DataBase::Initialisiere( InitDaten );

	// Hilfsfelder
	UWORD i;
	DateStamp *DSPointer 	= &(((ERechnungDaten *)InitDaten)->BestDatum);

	((ERechnungDaten *)InitDaten)->Niederlassung		= MyMitarbeiterPTR->UserDaten.Niederlassung;
	((ERechnungDaten *)InitDaten)->Bestellernummer	= GetUser();

	// Datumsfelder auf noch nicht belegt setzen
	for(i=0; i < 11; i++)
	{
		DSPointer[i].ds_Days		= 0;
		DSPointer[i].ds_Minute	= -1;
		DSPointer[i].ds_Tick		= -1;
	}

	// Bestelldatum mit dem aktuellen Datum füllen
	MyLocalePTR->AktDateTime(&((ERechnungDaten *)InitDaten)->BestDatum);

	// Mehrwert- bzw. Umsatzsteuerfelder aus den Voreinstellungen bedienen
	for(i=0; i < 10; i++)
	{
		((ERechnungDaten *)InitDaten)->MWSt[i]			= MyPrefsPTR->Daten->MWSt[i];
		((ERechnungDaten *)InitDaten)->MWSt_Typ[i]	= MyPrefsPTR->Daten->MWSt_Typ[i];
	}

	// Felder auf eingestellete Standardwerte setzen
	((ERechnungDaten *)InitDaten)->Waehrung_KZ		= MyPrefsPTR->Daten->Waehrung_KZ;
	((ERechnungDaten *)InitDaten)->Preissystem		= 2;
	((ERechnungDaten *)InitDaten)->VersMWSt			= MyPrefsPTR->Daten->MWSt_Versand_E;
	((ERechnungDaten *)InitDaten)->ZusMWSt				= MyPrefsPTR->Daten->MWSt_Zusatz_E;
	((ERechnungDaten *)InitDaten)->Konto_Zahlung_Ein	= MyPrefsPTR->Daten->Konto_Zahlung_Ein;
};

// Suchfelder die nicht durch die allgemeine Suchfunktion abgedeckt
// werden können, hier separat abhandeln
// Übergabe:	SuchKlasse		= Pointer auf eine DataBaseSearch-Klasse
// Rückgabe:	Gefunden ja/nein
BOOL ERechnung::SuchVergleich( DataBaseSearch* SuchKlasse )
{
	BOOL Gefunden = FALSE;
	switch( SuchKlasse->DatenbankfeldNr )
	{
		case 16:			// Artikelnummer
		case 17:			// Artikelanzahl
		case 18:			// Artikelpreis
			if( Daten->ErsterArtikel > 0 )
			{
				ULONG i = Daten->ErsterArtikel;

				while( i != 0 && Gefunden == FALSE)
				{
					MyRechnungArtikel->GetElementNr( i );
					Gefunden = SuchKlasse->Vergleich();
					i = MyRechnungArtikel->Daten->NaechsterArtikel;
				}
			}
			break;
		default:
			Gefunden = SuchKlasse->Vergleich();
			break;
	}
	return Gefunden;
};


// War die Suchfunktion erfolgreich, hier die entsprechenden Daten
// in eine Liste hängen
// Übergabe:	SuchListe		= Pointer auf eine ListenClass-Klasse an die der
//										  aktuelle DB-Satz angehängt wird
void ERechnung::SuchListeAnhaengen(ListenClass* SuchListe)
{
	char TextWert[1024];
	char Buffer[80];
	char Buffer2[40];
	DateStamp *DSPointer = &Daten->BestDatum;

	MyAppStringsPTR->GetCycleWert( AppStrings[MSG_ERechStatus], Buffer2, Daten->RStatus );
	MyLocalePTR->FormatDateC( Buffer, &DSPointer[Daten->RStatus] );

	sprintf( (char *)TextWert, "%lu; %s; %s; %s; %lu; %s",	AktElementNr,
																				Buffer2,
																				Buffer,
																				Daten->LiefRechNr,
																				Daten->LieferantenNr,
																				Daten->Bemerkung);
	TextWert[255] = 0;
	SuchListe->NeuerNode( TextWert );
};

// Lesen des Rechnungskopfes und all seiner Positionen
// Adresse des Lieferanten, ...
void ERechnung::LesenGesamtRech()
{
	// Wenn der Lieferant sich geändert hat
	if( LiefAdress.Lieferant != Daten->LieferantenNr )
	{
		// Ist denn nun überhaupt einer eingegeben worden?
		if( Daten->LieferantenNr > 0 )
		{
			// Lieferanten-DB lesen und Daten in Merkbereich kopieren
			MyLieferantPTR->GetElementNr( (ULONG)Daten->LieferantenNr );
			memcpy( (void *)&LiefLief, (const void *)MyLieferantPTR->Daten, sizeof(LieferantenDaten) );
			// Adress-DB lesen und Daten in Merkbereich kopieren
			MyAdressPTR->GetElementNr( LiefLief.Adresse );
			memcpy( (void *)&LiefAdress, (const void *)MyAdressPTR->Daten, sizeof(AdressDaten) );
		}
		// Kein Lieferant
		else
		{
			// Felder entsprechend auf Grundstellung
			MyLieferantPTR->Initialisiere( (STRPTR)&LiefLief );
			MyAdressPTR->Initialisiere( (STRPTR)&LiefAdress );
		}
	}

	// Die Positionen hinzulesen
	Rechnung::LesenPositionen();
};

// Rechnungskopf schreiben
void ERechnung::UpDateElement()
{
	// Diverse Änderungsvariablen declarieren
	BOOL Preisneu			= FALSE;
	BOOL MWStUpDate		= FALSE;
	BOOL Summe				= FALSE;
	ULONG i;
	DOUBLE ZWDouble;

	// logisch gelöschte Sätze nicht speichern,
	// deshalb zurück.
	if( Daten->Status == 0xffff )
		return;

	// Die Zuletzt gesicherten Daten dienen als
	// Vergleichsbasis
	AltDaten				= (ERechnungDaten *)UnDoBuffer[UnDoUsed];

	// Rechnungsstatus geändert?
	if( Daten->RStatus != AltDaten->RStatus )
	{
		// Werte > 9 sind nicht erlaubt
		if( Daten->RStatus > 9 )
			Daten->RStatus = 9;
		Statuswechsel( AltDaten->RStatus, Daten->RStatus );
	}

	// Zugehörige Niederlassung geändert?
	if( Daten->Niederlassung		!=	AltDaten->Niederlassung )
	{
		// Die Nummer kann nicht grösser als die Anzahl der
		// angelegten Niederlassungen sein und nicht < 1
		if( Daten->Niederlassung	> MyNiederlassungPTR->ElementeVorhanden() )
			Daten->Niederlassung		= MyNiederlassungPTR->ElementeVorhanden();
		if( Daten->Niederlassung	< 1 )
			Daten->Niederlassung		= 1;
	}

	// Zugehörige Bestellernummer geändert?
	if( Daten->Bestellernummer		!= AltDaten->Bestellernummer )
	{
		// Die Nummer kann nicht grösser als die Anzahl der
		// angelegten Mitarbeiter sein und nicht < 1
		if( Daten->Bestellernummer	> MyMitarbeiterPTR->ElementeVorhanden() )
			Daten->Bestellernummer	= MyMitarbeiterPTR->ElementeVorhanden();
		if( Daten->Bestellernummer	< 1 )
			Daten->Bestellernummer	= 1;
	}

	// Hat sich der Lieferant geändert?
	if( Daten->LieferantenNr != AltDaten->LieferantenNr )
	{
		// Die Nummer kann nicht grösser als die Anzahl der
		// angelegten Lieferanten sein und nicht < 1
		if( Daten->LieferantenNr > MyLieferantPTR->ElementeVorhanden() )
			Daten->LieferantenNr = MyLieferantPTR->ElementeVorhanden();
		
		// Wenn den nun ein Lieferant vorhanden ist...
		if( Daten->LieferantenNr )
		{
			// Lesen und in dem Zwischenbereich merken
			MyLieferantPTR->GetElementNr( (ULONG)Daten->LieferantenNr );
			memcpy( (void *)&LiefLief, (const void *)MyLieferantPTR->Daten, sizeof(LieferantenDaten) );
			MyAdressPTR->GetElementNr( LiefLief.Adresse );
			memcpy( (void *)&LiefAdress, (const void *)MyAdressPTR->Daten, sizeof(AdressDaten) );

			// Vorgaben des Lieferanten übernehmen
			Daten->Waehrung_KZ			= LiefLief.Waehrung_KZ;
			Daten->Preissystem			= LiefLief.Preissystem;
			Daten->MWStBefreit			= LiefLief.MWStBefreit;
			Daten->ZuAbNummer[0]			= LiefLief.ZuAbNummer;
			Daten->Konto_Zahlung_Ein	= LiefLief.Konto_Zahlung_Ein;
			if( Daten->ZuAbNummer[0] )
			{
				Daten->ZuAbTyp[0]		= MyPrefsPTR->Daten->ZuAbTyp[(LiefLief.ZuAbNummer - 1)];
				if( Daten->ZuAbTyp[0]	== 0 ||
					 Daten->ZuAbTyp[0]	== 5 )
					Daten->ZuAbWert[0]	= LiefLief.ZuAbWert;
				else
					// Bei Monetären Werten, in altes(!) Währungsformat umrechnen
					Daten->ZuAbWert[0]	= MyPrefsPTR->WaehrungUmrechnen(	MWSt_Durchschnitt,
																							LiefLief.ZuAbWert,
																							LiefLief.Waehrung_KZ,
																							AltDaten->Waehrung_KZ,
																							0);
			}
			else
			{
				Daten->ZuAbTyp[0]		= 0;
				Daten->ZuAbWert[0]	= 0.0;
			}

			Daten->ZuAbNummer[1]		= 0;
			Daten->ZuAbTyp[1]			= 0;
			Daten->ZuAbWert[1]		= 0.0;
			Daten->ZuAbNummer[2]		= 0;
			Daten->ZuAbTyp[2]			= 0;
			Daten->ZuAbWert[2]		= 0.0;

			// trägt der Lieferant ein Löschkennzeichen?
			if( LiefLief.Status	== 0xffff)
				// Fehlerkennzeichen setzen
				Rechnungsfehler	|= 1;
			else
				// Fehlerkennzeichen löschen
				Rechnungsfehler	&= (0xffffffff - 1);
		}
		// kein Lieferant ausgewählt
		else
		{
			// Lieferant auf 0 gesetzt, Felder initialisieren
			MyLieferantPTR->Initialisiere( (STRPTR)&LiefLief );
			MyAdressPTR->Initialisiere( (STRPTR)&LiefAdress );
			// Fehlerkennzeichen löschen
			Rechnungsfehler &= (0xffffffff - 1);
		}
	}

	// Geändertes Preissystem
	Preisneu					|= ( Daten->Preissystem	!= AltDaten->Preissystem );

	// Mehrwertsteuerbefreiung hat sich geändert
	if( Daten->MWStBefreit	!= AltDaten->MWStBefreit )
	{
		// Jetzt befreit?
		if( Daten->MWStBefreit )
		{
			// Pointer auf ein nulleraray setzen
			MWSt				= MWStNull;
			// Währungskennzeichen auf entsprechenden
			// Nettopreis setzen
			if( Daten->Waehrung_KZ > 1 )
				Daten->Waehrung_KZ = 2;
			else
				Daten->Waehrung_KZ = 0;
		}
		else
			MWSt				= Daten->MWSt;

		// Neukalkulation scheint dringend angeraten
		MWStUpDate			= TRUE;
	}

	// Wenn auch nur ein MWSt-Satz geändert wurde,
	// UpDate-Kennzeichen setzen
	if( Daten->MWSt[0]		!= AltDaten->MWSt[0] ||
		 Daten->MWSt[1]		!= AltDaten->MWSt[1] ||
		 Daten->MWSt[2]		!= AltDaten->MWSt[2] ||
		 Daten->MWSt[3]		!= AltDaten->MWSt[3] ||
		 Daten->MWSt[4]		!= AltDaten->MWSt[4] ||
		 Daten->MWSt[5]		!= AltDaten->MWSt[5] ||
		 Daten->MWSt[6]		!= AltDaten->MWSt[6] ||
		 Daten->MWSt[7]		!= AltDaten->MWSt[7] ||
		 Daten->MWSt[8]		!= AltDaten->MWSt[8] ||
		 Daten->MWSt[9]		!= AltDaten->MWSt[9] ||
		 Daten->MWSt_Typ[0]	!= AltDaten->MWSt_Typ[0] ||
		 Daten->MWSt_Typ[1]	!= AltDaten->MWSt_Typ[1] ||
		 Daten->MWSt_Typ[2]	!= AltDaten->MWSt_Typ[2] ||
		 Daten->MWSt_Typ[3]	!= AltDaten->MWSt_Typ[3] ||
		 Daten->MWSt_Typ[4]	!= AltDaten->MWSt_Typ[4] ||
		 Daten->MWSt_Typ[5]	!= AltDaten->MWSt_Typ[5] ||
		 Daten->MWSt_Typ[6]	!= AltDaten->MWSt_Typ[6] ||
		 Daten->MWSt_Typ[7]	!= AltDaten->MWSt_Typ[7] ||
		 Daten->MWSt_Typ[8]	!= AltDaten->MWSt_Typ[8] ||
		 Daten->MWSt_Typ[9]	!= AltDaten->MWSt_Typ[9] )
	{
		MWStUpDate			= TRUE;
	}

	// Geänderte Währung?
	if( Daten->Waehrung_KZ != AltDaten->Waehrung_KZ )
	{
		// Mehrwertsteuerbefreit?
		if( Daten->MWStBefreit )
		{
			MWSt				= MWStNull;
			// Nur Nettoangaben gestattet, Brutto
			// wird umgeschlüsselt
			if( Daten->Waehrung_KZ > 1 )
				Daten->Waehrung_KZ = 2;
			else
				Daten->Waehrung_KZ = 0;
		}
		if( Daten->Waehrung_KZ != AltDaten->Waehrung_KZ )
			NeueWaehrung();
	}

	// Versandkosten oder Mehrwertsteuer der Versankosten geändert?
	if( (AltDaten->Versandkosten	!= Daten->Versandkosten) ||
		 (AltDaten->VersMWSt			!= Daten->VersMWSt) )
	{
		// alle vier Versandkosten neu errechnen
		for( i = 0; i < 4; i++ )
		{
			Versandkosten[i] = MyPrefsPTR->WaehrungUmrechnen(	MWSt[Daten->VersMWSt],
																				Daten->Versandkosten,
																				Daten->Waehrung_KZ,
																				i,
																				MWSt_Typ[Daten->VersMWSt] );
		}
		Summe = TRUE;
	}

	if( (AltDaten->Zusatzkosten	!= Daten->Zusatzkosten) ||
		 (AltDaten->ZusMWSt			!= Daten->ZusMWSt) )
	{
		for( i = 0; i < 4; i++ )
		{
			Zusatzkosten[i] = MyPrefsPTR->WaehrungUmrechnen(	MWSt[Daten->ZusMWSt],
																				Daten->Zusatzkosten,
																				Daten->Waehrung_KZ,
																				i,
																				MWSt_Typ[Daten->ZusMWSt] );
		}
		Summe = TRUE;
	}

	// Skontosumme geändert?
	Summe		|= ( AltDaten->SkoRab != Daten->SkoRab );

	// Zu-/Abschläge geändert
	for( i = 0; i < 3; i++ )
	{
		// Zu-/Abschlag geändert?
		if( Daten->ZuAbNummer[i]	!= AltDaten->ZuAbNummer[i] )
		{
			// Werte des neuen aus den Einstellungen übernehmen,
			// oder löschen, wenn keiner ausgewählt wurde
			if( Daten->ZuAbNummer[i] )
				Daten->ZuAbTyp[i]			= MyPrefsPTR->Daten->ZuAbTyp[(Daten->ZuAbNummer[i] - 1)];
			else
			{
				Daten->ZuAbTyp[i]		= 0;
				Daten->ZuAbWert[i]	= 0.0;
			}
		}

		// Zu-/Abschlagsnummer oder Wert geändert?
		if( Daten->ZuAbNummer[i]	!= AltDaten->ZuAbNummer[i] ||
			 Daten->ZuAbWert[i]		!= AltDaten->ZuAbWert[i] )
		{
			// Nummer überhaupt vorhanden?
			if( Daten->ZuAbNummer[i]	> 0 )
			{
				// Wert-Limit von errechnen
				ZWDouble		= MyPrefsPTR->WaehrungUmrechnen(	MWSt_Durchschnitt,
																			MyPrefsPTR->Daten->ZuAb_Limit_Von[(Daten->ZuAbNummer[i] - 1)],
																			MyPrefsPTR->Daten->Waehrung_KZ,
																			Daten->Waehrung_KZ,
																			0 );
				// Wenn der Wert das Minimum unterschreitet, Minimum verwenden
				if( Daten->ZuAbWert[i]		< ZWDouble )
					Daten->ZuAbWert[i]		= ZWDouble;
				else
				{
					// Wert Limit bis errechnen
					ZWDouble	= MyPrefsPTR->WaehrungUmrechnen(	MWSt_Durchschnitt,
																			MyPrefsPTR->Daten->ZuAb_Limit_Bis[(Daten->ZuAbNummer[i] - 1)],
																			MyPrefsPTR->Daten->Waehrung_KZ,
																			Daten->Waehrung_KZ,
																			0 );
					// Wurde das Maximum überschritten, Maximum verwenden
					if( Daten->ZuAbWert[i]	> ZWDouble )
						Daten->ZuAbWert[i]	= ZWDouble;
				}
			}
		}

		if( Daten->ZuAbTyp[i]		!= AltDaten->ZuAbTyp[i]	||
			 Daten->ZuAbWert[i]		!= AltDaten->ZuAbWert[i] )
			Summe							= TRUE;
	}

	// Skontosumme geändert?
	Summe									|=	( AltDaten->Skonto			!= Daten->Skonto );

	// Komplette Preisneuermittlung?
	if( Preisneu )
		MyRechnungArtikel->PreisermittlungAlle();

	// Mehrwertsteuer geändert?
	if( MWStUpDate )
	{
		MWStAenderung();
		Summe = TRUE;
	}

	// Summen neu errechnen?
	if( Summe )
		ErrechneSummen( FALSE );

	// So, alles überstanden, dann Datensatz speichern
	DataBase::UpDateElement();
};

// Beleg löschen
void ERechnung::LoeschenAkt()
{
	if( Daten->Status == 0xffff )
		Statuswechsel( ERS_Storniert, Daten->RStatus );
	else
		Statuswechsel( Daten->RStatus, ERS_Storniert );
	DataBase::LoeschenAkt();
};

// Versandart und -kosten ermitteln
void ERechnung::Versandermitteln()
{
};

// Bei Versionsupdates von MT-Rechnung III erfolgt hier der UpDate
// der Datenbank. Übergabeparameter ist die Versionsnummer der DB
// vor dem UpDate
// Übergabe:	AlteVersion		= StringPointer auf die alte Versionsnummer
void ERechnung::UpdateSatz( STRPTR AlteVersion )
{
	// Pointer auf die Datenbank (ist zu diesem Zeitpunkt sonst
	// noch nicht sichergestellt
	Daten = (ERechnungDaten *)UserData;

	// Alte Versionen deren Versionsnummern noch linksbündig ange-
	// geben waren (vor Version 0.80)
	if( AlteVersion[1] == '.' )
	{
		if( Daten->RStatus < ERS_Wareneingang )
		{
			ULONG i = Daten->ErsterArtikel;

			while( i != 0 )
			{
				MyRechnungArtikel->GetElementNr( i );
				if( MyRechnungArtikel->Daten->Artikelnummer > 0 &&
					 MyRechnungArtikel->Daten->Artikelanzahl > 0.0 )
				{
					MyArtikelPTR->Mengenaenderung( 0x10, MyRechnungArtikel->Daten->Artikelnummer,
															 MyRechnungArtikel->Daten->Artikelanzahl);
				}
				i = MyRechnungArtikel->Daten->NaechsterArtikel;
			}

		}
	}

	if( (AlteVersion[1] == '.') ||
		 (strncmp(AlteVersion, " 1.02", 5) < 0) )
	{
		if( Daten->Rabatt == 0.0 )
		{
			Daten->ZuAbNummer[0] = 0;
			Daten->ZuAbTyp[0]		= 0;
		}
		else
		{
			Daten->ZuAbNummer[0] = 1;
			Daten->ZuAbTyp[0]		= 5;
		}
		Daten->ZuAbWert[0]	= Daten->Rabatt;
	}

};

// Statuswechsel einer Ausgangsrechnung Alt -> Neu
// Übergabe:	StatusAlt		= Status vor dem Update
//					StatusNeu		= Status nach dem Update
// Rückgabe:	Fehler aufgetreten ja/nein
BOOL ERechnung::Statuswechsel( UBYTE StatusAlt, UBYTE StatusNeu )
{
	BOOL ReturnWert = FALSE;

	UBYTE Update = 0;				// 0x00 = Kein Update
										// 0x01 = reservierte Menge aufaddieren
										// 0x02 = reservierte Menge abziehen
										// 0x04 = vorgemerkte Menge aufaddieren
										// 0x08 = vorgemerkte Menge abziehen
										// 0x10 = Bestellte Menge aufaddieren
										// 0x20 = Bestellte Menge abziehen
										// 0x40 = Bestand aufaddieren
										// 0x80 = Bestand abziehen

	// Prüfen des neuen Status
	switch( StatusNeu )
	{
		case ERS_Bestellt:
		case ERS_Lieferschein:
		case ERS_Rechnung:
			Update = 0x10;
			break;
		case ERS_Wareneingang:
		case ERS_Mahnung_1:
		case ERS_Mahnung_2:
		case ERS_Mahnung_3:
		case ERS_Mahnverfahren:
		case ERS_Bezahlt:
			Update = 0x40;
			break;
		case ERS_Storniert:
			if( Daten->RStatus < ERS_Wareneingang )
				Update = 0x20;
			else
				Update = 0x80;
			break;
	}

	// Prüfen des alten Status unter Einbeziehung gesetzter UpDate-
	// kennzeichen aus der Prüfung des neuen Status
	switch( StatusAlt )
	{
		case ERS_Bestellt:
		case ERS_Lieferschein:
		case ERS_Rechnung:
			Update |= 0x20;
			break;
		case ERS_Wareneingang:
		case ERS_Mahnung_1:
		case ERS_Mahnung_2:
		case ERS_Mahnung_3:
		case ERS_Mahnverfahren:
		case ERS_Bezahlt:
			Update |= 0x80;
			break;
	}

	// Update der Bestandsführung bei den Artikeln
	MTRech_Art* SuchArtikel = MyRechnungArtikel->FirstArtikel;

	switch( Update )
	{
		case 0x00:
		case 0x03:
		case 0x0c:
		case 0x30:
		case 0xc0:
			break;
		default:
			while( SuchArtikel )
			{
				if (SuchArtikel->ArtikelDaten.Bestandsf > 0)
				{
					MyArtikelPTR->Mengenaenderung( Update, SuchArtikel->ZuOrdnungTab.Artikelnummer, SuchArtikel->ZuOrdnungTab.Artikelanzahl );
					memcpy( (void *)&SuchArtikel->ArtikelDaten, (const void *)MyArtikelPTR->Daten, sizeof(ArtikelDaten) );
				}
				SuchArtikel = SuchArtikel->NextArtikel;
			}
			break;
	}
	return ReturnWert;
};

// Rechnungssumme geändert?
// Übergabe:	 Versandkennzeichen:	hier ohne Bedeutung
void ERechnung::Summenaenderung( BOOL VersandKZ )
{
	ErrechneSummen( VersandKZ );
};

// Automatische Bestellfunktion
// Übergaben:	Status:		1 = Bestellungen erstellen
//									2 = Bestellungen erstellen und drucken
// Rückgabe:	Anzahl Bestellungen
ULONG ERechnung::Bestellautomatik( UBYTE Status )
{

	ULONG AnzBest	= 0;

	if( Status )
	{
		ULONG i, j;
		// Anzahl Lieferanten ermitteln
		ULONG AnzLief	= MyLieferantPTR->ElementeVorhanden();
		// Ein Array mit einem ULONG je Lieferanten (+ einer) anlegen
		ULONG *LiefKZ	= new ULONG[(AnzLief+1)];
		DOUBLE ZW_Bestand;

		// Fenster blockieren
		WZ_LockWindows( surface );

		// Lieferantenarray initialisieren
		for( i = 0; i <= AnzLief; LiefKZ[i++] = 0 );

		// Alle Artikel durchlesen
		for( i = 1; i <= MyArtikelPTR->ElementeVorhanden(); i++ )
		{
			MyArtikelPTR->GetElementNr(i);

			// Ist er nicht schon gelöscht?
			if( Daten->Status != 0xffff )
			{
				// Aktuelle Menge und bereits bestellte Menge dient als Basis
				ZW_Bestand = MyArtikelPTR->Daten->AktBestand + MyArtikelPTR->Daten->BestellMenge;

				// Artikel hat Bestandsführung
				// Dem Artikel ist ein Lieferant zugeordnet
				// Der Lieferant ist auch gültig
				// Lieferantenkennzeichen ist noch null
				// Der Bestand ist kleiner als der Mindestand
				// Der Bestand ist auch kleiner als der Sollbestand
				if( MyArtikelPTR->Daten->Bestandsf				== 1	&&
					 MyArtikelPTR->Daten->Lieferant				> 0	&&
					 MyArtikelPTR->Daten->Lieferant				< AnzLief &&
					 LiefKZ[MyArtikelPTR->Daten->Lieferant]	== 0	&&
					 ZW_Bestand											< MyArtikelPTR->Daten->MinBestand &&
					 ZW_Bestand											< MyArtikelPTR->Daten->SolBestand )
				{
					// Bestellkopf anlegen
					NeuerDatensatz();
					Daten->LieferantenNr = MyArtikelPTR->Daten->Lieferant;

					MyLieferantPTR->GetElementNr( MyArtikelPTR->Daten->Lieferant );
					Daten->Waehrung_KZ	= MyLieferantPTR->Daten->Waehrung_KZ;

					UpDateElement();
					LiefKZ[MyArtikelPTR->Daten->Lieferant] = AktElementNr;

					AnzBest++;
				}
			}
		}

		// Wurden Bestellungen angelegt?
		if( AnzBest )
		{
			// Zweiter durchlauf, diesmal für die Positionen
			for( i = 1; i <= MyArtikelPTR->ElementeVorhanden(); i++ )
			{
				// Artikel lesen
				MyArtikelPTR->GetElementNr(i);

				if( Daten->Status != 0xffff )
				{
					ZW_Bestand = MyArtikelPTR->Daten->AktBestand + MyArtikelPTR->Daten->BestellMenge;

					// Artikel hat Bestandsführung
					// Dem Artikel ist ein Lieferant zugeordnet
					// Der Lieferant ist auch gültig
					// Lieferantenkennzeichen ist noch null
					// Der Bestand ist kleiner als der Mindest- oder Mitbestellbestand
					// Der Bestand ist auch kleiner als der Sollbestand
					if( MyArtikelPTR->Daten->Bestandsf				== 1	&&
						 MyArtikelPTR->Daten->Lieferant				> 0	&&
						 MyArtikelPTR->Daten->Lieferant				< AnzLief &&
						 LiefKZ[MyArtikelPTR->Daten->Lieferant]	> 0	&&
						 (ZW_Bestand										< MyArtikelPTR->Daten->MinBestand ||
						  ZW_Bestand										< MyArtikelPTR->Daten->MitbestellBestand) &&
						 ZW_Bestand											< MyArtikelPTR->Daten->SolBestand )
					{
						// Artikel in die Bestellung aufnehmen
						GetElementNr( LiefKZ[MyArtikelPTR->Daten->Lieferant] );
						LesenGesamtRech();
						MyRechnungArtikel->NeuerArtikel();

						ZW_Bestand = MyArtikelPTR->Daten->SolBestand - ZW_Bestand;

						if( ZW_Bestand < MyArtikelPTR->Daten->VerpackungLief ||
							 fmod(ZW_Bestand, MyArtikelPTR->Daten->VerpackungLief) > 0.000001 )
						{
							j = (ULONG)(ZW_Bestand / MyArtikelPTR->Daten->VerpackungLief);
							ZW_Bestand = (DOUBLE)(++j) * MyArtikelPTR->Daten->VerpackungLief;
						}

						MyRechnungArtikel->Daten->Artikelnummer	= i;
						MyRechnungArtikel->Daten->Artikelanzahl	= ZW_Bestand;
						MyRechnungArtikel->Daten->MWSt				= MyArtikelPTR->Daten->MWSt;

						MyRechnungArtikel->Preisermittlung();
						MyRechnungArtikel->UpDateElement();

						MyArtikelPTR->Daten->BestellMenge				+= ZW_Bestand;
						MyArtikelPTR->UpDateElement();

						UpDateElement();
					}
				}
			}

			// Status 2, Bestelldokumente drucken
			if( Status == 2 && *MyPrefsPTR->Daten->Bestelldokument)
			{
				for( i = 1; i <= AnzLief; i++ )
				{
					if( LiefKZ[i] )
					{
						MyAllgemein.Drucken( 0, NULL, NULL, NULL, NULL, NULL, MyPrefsPTR->Daten->Bestelldokument,
													LiefKZ[i], LiefKZ[i], this, DRU_DRUCK,
													MyPrefsPTR->Daten->SchnellDruckFragen );
					}
				}
			}
		}

		// Allociertes Array wieder freigeben
		delete [AnzLief] LiefKZ;

		// Fenster entsperren
		WZ_UnlockWindows( surface );
	}

	return AnzBest;
};

// Druckvorbereitungen
// Übergabe:	os = Pointer auf den Ausgabestream
//					Art	'1' = Einzelbeleg
//							'2' = Liste
//							'3' = kompakte Liste
void ERechnung::PrintVorbereiten( ofstream* os, UBYTE Art )
{
	TEXT Zwischenstring[300];
	ULONG j = 0;

	LesenGesamtRech();

	switch( Art )
	{
		case '1':
			// Adressdaten der Ausstellenden Niederlassung
			MyNiederlassungPTR->GetElementNr( Daten->Niederlassung );
			MyNiederlassungPTR->DataBase::PrintString( os, "/Nied" );

			// Daten des Mitarbeiters, der den Auftrag erfasst hat
			MyMitarbeiterPTR->GetElementNr( Daten->Bestellernummer );
			MyMitarbeiterPTR->DataBase::PrintString( os, "/Bes" );

			// Daten des Lieferant
			MyLieferantPTR->PrintString( os, "/Lief", &LiefLief, &LiefAdress );
			break;
		case '2':
			// Adressdaten der Ausstellenden Niederlassung
			MyNiederlassungPTR->DataBase::PrintTabelle( os, Art, Daten->Niederlassung, Daten->Niederlassung, NULL, NULL, 1 );

			// Daten des Mitarbeiters, der den Auftrag erfasst hat
			MyMitarbeiterPTR->DataBase::PrintTabelle( os, Art, Daten->Bestellernummer, Daten->Bestellernummer, NULL, NULL, 1 );

			// Lieferant
			MyLieferantPTR->PrintTabelle( os, Art, Daten->LieferantenNr, Daten->LieferantenNr, NULL, NULL, &LiefLief, &LiefAdress, 1 );
			break;
		// Bei Art 3 hier keine Aufbereitung
	}

	// Niederlassung
	// Bestellernummer
	// Lieferant
	if( MyPrefsPTR->Daten->Nr_Laenge )
	{
		sprintf(DruckWert[j++].Wert, "%0*lu", MyPrefsPTR->Daten->Nr_Laenge, Daten->Niederlassung);
		sprintf(DruckWert[j++].Wert, "%0*lu", MyPrefsPTR->Daten->Nr_Laenge, Daten->Bestellernummer);
		sprintf(DruckWert[j++].Wert, "%0*lu", MyPrefsPTR->Daten->Nr_Laenge, Daten->LieferantenNr);
	}
	else
	{
		sprintf(DruckWert[j++].Wert, "%lu", Daten->Niederlassung);
		sprintf(DruckWert[j++].Wert, "%lu", Daten->Bestellernummer);
		sprintf(DruckWert[j++].Wert, "%lu", Daten->LieferantenNr);
	}

	// Rechnungsnummer
	PSAufbereit(Daten->LiefRechNr, DruckWert[j++].Wert);

	// Rechnungsstatus
	MyAppStringsPTR->GetCycleWert( AppStrings[MSG_ERechStatus], Zwischenstring, Daten->RStatus );
	PSAufbereit(Zwischenstring, DruckWert[j++].Wert);

	// Bestelltdatum
	PSDruckDatum( DruckWert[j++].Wert, &Daten->BestDatum );

	// Lieferscheindatum
	PSDruckDatum( DruckWert[j++].Wert, &Daten->LDatum );

	// Rechnungsdatum
	PSDruckDatum( DruckWert[j++].Wert, &Daten->RDatum );

	// Wareneingangsdatum
	PSDruckDatum( DruckWert[j++].Wert, &Daten->WDatum );

	// Datum Mahnung1
	PSDruckDatum( DruckWert[j++].Wert, &Daten->MahnDatum[0] );

	// Datum Mahnung2
	PSDruckDatum( DruckWert[j++].Wert, &Daten->MahnDatum[1] );

	// Datum Mahnung3
	PSDruckDatum( DruckWert[j++].Wert, &Daten->MahnDatum[2] );

	// Datum MahnVerfahren
	PSDruckDatum( DruckWert[j++].Wert, &Daten->MahnDatum[3] );

	// Datum Storniert
	PSDruckDatum( DruckWert[j++].Wert, &Daten->SDatum );

	// Datum Bezahlt
	PSDruckDatum( DruckWert[j++].Wert, &Daten->BDatum );

	PrintVorbereiten2( j );
};

// (A)Rexx-lesen einer Rechnung
// Übergabe:	rxmsg = Pointer auf den Rexx Message Struktur
//					Position = gewünschte Rechnung
// Rückgabe:	0 = Ok
//					2 = Fehler aufgetreten
ULONG ERechnung::GetRexx( struct RexxMsg *rxmsg, ULONG Position )
{
	ULONG ReturnWert = 0;
	TEXT Buffer[80];

	GetElementNr( Position );
	LesenGesamtRech();

	sprintf(Buffer, "%lu", Daten->Status);
	ReturnWert += SetRexxVar( (struct Message *)rxmsg, "IB.STATE", (STRPTR)Buffer, strlen(Buffer) );

	// Niederlassungsdaten
	ReturnWert += MyNiederlassungPTR->GetRexx( rxmsg, Daten->Niederlassung, "IB.", NULL, NULL );

	// Mitarbeiterdaten
	ReturnWert += MyMitarbeiterPTR->GetRexx( rxmsg, Daten->Bestellernummer, "IB.", NULL, NULL );

	// Lieferant
	ReturnWert += MyLieferantPTR->GetRexx( rxmsg, Daten->LieferantenNr, "IB.", &LiefLief, &LiefAdress );

	// Allgemeine Rechnungsdaten (gemeinsam von Eingangs- und Ausgangsrechnungen genutzt)
	ReturnWert += Rechnung::GetRexx( rxmsg, Position );

	// Niederlassung
	sprintf(Buffer, "%lu", Daten->Niederlassung);
	ReturnWert += SetRexxVar( (struct Message *)rxmsg, "IB.OFFICE_NUMBER", (STRPTR)Buffer, strlen(Buffer) );

	// Bestellernummer
	sprintf(Buffer, "%lu", Daten->Bestellernummer);
	ReturnWert += SetRexxVar( (struct Message *)rxmsg, "IB.ORDERER_NUMBER", (STRPTR)Buffer, strlen(Buffer) );

	// Lieferant
	sprintf(Buffer, "%lu", Daten->LieferantenNr);
	ReturnWert += SetRexxVar( (struct Message *)rxmsg, "IB.INVOICEE_NUMBER", (STRPTR)Buffer, strlen(Buffer) );

	// Rechnungsnummer, Lieferant
	ReturnWert += SetRexxVar( (struct Message *)rxmsg, "IB.BILL_NUMBER", (STRPTR)Daten->LiefRechNr, strlen(Daten->LiefRechNr) );

	// Rechnungsstatus
	sprintf(Buffer, "%lu", Daten->RStatus);
	ReturnWert += SetRexxVar( (struct Message *)rxmsg, "IB.BILL_STATE", (STRPTR)Buffer, strlen(Buffer) );

	// Bestelltdatum
	MyLocalePTR->FormatDateC( Buffer, &Daten->BestDatum, "%Y%m%d");
	ReturnWert += SetRexxVar( (struct Message *)rxmsg, "IB.DATE_ORDER", (STRPTR)Buffer, strlen(Buffer) );

	// Lieferscheindatum
	MyLocalePTR->FormatDateC( Buffer, &Daten->LDatum, "%Y%m%d");
	ReturnWert += SetRexxVar( (struct Message *)rxmsg, "IB.DATE_DELIVERY_NOTE", (STRPTR)Buffer, strlen(Buffer) );

	// Rechnungsdatum
	MyLocalePTR->FormatDateC( Buffer, &Daten->RDatum, "%Y%m%d");
	ReturnWert += SetRexxVar( (struct Message *)rxmsg, "IB.DATE_BILL", (STRPTR)Buffer, strlen(Buffer) );

	// Wareneingangsdatum
	MyLocalePTR->FormatDateC( Buffer, &Daten->WDatum, "%Y%m%d");
	ReturnWert += SetRexxVar( (struct Message *)rxmsg, "IB.DATE_GOODS_RECEIVED", (STRPTR)Buffer, strlen(Buffer) );

	// Datum Mahnung1
	MyLocalePTR->FormatDateC( Buffer, &Daten->MahnDatum[0], "%Y%m%d");
	ReturnWert += SetRexxVar( (struct Message *)rxmsg, "IB.DATE_DUNNING.1", (STRPTR)Buffer, strlen(Buffer) );

	// Datum Mahnung2
	MyLocalePTR->FormatDateC( Buffer, &Daten->MahnDatum[1], "%Y%m%d");
	ReturnWert += SetRexxVar( (struct Message *)rxmsg, "IB.DATE_DUNNING.2", (STRPTR)Buffer, strlen(Buffer) );

	// Datum Mahnung3
	MyLocalePTR->FormatDateC( Buffer, &Daten->MahnDatum[2], "%Y%m%d");
	ReturnWert += SetRexxVar( (struct Message *)rxmsg, "IB.DATE_DUNNING.3", (STRPTR)Buffer, strlen(Buffer) );

	// Datum MahnVerfahren
	MyLocalePTR->FormatDateC( Buffer, &Daten->MahnDatum[3], "%Y%m%d");
	ReturnWert += SetRexxVar( (struct Message *)rxmsg, "IB.DATE_DUNNING.4", (STRPTR)Buffer, strlen(Buffer) );

	// Datum Storniert
	MyLocalePTR->FormatDateC( Buffer, &Daten->SDatum, "%Y%m%d");
	ReturnWert += SetRexxVar( (struct Message *)rxmsg, "IB.DATE_CANCEL", (STRPTR)Buffer, strlen(Buffer) );

	// Datum Bezahlt
	MyLocalePTR->FormatDateC( Buffer, &Daten->BDatum, "%Y%m%d");
	ReturnWert += SetRexxVar( (struct Message *)rxmsg, "IB.DATE_PAYED", (STRPTR)Buffer, strlen(Buffer) );

	// Buchungskonto für die Zahlung von Eingangsbelegen       (V1.04)
	sprintf(Buffer, "%u", MyKontenPosPTR->ToCycle(Daten->Konto_Zahlung_Ein));
	ReturnWert += SetRexxVar( (struct Message *)rxmsg, "IB.ACCOUNT_PAY_IN", (STRPTR)Buffer, strlen(Buffer) );



	if( ReturnWert > 0 )
		ReturnWert = 2;

	return ReturnWert;
};

// (A)Rexx-schreiben einer Rechnung
// Übergabe:	rxmsg		= Pointer auf den Rexx Message Struktur
//					Position	= gewünschte Rechnung
// Rückgabe:	0 = Ok
//					2 = Fehler aufgetreten
ULONG ERechnung::SetRexx( struct RexxMsg *rxmsg, ULONG Position )
{
	STRPTR	Buffer = NULL;
	ULONG		ReturnWert = 0;

	GetElementNr( Position );
	LesenGesamtRech();

	// Niederlassung
	Daten->Niederlassung			= MyARexx.GetRexxLong("IB.OFFICE_NUMBER", 1, MyNiederlassungPTR->ElementeVorhanden());

	// Bestellernummer
	Daten->Bestellernummer		= MyARexx.GetRexxLong("IB.ORDERER_NUMBER", 1, MyMitarbeiterPTR->ElementeVorhanden());

	// Lieferant
	Daten->LieferantenNr			= MyARexx.GetRexxLong("IB.INVOICEE_NUMBER", 0, MyLieferantPTR->ElementeVorhanden());

	// Rechnungsnummer, Lieferant
	ReturnWert += GetRexxVar( (struct Message *)rxmsg, "IB.BILL_NUMBER", (UBYTE **)&Buffer );
	strncpy( Daten->LiefRechNr, Buffer, 19 );

	// Rechnungsstatus
	Daten->RStatus					= MyARexx.GetRexxLong("IB.BILL_STATE", 0, 9);

	// Bestelltdatum
	Daten->BestDatum				= MyARexx.RexxDatum( "IB.DATE_ORDER" );

	// Lieferscheindatum
	Daten->LDatum					= MyARexx.RexxDatum( "IB.DATE_DELIVERY_NOTE" );

	// Rechnungsdatum
	Daten->RDatum					= MyARexx.RexxDatum( "IB.DATE_BILL" );

	// Wareneingangsdatum
	Daten->WDatum					= MyARexx.RexxDatum( "IB.DATE_GOODS_RECEIVED" );

	// Datum Mahnung1
	Daten->MahnDatum[0]			= MyARexx.RexxDatum( "IB.DATE_DUNNING.1" );

	// Datum Mahnung2
	Daten->MahnDatum[1]			= MyARexx.RexxDatum( "IB.DATE_DUNNING.2" );

	// Datum Mahnung3
	Daten->MahnDatum[2]			= MyARexx.RexxDatum( "IB.DATE_DUNNING.3" );

	// Datum MahnVerfahren
	Daten->MahnDatum[3]			= MyARexx.RexxDatum( "IB.DATE_DUNNING.4" );

	// Datum Storniert
	Daten->SDatum					= MyARexx.RexxDatum( "IB.DATE_CANCEL" );

	// Datum Bezahlt
	Daten->BDatum					= MyARexx.RexxDatum( "IB.DATE_PAYED" );

	// Buchungskonto für die Zahlung von Eingangsbelegen       (V1.04)
	Daten->Konto_Zahlung_Ein	= MyKontenPosPTR->FromCycle(MyARexx.GetRexxLong("IB.ACCOUNT_PAY_IN", 0, MyKontenPosPTR->AnzCyclePos));



	// Allgemeine Rechnungsdaten (gemeinsam von Eingangs- und Ausgangsrechnungen genutzt)
	ReturnWert += Rechnung::SetRexx( rxmsg, Position );

	// Ausgabe der Daten, da sich die ganzen Summen usw. geändert haben können.
	ReturnWert += GetRexx( rxmsg, Position );

	if( ReturnWert > 0 )
		ReturnWert = 2;

	return ReturnWert;
};

// Buchführung in künftigen Versionen....
// Rückgabe:	Buchung durchgeführt ja/nein
BOOL ERechnung::Buchen()
{
	// hier kommt mal die Buchung
	return Daten->Gebucht;
}; 