Blob


1 use std::{fmt::{self, Display, Formatter}, str::FromStr};
2 use chrono::NaiveDate;
3 use serde::{Serialize, Deserialize};
5 #[derive(Debug, Default, Clone, Serialize, Deserialize)]
6 pub struct Business {
7 pub name: String,
8 pub owner_name: String,
9 pub address: String,
10 pub zip_city: String,
11 pub email: String,
12 pub iban: String,
13 pub bic: String,
14 pub bank: String,
15 pub ustid: String,
16 }
18 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize)]
19 pub struct CustomerId(pub usize);
21 #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
22 pub struct Customer {
23 pub id: CustomerId,
24 pub name: String,
25 pub address: String,
26 pub zip_city: String,
27 }
29 #[derive(Debug, Clone, Serialize, Deserialize)]
30 pub struct Record {
31 pub description: String,
32 pub date: NaiveDate,
33 pub count: f32,
34 pub price: f32,
35 }
37 #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
38 pub struct InvoiceId {
39 pub year: u16,
40 pub month: u8,
41 pub n: u32,
42 }
44 #[derive(Debug, Clone, Serialize, Deserialize)]
45 pub struct Invoice {
46 pub id: InvoiceId,
47 pub date: NaiveDate,
48 pub business: Business,
49 pub customer: Customer,
50 pub records: Vec<Record>,
51 }
53 impl Record {
54 pub fn date(&self) -> String {
55 self.date.format("%Y-%m-%d").to_string()
56 }
57 }
59 impl Invoice {
60 pub fn file_name(&self) -> String {
61 format!("invoice-{}.pdf", self.id)
62 }
63 pub fn date(&self) -> String {
64 self.date.format("%Y-%m-%d").to_string()
65 }
66 }
68 impl Display for Customer {
69 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
70 write!(f, "{} ({})", self.name, self.id)
71 }
72 }
74 impl Display for CustomerId {
75 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
76 write!(f, "{:03}", self.0)
77 }
78 }
80 impl Display for InvoiceId {
81 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
82 write!(f, "{:04}-{:02}-{:03}", self.year, self.month, self.n)
83 }
84 }
86 impl FromStr for InvoiceId {
87 type Err = ();
88 fn from_str(s: &str) -> Result<Self, Self::Err> {
89 fn parse(s: &str) -> Option<InvoiceId> {
90 let mut iter = s.split('-');
91 let year = iter.next()?.parse().ok()?;
92 let month = iter.next()?.parse().ok()?;
93 let n = iter.next()?.parse().ok()?;
95 if year < 1000 || year > 9999 || month < 1 || month > 12 {
96 return None;
97 }
99 Some(InvoiceId {
100 year,
101 month,
102 n,
103 })
105 parse(s).ok_or(())