1313// You should have received a copy of the GNU Affero General Public License
1414// along with this program. If not, see <http://www.gnu.org/licenses/>.
1515
16+ using System . Reflection . Metadata ;
1617using Deeplex . Saverwalter . Model ;
1718
1819namespace Deeplex . Saverwalter . BetriebskostenabrechnungService
1920{
21+ public class BetriebskostenrechnungEntry
22+ {
23+ public Betriebskostenrechnung ? Rechnung { get ; }
24+ public double Betrag { get ; }
25+ public BetriebskostenrechnungEntry (
26+ Betriebskostenrechnung ? rechnung ,
27+ Zeitraum zeitraum ,
28+ List < Note > notes )
29+ {
30+ Rechnung = rechnung ;
31+
32+ if ( rechnung != null )
33+ {
34+ var abzug = 0.0 ;
35+ foreach ( var hkvo in rechnung . Umlage . HKVOs )
36+ {
37+ var rechnungen = hkvo . Heizkosten . Betriebskostenrechnungen . Where ( r
38+ => r . BetreffendesJahr == zeitraum . Jahr ) . ToList ( ) ;
39+ foreach ( var r in rechnungen )
40+ {
41+ abzug += r . Betrag * hkvo . Strompauschale ;
42+ }
43+ }
44+
45+ Betrag = rechnung . Betrag - abzug ;
46+
47+ if ( Betrag < 0 )
48+ {
49+ notes . Add ( $ "Pauschale der Heizkosten ist mehr als Allgemeinstromrechnung { Betrag : N2} €", Severity . Warning ) ;
50+ }
51+
52+
53+ }
54+ }
55+ }
56+
2057 public class Abrechnungseinheit
2158 {
22- public Dictionary < Umlage , Betriebskostenrechnung ? > Rechnungen { get ; } = new ( ) ;
59+ public Dictionary < Umlage , BetriebskostenrechnungEntry ? > Rechnungen { get ; } = new ( ) ;
2360 public double BetragKalt { get ; }
2461 public double BetragWarm { get ; }
2562 public double GesamtBetragKalt { get ; }
@@ -59,10 +96,13 @@ public Abrechnungseinheit(List<Umlage> umlagen, Vertrag vertrag, Zeitraum zeitra
5996
6097 foreach ( var umlage in umlagen )
6198 {
62- Rechnungen [ umlage ] = umlage . Betriebskostenrechnungen
63- . SingleOrDefault ( rechnung => rechnung . BetreffendesJahr == zeitraum . Jahr ) ;
99+ // TODO: This limits us to one Rechnung per Umlage per Jahr
100+ Rechnungen [ umlage ] = new BetriebskostenrechnungEntry (
101+ umlage . Betriebskostenrechnungen
102+ . SingleOrDefault ( rechnung => rechnung . BetreffendesJahr == zeitraum . Jahr ) ,
103+ zeitraum , notes ) ;
64104
65- if ( Rechnungen [ umlage ] == null )
105+ if ( Rechnungen [ umlage ] ? . Rechnung == null )
66106 {
67107 notes . Add ( $ "Keine Rechnung für { umlage . Typ . Bezeichnung } gefunden.", Severity . Warning ) ;
68108 }
@@ -83,32 +123,6 @@ public Abrechnungseinheit(List<Umlage> umlagen, Vertrag vertrag, Zeitraum zeitra
83123 Heizkostenberechnungen = CalculateHeizkosten ( rechnungenWarm , wohnung , VerbrauchAnteile , zeitraum , notes ) ;
84124 BetragWarm = Heizkostenberechnungen . Sum ( heizkosten => heizkosten . Betrag ) ;
85125
86- rechnungenWarm . ForEach ( warmeRechnung =>
87- {
88- if ( warmeRechnung . Umlage . HKVO is HKVO hkvo )
89- {
90- var stromRechnung = rechnungenKalt . FirstOrDefault ( kalteRechnung =>
91- kalteRechnung . Umlage . UmlageId == hkvo . Betriebsstrom . UmlageId ) ;
92-
93- if ( stromRechnung == null )
94- {
95- notes . Add ( "Keine Stromrechnung für Heizung gefunden" , Severity . Error ) ;
96- return ;
97- }
98-
99- var delta = warmeRechnung . Betrag * hkvo . Strompauschale ;
100- // Das wird bereits in der Heizkostenberechnung gemacht und als Pauschalbetrag verbucht.
101- // Für die Stromrechnung allerdings muss der Teil noch abgezogen werden.
102- // warmeRechnung.Betrag += delta;
103- stromRechnung . Betrag -= delta ;
104-
105- if ( stromRechnung . Betrag < 0 )
106- {
107- notes . Add ( $ "Pauschale der Heizkosten ({ hkvo . Strompauschale : N2} %) ist mehr als Allgemeinstromrechnung { stromRechnung . Betrag : N2} €", Severity . Warning ) ;
108- }
109- }
110- } ) ;
111-
112126 GesamtBetragWarm = rechnungenWarm . Sum ( e => e . Betrag ) ;
113127 BetragKalt = GetSum ( rechnungenKalt , notes ) ;
114128 GesamtBetragKalt = rechnungenKalt . Sum ( rechnung => rechnung . Betrag ) ;
@@ -129,35 +143,53 @@ public double GetAnteil(Umlage umlage)
129143 } ;
130144 }
131145
132- private double GetSum ( List < Betriebskostenrechnung > rechnungen , List < Note > notes )
146+ private double GetSum ( List < BetriebskostenrechnungEntry > rechnungen , List < Note > notes )
133147 {
134148 var PersZeitanteil = PersonenZeitanteile . Sum ( z => z . Anteil ) ;
135149
136- return rechnungen . Sum ( rechnung => rechnung . Umlage . Schluessel switch
150+ return rechnungen . Sum ( rechnung =>
137151 {
138- Umlageschluessel . NachNutzeinheit => rechnung . Betrag * NEZeitanteil ,
139- Umlageschluessel . NachWohnflaeche => rechnung . Betrag * WFZeitanteil ,
140- Umlageschluessel . NachNutzflaeche => rechnung . Betrag * NFZeitanteil ,
141- Umlageschluessel . NachMiteigentumsanteil => rechnung . Betrag * MEAZeitanteil ,
142- Umlageschluessel . NachPersonenzahl => rechnung . Betrag * PersZeitanteil ,
143- Umlageschluessel . NachVerbrauch => rechnung . Betrag * GetVerbrauchAnteil ( rechnung , notes ) ,
144- _ => 0
152+ if ( rechnung . Rechnung == null )
153+ {
154+ notes . Add ( $ "Keine Rechnung für { rechnung . Rechnung ? . Umlage . Typ . Bezeichnung } gefunden.", Severity . Warning ) ;
155+
156+ return 0 ;
157+ }
158+
159+ return rechnung . Rechnung . Umlage . Schluessel switch
160+ {
161+ Umlageschluessel . NachNutzeinheit => rechnung . Betrag * NEZeitanteil ,
162+ Umlageschluessel . NachWohnflaeche => rechnung . Betrag * WFZeitanteil ,
163+ Umlageschluessel . NachNutzflaeche => rechnung . Betrag * NFZeitanteil ,
164+ Umlageschluessel . NachMiteigentumsanteil => rechnung . Betrag * MEAZeitanteil ,
165+ Umlageschluessel . NachPersonenzahl => rechnung . Betrag * PersZeitanteil ,
166+ Umlageschluessel . NachVerbrauch => rechnung . Betrag * GetVerbrauchAnteil ( rechnung , notes ) ,
167+ _ => 0
168+ } ;
145169 } ) ;
146170 }
147171
148- private double GetVerbrauchAnteil ( Betriebskostenrechnung rechnung , List < Note > notes )
172+ private double GetVerbrauchAnteil ( BetriebskostenrechnungEntry rechnung , List < Note > notes )
149173 {
150- var verbrauchAnteile = VerbrauchAnteile . Where ( anteil => anteil . Umlage == rechnung . Umlage ) . ToList ( ) ;
174+ var lRechnung = rechnung . Rechnung ;
175+ if ( lRechnung == null )
176+ {
177+ notes . Add ( $ "Keine Rechnung für { rechnung . Rechnung ? . Umlage . Typ . Bezeichnung } gefunden.",
178+ Severity . Error ) ;
179+ return 0 ;
180+ }
181+
182+ var verbrauchAnteile = VerbrauchAnteile . Where ( anteil => anteil . Umlage == lRechnung . Umlage ) . ToList ( ) ;
151183 if ( verbrauchAnteile . Count == 0 )
152184 {
153- notes . Add ( $ "Keinen Anteil für { rechnung . Umlage . Typ . Bezeichnung } gefunden",
185+ notes . Add ( $ "Keinen Anteil für { lRechnung . Umlage . Typ . Bezeichnung } gefunden",
154186 Severity . Error ) ;
155187
156188 return 0 ;
157189 }
158190 else if ( verbrauchAnteile . Count > 1 )
159191 {
160- notes . Add ( $ "Mehr als einen Anteil für { rechnung . Umlage . Typ . Bezeichnung } gefunden",
192+ notes . Add ( $ "Mehr als einen Anteil für { lRechnung . Umlage . Typ . Bezeichnung } gefunden",
161193 Severity . Error ) ;
162194
163195 return 0 ;
@@ -167,7 +199,7 @@ private double GetVerbrauchAnteil(Betriebskostenrechnung rechnung, List<Note> no
167199
168200 if ( verbrauchAnteil . Anteil . Count > 1 )
169201 {
170- notes . Add ( $ "Verbrauch von Rechnung { rechnung . Umlage . Typ . Bezeichnung } enthält mehr als einen Zählertypen",
202+ notes . Add ( $ "Verbrauch von Rechnung { lRechnung . Umlage . Typ . Bezeichnung } enthält mehr als einen Zählertypen",
171203 Severity . Error ) ;
172204
173205 return 0 ;
@@ -193,7 +225,7 @@ [.. umlage.Wohnungen.Select(gr => gr.WohnungId).ToList()],
193225 }
194226
195227 private static List < Heizkostenberechnung > CalculateHeizkosten (
196- List < Betriebskostenrechnung > rechnungen ,
228+ List < BetriebskostenrechnungEntry > rechnungen ,
197229 Wohnung wohnung ,
198230 List < VerbrauchAnteil > verbrauchAnteile ,
199231 Zeitraum zeitraum ,
0 commit comments