koprogo_api/application/dto/
notice_dto.rs1use crate::domain::entities::{Notice, NoticeCategory, NoticeStatus, NoticeType};
2use chrono::{DateTime, Utc};
3use serde::{Deserialize, Serialize};
4use uuid::Uuid;
5
6#[derive(Debug, Serialize, Deserialize)]
8pub struct CreateNoticeDto {
9 pub building_id: Uuid,
10 pub notice_type: NoticeType,
11 pub category: NoticeCategory,
12 pub title: String,
13 pub content: String,
14 pub event_date: Option<DateTime<Utc>>,
16 pub event_location: Option<String>,
17 pub contact_info: Option<String>,
19 pub expires_at: Option<DateTime<Utc>>,
21}
22
23#[derive(Debug, Serialize, Deserialize)]
25pub struct UpdateNoticeDto {
26 pub title: Option<String>,
27 pub content: Option<String>,
28 pub category: Option<NoticeCategory>,
29 pub event_date: Option<Option<DateTime<Utc>>>,
30 pub event_location: Option<Option<String>>,
31 pub contact_info: Option<Option<String>>,
32 pub expires_at: Option<Option<DateTime<Utc>>>,
33}
34
35#[derive(Debug, Serialize, Deserialize)]
37pub struct SetExpirationDto {
38 pub expires_at: Option<DateTime<Utc>>,
39}
40
41#[derive(Debug, Serialize, Clone)]
43pub struct NoticeResponseDto {
44 pub id: Uuid,
45 pub building_id: Uuid,
46 pub author_id: Uuid,
47 pub author_name: String, pub notice_type: NoticeType,
49 pub category: NoticeCategory,
50 pub title: String,
51 pub content: String,
52 pub status: NoticeStatus,
53 pub is_pinned: bool,
54 pub published_at: Option<DateTime<Utc>>,
55 pub expires_at: Option<DateTime<Utc>>,
56 pub archived_at: Option<DateTime<Utc>>,
57 pub event_date: Option<DateTime<Utc>>,
59 pub event_location: Option<String>,
60 pub contact_info: Option<String>,
62 pub created_at: DateTime<Utc>,
64 pub updated_at: DateTime<Utc>,
65 pub is_expired: bool,
67 pub days_until_event: Option<i64>, }
69
70impl NoticeResponseDto {
71 pub fn from_notice(notice: Notice, author_name: String) -> Self {
73 let is_expired = notice.is_expired();
74 let days_until_event = if notice.notice_type == NoticeType::Event {
75 notice.event_date.map(|event_date| {
76 let now = Utc::now();
77 (event_date - now).num_days()
78 })
79 } else {
80 None
81 };
82
83 Self {
84 id: notice.id,
85 building_id: notice.building_id,
86 author_id: notice.author_id,
87 author_name,
88 notice_type: notice.notice_type,
89 category: notice.category,
90 title: notice.title,
91 content: notice.content,
92 status: notice.status,
93 is_pinned: notice.is_pinned,
94 published_at: notice.published_at,
95 expires_at: notice.expires_at,
96 archived_at: notice.archived_at,
97 event_date: notice.event_date,
98 event_location: notice.event_location,
99 contact_info: notice.contact_info,
100 created_at: notice.created_at,
101 updated_at: notice.updated_at,
102 is_expired,
103 days_until_event,
104 }
105 }
106}
107
108#[derive(Debug, Serialize, Clone)]
110pub struct NoticeSummaryDto {
111 pub id: Uuid,
112 pub building_id: Uuid,
113 pub author_name: String,
114 pub notice_type: NoticeType,
115 pub category: NoticeCategory,
116 pub title: String,
117 pub status: NoticeStatus,
118 pub is_pinned: bool,
119 pub published_at: Option<DateTime<Utc>>,
120 pub event_date: Option<DateTime<Utc>>, pub created_at: DateTime<Utc>,
122 pub is_expired: bool,
123}
124
125impl NoticeSummaryDto {
126 pub fn from_notice(notice: Notice, author_name: String) -> Self {
128 let is_expired = notice.is_expired();
129
130 Self {
131 id: notice.id,
132 building_id: notice.building_id,
133 author_name,
134 notice_type: notice.notice_type,
135 category: notice.category,
136 title: notice.title,
137 status: notice.status.clone(),
138 is_pinned: notice.is_pinned,
139 published_at: notice.published_at,
140 event_date: notice.event_date,
141 created_at: notice.created_at,
142 is_expired,
143 }
144 }
145}