#pragma +
// Name:						ARechnung
// 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-2000 by MT Graphic & Design
// Version:					V1.08
//
//    Copyright (C) 1997-2000 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 "Versand.h"
#include "RechnungArtikel.h"
#include "Rechnung.h"
#include "ARechnung.h"
#include "Einstellungen.h"
#include "KontenPos.h"
#include "LocaleStrings.h"
#include "Allgemein.h"
#include "MTARexx.h"

extern Laender				*MyLaenderPTR;
extern Adress				*MyAdressPTR;
extern Versand				*MyVersandPTR;
extern Kunden				*MyKundenPTR;
extern Mitarbeiter		*MyMitarbeiterPTR;
extern Niederlassung		*MyNiederlassungPTR;
extern Artikel				*MyArtikelPTR;
extern RechnungArtikel	*MyARechnungArtikelPTR;
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
ARechnung::ARechnung(STRPTR Dateiname, STRPTR Datenbankbez, UWORD User ) : Rechnung( Dateiname, Datenbankbez, User, sizeof(ARechnungDaten), 450, MyARechnungArtikelPTR )
{
	// Pointer auf den Datenbereich setzen
	Daten			= (ARechnungDaten *)UserData;

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

	// Vorgaben für die Versandart
	VersandNr	= 0xffffffff;

	VersandArtPosAlt	= -2;
	VersandArtPos		= -2;

	// Felder für die Suchfunktion zuordnen
	Such_DB_Anzahl	= 30;
	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_ARechStatus];
	Such_DB_Feld[2]	= (void *)&Daten->ADatum;
	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->MahnDatum[0];
	Such_DB_Typ[5]		= 2;
	Such_DB_CS[5]		= NULL;
	Such_DB_Feld[6]	= (void *)&Daten->MahnDatum[1];
	Such_DB_Typ[6]		= 2;
	Such_DB_CS[6]		= NULL;
	Such_DB_Feld[7]	= (void *)&Daten->MahnDatum[2];
	Such_DB_Typ[7]		= 2;
	Such_DB_CS[7]		= NULL;
	Such_DB_Feld[8]	= (void *)&Daten->MahnDatum[3];
	Such_DB_Typ[8]		= 2;
	Such_DB_CS[8]		= NULL;
	Such_DB_Feld[9]	= (void *)&Daten->ABDatum;
	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->Verkaufernummer;
	Such_DB_Typ[13]	= 7;
	Such_DB_CS[13]		= NULL;
	Such_DB_Feld[14]	= (void *)&Daten->RechEmpf;
	Such_DB_Typ[14]	= 7;
	Such_DB_CS[14]		= NULL;
	Such_DB_Feld[15]	= (void *)&Daten->WareEmpf;
	Such_DB_Typ[15]	= 7;
	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->Versandart;
	Such_DB_Typ[19]	= 7;
	Such_DB_CS[19]		= MyVersandPTR->CycleVersand;
	Such_DB_Feld[20]	= (void *)&Daten->Versandkosten;
	Such_DB_Typ[20]	= 11;
	Such_DB_CS[20]		= NULL;
	Such_DB_Feld[21]	= (void *)&Daten->Skonto;
	Such_DB_Typ[21]	= 11;
	Such_DB_CS[21]		= NULL;
	Such_DB_Feld[22]	= (void *)Daten->Bemerkung;
	Such_DB_Typ[22]	= 0;
	Such_DB_CS[22]		= NULL;
	Such_DB_Feld[23]	= (void *)&Daten->Waehrung_KZ;
	Such_DB_Typ[23]	= 5;
	Such_DB_CS[23]		= MyPrefsPTR->CycleWaehrung;
	Such_DB_Feld[24]	= (void *)&Daten->Preissystem;
	Such_DB_Typ[24]	= 5;
	Such_DB_CS[24]		= AppStrings[MSG_PreisSys];
	Such_DB_Feld[25]	= (void *)&Daten->Waehrung_KZ;
	Such_DB_Typ[25]	= 4;
	Such_DB_CS[25]		= NULL;
	Such_DB_Feld[26]	= (void *)&Daten->ZuAbNummer;
	Such_DB_Typ[26]	= 5;
	Such_DB_CS[26]		= MyPrefsPTR->CycleZuAb;
	Such_DB_Feld[27]	= (void *)&Daten->ZuAbTyp;
	Such_DB_Typ[27]	= 5;
	Such_DB_CS[27]		= AppStrings[MSG_ZuAbTyp];;
	Such_DB_Feld[28]	= (void *)&Daten->ZuAbWert;
	Such_DB_Typ[28]	= 11;
	Such_DB_CS[28]		= NULL;
	Such_DB_Feld[29]	= (void *)&Daten->Gebucht;
	Such_DB_Typ[29]	= 4;
	Such_DB_CS[29]		= NULL;

	Such_DB_Nr			= 6;

	Such_DB_Felder_Laenge = strlen( AppStrings[MSG_Such_Adr_Dummy] ) + 1 +
									strlen( AppStrings[MSG_Such_ARechnungA] ) +
									strlen( AppStrings[MSG_Such_ARechnungB] );
	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_ARechnungA] );
	strcat( Such_DB_Felder_String, AppStrings[MSG_Such_ARechnungB] );

	// 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 ARechnungDruWert[] =
	{
		{"ARNiederlassungNr",	"(", NULL, 16, ")", TRUE},
		{"ARVerkaeuferNr",		"(", NULL, 16, ")", TRUE},
		{"ARRechEmpfNr",			"(", NULL, 16, ")", TRUE},
		{"ARWareEmpfNr",			"(", NULL, 16, ")", TRUE},
		{"ARRechStatus",			"(", NULL, 32, ")", TRUE},
		{"ARAngebotDatum",		"[", NULL, 80, "]", TRUE},
		{"ARBestDatum",			"[", NULL, 80, "]", TRUE},
		{"ARLieferscheinDatum",	"[", NULL, 80, "]", TRUE},
		{"ARRechnungDatum",		"[", NULL, 80, "]", TRUE},
		{"ARMahn1Datum",			"[", NULL, 80, "]", TRUE},
		{"ARMahn2Datum",			"[", NULL, 80, "]", TRUE},
		{"ARMahn3Datum",			"[", NULL, 80, "]", TRUE},
		{"ARMahnVerDatum",		"[", NULL, 80, "]", TRUE},
		{"ARAbgeDatum",			"[", NULL, 80, "]", TRUE},
		{"ARStornoDatum",			"[", NULL, 80, "]", TRUE},
		{"ARBezahltDatum",		"[", NULL, 80, "]", TRUE},
		{"ARVersandbez1",			"(", NULL, 60, ")", TRUE},
		{"ARVersandbez2",			"(", NULL, 60, ")", TRUE},
		{"ARVersandbez3",			"(", NULL, 60, ")", TRUE},
		{"ARBemerkung",			"[", NULL, 240, "]", TRUE},
		{"ARWaehrung",				"", NULL, 4, "", TRUE},
		{"ARWaehrungSymbol",		"(", NULL, 8, ")", TRUE},
		{"ARVersandMWStSatz",	"(", NULL, 40, ")", TRUE},
		{"ARVersandkostenGef",	"", NULL, 8, "", TRUE},
		{"ARVersandWert",			"[", NULL, 120, "]", TRUE},
		{"ARZusatzkostenGef",	"", NULL, 8, "", TRUE},
		{"ARZusatzWert",			"[", NULL, 120, "]", TRUE},
		{"ARVersZusWert",			"[", NULL, 120, "]", TRUE},
		{"ARVersMWStWert",		"[", NULL, 80, "]", TRUE},
		{"ARZusMWStWert",			"[", NULL, 80, "]", TRUE},
		{"ARVersZusMWStWert",	"[", NULL, 80, "]", TRUE},
		{"ARSkontoGef",			"", NULL, 8, "", TRUE},
		{"ARSkontoSatz",			"(", NULL, 40, ")", TRUE},
		{"ARSkontoWert",			"[", NULL, 120, "]", TRUE},
		{"ARSkontoMWStWert",		"[", NULL, 80, "]", TRUE},
		{"ARGesamtWert",			"[", NULL, 120, "]", TRUE},
		{"ARGesamtminRabWert",	"[", NULL, 120, "]", TRUE},
		{"ARGesamtminRabSkonWert",	"[", NULL, 120, "]", TRUE},
		{"ARGesamtZusWert",		"[", NULL, 120, "]", TRUE},
		{"ARGesamtZusminRabWert",	"[", NULL, 120, "]", TRUE},
		{"ARGesamtZusminRabSkonWert",	"[", NULL, 120, "]", TRUE},
		{"ARMWStSatz",				"[", NULL, 400, "]", TRUE},
		{"ARMWStBel",				"[", NULL, 64, "]", TRUE},
		{"ARMWStGesWert",			"[", NULL, 800, "]", TRUE},
		{"ARMWStGesMinRabWert",	"[", NULL, 800, "]", TRUE},
		{"ARMWStGesMinRabSkoWert",	"[", NULL, 800, "]", TRUE},
		{"ARjeMWStWert",			"[", NULL, 1000, "]", TRUE},
		{"ARjeMWStMinRabWert",	"[", NULL, 1000, "]", TRUE},
		{"ARjeMWStMinRabSkoWert","[", NULL, 1000, "]", TRUE},
		{"ARMWStSummeWert",		"[", NULL, 120, "]", TRUE},
		{"ARMWStSummeMinRabWert",	"[", NULL, 120, "]", TRUE},
		{"ARMWStSummeMinRabSkoWert", "[", NULL, 120, "]", TRUE},
		{"ARZMWStGesWert",		"[", NULL, 800, "]", TRUE},
		{"ARZMWStGesMinRabWert","[", NULL, 800, "]", TRUE},
		{"ARZMWStGesMinRabSkoWert",	"[", NULL, 800, "]", TRUE},
		{"ARZjeMWStWert",			"[", NULL, 1000, "]", TRUE},
		{"ARZjeMWStMinRabWert",	"[", NULL, 1000, "]", TRUE},
		{"ARZjeMWStMinRabSkoWert","[", NULL, 1000, "]", TRUE},
		{"ARZMWStSummeWert",		"[", NULL, 120, "]", TRUE},
		{"ARZMWStSummeMinRabWert",	"[", NULL, 120, "]", TRUE},
		{"ARZMWStSummeMinRabSkoWert", "[", NULL, 120, "]", TRUE},
		{"ARZuAbNr",				"[", NULL, 16,  "]", TRUE},
		{"ARZuAbWert",				"[", NULL, 600, "]", TRUE},
		{"ARZuAbBezeich",			"[", NULL, 300, "]", TRUE},
		{"ARZuAbTyp",				"[", NULL, 16,  "]", TRUE},
		{"ARZuAbBetrag",			"[", NULL, 600, "]", TRUE},
		{"",							"",  NULL, 0, "", TRUE},
		{"ARBezahltWert",			"[", NULL, 120, "]", TRUE},
		{"ARRueckgabeWert",		"[", NULL, 120, "]", TRUE},
		{"ARBarbeleg",				"", NULL, 8, "", TRUE},
		{"",							"",  NULL, 0, "", FALSE}
	};

	// oben definierte Druckfelder initialisieren
	DruckWertInit( ARechnungDruWert );

	// Algemeine Felder die bei Ein- und Ausgangsrechnungen
	// gleichermassen verwendet werden können, auf Pointer
	// in die Rechnungsstruktur stellen
	MyRechnungArtikel->Artikel_KZ		= &MyPrefsPTR->Daten->ARechArt;
	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]	= 'A';
	Startstring[2]	= 'R';
	Startstring[3]	= '\0';

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

	// Adressfelder Initialisieren (Rechnungs- und Warenempfänger)
	MyKundenPTR->Initialisiere( (STRPTR)&RempfKunde );
	MyAdressPTR->Initialisiere( (STRPTR)&RempfAdress );
	MyKundenPTR->Initialisiere( (STRPTR)&WempfKunde );
	MyAdressPTR->Initialisiere( (STRPTR)&WempfAdress );
};

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

	// Hilfsfelder
	UWORD i;
	DateStamp *DSPointer 	= &(((ARechnungDaten *)InitDaten)->ADatum);

	// Versandartmerker auf ungültige Werte setzen (=noch nicht verwendet)
	VersandArtPosAlt			= -2;
	VersandArtPos				= -2;

	// Gewicht auf 0
	ZW_Gewicht					= 0.0;

	// Erste Versandart ermitteln und Damit die Felder füllen
	MyVersandPTR->GetFirstElement();
	((ARechnungDaten *)InitDaten)->VersMWSt			= MyVersandPTR->Daten->MWSt;
	((ARechnungDaten *)InitDaten)->ZusMWSt				= MyVersandPTR->Daten->ZusMWSt;
	((ARechnungDaten *)InitDaten)->SkoRab				= MyVersandPTR->Daten->SkoRab;
	((ARechnungDaten *)InitDaten)->Verkaufernummer	= GetUser();
	((ARechnungDaten *)InitDaten)->Niederlassung		= MyMitarbeiterPTR->UserDaten.Niederlassung;

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

	// Angebotsdatum mit dem aktuellen Datum füllen
	MyLocalePTR->AktDateTime(&((ARechnungDaten *)InitDaten)->ADatum);

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

	// Währung auf eingestellete Standardwährung setzen
	((ARechnungDaten *)InitDaten)->Waehrung_KZ		= MyPrefsPTR->Daten->Waehrung_KZ;
};

