grid_tariffs/
feed_in_revenue.rs1use serde::Serialize;
2
3use crate::{Cost, CostPeriods, CostPeriodsSimple, Language, Money, currency::Currency};
4
5#[derive(Debug, Clone, Copy, Serialize)]
8#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
9pub enum FeedInRevenue {
10 Simple(Cost),
11 Unverified,
13 Unlisted,
15 SpotPriceVariable {
17 base_cost: Money,
18 spot_price_multiplier: f64,
19 approximated: bool,
21 },
22 Periods(CostPeriods),
23}
24
25impl FeedInRevenue {
26 pub const fn is_unverified(&self) -> bool {
27 matches!(self, Self::Unverified)
28 }
29
30 pub(super) const fn new_periods(periods: CostPeriods) -> Self {
31 Self::Periods(periods)
32 }
33
34 pub(super) const fn fixed_subunit(subunit: f64) -> Self {
35 Self::Simple(Cost::fixed_subunit(subunit))
36 }
37
38 pub const fn spot_price_variable(
39 base_cost_subunit: f64,
40 spot_price_multiplier: f64,
41 approximated: bool,
42 ) -> Self {
43 Self::SpotPriceVariable {
44 base_cost: Money::new_subunit(base_cost_subunit),
45 spot_price_multiplier,
46 approximated,
47 }
48 }
49
50 pub fn simplified(
51 &self,
52 fuse_size: u16,
53 yearly_consumption: u32,
54 language: Language,
55 ) -> FeedInRevenueSimplified {
56 FeedInRevenueSimplified::new(self, fuse_size, yearly_consumption, language)
57 }
58}
59
60#[derive(Debug, Clone, Serialize)]
63#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
64pub enum FeedInRevenueSimplified {
65 Simple(Option<Money>),
66 Unverified,
68 Unlisted,
70 SpotPriceVariable {
72 base_cost: Money,
73 spot_price_multiplier: f64,
74 approximated: bool,
76 info: String,
77 },
78 Periods(CostPeriodsSimple),
79}
80
81impl FeedInRevenueSimplified {
82 fn new(
83 revenue: &FeedInRevenue,
84 fuse_size: u16,
85 yearly_consumption: u32,
86 language: Language,
87 ) -> Self {
88 match *revenue {
89 FeedInRevenue::Unlisted => Self::Unlisted,
90 FeedInRevenue::Unverified => Self::Unverified,
91 FeedInRevenue::Simple(cost) => {
92 Self::Simple(cost.cost_for(fuse_size, yearly_consumption))
93 }
94 FeedInRevenue::SpotPriceVariable {
95 base_cost,
96 spot_price_multiplier,
97 approximated,
98 } => Self::SpotPriceVariable {
99 base_cost,
100 spot_price_multiplier,
101 approximated,
102 info: Default::default(),
103 },
104 FeedInRevenue::Periods(periods) => Self::Periods(CostPeriodsSimple::new(
105 periods,
106 fuse_size,
107 yearly_consumption,
108 language,
109 )),
110 }
111 .add_info(language)
112 }
113
114 fn add_info(mut self, language: Language) -> Self {
115 match self {
116 FeedInRevenueSimplified::SpotPriceVariable {
117 base_cost,
118 spot_price_multiplier,
119 approximated,
120 info,
121 } => {
122 let percentage = spot_price_multiplier * 100.;
123 let mut info = match language {
124 Language::En => format!(
125 "The grid operator bases its feed-in revenue on a fixed part of {} and {}% of the current spot price.",
126 base_cost.display(Currency::SEK),
127 percentage
128 ),
129 Language::Sv => format!(
130 "Nätbolaget baserar sin nätnytta på en fast del om {} samt {}% av spotpriset.",
131 base_cost.display(Currency::SEK),
132 percentage
133 ),
134 };
135 if approximated {
136 info.push_str(match language {
137 Language::En => " The base fee and percentage are estimated, as the grid operator doesn't list them on their website.",
138 Language::Sv => " Basavgift och procentsats är uppskattade, eftersom nätbolaget inte skriver ut exakt vad de är på sin webbplats.",
139 })
140 }
141 FeedInRevenueSimplified::SpotPriceVariable {
142 base_cost,
143 spot_price_multiplier,
144 approximated,
145 info,
146 }
147 }
148 _ => self,
149 }
150 }
151}