1 use std::{fmt::{self, Display, Formatter}, str::FromStr};
3 use serde::{Serialize, Deserialize};
5 #[derive(Debug, Default, Clone, Serialize, Deserialize)]
8 pub owner_name: String,
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)]
29 #[derive(Debug, Clone, Serialize, Deserialize)]
31 pub description: String,
37 #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
38 pub struct InvoiceId {
44 #[derive(Debug, Clone, Serialize, Deserialize)]
48 pub business: Business,
49 pub customer: Customer,
50 pub records: Vec<Record>,
54 pub fn date(&self) -> String {
55 self.date.format("%Y-%m-%d").to_string()
60 pub fn file_name(&self) -> String {
61 format!("invoice-{}.pdf", self.id)
63 pub fn date(&self) -> String {
64 self.date.format("%Y-%m-%d").to_string()
68 impl Display for Customer {
69 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
70 write!(f, "{} ({})", self.name, self.id)
74 impl Display for CustomerId {
75 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
76 write!(f, "{:03}", self.0)
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)
86 impl FromStr for InvoiceId {
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 {