// 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 ARechnung::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 ARechnung::SuchListeAnhaengen(ListenClass* SuchListe)
{
	char Buffer[80];
	char Buffer2[50];
	char TextWert[1024];
	DateStamp *DSPointer = &Daten->ADatum;

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

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

// Lesen des Rechnungskopfes und all seiner Positionen
// Adressen der Rechnungs- und Warenempfänger, ...
void ARechnung::LesenGesamtRech()
{
	// Wenn der Rechnungsempfänger sich geändert hat
	if( RempfAdress.Kunde != Daten->RechEmpf )
	{
		// Ist denn nun überhaupt einer eingegeben worden?
		if( Daten->RechEmpf > 0 )
		{
			// Kunden-DB lesen und Daten in Merkbereich kopieren
			MyKundenPTR->GetElementNr( (ULONG)Daten->RechEmpf );
			memcpy( (void *)&RempfKunde, (const void *)MyKundenPTR->Daten, sizeof(KundenDaten) );
			// Adress-DB lesen und Daten in Merkbereich kopieren
			MyAdressPTR->GetElementNr( RempfKunde.Adresse );
			memcpy( (void *)&RempfAdress, (const void *)MyAdressPTR->Daten, sizeof(AdressDaten) );
		}
		// Kein Rechnungsempfänger
		else
		{
			// Felder entsprechend auf Grundstellung
			MyKundenPTR->Initialisiere( (STRPTR)&RempfKunde );
			MyAdressPTR->Initialisiere( (STRPTR)&RempfAdress );
		}
	}

	// Wenn der Warenempfänger sich geändert hat
	if( WempfAdress.Kunde != Daten->WareEmpf )
	{
		// Ist denn nun überhaupt einer eingegeben worden?
		if( Daten->WareEmpf > 0 )
		{
			// Kunden-DB lesen und Daten in Merkbereich kopieren
			MyKundenPTR->GetElementNr( (ULONG)Daten->WareEmpf );
			memcpy( (void *)&WempfKunde, (const void *)MyKundenPTR->Daten, sizeof(KundenDaten) );
			// Adress-DB lesen und Daten in Merkbereich kopieren
			MyAdressPTR->GetElementNr( WempfKunde.Adresse );
			memcpy( (void *)&WempfAdress, (const void *)MyAdressPTR->Daten, sizeof(AdressDaten) );
		}
		// Kein Warenempfänger
		else
		{
			// Felder entsprechend auf Grundstellung
			MyKundenPTR->Initialisiere( (STRPTR)&WempfKunde );
			MyAdressPTR->Initialisiere( (STRPTR)&WempfAdress );
		}
	}

	// Versandart ermitteln und daten in Merkbereich kopieren
	MyVersandPTR->GetElementNr( (ULONG)Daten->Versandart + 1 );
	memcpy( (void *)&VersandDaten, (const void *)MyVersandPTR->Daten, sizeof(VersandDaten) );
	VersandNr = MyVersandPTR->AktElementNr;

	// Wenn der Auftrag mehrwertsteuerbefreit ist, Pointer
	// auf nen Nullerbereich setzen, ansonsten auf die reale
	// Tabelle
	if( Daten->MWStBefreit )
		MWSt				= MWStNull;
	else
		MWSt				= Daten->MWSt;
	
	// Die Positionen hinzulesen
	Rechnung::LesenPositionen();
};

// Rechnungskopf schreiben
void ARechnung::UpDateElement()
{
	// Diverse Änderungsvariablen declarieren
	BOOL Preisneu			= FALSE;
	BOOL MWStUpDate		= FALSE;
	BOOL Summe				= FALSE;
	BOOL Versanderm		= FALSE;
	BOOL Versandaender	= FALSE;
	BOOL Versandpreis		= FALSE;
	DOUBLE ZWDouble;
	ULONG i;
                                  	
	// logisch gelöschte Sätze nicht speichern,
	// deshalb zurück.
	if( Daten->Status == 0xffff )
		return;

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

	// Rechnungsstatus geändert?
	if( Daten->RStatus != AltDaten->RStatus )
	{
		// Werte > 10 sind nicht erlaubt
		if( Daten->RStatus > 10 )
			Daten->RStatus = 10;
		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 Verkäufernummer geändert?
	if( Daten->Verkaufernummer		!= AltDaten->Verkaufernummer )
	{
		// Die Nummer kann nicht grösser als die Anzahl der
		// angelegten Mitarbeiter sein und nicht < 1
		if( Daten->Verkaufernummer	> MyMitarbeiterPTR->ElementeVorhanden() )
			Daten->Verkaufernummer	= MyMitarbeiterPTR->ElementeVorhanden();
		if( Daten->Verkaufernummer	< 1 )
			Daten->Verkaufernummer	= 1;
	}

	// Hat sich der Rechnungsempfänger geändert?
	if( Daten->RechEmpf != AltDaten->RechEmpf )
	{
		// Naja, jetzt kommt Arbeit auf uns zu...
		// Rechnungsempfängernummer kann nicht grösser als die
		// Anzahl vorhandener Kunden sein, eventuell korrigieren
		if( Daten->RechEmpf > MyKundenPTR->ElementeVorhanden() )
			Daten->RechEmpf = MyKundenPTR->ElementeVorhanden();

		// So, mal schaun was wir für nen Status haben
		switch( Daten->RStatus )
		{
			case ARS_Lieferschein:
			case ARS_Rechnung:
			case ARS_Mahnung_1:
			case ARS_Mahnung_2:
			case ARS_Mahnung_3:
			case ARS_Mahnverfahren:
			case ARS_Abgeschrieben:
				// In diesen Fällen gilt es den Kontostand anzu-
				// passen, mal schaun ob bisher schon ein Rechnungs-
				// empfänger eingegeben wurde...
				if( AltDaten->RechEmpf )
				{
					// Kunde lesen
					MyKundenPTR->GetElementNr( AltDaten->RechEmpf );

					// Entsprechend der bei ihm vorgegebenen Währung
					// den Kontostand um den Bruttowert dieser Währung
					// wieder draufaddieren
					if( Daten->Waehrung_KZ > 1 )
						MyKundenPTR->Daten->Kontostand += Gesamtsumme[3];
					else
						MyKundenPTR->Daten->Kontostand += Gesamtsumme[1];

					// Das ganze speichern
					MyKundenPTR->UpDateElement();
				}

				// In diesen Fällen gilt es den Kontostand anzu-
				// passen, mal schaun ob bisher schon ein Rechnungs-
				// empfänger eingegeben wurde...
				if( Daten->RechEmpf )
				{
					// Kunde lesen
					MyKundenPTR->GetElementNr( (ULONG)Daten->RechEmpf );

					// Entsprechend der bei ihm vorgegebenen Währung
					// den Kontostand um den Bruttowert dieser Währung
					// wieder abziehen
					if( Daten->Waehrung_KZ > 1 )
						MyKundenPTR->Daten->Kontostand -= Gesamtsumme[3];
					else
						MyKundenPTR->Daten->Kontostand -= Gesamtsumme[1];

					// Das ganze speichern
					MyKundenPTR->UpDateElement();

					// Mal sehen, ob das Kreditlimit des Kunden das
					// Überhaupt gestattet
					if( (MyKundenPTR->Daten->KreditLimit > 0) &&
						 (MyKundenPTR->Daten->Kontostand < (0 - MyKundenPTR->Daten->KreditLimit)) )
						// Na Schlingel, über die Strenge geschlagen? Fehler setzen
						Rechnungsfehler	|= 4;
					else
						// eventuell gesetzten Fehler revidieren
						Rechnungsfehler	&= (0xffffffff - 4);
				}
				else 
					// eventuell gesetzten Fehler revidieren, kein Kunde
					Rechnungsfehler		&= (0xffffffff - 4);
				break;
		}

		// Wenn den nun ein Rechnungsempfänger vorhanden ist...
		if( Daten->RechEmpf )
		{
			// Lesen und in dem Zwischenbereich merken
			MyKundenPTR->GetElementNr( (ULONG)Daten->RechEmpf );
			memcpy( (void *)&RempfKunde, (const void *)MyKundenPTR->Daten, sizeof(KundenDaten) );
			MyAdressPTR->GetElementNr( RempfKunde.Adresse );
			memcpy( (void *)&RempfAdress, (const void *)MyAdressPTR->Daten, sizeof(AdressDaten) );

			// Vorgaben des Kunden übernehmen
			Daten->Waehrung_KZ		= RempfKunde.Waehrung_KZ;
			Daten->Preissystem		= RempfKunde.Preissystem;
			Daten->MWStBefreit		= RempfKunde.MWStBefreit;
			Daten->ZuAbNummer[0]		= RempfKunde.ZuAbNummer;
			// Versandart nur übernehmen, wenn vom Warenempfänger
			// nicht bereits Vorgaben vorhanden sein können
			if( Daten->WareEmpf == 0 )
				Daten->Versandart		= RempfKunde.Versandart;

			// wurde eine Zu-/Abschlägsnummer übernommen?
			if( Daten->ZuAbNummer[0] )
			{
				// Entsprechende Wert und Typ aus den Einstellungen
				// holen und übernehmen
				Daten->ZuAbTyp[0]		= MyPrefsPTR->Daten->ZuAbTyp[(RempfKunde.ZuAbNummer - 1)];
				if( Daten->ZuAbTyp[0]	== 0 ||
					 Daten->ZuAbTyp[0]	== 5 )
					Daten->ZuAbWert[0]	= RempfKunde.ZuAbWert;
				else
					// Bei Monetären Werten, in altes(!) Währungsformat umrechnen, da
					// später alle Werte vom alten auf das neue Format umgerechnet werden,
					// sollte es sich geändert haben
					Daten->ZuAbWert[0]	= MyPrefsPTR->WaehrungUmrechnen(	MWSt_Durchschnitt,
																							RempfKunde.ZuAbWert,
																							RempfKunde.Waehrung_KZ,
																							AltDaten->Waehrung_KZ,
																							0);
			}
			else
			{
				// kein Zu-/Abschlag, Typ und Wert zurücksetzen
				Daten->ZuAbTyp[0]		= 0;
				Daten->ZuAbWert[0]	= 0.0;
			}

			// die Anderen zwei Zu-/Abschläge auf 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 Rechnungsempfänger ein Löschkennzeichen?
			if( RempfKunde.Status	== 0xffff)
				// Rechnungsfehler setzen
				Rechnungsfehler		|= 2;
			else
				// Rechnungsfehler zurücksetzen
				Rechnungsfehler		&= (0xffffffff - 2);

			// Neuberechnungen nötig
			Summe							= TRUE;
			Versandaender				= TRUE;
			Versanderm					= TRUE;
		}
		else
		{
			// Rechnungsempfänger auf 0 gesetzt, Felder initialisieren
			MyKundenPTR->Initialisiere( (STRPTR)&RempfKunde );
			MyAdressPTR->Initialisiere( (STRPTR)&RempfAdress );
			// Fehler Rechnungsempfänger gelöscht, entfernen
			Rechnungsfehler &= (0xffffffff - 2);
		}
	}

	// Preissystem geändert, dann kennzeichen setzen
	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änderter Warenempfänger?
	if( Daten->WareEmpf != AltDaten->WareEmpf )
	{
		// Eingegebener Warenempfänger kann nicht grösser
		// als die maximale Kundenzahl sein
		if( Daten->WareEmpf > MyKundenPTR->ElementeVorhanden() )
			Daten->WareEmpf = MyKundenPTR->ElementeVorhanden();

		// Warenempfänger > 0 ?
		if( Daten->WareEmpf )
		{
			// Aus Datenbank lesen und merken
			MyKundenPTR->GetElementNr( (ULONG)Daten->WareEmpf );
			memcpy( (void *)&WempfKunde, (const void *)MyKundenPTR->Daten, sizeof(KundenDaten) );
			MyAdressPTR->GetElementNr( WempfKunde.Adresse );
			memcpy( (void *)&WempfAdress, (const void *)MyAdressPTR->Daten, sizeof(AdressDaten) );

			// Versandart übernehmen
			Daten->Versandart		= WempfKunde.Versandart;

			// Wenn der Warenempfänger gelöscht wurde, Fehler
			// setzen
			if( WempfKunde.Status == 0xffff)
				Rechnungsfehler |= 1;
			else
				Rechnungsfehler &= (0xffffffff - 1);
		}
		else
		{
			// Kein Warenempfänger, also Merkbereich initialisieren
			// Fehler eines logisch gelöschten Warenempfänger löschen
			MyKundenPTR->Initialisiere( (STRPTR)&WempfKunde );
			MyAdressPTR->Initialisiere( (STRPTR)&WempfAdress );
			Rechnungsfehler &= (0xffffffff - 1);
		}
	}

	// 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;
		}
		// Nochmal schau obs geändert wurde, wenn ja
		// Währungsänderungsroutine aufrufen
		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] );
		}
		Daten->Preisaender	= !VersandErmittelt;
		VersandErmittelt		= FALSE;
		Summe						= TRUE;
		Versandpreis			= TRUE;
	}

	// Geänderte Versandart?
	if( AltDaten->Versandart != Daten->Versandart )
	{
		// Plausibilitätsprüfung
		if( Daten->Versandart		>= MyVersandPTR->ElementeVorhanden() )
			Daten->Versandart			= MyVersandPTR->ElementeVorhanden();

		// Alte Versandart zurücksetzen (Mengenfortschreibung)
		i = Daten->Versandart;
		Daten->Versandart			= AltDaten->Versandart;
		VersandArtPosAlt			= VersandArtPos;
		VersandArtPos				= -1;
		Versandaenderung();
		// neue Versandart lesen und Daten übernehmen
		Daten->Versandart			= i;
		Daten->Preisaender		= FALSE;
		MyVersandPTR->GetElementNr( Daten->Versandart + 1 );
		VersandNr					= MyVersandPTR->AktElementNr;
		Daten->VersMWSt			= MyVersandPTR->Daten->MWSt;
		Daten->ZusMWSt				= MyVersandPTR->Daten->ZusMWSt;
		Daten->SkoRab				= MyVersandPTR->Daten->SkoRab;
		memcpy( (void *)&VersandDaten, (const void *)MyVersandPTR->Daten, sizeof(VersandDaten) );
		
		// Kennzeichen sezten für
		Summe							= TRUE;
		Versandaender				= TRUE;
		if( Versandpreis			== FALSE )
			Versanderm				= TRUE;
	}

	// Zu-/Abschläge prüfen
	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;
	}

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

	// Versandänderung?
	if( Versandaender )
		Versandaenderung();
	
	// Komplette Preisneuermittlung?
	if( Preisneu )
		MyRechnungArtikel->PreisermittlungAlle();

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

	// Summen neu errechnen?
	if( Summe )
		Summenaenderung( Versanderm );

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

