1use std::fmt::Display;
2
3use chrono::{DateTime, FixedOffset};
4use serde::{Deserialize, Serialize};
5#[cfg(feature = "sqlx")]
6use sqlx::FromRow;
7#[cfg(feature = "tabled")]
8use tabled::Tabled;
9
10#[cfg(feature = "tabled")]
11use crate::common::display_option;
12use crate::common::is_false;
13
14#[cfg_attr(feature = "sqlx", derive(FromRow))]
15#[cfg_attr(feature = "tabled", derive(Tabled))]
16#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
17pub struct UserBudget {
18 #[cfg_attr(feature = "sqlx", sqlx(try_from = "i32"))]
19 pub id: u32,
20 #[cfg_attr(feature = "sqlx", sqlx(try_from = "i32"))]
21 pub user: u32,
22 pub username: String,
23 pub year: u32,
24 pub amount: u32,
25}
26
27impl Display for UserBudget {
28 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29 f.write_str(&format!("UserBudget(id={})", self.id))
30 }
31}
32
33#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Default)]
34pub struct UserBudgetListParams {
35 pub user: Option<u32>,
36 pub project: Option<u32>,
37 pub all: Option<bool>,
38 pub year: Option<u32>,
39}
40
41#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Default)]
42pub struct UserBudgetOverParams {
43 pub end: Option<DateTime<FixedOffset>>,
44 pub budget: Option<u32>,
45 pub user: Option<u32>,
46 pub project: Option<u32>,
47 pub all: Option<bool>,
48 pub combined: Option<bool>,
49 pub detail: Option<bool>,
50}
51
52#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
53pub struct UserBudgetCreateData {
54 pub user: u32,
55 #[serde(skip_serializing_if = "Option::is_none")]
56 pub year: Option<u32>,
57 #[serde(skip_serializing_if = "Option::is_none")]
58 pub amount: Option<i64>,
59}
60
61impl UserBudgetCreateData {
62 pub fn new(user: u32) -> Self {
63 Self {
64 user,
65 year: None,
66 amount: None,
67 }
68 }
69}
70
71#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
72pub struct UserBudgetModifyData {
73 pub id: u32,
74
75 #[serde(skip_serializing_if = "Option::is_none")]
76 pub amount: Option<u32>,
77 #[serde(default, skip_serializing_if = "is_false")]
78 pub force: bool,
79}
80
81impl UserBudgetModifyData {
82 pub fn new(id: u32) -> Self {
83 Self {
84 id,
85 amount: None,
86 force: false,
87 }
88 }
89}
90
91#[cfg_attr(feature = "tabled", derive(Tabled))]
92#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
93pub struct UserBudgetOverSimple {
94 pub budget_id: u32,
95 pub user_id: u32,
96 pub user_name: String,
97 pub over: bool,
98}
99
100#[cfg_attr(feature = "tabled", derive(Tabled))]
101#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
102pub struct UserBudgetOverCombined {
103 pub budget_id: u32,
104 pub user_id: u32,
105 pub user_name: String,
106 #[cfg_attr(feature = "tabled", tabled(display = "display_option"))]
107 pub project_budget_id: Option<u32>,
108 pub project_id: u32,
109 pub project_name: String,
110 pub over: bool,
111}
112
113#[cfg_attr(feature = "tabled", derive(Tabled))]
114#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
115pub struct UserBudgetOverDetail {
116 pub budget_id: u32,
117 pub user_id: u32,
118 pub user_name: String,
119 pub over: bool,
120 pub cost: f64,
121 pub budget: u32,
122}
123
124#[cfg_attr(feature = "tabled", derive(Tabled))]
125#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
126pub struct UserBudgetOverCombinedDetail {
127 pub budget_id: u32,
128 pub user_id: u32,
129 pub user_name: String,
130 #[cfg_attr(feature = "tabled", tabled(display = "display_option"))]
131 pub project_budget_id: Option<u32>,
132 pub project_id: u32,
133 pub project_name: String,
134 pub over: bool,
135 pub project_cost: f64,
136 #[cfg_attr(feature = "tabled", tabled(display = "display_option"))]
137 pub project_budget: Option<u32>,
138 pub user_cost: f64,
139 pub user_budget: u32,
140}
141
142#[cfg_attr(feature = "tabled", derive(Tabled))]
143#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
144pub struct UserBudgetSync {
145 pub updated_budget_count: u32,
146}