diff --git a/src/bo4e/bo/ansprechpartner.py b/src/bo4e/bo/ansprechpartner.py index 23adec4eb..c1c01915f 100644 --- a/src/bo4e/bo/ansprechpartner.py +++ b/src/bo4e/bo/ansprechpartner.py @@ -25,19 +25,27 @@ class Ansprechpartner(Geschaeftsobjekt): # required attributes bo_typ: BoTyp = attr.ib(default=BoTyp.ANSPRECHPARTNER) - nachname: str - geschaeftspartner: Geschaeftspartner + nachname: str #: Nachname (Familienname) des Ansprechpartners + geschaeftspartner: Geschaeftspartner #: Der Geschäftspartner, für den dieser Ansprechpartner modelliert wird # optional attributes - anrede: Anrede = attr.ib(default=None) + anrede: Anrede = attr.ib(default=None) #: Mögliche Anrede des Ansprechpartners individuelle_anrede: str = attr.ib(default=None) - titel: Titel = attr.ib(default=None) - vorname: str = attr.ib(default=None) - e_mail_adresse: str = attr.ib(default=None) - kommentar: str = attr.ib(default=None) + """ + Im Falle einer nicht standardisierten Anrede kann hier eine frei definierbare Anrede vorgegeben werden. + Beispiel: "Sehr geehrte Frau Müller, sehr geehrter Herr Dr. Müller" + """ + + titel: Titel = attr.ib(default=None) #: Möglicher Titel des Ansprechpartners + vorname: str = attr.ib(default=None) #: Vorname des Ansprechpartners + e_mail_adresse: str = attr.ib(default=None) #: E-Mail Adresse + kommentar: str = attr.ib(default=None) #: Weitere Informationen zum Ansprechpartner + #: Adresse des Ansprechpartners, falls diese von der Adresse des Geschäftspartners abweicht adresse: Adresse = attr.ib(default=None) - rufnummer: Rufnummer = attr.ib(default=None) - zustaendigkeit: Zustaendigkeit = attr.ib(default=None) + #: Liste der Telefonnummern, unter denen der Ansprechpartner erreichbar ist + rufnummer: Rufnummer = attr.ib(default=None) # todo: make this a list and rename to rufnummern + #: Liste der Abteilungen und Zuständigkeiten des Ansprechpartners + zustaendigkeit: Zustaendigkeit = attr.ib(default=None) # todo: make this a list and rename to "zustaendigkeiten" class AnsprechpartnerSchema(GeschaeftsobjektSchema): diff --git a/src/bo4e/bo/geschaeftsobjekt.py b/src/bo4e/bo/geschaeftsobjekt.py index 746d1ed35..df0f5b2ec 100644 --- a/src/bo4e/bo/geschaeftsobjekt.py +++ b/src/bo4e/bo/geschaeftsobjekt.py @@ -24,19 +24,21 @@ def _create_empty_referenzen_list() -> List[ExterneReferenz]: @attr.s(auto_attribs=True, kw_only=True) -class Geschaeftsobjekt: +class Geschaeftsobjekt: # Base class for all business objects """ - Base class for all business objects + Das BO Geschäftsobjekt ist der Master für alle Geschäftsobjekte. + Alle Attribute, die hier in diesem BO enthalten sind, werden an alle BOs vererbt. """ # required attributes - versionstruktur: str = attr.ib(default="2") - bo_typ: BoTyp = attr.ib(default=BoTyp.GESCHAEFTSOBJEKT) + versionstruktur: str = attr.ib(default="2") #: Version der BO-Struktur aka "fachliche Versionierung" + bo_typ: BoTyp = attr.ib(default=BoTyp.GESCHAEFTSOBJEKT) #: Der Typ des Geschäftsobjektes + # bo_typ is used as discriminator f.e. for databases or deserialization # optional attributes externe_referenzen: Optional[List[ExterneReferenz]] = attr.ib( default=_create_empty_referenzen_list(), validator=attr.validators.instance_of(List) # type:ignore[arg-type] - ) + ) #: Hier können IDs anderer Systeme hinterlegt werden (z.B. eine SAP-GP-Nummer oder eine GUID) class GeschaeftsobjektSchema(CaseConverterSchema): diff --git a/src/bo4e/bo/geschaeftspartner.py b/src/bo4e/bo/geschaeftspartner.py index f094821e9..1641e8dd8 100644 --- a/src/bo4e/bo/geschaeftspartner.py +++ b/src/bo4e/bo/geschaeftspartner.py @@ -20,27 +20,64 @@ @attr.s(auto_attribs=True, kw_only=True) class Geschaeftspartner(Geschaeftsobjekt): """ - Object containing information about a Geschaeftspartner + Mit diesem Objekt können Geschäftspartner übertragen werden. + Sowohl Unternehmen, als auch Privatpersonen können Geschäftspartner sein. + Hinweis: Marktteilnehmer haben ein eigenes BO, welches sich von diesem BO ableitet. + Hier sollte daher keine Zuordnung zu Marktrollen erfolgen. """ # required attributes bo_typ: BoTyp = attr.ib(default=BoTyp.GESCHAEFTSPARTNER) name1: str + """ + Erster Teil des Namens. + Hier kann der Firmenname oder bei Privatpersonen beispielsweise der Nachname dagestellt werden. + Beispiele: Yellow Strom GmbH oder Hagen + """ + # todo: replace name1/2/3 with something more readable. no one wants to deal with that. maybe serialize as name1/2/3 + # but resolve to readable python fields under the hood + gewerbekennzeichnung: bool + """ + Kennzeichnung ob es sich um einen Gewerbe/Unternehmen (gewerbeKennzeichnung = true) + oder eine Privatperson handelt. (gewerbeKennzeichnung = false) + """ + #: Rollen, die die Geschäftspartner inne haben (z.B. Interessent, Kunde) geschaeftspartnerrolle: List[Geschaeftspartnerrolle] = attr.ib(validator=attr.validators.instance_of(List)) + # todo: rename to plural # optional attributes + #: Die Anrede für den GePa, Z.B. "Herr" anrede: Anrede = attr.ib(default=None) name2: Optional[str] = attr.ib(default=None) + """ + Zweiter Teil des Namens. + Hier kann der eine Erweiterung zum Firmennamen oder bei Privatpersonen beispielsweise der Vorname dagestellt werden. + Beispiele: Bereich Süd oder Nina + """ + name3: Optional[str] = attr.ib(default=None) + """ + Dritter Teil des Namens. + Hier können weitere Ergänzungen zum Firmennamen oder bei Privatpersonen Zusätze zum Namen dagestellt werden. + Beispiele: und Afrika oder Sängerin + """ + #: Handelsregisternummer des Geschäftspartners hrnummer: Optional[str] = attr.ib(default=None) + #: Amtsgericht bzw Handelsregistergericht, das die Handelsregisternummer herausgegeben hat amtsgericht: Optional[str] = attr.ib(default=None) + #: Bevorzugte Kontaktwege des Geschäftspartners kontaktweg: List[Kontaktart] = attr.ib(default=[]) + #: Die Steuer-ID des Geschäftspartners; Beispiel: "DE 813281825" umsatzsteuer_id: Optional[str] = attr.ib(default=None) + #: Die Gläubiger-ID welche im Zahlungsverkehr verwendet wird; Z.B. "DE 47116789" glaeubiger_id: Optional[str] = attr.ib(default=None) + #: E-Mail-Adresse des Ansprechpartners. Z.B. "info@hochfrequenz.de" e_mail_adresse: Optional[str] = attr.ib(default=None) + #: Internetseite des Marktpartners website: Optional[str] = attr.ib(default=None) - partneradresse: Adresse = attr.ib(default=None) + #: Adressen der Geschäftspartner, an denen sich der Hauptsitz befindet + partneradresse: Adresse = attr.ib(default=None) # todo: is it plural or not? the docs are bad class GeschaeftspartnerSchema(GeschaeftsobjektSchema): diff --git a/src/bo4e/bo/marktlokation.py b/src/bo4e/bo/marktlokation.py index 409a7f042..f8cb5f6b3 100644 --- a/src/bo4e/bo/marktlokation.py +++ b/src/bo4e/bo/marktlokation.py @@ -49,28 +49,78 @@ def _validate_marktlokations_id(self, marktlokations_id_attribute, value): # required attributes bo_typ: BoTyp = attr.ib(default=BoTyp.MARKTLOKATION) + #: Identifikationsnummer einer Marktlokation, an der Energie entweder verbraucht, oder erzeugt wird. marktlokations_id: str = attr.ib(validator=_validate_marktlokations_id) + #: Sparte der Marktlokation, z.B. Gas oder Strom sparte: Sparte + #: Kennzeichnung, ob Energie eingespeist oder entnommen (ausgespeist) wird energierichtung: Energierichtung + #: Die Bilanzierungsmethode, RLM oder SLP bilanzierungsmethode: Bilanzierungsmethode netzebene: Netzebene + """ + Netzebene, in der der Bezug der Energie erfolgt. + Bei Strom Spannungsebene der Lieferung, bei Gas Druckstufe. + Beispiel Strom: Niederspannung Beispiel Gas: Niederdruck. + """ # optional attributes + #: Verbrauchsart der Marktlokation. verbrauchsart: Verbrauchsart = attr.ib(default=None) + #: Gibt an, ob es sich um eine unterbrechbare Belieferung handelt unterbrechbar: bool = attr.ib(default=None) + #: Codenummer des Netzbetreibers, an dessen Netz diese Marktlokation angeschlossen ist. netzbetreibercodenr: str = attr.ib(default=None) + #: Typ des Netzgebietes, z.B. Verteilnetz gebietstyp: Gebiettyp = attr.ib(default=None) - netzgebietsnr: str = attr.ib(default=None) + #: Die ID des Gebietes in der ene't-Datenbank + netzgebietsnr: str = attr.ib(default=None) # todo: rename to "id" (see 2021-12-15 update) + #: Bilanzierungsgebiet, dem das Netzgebiet zugeordnet ist - im Falle eines Strom Netzes bilanzierungsgebiet: str = attr.ib(default=None) + #: Codenummer des Grundversorgers, der für diese Marktlokation zuständig ist grundversorgercodenr: str = attr.ib(default=None) + #: Die Gasqualität in diesem Netzgebiet. H-Gas oder L-Gas. Im Falle eines Gas-Netzes gasqualitaet: Gasqualitaet = attr.ib(default=None) + #: Geschäftspartner, dem diese Marktlokation gehört endkunde: Geschaeftspartner = attr.ib(default=None) - zugehoerige_messlokation: Messlokationszuordnung = attr.ib(default=None) + zugehoerige_messlokation: Messlokationszuordnung = attr.ib(default=None) # todo: rename to plural + """ + Aufzählung der Messlokationen, die zu dieser Marktlokation gehören. + Es können 3 verschiedene Konstrukte auftreten: + + Beziehung 1 : 0 : Hier handelt es sich um Pauschalanlagen ohne Messung. D.h. die Verbrauchsdaten sind direkt über + die Marktlokation abgreifbar. + Beziehung 1 : 1 : Das ist die Standard-Beziehung für die meisten Fälle. In diesem Fall gibt es zu einer + Marktlokation genau eine Messlokation. + Beziehung 1 : N : Hier liegt beispielsweise eine Untermessung vor. Der Verbrauch einer Marklokation berechnet sich + hier aus mehreren Messungen. + + Es gibt praktisch auch noch die Beziehung N : 1, beispielsweise bei einer Zweirichtungsmessung bei der durch eine + Messeinrichtung die Messung sowohl für die Einspreiseseite als auch für die Aussspeiseseite erfolgt. + Da Abrechnung und Bilanzierung jedoch für beide Marktlokationen getrennt erfolgt, werden nie beide Marktlokationen + gemeinsam betrachtet. Daher lässt sich dieses Konstrukt auf zwei 1:1-Beziehung zurückführen, + wobei die Messlokation in beiden Fällen die gleiche ist. + + In den Zuordnungen sind ist die arithmetische Operation mit der der Verbrauch einer Messlokation zum Verbrauch einer + Marktlokation beitrögt mit aufgeführt. + Der Standard ist hier die Addition. + """ # only one of the following three optional attributes can be set + #: Die Adresse, an der die Energie-Lieferung oder -Einspeisung erfolgt lokationsadresse: Adresse = attr.ib(default=None) geoadresse: Geokoordinaten = attr.ib(default=None) + """ + Alternativ zu einer postalischen Adresse kann hier ein Ort mittels Geokoordinaten angegeben werden + (z.B. zur Identifikation von Sendemasten). + """ katasterinformation: Katasteradresse = attr.ib(default=None) + """ + Alternativ zu einer postalischen Adresse und Geokoordinaten kann hier eine Ortsangabe mittels Gemarkung und + Flurstück erfolgen. + """ + + # todo: add kundengruppe @lokationsadresse.validator @geoadresse.validator diff --git a/src/bo4e/bo/marktteilnehmer.py b/src/bo4e/bo/marktteilnehmer.py index 4a46178d4..73aa888c9 100644 --- a/src/bo4e/bo/marktteilnehmer.py +++ b/src/bo4e/bo/marktteilnehmer.py @@ -22,11 +22,15 @@ class Marktteilnehmer(Geschaeftspartner): # required attributes bo_typ: BoTyp = attr.ib(default=BoTyp.MARKTTEILNEHMER) + #: Gibt im Klartext die Bezeichnung der Marktrolle an marktrolle: Marktrolle + #: Gibt die Codenummer der Marktrolle an rollencodenummer: str = attr.ib(validator=matches_re(r"^\d{13}$")) + #: Gibt den Typ des Codes an rollencodetyp: Rollencodetyp # optional attributes + #: Die 1:1-Kommunikationsadresse des Marktteilnehmers; Diese wird in der Marktkommunikation verwendet. makoadresse: str = attr.ib(default=None) diff --git a/src/bo4e/bo/messlokation.py b/src/bo4e/bo/messlokation.py index 8fdaa8857..89d065acb 100644 --- a/src/bo4e/bo/messlokation.py +++ b/src/bo4e/bo/messlokation.py @@ -49,24 +49,51 @@ def _validate_messlokations_id(self, messlokations_id_attribute, value): # required attributes bo_typ: BoTyp = attr.ib(default=BoTyp.MESSLOKATION) + #: Die Messlokations-Identifikation; Das ist die frühere Zählpunktbezeichnung messlokations_id: str = attr.ib(validator=_validate_messlokations_id) + #: Sparte der Messlokation, z.B. Gas oder Strom sparte: Sparte # optional attributes + #: Spannungsebene der Messung netzebene_messung: Optional[Netzebene] = attr.ib(default=None) + #: Die Nummer des Messgebietes in der ene't-Datenbank messgebietnr: Optional[str] = attr.ib(default=None) + #: Liste der Hardware, die zu dieser Messstelle gehört geraete: Optional[List[Hardware]] = attr.ib(default=None) - messdienstleistung: Optional[List[Dienstleistung]] = attr.ib(default=None) + #: Liste der Messdienstleistungen, die zu dieser Messstelle gehört + messdienstleistung: Optional[List[Dienstleistung]] = attr.ib(default=None) # todo: rename to plural + #: Zähler, die zu dieser Messlokation gehören messlokationszaehler: Optional[List[Zaehler]] = attr.ib(default=None) # only one of the following two optional codenr attributes can be set grundzustaendiger_msb_codenr: Optional[str] = attr.ib(default=None) + """ + Codenummer des grundzuständigen Messstellenbetreibers, der für diese Messlokation zuständig ist. + (Dieser ist immer dann Messstellenbetreiber, wenn kein anderer MSB die Einrichtungen an der Messlokation betreibt.) + """ grundzustaendiger_msbim_codenr: Optional[str] = attr.ib(default=None) - + """ + Codenummer des grundzuständigen Messstellenbetreibers für intelligente Messsysteme, der für diese Messlokation + zuständig ist. + (Dieser ist immer dann Messstellenbetreiber, wenn kein anderer MSB die Einrichtungen an der Messlokation betreibt.) + """ # only one of the following three optional address attributes can be set messadresse: Optional[Adresse] = attr.ib(default=None) + """ + Die Adresse, an der die Messeinrichtungen zu finden sind. + (Nur angeben, wenn diese von der Adresse der Marktlokation abweicht.) + """ geoadresse: Optional[Geokoordinaten] = attr.ib(default=None) + """ + Alternativ zu einer postalischen Adresse kann hier ein Ort mittels Geokoordinaten angegeben werden + (z.B. zur Identifikation von Sendemasten). + """ katasterinformation: Optional[Katasteradresse] = attr.ib(default=None) + """ + Alternativ zu einer postalischen Adresse und Geokoordinaten kann hier eine Ortsangabe mittels Gemarkung und + Flurstück erfolgen. + """ @messadresse.validator @geoadresse.validator diff --git a/src/bo4e/bo/vertrag.py b/src/bo4e/bo/vertrag.py index 2a3221388..9b3cb319f 100644 --- a/src/bo4e/bo/vertrag.py +++ b/src/bo4e/bo/vertrag.py @@ -39,21 +39,45 @@ class Vertrag(Geschaeftsobjekt): # required attributes bo_typ: BoTyp = attr.ib(default=BoTyp.VERTRAG) + #: Eine im Verwendungskontext eindeutige Nummer für den Vertrag vertragsnummer: str = attr.ib(validator=attr.validators.instance_of(str)) + #: Hier ist festgelegt, um welche Art von Vertrag es sich handelt. vertragsart: Vertragsart = attr.ib(validator=attr.validators.instance_of(Vertragsart)) + #: Gibt den Status des Vertrags an vertragsstatus: Vertragsstatus = attr.ib(validator=attr.validators.instance_of(Vertragsstatus)) + #: Unterscheidungsmöglichkeiten für die Sparte sparte: Sparte = attr.ib(validator=attr.validators.instance_of(Sparte)) + #: Gibt an, wann der Vertrag beginnt (inklusiv) vertragsbeginn: datetime = attr.ib(validator=attr.validators.instance_of(datetime)) + #: Gibt an, wann der Vertrag (voraussichtlich) endet oder beendet wurde (exklusiv) vertragsende: datetime = attr.ib(validator=attr.validators.instance_of(datetime)) - + # todo: add von/bis validator vertragspartner1: Geschaeftspartner = attr.ib(validator=attr.validators.instance_of(Geschaeftspartner)) + """ + Der "erstgenannte" Vertragspartner. + In der Regel der Aussteller des Vertrags. + Beispiel: "Vertrag zwischen Vertragspartner 1 ..." + """ vertragspartner2: Geschaeftspartner = attr.ib(validator=attr.validators.instance_of(Geschaeftspartner)) + """ + Der "zweitgenannte" Vertragspartner. + In der Regel der Empfänger des Vertrags. + Beispiel "Vertrag zwischen Vertragspartner 1 und Vertragspartner 2". + """ vertragsteile: List[Vertragsteil] = attr.ib(validator=at_least_one_vertragsteil) + """ + Der Vertragsteil wird dazu verwendet, eine vertragliche Leistung in Bezug zu einer Lokation + (Markt- oder Messlokation) festzulegen. + """ # optional attributes + #: Beschreibung zum Vertrag beschreibung: Optional[str] = attr.ib(default=None) + #: Festlegungen zu Laufzeiten und Kündigungsfristen vertragskonditionen: Optional[Vertragskonditionen] = attr.ib(default=None) + #: Unterzeichner des Vertragspartners 1 unterzeichnervp1: Optional[List[Unterschrift]] = attr.ib(default=None) + #: Unterzeichner des Vertragspartners 2 unterzeichnervp2: Optional[List[Unterschrift]] = attr.ib(default=None) diff --git a/src/bo4e/bo/zaehler.py b/src/bo4e/bo/zaehler.py index ba005d7b4..6f72131b5 100644 --- a/src/bo4e/bo/zaehler.py +++ b/src/bo4e/bo/zaehler.py @@ -40,20 +40,20 @@ class Zaehler(Geschaeftsobjekt): bo_typ: BoTyp = attr.ib(default=BoTyp.ZAEHLER) zaehlernummer: str = attr.ib( validator=attr.validators.instance_of(str) - ) # Nummerierung des Zählers, vergeben durch den Messstellenbetreiber - sparte: Sparte - zaehlerauspraegung: Zaehlerauspraegung - zaehlertyp: Zaehlertyp - zaehlwerke: List[Zaehlwerk] = attr.ib(validator=at_least_one_zaehlwerk) - tarifart: Tarifart # Spezifikation bezüglich unterstützter Tarifarten + ) #: Nummerierung des Zählers,vergeben durch den Messstellenbetreiber + sparte: Sparte #: Strom oder Gas + zaehlerauspraegung: Zaehlerauspraegung #: Spezifikation die Richtung des Zählers betreffend + zaehlertyp: Zaehlertyp #: Typisierung des Zählers + zaehlwerke: List[Zaehlwerk] = attr.ib(validator=at_least_one_zaehlwerk) #: Die Zählwerke des Zählers + tarifart: Tarifart #: Spezifikation bezüglich unterstützter Tarifarten # optional attributes - zaehlerkonstante: Optional[Decimal] = attr.ib(default=None) # Zählerkonstante auf dem Zähler - eichung_bis: Optional[datetime] = attr.ib(default=None) # Bis zu diesem Datum ist der Zähler geeicht. + zaehlerkonstante: Optional[Decimal] = attr.ib(default=None) #: Zählerkonstante auf dem Zähler + eichung_bis: Optional[datetime] = attr.ib(default=None) #: Bis zu diesem Datum (exklusiv) ist der Zähler geeicht. letzte_eichung: Optional[datetime] = attr.ib( default=None - ) # Zu diesem Datum fand die letzte Eichprüfung des Zählers statt. - zaehlerhersteller: Optional[Geschaeftspartner] = attr.ib(default=None) # Der Hersteller des Zählers. + ) #: Zu diesem Datum fand die letzte Eichprüfung des Zählers statt. + zaehlerhersteller: Optional[Geschaeftspartner] = attr.ib(default=None) #: Der Hersteller des Zählers class ZaehlerSchema(GeschaeftsobjektSchema):