// Neuen Beleg einfügen
void ARechnung::NeuerDatensatz()
{
	VersandArtPos		= -1;
	VersandArtPosAlt	= -1;
	DataBase::NeuerDatensatz();
};

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

// Versandart und -kosten ermitteln
void ARechnung::Versandermitteln()
{
	// zwischenmerken der aktuellen Versandkosten
	DOUBLE ZW_VersandMerk	= Daten->Versandkosten;
	// aktuellen Key in der Versandarten-DB merken
	VersandArtPosAlt			= VersandArtPos;
	// und aktuellen auf -1 (neu ermitteln) stellen
	VersandArtPos				= -1;

	// Prüfen ob manuelle Änderung an den Versankosten
	// stattgefunden hat, Wert nur initialisieren, wenn
	// noch nichts eingetippt wurde
	if( Daten->Preisaender	== FALSE )
	{
		Daten->Versandkosten	= 0;
		Daten->Zusatzkosten	= 0;
		Versandkosten[0]		= 0;
		Versandkosten[1]		= 0;
		Versandkosten[2]		= 0;
		Versandkosten[3]		= 0;
		Zusatzkosten[0]		= 0;
		Zusatzkosten[1]		= 0;
		Zusatzkosten[2]		= 0;
		Zusatzkosten[3]		= 0;
	}
	// Gewichtstabelle in der Versandart durchrauschen, bis eine passende
	// Position gefunden wurde, oder das Ende erreicht wurde.
	for( LONG LongWert = 9; (LongWert >= 0) && (VersandArtPos < 0); LongWert--)
	{
		// Wenn eine Versandvorgabe vorhanden ist und das Gewicht kleiner
		// oder gleich dem Gewicht des aktuellen Auftrags ist...
		if( (VersandDaten.AbGewicht[LongWert] <= ZW_Gewicht) && (VersandDaten.Versandkosten[LongWert] > 0) )
		{
			// Position merken
			VersandArtPos			= LongWert;
			// Noch keine manuelle Versandkosteneingabe
			if( Daten->Preisaender	== FALSE )
			{
				// Werte in beiden Währungen Brutto wie Netto errechnen
				for( ULONG i = 0; i < 4; i++ )
				{
					Versandkosten[i]	= MyPrefsPTR->WaehrungUmrechnen(	MWSt[VersandDaten.MWSt],
																						VersandDaten.Versandkosten[LongWert],
																						VersandDaten.Waehrung_KZ,
																						i,
																						MWSt_Typ[VersandDaten.MWSt]);
					Zusatzkosten[i]	= MyPrefsPTR->WaehrungUmrechnen(	MWSt[VersandDaten.ZusMWSt],
																						VersandDaten.Zusatzkosten[LongWert],
																						VersandDaten.Waehrung_KZ,
																						i,
																						MWSt_Typ[VersandDaten.ZusMWSt]);
				}
				// Werte für aktuell ausgewählte Währung in die DB-Struktur
				// stellen
				Daten->Versandkosten = Versandkosten[Daten->Waehrung_KZ];
				Daten->Zusatzkosten	= Zusatzkosten[Daten->Waehrung_KZ];
			}
		}
	}
	// Versandart geändert? entsprechende Routine aufrufen, umd die
	// Fortschreibungen abzuhandeln
	if( VersandArtPos		!= VersandArtPosAlt )
		Versandaenderung();

	// Versandkosten geändert? Entsprechendes Kennzeichen setzen!
	VersandErmittelt		= ( ZW_VersandMerk	!= Daten->Versandkosten );
};

