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