1use chrono::{DateTime, NaiveDate, TimeZone};
2use serde::Serialize;
3
4use crate::{
5 FeedInRevenueSimplified, GridOperator, Language, Money, PowerTariff, PowerTariffSimplified,
6 TransferFeeSimplified, costs::Cost, feed_in_revenue::FeedInRevenue, helpers,
7 transfer_fee::TransferFee,
8};
9
10#[derive(Debug, Clone, Serialize)]
11#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
12pub struct PriceList {
13 variant: Option<&'static str>,
14 from_date: NaiveDate,
15 monthly_fee: Cost,
17 monthly_production_fee: Cost,
19 transfer_fee: TransferFee,
20 feed_in_revenue: FeedInRevenue,
21 power_tariff: PowerTariff,
22}
23
24impl PriceList {
25 pub const fn builder() -> PriceListBuilder {
26 PriceListBuilder::new()
27 }
28
29 pub const fn variant(&self) -> Option<&'static str> {
30 self.variant
31 }
32
33 pub const fn from_date(&self) -> NaiveDate {
34 self.from_date
35 }
36
37 pub const fn monthly_fee(&self) -> &Cost {
38 &self.monthly_fee
39 }
40
41 pub const fn monthly_production_fee(&self) -> &Cost {
42 &self.monthly_production_fee
43 }
44
45 pub const fn transfer_fee(&self) -> &TransferFee {
46 &self.transfer_fee
47 }
48
49 pub const fn feed_in_revenue(&self) -> &FeedInRevenue {
50 &self.feed_in_revenue
51 }
52
53 pub const fn power_tariff(&self) -> &PowerTariff {
54 &self.power_tariff
55 }
56
57 pub fn kwh_fee<Tz: TimeZone>(
62 &self,
63 timestamp: DateTime<Tz>,
64 spotprice: Money,
65 fuse_size: u16,
66 yearly_consumption: u32,
67 ) -> Money
68 where
69 DateTime<Tz>: Copy,
70 {
71 self.transfer_fee()
72 .kwh_cost(timestamp, spotprice, fuse_size, yearly_consumption)
73 }
74
75 pub fn kwh_revenue<Tz: TimeZone>(
80 &self,
81 timestamp: DateTime<Tz>,
82 spotprice: Money,
83 fuse_size: u16,
84 yearly_consumption: u32,
85 ) -> Money
86 where
87 DateTime<Tz>: Copy,
88 {
89 self.feed_in_revenue()
90 .kwh_revenue(timestamp, spotprice, fuse_size, yearly_consumption)
91 }
92
93 pub fn simplified(
94 &self,
95 op: &GridOperator,
96 fuse_size: u16,
97 yearly_consumption: u32,
98 language: Language,
99 ) -> PriceListSimplified {
100 PriceListSimplified::new(op, self, fuse_size, yearly_consumption, language)
101 }
102}
103
104#[derive(Debug, Clone)]
105pub struct PriceListBuilder {
106 variant: Option<&'static str>,
107 from_date: Option<NaiveDate>,
108 monthly_fee: Option<Cost>,
110 monthly_production_fee: Option<Cost>,
112 transfer_fee: Option<TransferFee>,
113 feed_in_revenue: Option<FeedInRevenue>,
114 power_tariff: Option<PowerTariff>,
115}
116
117impl Default for PriceListBuilder {
118 fn default() -> Self {
119 Self::new()
120 }
121}
122
123impl PriceListBuilder {
124 pub const fn new() -> Self {
125 Self {
126 variant: None,
127 from_date: None,
128 monthly_fee: None,
129 monthly_production_fee: None,
130 transfer_fee: None,
131 feed_in_revenue: None,
132 power_tariff: None,
133 }
134 }
135
136 pub const fn build(self) -> PriceList {
137 PriceList {
138 variant: self.variant,
139 from_date: self.from_date.expect("`from_date` required"),
140 monthly_fee: self.monthly_fee.expect("`monthly_fee` required"),
141 monthly_production_fee: self
142 .monthly_production_fee
143 .expect("`monthly_production_fee` required"),
144 transfer_fee: self.transfer_fee.expect("`transfer_fee` required"),
145 feed_in_revenue: self.feed_in_revenue.expect("`feed_in_revenue` required"),
146 power_tariff: self.power_tariff.expect("`grid_tariff` required"),
147 }
148 }
149
150 pub const fn variant(mut self, name: &'static str) -> Self {
151 self.variant = Some(name);
152 self
153 }
154
155 #[allow(clippy::wrong_self_convention)]
156 pub const fn from_date(mut self, year: i32, month: u32, day: u32) -> Self {
157 self.from_date = Some(helpers::date(year, month, day));
158 self
159 }
160
161 pub const fn monthly_fee(mut self, monthly_fee: Cost) -> Self {
162 self.monthly_fee = Some(monthly_fee);
163 self
164 }
165
166 pub const fn monthly_production_fee(mut self, monthly_production_fee: Cost) -> Self {
167 self.monthly_production_fee = Some(monthly_production_fee);
168 self
169 }
170
171 pub const fn transfer_fee(mut self, transfer_fee: TransferFee) -> Self {
172 self.transfer_fee = Some(transfer_fee);
173 self
174 }
175
176 pub const fn feed_in_revenue(mut self, feed_in_revenue: FeedInRevenue) -> Self {
178 self.feed_in_revenue = Some(feed_in_revenue);
179 self
180 }
181
182 pub const fn power_tariff(mut self, power_tariff: PowerTariff) -> Self {
183 self.power_tariff = Some(power_tariff);
184 self
185 }
186}
187
188#[derive(Debug, Clone, Serialize)]
189#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
190pub struct PriceListSimplified {
191 variant: Option<&'static str>,
192 fuse_size: u16,
193 yearly_consumption_based: bool,
195 from_date: NaiveDate,
196 monthly_fee: Option<Money>,
198 monthly_production_fee: Option<Money>,
200 transfer_fee: TransferFeeSimplified,
201 feed_in_revenue: FeedInRevenueSimplified,
202 power_tariff: PowerTariffSimplified,
203}
204
205impl PriceListSimplified {
206 fn new(
207 op: &GridOperator,
208 pl: &PriceList,
209 fuse_size: u16,
210 yearly_consumption: u32,
211 language: Language,
212 ) -> Self {
213 Self {
214 variant: pl.variant,
215 fuse_size,
216 yearly_consumption_based: pl.monthly_fee.is_yearly_consumption_based(fuse_size)
217 || pl
218 .monthly_production_fee
219 .is_yearly_consumption_based(fuse_size)
220 || pl.transfer_fee.is_yearly_consumption_based(fuse_size),
221 from_date: pl.from_date,
222 monthly_fee: pl.monthly_fee.cost_for(fuse_size, yearly_consumption),
223 monthly_production_fee: pl
224 .monthly_production_fee
225 .cost_for(fuse_size, yearly_consumption),
226 transfer_fee: pl
227 .transfer_fee
228 .simplified(fuse_size, yearly_consumption, language),
229 feed_in_revenue: pl
230 .feed_in_revenue
231 .simplified(fuse_size, yearly_consumption, language),
232 power_tariff: pl
233 .power_tariff
234 .simplified(op, fuse_size, yearly_consumption, language),
235 }
236 }
237}