backbone_maintenance/application/service/
maintenance_query_service.rs1use anyhow::Result;
14use async_trait::async_trait;
15use sqlx::PgPool;
16
17use crate::exports::{
18 MaintenanceQueryService, MaintenanceScheduleDto, MaintenanceScheduleId, MaintenanceScheduleSummary,
19 MaintenanceVisitDto, MaintenanceVisitId, MaintenanceVisitPartDto, MaintenanceVisitPartId,
20 MaintenanceVisitPartSummary, MaintenanceVisitSummary,
21};
22use crate::infrastructure::persistence::{
23 MaintenanceScheduleRepository, MaintenanceVisitPartRepository, MaintenanceVisitRepository,
24};
25
26pub struct MaintenanceQueryServiceImpl {
29 pool: PgPool,
30}
31
32impl MaintenanceQueryServiceImpl {
33 pub fn new(pool: PgPool) -> Self {
34 Self { pool }
35 }
36}
37
38#[async_trait]
39impl MaintenanceQueryService for MaintenanceQueryServiceImpl {
40 async fn get_maintenance_schedule(
41 &self,
42 id: MaintenanceScheduleId,
43 ) -> Result<Option<MaintenanceScheduleDto>> {
44 let s = MaintenanceScheduleRepository::new(self.pool.clone())
45 .find_by_id(&id.into_inner().to_string())
46 .await?;
47 Ok(s.map(MaintenanceScheduleDto::from))
48 }
49
50 async fn get_maintenance_schedule_summary(
51 &self,
52 id: MaintenanceScheduleId,
53 ) -> Result<Option<MaintenanceScheduleSummary>> {
54 let s = MaintenanceScheduleRepository::new(self.pool.clone())
55 .find_by_id(&id.into_inner().to_string())
56 .await?;
57 Ok(s.map(|s| MaintenanceScheduleSummary {
58 id: MaintenanceScheduleId(s.id),
59 name: s.name,
60 status: s.status,
61 }))
62 }
63
64 async fn maintenance_schedule_exists(&self, id: MaintenanceScheduleId) -> Result<bool> {
65 MaintenanceScheduleRepository::new(self.pool.clone())
66 .exists(&id.into_inner().to_string())
67 .await
68 }
69
70 async fn get_maintenance_visit(&self, id: MaintenanceVisitId) -> Result<Option<MaintenanceVisitDto>> {
71 let v = MaintenanceVisitRepository::new(self.pool.clone())
72 .find_by_id(&id.into_inner().to_string())
73 .await?;
74 Ok(v.map(MaintenanceVisitDto::from))
75 }
76
77 async fn get_maintenance_visit_summary(
78 &self,
79 id: MaintenanceVisitId,
80 ) -> Result<Option<MaintenanceVisitSummary>> {
81 let v = MaintenanceVisitRepository::new(self.pool.clone())
82 .find_by_id(&id.into_inner().to_string())
83 .await?;
84 Ok(v.map(|v| MaintenanceVisitSummary {
85 id: MaintenanceVisitId(v.id),
86 status: v.status,
87 }))
88 }
89
90 async fn maintenance_visit_exists(&self, id: MaintenanceVisitId) -> Result<bool> {
91 MaintenanceVisitRepository::new(self.pool.clone())
92 .exists(&id.into_inner().to_string())
93 .await
94 }
95
96 async fn get_maintenance_visit_part(
97 &self,
98 id: MaintenanceVisitPartId,
99 ) -> Result<Option<MaintenanceVisitPartDto>> {
100 let p = MaintenanceVisitPartRepository::new(self.pool.clone())
101 .find_by_id(&id.into_inner().to_string())
102 .await?;
103 Ok(p.map(MaintenanceVisitPartDto::from))
104 }
105
106 async fn get_maintenance_visit_part_summary(
107 &self,
108 id: MaintenanceVisitPartId,
109 ) -> Result<Option<MaintenanceVisitPartSummary>> {
110 let p = MaintenanceVisitPartRepository::new(self.pool.clone())
111 .find_by_id(&id.into_inner().to_string())
112 .await?;
113 Ok(p.map(|p| MaintenanceVisitPartSummary {
114 id: MaintenanceVisitPartId(p.id),
115 }))
116 }
117
118 async fn maintenance_visit_part_exists(&self, id: MaintenanceVisitPartId) -> Result<bool> {
119 MaintenanceVisitPartRepository::new(self.pool.clone())
120 .exists(&id.into_inner().to_string())
121 .await
122 }
123}
124
125impl From<crate::domain::entity::MaintenanceSchedule> for MaintenanceScheduleDto {
129 fn from(s: crate::domain::entity::MaintenanceSchedule) -> Self {
130 Self {
131 id: MaintenanceScheduleId(s.id),
132 asset_id: s.asset_id,
133 name: s.name,
134 interval_days: s.interval_days,
135 next_due_date: s.next_due_date,
136 status: s.status,
137 metadata: serde_json::to_value(&s.metadata).unwrap_or_default(),
138 }
139 }
140}
141
142impl From<crate::domain::entity::MaintenanceVisit> for MaintenanceVisitDto {
143 fn from(v: crate::domain::entity::MaintenanceVisit) -> Self {
144 Self {
145 id: MaintenanceVisitId(v.id),
146 asset_id: v.asset_id,
147 schedule_id: v.schedule_id,
148 maintenance_type: v.maintenance_type,
149 status: v.status,
150 warehouse_id: v.warehouse_id,
151 warranty_claim_id: v.warranty_claim_id,
152 scheduled_date: v.scheduled_date,
153 performed_date: v.performed_date,
154 labor_cost: v.labor_cost,
155 parts_cost: v.parts_cost,
156 total_cost: v.total_cost,
157 maintenance_expense_account_id: v.maintenance_expense_account_id,
158 parts_inventory_account_id: v.parts_inventory_account_id,
159 labor_payable_account_id: v.labor_payable_account_id,
160 journal_id: v.journal_id,
161 accounting_post_id: v.accounting_post_id,
162 notes: v.notes,
163 metadata: serde_json::to_value(&v.metadata).unwrap_or_default(),
164 }
165 }
166}
167
168impl From<crate::domain::entity::MaintenanceVisitPart> for MaintenanceVisitPartDto {
169 fn from(p: crate::domain::entity::MaintenanceVisitPart) -> Self {
170 Self {
171 id: MaintenanceVisitPartId(p.id),
172 visit_id: p.visit_id,
173 item_id: p.item_id,
174 quantity: p.quantity,
175 unit_cost: p.unit_cost,
176 amount: p.amount,
177 metadata: serde_json::to_value(&p.metadata).unwrap_or_default(),
178 }
179 }
180}