// 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 ARechnung::UpdateSatz( STRPTR AlteVersion )
{
	// Pointer auf die Datenbank (ist zu diesem Zeitpunkt sonst
	// noch nicht sichergestellt
	Daten = (ARechnungDaten *)UserData;

	// Alte Versionen deren Versionsnummern noch linksbündig ange-
	// geben waren (vor Version 0.80)
	if( AlteVersion[1] == '.' )
	{
		Daten->ADatum.ds_Days		= Daten->BestDatum.ds_Days;
		Daten->ADatum.ds_Minute		= Daten->BestDatum.ds_Minute;
		Daten->ADatum.ds_Tick		= Daten->BestDatum.ds_Tick;
		Daten->BestDatum.ds_Days	= 0;
		Daten->BestDatum.ds_Minute	= -1;
		Daten->BestDatum.ds_Tick	= -1;

		if( Daten->RStatus > ARS_Angebot )
			Daten->RStatus++;
		else
		{
			ULONG i = Daten->ErsterArtikel;
			DOUBLE ZW_Gewicht = 0;

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

			MyVersandPTR->GetElementNr( (ULONG)Daten->Versandart + 1 );

			VersandArtPos		= -1;

			for( LONG LongWert = 9; (LongWert >= 0) && (VersandArtPos < 0); LongWert--)
			{
				if( (MyVersandPTR->Daten->AbGewicht[LongWert] <= ZW_Gewicht) &&
					 (MyVersandPTR->Daten->Versandkosten[LongWert] > 0) )
					VersandArtPos			= LongWert;
			}

			if( VersandArtPos >= 0 &&
				 MyVersandPTR->Daten->Artikel[VersandArtPos] > 0 &&
				 MyVersandPTR->Daten->Menge[VersandArtPos]	> 0 )
				MyArtikelPTR->Mengenaenderung( 0x04, MyVersandPTR->Daten->Artikel[VersandArtPos],
														 MyVersandPTR->Daten->Menge[VersandArtPos] );
		}
	}

	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 ARechnung::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

	UBYTE	Konto	= 0;				// 0 = Kundenkonto unverändert
										// 1 = Rechnungssumme vom Kundenkonto abziehen
										// 2 = Rechnungssumme zum Kundenkonto addieren

	// Prüfen des neuen Status
	switch( StatusNeu )
	{
		case ARS_Angebot:
			Update = 0x04;
			Konto  = 2;
			break;
		case ARS_Bestellt:
			Update = 0x01;
			Konto  = 2;
			break;
		case ARS_Lieferschein:
		case ARS_Rechnung:
		case ARS_Mahnung_1:
		case ARS_Mahnung_2:
		case ARS_Mahnung_3:
		case ARS_Mahnverfahren:
		case ARS_Abgeschrieben:
			Update = 0x80;
			Konto  = 1;
			break;
		case ARS_Storniert:
			Konto  = 2;
			break;
		case ARS_Bezahlt:
			Update = 0x80;
			Konto  = 2;
			break;
	}

	// Prüfen des alten Status unter Einbeziehung gesetzter UpDate-
	// kennzeichen aus der Prüfung des neuen Status
	switch( StatusAlt )
	{
		case ARS_Angebot:
			Update |= 0x08;
			if( Konto == 2 )
				Konto = 0;
			break;
		case ARS_Bestellt:
			Update |= 0x02;
			if( Konto == 2 )
				Konto = 0;
			break;
		case ARS_Lieferschein:
		case ARS_Rechnung:
		case ARS_Mahnung_1:
		case ARS_Mahnung_2:
		case ARS_Mahnung_3:
		case ARS_Mahnverfahren:
		case ARS_Abgeschrieben:
			Update |= 0x40;
			if( Konto == 1 )
				Konto = 0;
			break;
		case ARS_Storniert:
			if( Konto == 2 )
				Konto = 0;
			break;
		case ARS_Bezahlt:
			Update |= 0x40;
			if( Konto == 2 )
				Konto = 0;
			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)
				{
					SuchArtikel->ArtikelMerker = MyArtikelPTR->Mengenaenderung( Update,	SuchArtikel->ZuOrdnungTab.Artikelnummer,
																												SuchArtikel->ZuOrdnungTab.Artikelanzahl,
																												&SuchArtikel->MengeMerker );
					memcpy( (void *)&SuchArtikel->ArtikelDaten, (const void *)MyArtikelPTR->Daten, sizeof(ArtikelDaten) );

					if( SuchArtikel->ArtikelMerker > 0 )
					{
						SuchArtikel->Artikelfehler |= 4;
						ReturnWert = TRUE;
					}
					else
						SuchArtikel->Artikelfehler &= (0xffffffff - 4);
				}
				SuchArtikel = SuchArtikel->NextArtikel;
			}

			if( VersandArtPos > -1 &&
				 VersandDaten.Artikel[ VersandArtPos ] > 0 &&
				 VersandDaten.Menge[ VersandArtPos ] > 0 )
			{
				MyArtikelPTR->Mengenaenderung( Update, VersandDaten.Artikel[ VersandArtPos ],
																	VersandDaten.Menge[ VersandArtPos ] );
			}
			break;
	}

	// Update des Kundenkontos
	if( (Konto > 0) && (Daten->RechEmpf > 0) )
	{
		MyKundenPTR->GetElementNr( Daten->RechEmpf );

		if( Daten->Waehrung_KZ > 1 )
			Update = 3;
		else
			Update = 1;

		if( Konto == 1 )
			MyKundenPTR->Daten->Kontostand -= Gesamtsumme[Update];
		else
			MyKundenPTR->Daten->Kontostand += Gesamtsumme[Update];

		if( (MyKundenPTR->Daten->KreditLimit > 0) &&
			 (MyKundenPTR->Daten->Kontostand < (0 - MyKundenPTR->Daten->KreditLimit)) )
		{
			Rechnungsfehler |= 4;
			ReturnWert = TRUE;
		}
		else
			Rechnungsfehler &= (0xffffffff - 4);

		MyKundenPTR->UpDateElement();

		memcpy( (void *)&RempfKunde, (const void *)MyKundenPTR->Daten, sizeof(KundenDaten) );
	}
	return ReturnWert;
};

