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, Clone, Serialize, Deserialize, Default)]
47pub struct ArchiveNoticeDto {
48 pub reason: Option<String>,
49}
50
51#[derive(Debug, Serialize, Clone)]
53pub struct NoticeResponseDto {
54 pub id: Uuid,
55 pub building_id: Uuid,
56 pub author_id: Uuid,
57 pub author_name: String, pub notice_type: NoticeType,
59 pub category: NoticeCategory,
60 pub title: String,
61 pub content: String,
62 pub status: NoticeStatus,
63 pub is_pinned: bool,
64 pub published_at: Option<DateTime<Utc>>,
65 pub expires_at: Option<DateTime<Utc>>,
66 pub archived_at: Option<DateTime<Utc>>,
67 pub event_date: Option<DateTime<Utc>>,
69 pub event_location: Option<String>,
70 pub contact_info: Option<String>,
72 pub created_at: DateTime<Utc>,
74 pub updated_at: DateTime<Utc>,
75 pub is_expired: bool,
77 pub days_until_event: Option<i64>, }
79
80impl NoticeResponseDto {
81 pub fn from_notice(notice: Notice, author_name: String) -> Self {
83 let is_expired = notice.is_expired();
84 let days_until_event = if notice.notice_type == NoticeType::Event {
85 notice.event_date.map(|event_date| {
86 let now = Utc::now();
87 (event_date - now).num_days()
88 })
89 } else {
90 None
91 };
92
93 Self {
94 id: notice.id,
95 building_id: notice.building_id,
96 author_id: notice.author_id,
97 author_name,
98 notice_type: notice.notice_type,
99 category: notice.category,
100 title: notice.title,
101 content: notice.content,
102 status: notice.status,
103 is_pinned: notice.is_pinned,
104 published_at: notice.published_at,
105 expires_at: notice.expires_at,
106 archived_at: notice.archived_at,
107 event_date: notice.event_date,
108 event_location: notice.event_location,
109 contact_info: notice.contact_info,
110 created_at: notice.created_at,
111 updated_at: notice.updated_at,
112 is_expired,
113 days_until_event,
114 }
115 }
116}
117
118#[derive(Debug, Serialize, Clone)]
120pub struct NoticeSummaryDto {
121 pub id: Uuid,
122 pub building_id: Uuid,
123 pub author_name: String,
124 pub notice_type: NoticeType,
125 pub category: NoticeCategory,
126 pub title: String,
127 pub status: NoticeStatus,
128 pub is_pinned: bool,
129 pub published_at: Option<DateTime<Utc>>,
130 pub event_date: Option<DateTime<Utc>>, pub created_at: DateTime<Utc>,
132 pub is_expired: bool,
133}
134
135impl NoticeSummaryDto {
136 pub fn from_notice(notice: Notice, author_name: String) -> Self {
138 let is_expired = notice.is_expired();
139
140 Self {
141 id: notice.id,
142 building_id: notice.building_id,
143 author_name,
144 notice_type: notice.notice_type,
145 category: notice.category,
146 title: notice.title,
147 status: notice.status.clone(),
148 is_pinned: notice.is_pinned,
149 published_at: notice.published_at,
150 event_date: notice.event_date,
151 created_at: notice.created_at,
152 is_expired,
153 }
154 }
155}