1use chrono::{DateTime, NaiveDate, TimeZone};
2use serde::Serialize;
3
4use crate::{
5 FeedInRevenueSimplified, 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 fuse_size: u16,
96 yearly_consumption: u32,
97 language: Language,
98 ) -> PriceListSimplified {
99 PriceListSimplified::new(self, fuse_size, yearly_consumption, language)
100 }
101}
102
103#[derive(Debug, Clone)]
104pub struct PriceListBuilder {
105 variant: Option<&'static str>,
106 from_date: Option<NaiveDate>,
107 monthly_fee: Option<Cost>,
109 monthly_production_fee: Option<Cost>,
111 transfer_fee: Option<TransferFee>,
112 feed_in_revenue: Option<FeedInRevenue>,
113 power_tariff: Option<PowerTariff>,
114}
115
116impl Default for PriceListBuilder {
117 fn default() -> Self {
118 Self::new()
119 }
120}
121
122impl PriceListBuilder {
123 pub const fn new() -> Self {
124 Self {
125 variant: None,
126 from_date: None,
127 monthly_fee: None,
128 monthly_production_fee: None,
129 transfer_fee: None,
130 feed_in_revenue: None,
131 power_tariff: None,
132 }
133 }
134
135 pub const fn build(self) -> PriceList {
136 PriceList {
137 variant: self.variant,
138 from_date: self.from_date.expect("`from_date` required"),
139 monthly_fee: self.monthly_fee.expect("`monthly_fee` required"),
140 monthly_production_fee: self
141 .monthly_production_fee
142 .expect("`monthly_production_fee` required"),
143 transfer_fee: self.transfer_fee.expect("`transfer_fee` required"),
144 feed_in_revenue: self.feed_in_revenue.expect("`feed_in_revenue` required"),
145 power_tariff: self.power_tariff.expect("`grid_tariff` required"),
146 }
147 }
148
149 pub const fn variant(mut self, name: &'static str) -> Self {
150 self.variant = Some(name);
151 self
152 }
153
154 #[allow(clippy::wrong_self_convention)]
155 pub const fn from_date(mut self, year: i32, month: u32, day: u32) -> Self {
156 self.from_date = Some(helpers::date(year, month, day));
157 self
158 }
159
160 pub const fn monthly_fee(mut self, monthly_fee: Cost) -> Self {
161 self.monthly_fee = Some(monthly_fee);
162 self
163 }
164
165 pub const fn monthly_production_fee(mut self, monthly_production_fee: Cost) -> Self {
166 self.monthly_production_fee = Some(monthly_production_fee);
167 self
168 }
169
170 pub const fn transfer_fee(mut self, transfer_fee: TransferFee) -> Self {
171 self.transfer_fee = Some(transfer_fee);
172 self
173 }
174
175 pub const fn feed_in_revenue(mut self, feed_in_revenue: FeedInRevenue) -> Self {
176 self.feed_in_revenue = Some(feed_in_revenue);
177 self
178 }
179
180 pub const fn power_tariff(mut self, power_tariff: PowerTariff) -> Self {
181 self.power_tariff = Some(power_tariff);
182 self
183 }
184}
185
186#[derive(Debug, Clone, Serialize)]
187#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
188pub struct PriceListSimplified {
189 variant: Option<&'static str>,
190 fuse_size: u16,
191 yearly_consumption_based: bool,
193 from_date: NaiveDate,
194 monthly_fee: Option<Money>,
196 monthly_production_fee: Option<Money>,
198 transfer_fee: TransferFeeSimplified,
199 feed_in_revenue: FeedInRevenueSimplified,
200 power_tariff: PowerTariffSimplified,
201}
202
203impl PriceListSimplified {
204 fn new(pl: &PriceList, fuse_size: u16, yearly_consumption: u32, language: Language) -> Self {
205 Self {
206 variant: pl.variant,
207 fuse_size,
208 yearly_consumption_based: pl.monthly_fee.is_yearly_consumption_based(fuse_size)
209 || pl
210 .monthly_production_fee
211 .is_yearly_consumption_based(fuse_size)
212 || pl.transfer_fee.is_yearly_consumption_based(fuse_size),
213 from_date: pl.from_date,
214 monthly_fee: pl.monthly_fee.cost_for(fuse_size, yearly_consumption),
215 monthly_production_fee: pl
216 .monthly_production_fee
217 .cost_for(fuse_size, yearly_consumption),
218 transfer_fee: pl
219 .transfer_fee
220 .simplified(fuse_size, yearly_consumption, language),
221 feed_in_revenue: pl
222 .feed_in_revenue
223 .simplified(fuse_size, yearly_consumption, language),
224 power_tariff: pl
225 .power_tariff
226 .simplified(fuse_size, yearly_consumption, language),
227 }
228 }
229}