// Änderung der Versandart
void ARechnung::Versandaenderung()
{
	UBYTE Update = 0;				// 0x00 = Kein Update
	UBYTE Update2 = 0;			// 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

	// Entsprechend dem aktuellen Rechnungsstatus Update-Kennzeichen
	// setzen, sowohl fürs Händling der alten, wie auch der neuen
	// Versandkosten
	switch( Daten->RStatus )
	{
		case ARS_Angebot:
			Update	= 0x08;
			Update2	= 0x04;
			break;
		case ARS_Bestellt:
			Update	= 0x02;
			Update2	= 0x01;
			break;
		case ARS_Lieferschein:
		case ARS_Rechnung:
		case ARS_Mahnung_1:
		case ARS_Mahnung_2:
		case ARS_Mahnung_3:
		case ARS_Mahnverfahren:
		case ARS_Abgeschrieben:
		case ARS_Bezahlt:
			Update	= 0x40;
			Update2	= 0x80;
			break;
	}
	// Update wirklich auch nur dann durchführen, wenn eine Änderung der
	// Versandposition stattgefunden hat
	if( VersandArtPosAlt != VersandArtPos )
	{
		// Updatekennzeichen gesetzt?
		// Gültige alte Versandposition vorhanden, die auch upgedated werden kann?
		// Ist der Versandposition ein bestandsführender Artikel zugeordnet?
		// Hat der Artikel auch eine zugeordnete Menge?
		if( Update > 0 &&
			 VersandArtPosAlt > -1 &&
			 VersandDaten.Artikel[ VersandArtPosAlt ] > 0 &&
			 VersandDaten.Menge[ VersandArtPosAlt ] > 0 )
		{
			// Artikel updaten
			MyArtikelPTR->Mengenaenderung( Update, VersandDaten.Artikel[ VersandArtPosAlt ],
																VersandDaten.Menge[ VersandArtPosAlt ] );
		}
		// Updatekennzeichen gesetzt?
		// Gültige neu Versandposition vorhanden, die auch upgedated werden kann?
		// Ist der Versandposition ein bestandsführender Artikel zugeordnet?
		// Hat der Artikel auch eine zugeordnete Menge?
		if( Update2 > 0 &&
			 VersandArtPos > -1 &&
			 VersandDaten.Artikel[ VersandArtPos ] > 0 &&
			 VersandDaten.Menge[ VersandArtPos ] > 0 )
		{
			// Artikel updaten
			MyArtikelPTR->Mengenaenderung( Update2, VersandDaten.Artikel[ VersandArtPos ],
																VersandDaten.Menge[ VersandArtPos ] );
		}
	}
};

