1use core::fmt;
2use std::str::FromStr;
3
4use chrono::{NaiveDate, Utc};
5use serde::{Deserialize, Serialize};
6
7use crate::{Money, SE_TAX_REDUCTIONS, SE_TAXES, Tax, TaxAppliedBy, TaxReduction, helpers::date};
8
9#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
10#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
11pub enum Country {
12 SE,
13}
14
15impl Country {
16 pub const fn all() -> &'static [Self] {
17 &[Country::SE]
18 }
19
20 pub const fn taxes(&self) -> &'static [Tax] {
21 match self {
22 Country::SE => SE_TAXES,
23 }
24 }
25
26 pub const fn tax_reductions(&self) -> &'static [TaxReduction] {
27 match self {
28 Country::SE => SE_TAX_REDUCTIONS,
29 }
30 }
31
32 pub fn current_taxes(&self, today: NaiveDate) -> Vec<Tax> {
33 self.taxes()
34 .iter()
35 .filter(|tax| tax.valid_for(today))
36 .copied()
37 .collect()
38 }
39
40 pub fn current_tax_reductions(&self, today: NaiveDate) -> Vec<TaxReduction> {
41 self.tax_reductions()
42 .iter()
43 .filter(|tax| tax.valid_for(today))
44 .copied()
45 .collect()
46 }
47
48 pub(crate) const fn vat_rate(&self) -> f64 {
49 match self {
50 Country::SE => 1.25,
51 }
52 }
53
54 pub(crate) const fn add_vat(&self, value: f64) -> f64 {
55 value * self.vat_rate()
56 }
57
58 pub(crate) fn is_holiday(&self, date_naive: NaiveDate) -> bool {
59 SE_HOLIDAYS.contains(&date_naive)
60 }
61}
62
63impl Country {
64 pub fn code(&self) -> &'static str {
65 match self {
66 Country::SE => "SE",
67 }
68 }
69
70 pub fn english_name(&self) -> &'static str {
71 match self {
72 Country::SE => "Sweden",
73 }
74 }
75}
76
77impl FromStr for Country {
78 type Err = &'static str;
79
80 fn from_str(s: &str) -> Result<Self, Self::Err> {
81 match s.to_ascii_uppercase().as_ref() {
82 "SE" => Ok(Country::SE),
83 _ => Err("no such country"),
84 }
85 }
86}
87
88impl fmt::Display for Country {
89 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
90 f.write_str(match self {
91 Country::SE => "SE",
92 })
93 }
94}
95
96#[derive(Debug, Serialize)]
97pub struct CountryInfo {
98 country: Country,
99 taxes: Vec<Tax>,
101 tax_reductions: Vec<TaxReduction>,
103}
104
105impl CountryInfo {
106 pub fn current(country: Country) -> Self {
107 let today = Utc::now().date_naive();
108 Self {
109 country,
110 taxes: country.current_taxes(today),
111 tax_reductions: country.current_tax_reductions(today),
112 }
113 }
114}
115
116impl From<Country> for CountryInfo {
117 fn from(country: Country) -> Self {
118 let taxes = country.taxes().to_vec();
119 let tax_reductions = country.tax_reductions().to_vec();
120 Self {
121 country,
122 taxes,
123 tax_reductions,
124 }
125 }
126}
127
128static SE_HOLIDAYS: &[NaiveDate] = &[
129 date(2025, 1, 1),
130 date(2025, 1, 6),
131 date(2025, 4, 18),
132 date(2025, 4, 20),
133 date(2025, 4, 21),
134 date(2025, 5, 1),
135 date(2025, 5, 29),
136 date(2025, 6, 6),
137 date(2025, 6, 8),
138 date(2025, 6, 21),
139 date(2025, 11, 1),
140 date(2025, 12, 24),
141 date(2025, 12, 25),
142 date(2025, 12, 26),
143 date(2025, 12, 31),
144 date(2026, 1, 1),
145 date(2026, 1, 6),
146 date(2026, 4, 3),
147 date(2026, 4, 5),
148 date(2026, 4, 6),
149 date(2026, 5, 1),
150 date(2026, 5, 14),
151 date(2026, 5, 24),
152 date(2026, 6, 6),
153 date(2026, 6, 20),
154 date(2026, 10, 31),
155 date(2026, 12, 24),
156 date(2026, 12, 25),
157 date(2026, 12, 26),
158 date(2026, 12, 31),
159 date(2027, 1, 1),
160 date(2027, 1, 6),
161 date(2027, 3, 26),
162 date(2027, 3, 28),
163 date(2027, 3, 29),
164 date(2027, 5, 1),
165 date(2027, 5, 6),
166 date(2027, 5, 16),
167 date(2027, 6, 6),
168 date(2027, 6, 26),
169 date(2027, 11, 6),
170 date(2027, 12, 24),
171 date(2027, 12, 25),
172 date(2027, 12, 26),
173 date(2027, 12, 31),
174 date(2028, 1, 1),
175 date(2028, 1, 6),
176 date(2028, 4, 14),
177 date(2028, 4, 16),
178 date(2028, 4, 17),
179 date(2028, 5, 1),
180 date(2028, 5, 25),
181 date(2028, 6, 4),
182 date(2028, 6, 6),
183 date(2028, 6, 24),
184 date(2028, 11, 4),
185 date(2028, 12, 24),
186 date(2028, 12, 25),
187 date(2028, 12, 26),
188 date(2028, 12, 31),
189];