// Rechnungssumme geändert?
// Übergabe: Versandkennzeichen:	true = Versandkosten neu ermitteln
//												false = Versandkosten nicht neu ermitteln
void ARechnung::Summenaenderung( BOOL VersandKZ )
{
	ULONG i;
	DOUBLE AlteSumme[4] = {	Gesamtsumme[0],
									Gesamtsumme[1],
									Gesamtsumme[2],
									Gesamtsumme[3] };

	// Alles neu ausrechnen
	ErrechneSummen( VersandKZ );

	switch( Daten->RStatus )
	{
		case ARS_Lieferschein:
		case ARS_Rechnung:
		case ARS_Mahnung_1:
		case ARS_Mahnung_2:
		case ARS_Mahnung_3:
		case ARS_Mahnverfahren:
		case ARS_Abgeschrieben:
			// Bruttokennzeichen zur aktuellen Währung ermitteln
			if( Daten->Waehrung_KZ > 1 )
				i = 3;
			else
				i = 1;

			// Wenn die Gesamtsumme sich geändert hat und ein Rechnungs-
			// empfänger eingetragen ist
			if( (Gesamtsumme[i] != AlteSumme[i]) && (Daten->RechEmpf > 0) )
			{
				// Rechnungsempfänger lesen
				MyKundenPTR->GetElementNr( Daten->RechEmpf );

				// Kontostand aktualisieren
				MyKundenPTR->Daten->Kontostand -= (Gesamtsumme[i] - AlteSumme[i]);

				// Kreditlimit prüfen und eventuell Fehlerkennzeichen setzen
				// oder entfernen
				if( (MyKundenPTR->Daten->KreditLimit > 0.0) &&
					 (MyKundenPTR->Daten->Kontostand < (0.0 - MyKundenPTR->Daten->KreditLimit)) )
				{
					Rechnungsfehler |= 4;
				}
				else
					Rechnungsfehler &= (0xffffffff - 4);

				// Zurück in die Datenbank damit
				MyKundenPTR->UpDateElement();

				// Das ganze in den Rechnungszwischenspeicherbereich kopieren
				memcpy( (void *)&RempfKunde, (const void *)MyKundenPTR->Daten, sizeof(KundenDaten) );
			}
			break;
	}
};

// Automatische Mahnfunktion
// Übergaben:	Status:		1 = Liste der zu mahnenden Rechnungen erstellen
//									2 = Mahnungen drucken
//					MahnListe:	Liste, in die die gemahnten Rechnungen gestellt werden
// Rückgabe:	Anzahl Mahnungen
ULONG ARechnung::Mahnautomatik( UBYTE Status, ListenClass* MahnListe )
{

	ULONG AnzMahn	= 0;

	if( Status )
	{
		LONG	Tage[3];
		struct DateStamp	Heute;
		ULONG i, j;

		STRPTR Dokument;

		WZ_LockWindows( surface );

		MyLocalePTR->AktDateTime(&Heute);

		Tage[0]	= Heute.ds_Days - MyPrefsPTR->Daten->MahnNachTagen[0];
		Tage[1]	= Heute.ds_Days - MyPrefsPTR->Daten->MahnNachTagen[1];
		Tage[2]	= Heute.ds_Days - MyPrefsPTR->Daten->MahnNachTagen[2];

		GetFirstElement();
		j = ElementeVorhanden();

		for( i = 0; i < j; i++ )
		{
			if( Daten->Status != 0xffff )
			{
				Dokument = NULL;

				switch( Daten->RStatus )
				{
					case ARS_Rechnung:	// Unbezahlte Rechnung
						if( Daten->RDatum.ds_Days < Tage[0] )
							Dokument = MyPrefsPTR->Daten->Mahndokument[0];
						break;
					case ARS_Mahnung_1:	// 1. Mahnung
						if( Daten->MahnDatum[0].ds_Days < Tage[1] )
							Dokument = MyPrefsPTR->Daten->Mahndokument[1];
						break;
					case ARS_Mahnung_2:	// 2. Mahnung
						if( Daten->MahnDatum[1].ds_Days < Tage[2] )
							Dokument = MyPrefsPTR->Daten->Mahndokument[2];
						break;
				}

				if( Dokument )
				{
					AnzMahn++;
					if( Status == 1 )
					{
						SuchListeAnhaengen( MahnListe );
					}
					else
					{
						Daten->MahnDatum[(Daten->RStatus - 3)].ds_Days		= Heute.ds_Days;
						Daten->MahnDatum[(Daten->RStatus - 3)].ds_Minute	= Heute.ds_Minute;
						Daten->MahnDatum[(Daten->RStatus - 3)].ds_Tick		= Heute.ds_Tick;
						Daten->RStatus++;
						UpDateElement();

						MyVersandPTR->GetElementNr( (ULONG)Daten->Versandart + 1 );
						if( *MyVersandPTR->Daten->Dokument[(Daten->RStatus * 6)]			== 0 &&
							 *MyVersandPTR->Daten->Dokument[((Daten->RStatus * 6) + 1)]	== 0 &&
							 *MyVersandPTR->Daten->Dokument[((Daten->RStatus * 6) + 2)]	== 0 &&
							 *MyVersandPTR->Daten->Dokument[((Daten->RStatus * 6) + 3)]	== 0 &&
							 *MyVersandPTR->Daten->Dokument[((Daten->RStatus * 6) + 4)]	== 0 &&
							 *MyVersandPTR->Daten->Dokument[((Daten->RStatus * 6) + 5)]	== 0 )
						{
							if( *Dokument )
								MyAllgemein.Drucken( 0, NULL, NULL, NULL, NULL, NULL, Dokument, (i+1), (i+1),
															this, DRU_DRUCK, MyPrefsPTR->Daten->SchnellDruckFragen );
						}
						else
						{
							for(ULONG k = 0; k < 6;k++)
							{
								if( *MyVersandPTR->Daten->Dokument[((Daten->RStatus * 6) + k)] )
									MyAllgemein.Drucken( 0, NULL, NULL, NULL, NULL, NULL,
																MyVersandPTR->Daten->Dokument[((Daten->RStatus * 6) + k)], (i+1), (i+1),
																this, DRU_DRUCK, MyPrefsPTR->Daten->SchnellDruckFragen );
							}
						}
					}
				}
			}

			GetNextElement();
		}

		WZ_UnlockWindows( surface );
	}

	return AnzMahn;
};

// Druckvorbereitungen
// Übergabe:	os = Pointer auf den Ausgabestream
//					Art	'1' = Einzelbeleg
//							'2' = Liste
//							'3' = kompakte Liste
void ARechnung::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->Verkaufernummer );
			MyMitarbeiterPTR->DataBase::PrintString( os, "/Verk" );

			// Daten des Rechnungsempfängers
			MyKundenPTR->PrintString( os, "/Rempf", &RempfKunde, &RempfAdress );

			// Daten des Warenemempfängers
			if( Daten->WareEmpf == 0)
				MyKundenPTR->PrintString( os, "/Wempf", &RempfKunde, &RempfAdress );
			else
				MyKundenPTR->PrintString( os, "/Wempf", &WempfKunde, &WempfAdress );
			break;
		case '2':
			// Adressdaten der Ausstellenden Niederlassung
			MyNiederlassungPTR->DataBase::PrintTabelle( os, Art, Daten->Niederlassung, Daten->Niederlassung, NULL, NULL );

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

			// Daten des Rechnungsempfängers
			MyKundenPTR->PrintTabelle( os, Art, Daten->RechEmpf, Daten->RechEmpf, NULL, NULL, &RempfKunde, &RempfAdress );

			// Daten des Warenemempfängers
			if( Daten->WareEmpf == 0 )
				MyKundenPTR->PrintTabelle( os, Art, Daten->RechEmpf, Daten->RechEmpf, NULL, NULL, &RempfKunde, &RempfAdress );
			else
				MyKundenPTR->PrintTabelle( os, Art, Daten->WareEmpf, Daten->WareEmpf, NULL, NULL, &WempfKunde, &WempfAdress );
		 	break;
		// Bei Art 3 hier keine Aufbereitung
	}

	// Niederlassung
	// Verkäufernummer
	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->Verkaufernummer);
	}
	else
	{
		sprintf(DruckWert[j++].Wert, "%lu", Daten->Niederlassung);
		sprintf(DruckWert[j++].Wert, "%lu", Daten->Verkaufernummer);
	}

	// Rechnungsempfaenger
	if( Daten->RechEmpf == 0 )
	{
		DruckWert[j].Wert[0]		= '0';
		DruckWert[j++].Wert[1]	= 0;
	}
	else
	{
		if( MyPrefsPTR->Daten->KundNr == 0 )
		{
			if( MyPrefsPTR->Daten->Nr_Laenge )
				sprintf(DruckWert[j++].Wert, "%0*lu", MyPrefsPTR->Daten->Nr_Laenge, Daten->RechEmpf);
			else
				sprintf(DruckWert[j++].Wert, "%lu", Daten->RechEmpf);
		}
		else
			MyKundenPTR->KundenNrErmitteln(	DruckWert[j++].Wert, MyPrefsPTR->Daten->KundNr,
														Daten->RechEmpf,
														&RempfKunde );
	}

	// Warenempfaenger
	if( Daten->WareEmpf == 0 )
	{
		DruckWert[j].Wert[0]		= '0';
		DruckWert[j++].Wert[1]	= 0;
	}
	else
	{
		if( MyPrefsPTR->Daten->KundNr == 0 )
		{
			if( MyPrefsPTR->Daten->Nr_Laenge )
				sprintf(DruckWert[j++].Wert, "%0*lu", MyPrefsPTR->Daten->Nr_Laenge, Daten->WareEmpf);
			else
				sprintf(DruckWert[j++].Wert, "%lu", Daten->WareEmpf);
		}
		else
			MyKundenPTR->KundenNrErmitteln(	DruckWert[j++].Wert, MyPrefsPTR->Daten->KundNr,
														Daten->WareEmpf,
														&WempfKunde );
	}

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

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

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

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

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

	// 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 Abgeschrieben
	PSDruckDatum( DruckWert[j++].Wert, &Daten->ABDatum );

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

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

	// Versandbezeichnungen
	PSAufbereit(VersandDaten.Bezeichnung[0], DruckWert[j++].Wert);
	PSAufbereit(VersandDaten.Bezeichnung[1], DruckWert[j++].Wert);
	PSAufbereit(VersandDaten.Bezeichnung[2], DruckWert[j++].Wert);

	// allgemeine Vorbereitungen die bei Ein- und Ausgangsbeleg identisch sind
	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 ARechnung::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, "OB.STATE", (STRPTR)Buffer, strlen(Buffer) );

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

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

	// Rechnungsempfänder
	ReturnWert += MyKundenPTR->GetRexx( rxmsg, Daten->RechEmpf, "OB.INVOICEE.", &RempfKunde, &RempfAdress );

	// Warenempfänger
	if( Daten->WareEmpf == 0)
		ReturnWert += MyKundenPTR->GetRexx( rxmsg, Daten->RechEmpf, "OB.CONSIGNEE.", &RempfKunde, &RempfAdress );
	else
		ReturnWert += MyKundenPTR->GetRexx( rxmsg, Daten->WareEmpf, "OB.CONSIGNEE.", &WempfKunde, &WempfAdress );

	// Versanddaten
	ReturnWert += MyVersandPTR->GetRexx( rxmsg, Daten->Versandart, "OB.", &VersandDaten );

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

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

	// Verkäufernummer
	sprintf(Buffer, "%lu", Daten->Verkaufernummer);
	ReturnWert += SetRexxVar( (struct Message *)rxmsg, "OB.SELLER_NUMBER", (STRPTR)Buffer, strlen(Buffer) );

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

	// Warenempfaenger
	sprintf(Buffer, "%lu", Daten->WareEmpf);
	ReturnWert += SetRexxVar( (struct Message *)rxmsg, "OB.CONSIGNEE_NUMBER", (STRPTR)Buffer, strlen(Buffer) );

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

	// Angebotsdatum
	MyLocalePTR->FormatDateC( Buffer, &Daten->ADatum, "%Y%m%d");
	ReturnWert += SetRexxVar( (struct Message *)rxmsg, "OB.DATE_TENDER", (STRPTR)Buffer, strlen(Buffer) );

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

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

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

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

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

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

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

	// Datum Abgeschrieben
	MyLocalePTR->FormatDateC( Buffer, &Daten->ABDatum, "%Y%m%d");
	ReturnWert += SetRexxVar( (struct Message *)rxmsg, "OB.DATE_WRITING_OFF", (STRPTR)Buffer, strlen(Buffer) );

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

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

	// Versandart
	sprintf(Buffer, "%lu", Daten->Versandart);
	ReturnWert += SetRexxVar( (struct Message *)rxmsg, "OB.NUMBER_DISPATCH", (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 ARechnung::SetRexx( struct RexxMsg *rxmsg, ULONG Position )
{
	STRPTR	Buffer = NULL;
	ULONG		ReturnWert = 0;

	GetElementNr( Position );
	LesenGesamtRech();

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

	// Verkäufernummer
	Daten->Verkaufernummer		= MyARexx.GetRexxLong("OB.SELLER_NUMBER", 1, MyMitarbeiterPTR->ElementeVorhanden());

	// Versandart
	Daten->Versandart				= MyARexx.GetRexxLong("OB.NUMBER_DISPATCH", 0, MyVersandPTR->ElementeVorhanden());

	// Rechnungsempfaenger
	Daten->RechEmpf				= MyARexx.GetRexxLong("OB.INVOICEE_NUMBER", 0, MyKundenPTR->ElementeVorhanden());

	// Warenempfaenger
	Daten->WareEmpf				= MyARexx.GetRexxLong("OB.CONSIGNEE_NUMBER", 0, MyKundenPTR->ElementeVorhanden());

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

	// Angebotsdatum
	Daten->ADatum					= MyARexx.RexxDatum( "OB.DATE_TENDER" );

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

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

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

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

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

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

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

	// Datum Abgeschrieben
	Daten->ABDatum					= MyARexx.RexxDatum( "OB.DATE_WRITING_OFF" );

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

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



	// 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 ARechnung::Buchen()
{
	// hier kommt mal die Buchung
	return Daten->Gebucht;
};