1#![recursion_limit = "1024"]
18#![allow(unused_imports)]
19
20pub mod domain;
22pub mod infrastructure;
23pub mod application;
24pub mod presentation;
25pub mod seeders;
26pub mod exports;
27
28pub use domain::entity::*;
30
31pub use infrastructure::persistence::*;
33
34pub use application::service::AccountService;
36pub use application::service::AccountingPostService;
37pub use application::service::CostCenterService;
38pub use application::service::EmvQrConfigService;
39pub use application::service::BankCheckSequenceService;
40pub use application::service::PrintedCheckService;
41pub use application::service::TaxTagRepairRunService;
42pub use application::service::FinancialStatementService;
43pub use application::service::FiscalPeriodService;
44pub use application::service::JournalService;
45pub use application::service::JournalLineService;
46pub use application::service::LedgerService;
47pub use application::service::ReconciliationService;
48pub use application::service::ReconciliationItemService;
49pub use application::service::FullReconcileService;
50pub use application::service::PartialReconcileService;
51
52pub use application::validator::{ValidationError, ValidationResult};
54
55pub use application::workflows::*;
57
58use std::sync::Arc;
59use axum::Router;
60use sqlx::PgPool;
61
62pub struct AccountingModule {
75 pub(crate) account_service: Arc<AccountService>,
76 pub(crate) accounting_post_service: Arc<AccountingPostService>,
77 pub(crate) cost_center_service: Arc<CostCenterService>,
78 pub(crate) emv_qr_config_service: Arc<EmvQrConfigService>,
79 pub(crate) bank_check_sequence_service: Arc<BankCheckSequenceService>,
80 pub(crate) printed_check_service: Arc<PrintedCheckService>,
81 pub(crate) tax_tag_repair_run_service: Arc<TaxTagRepairRunService>,
82 pub(crate) financial_statement_service: Arc<FinancialStatementService>,
83 pub(crate) fiscal_period_service: Arc<FiscalPeriodService>,
84 pub(crate) journal_service: Arc<JournalService>,
85 pub(crate) journal_line_service: Arc<JournalLineService>,
86 pub(crate) ledger_service: Arc<LedgerService>,
87 pub(crate) reconciliation_service: Arc<ReconciliationService>,
88 pub(crate) reconciliation_item_service: Arc<ReconciliationItemService>,
89 pub(crate) full_reconcile_service: Arc<FullReconcileService>,
90 pub(crate) partial_reconcile_service: Arc<PartialReconcileService>,
91 pub(crate) db_pool: PgPool,
93 pub(crate) reconcile_write_service:
94 Arc<crate::application::service::reconcile_write_service::ReconcileWriteService>,
95 pub(crate) check_printing_service:
98 Arc<crate::application::service::check_printing_service::CheckPrintingService>,
99 pub(crate) emv_qr_service:
102 Arc<crate::application::service::emv_qr_service::EmvQrService>,
103 pub(crate) tax_tag_repair_service:
105 Arc<crate::application::service::tax_tag_repair_service::TaxTagRepairService>,
106 pub(crate) deferred_tax: Option<Arc<dyn crate::domain::repositories::DeferredTaxLookup>>,
109 pub(crate) budget_control: Option<Arc<dyn crate::domain::repositories::BudgetControlPort>>,
113 pub(crate) chart_install_service:
115 Arc<crate::application::service::chart_install_service::ChartInstallService>,
116 pub(crate) reporting_service:
118 Arc<crate::application::service::reporting_service::ReportingService>,
119 }
121
122impl AccountingModule {
123 pub fn builder() -> AccountingModuleBuilder {
125 AccountingModuleBuilder::new()
126 }
127
128 pub fn all_crud_routes(&self) -> Router {
134 use presentation::http::{
135 create_account_routes,
136 create_accounting_post_routes,
137 create_cost_center_routes,
138 create_emv_qr_config_routes,
139 create_bank_check_sequence_routes,
140 create_printed_check_routes,
141 create_tax_tag_repair_run_routes,
142 create_financial_statement_routes,
143 create_fiscal_period_routes,
144 create_journal_routes,
145 create_journal_line_routes,
146 create_ledger_routes,
147 create_reconciliation_routes,
148 create_reconciliation_item_routes,
149 create_full_reconcile_routes,
150 create_partial_reconcile_routes,
151 };
152
153 Router::new()
154 .merge(create_account_routes(self.account_service.clone()))
155 .merge(create_accounting_post_routes(self.accounting_post_service.clone()))
156 .merge(create_cost_center_routes(self.cost_center_service.clone()))
157 .merge(create_emv_qr_config_routes(self.emv_qr_config_service.clone()))
158 .merge(create_bank_check_sequence_routes(self.bank_check_sequence_service.clone()))
159 .merge(create_printed_check_routes(self.printed_check_service.clone()))
160 .merge(create_tax_tag_repair_run_routes(self.tax_tag_repair_run_service.clone()))
161 .merge(create_financial_statement_routes(self.financial_statement_service.clone()))
162 .merge(create_fiscal_period_routes(self.fiscal_period_service.clone()))
163 .merge(create_journal_routes(self.journal_service.clone()))
164 .merge(create_journal_line_routes(self.journal_line_service.clone()))
165 .merge(create_ledger_routes(self.ledger_service.clone()))
166 .merge(create_reconciliation_routes(self.reconciliation_service.clone()))
167 .merge(create_reconciliation_item_routes(self.reconciliation_item_service.clone()))
168 .merge(create_full_reconcile_routes(self.full_reconcile_service.clone()))
169 .merge(create_partial_reconcile_routes(self.partial_reconcile_service.clone()))
170 }
171
172 #[deprecated(note = "mounts unvalidated generic CRUD; prefer readonly_routes() + validated writes, or all_crud_routes() for the full/unguarded surface")]
178 pub fn routes(&self) -> Router {
179 self.all_crud_routes()
180 }
181
182 pub fn readonly_routes(&self) -> Router {
188 use presentation::http::{
189 create_account_read_routes,
190 create_accounting_post_read_routes,
191 create_cost_center_read_routes,
192 create_emv_qr_config_read_routes,
193 create_bank_check_sequence_read_routes,
194 create_printed_check_read_routes,
195 create_tax_tag_repair_run_read_routes,
196 create_financial_statement_read_routes,
197 create_fiscal_period_read_routes,
198 create_journal_read_routes,
199 create_journal_line_read_routes,
200 create_ledger_read_routes,
201 create_reconciliation_read_routes,
202 create_reconciliation_item_read_routes,
203 create_full_reconcile_read_routes,
204 create_partial_reconcile_read_routes,
205 };
206
207 Router::new()
208 .merge(create_account_read_routes(self.account_service.clone()))
209 .merge(create_accounting_post_read_routes(self.accounting_post_service.clone()))
210 .merge(create_cost_center_read_routes(self.cost_center_service.clone()))
211 .merge(create_emv_qr_config_read_routes(self.emv_qr_config_service.clone()))
212 .merge(create_bank_check_sequence_read_routes(self.bank_check_sequence_service.clone()))
213 .merge(create_printed_check_read_routes(self.printed_check_service.clone()))
214 .merge(create_tax_tag_repair_run_read_routes(self.tax_tag_repair_run_service.clone()))
215 .merge(create_financial_statement_read_routes(self.financial_statement_service.clone()))
216 .merge(create_fiscal_period_read_routes(self.fiscal_period_service.clone()))
217 .merge(create_journal_read_routes(self.journal_service.clone()))
218 .merge(create_journal_line_read_routes(self.journal_line_service.clone()))
219 .merge(create_ledger_read_routes(self.ledger_service.clone()))
220 .merge(create_reconciliation_read_routes(self.reconciliation_service.clone()))
221 .merge(create_reconciliation_item_read_routes(self.reconciliation_item_service.clone()))
222 .merge(create_full_reconcile_read_routes(self.full_reconcile_service.clone()))
223 .merge(create_partial_reconcile_read_routes(self.partial_reconcile_service.clone()))
224 }
225
226 pub fn budget_control(
233 &self,
234 ) -> Option<Arc<dyn crate::domain::repositories::BudgetControlPort>> {
235 self.budget_control.clone()
236 }
237
238 pub fn reporting_service(
241 &self,
242 ) -> std::sync::Arc<crate::application::service::reporting_service::ReportingService> {
243 self.reporting_service.clone()
244 }
245
246 pub fn reconcile_write_service(
250 &self,
251 ) -> std::sync::Arc<crate::application::service::reconcile_write_service::ReconcileWriteService>
252 {
253 self.reconcile_write_service.clone()
254 }
255
256 pub fn reconcile_write_service_with_exchange_account(
261 &self,
262 exchange_account_id: uuid::Uuid,
263 ) -> std::sync::Arc<crate::application::service::reconcile_write_service::ReconcileWriteService>
264 {
265 std::sync::Arc::new(
266 crate::application::service::reconcile_write_service::ReconcileWriteService::new(
267 std::sync::Arc::new(
268 crate::infrastructure::persistence::reconcile_graph_repository::SqlxReconcileGraphRepository::new(),
269 ),
270 std::sync::Arc::new(
271 crate::infrastructure::persistence::posting_repository::SqlxPostingRepository::new(
272 self.db_pool.clone(),
273 ),
274 ),
275 self.db_pool.clone(),
276 Some(exchange_account_id),
277 )
278 .with_deferred_tax_if_set(self.deferred_tax.clone()),
279 )
280 }
281
282 pub fn chart_install_service(
287 &self,
288 ) -> std::sync::Arc<crate::application::service::chart_install_service::ChartInstallService>
289 {
290 self.chart_install_service.clone()
291 }
292
293 pub fn check_printing_service(
297 &self,
298 ) -> std::sync::Arc<crate::application::service::check_printing_service::CheckPrintingService>
299 {
300 self.check_printing_service.clone()
301 }
302
303 pub fn emv_qr_service(
306 &self,
307 ) -> std::sync::Arc<crate::application::service::emv_qr_service::EmvQrService> {
308 self.emv_qr_service.clone()
309 }
310
311 pub fn tax_tag_repair_service(
315 &self,
316 ) -> std::sync::Arc<crate::application::service::tax_tag_repair_service::TaxTagRepairService>
317 {
318 self.tax_tag_repair_service.clone()
319 }
320 }
322
323pub struct AccountingModuleBuilder {
325 db_pool: Option<PgPool>,
326 deferred_tax: Option<Arc<dyn crate::domain::repositories::DeferredTaxLookup>>,
328 budget_control: Option<Arc<dyn crate::domain::repositories::BudgetControlPort>>,
329 chart_datasets: Vec<Arc<crate::domain::chart_dataset::ChartDataset>>,
330 }
332
333impl AccountingModuleBuilder {
334 pub fn new() -> Self {
336 Self {
337 db_pool: None,
338 deferred_tax: None,
340 budget_control: None,
341 chart_datasets: Vec::new(),
342 }
344 }
345
346 pub fn with_database(mut self, pool: PgPool) -> Self {
348 self.db_pool = Some(pool);
349 self
350 }
351
352 pub fn with_chart_dataset(
358 mut self,
359 dataset: Arc<crate::domain::chart_dataset::ChartDataset>,
360 ) -> Self {
361 self.chart_datasets.push(dataset);
362 self
363 }
364
365 pub fn with_deferred_tax(
370 mut self,
371 port: Arc<dyn crate::domain::repositories::DeferredTaxLookup>,
372 ) -> Self {
373 self.deferred_tax = Some(port);
374 self
375 }
376
377 pub fn with_budget_control(
384 mut self,
385 port: Arc<dyn crate::domain::repositories::BudgetControlPort>,
386 ) -> Self {
387 self.budget_control = Some(port);
388 self
389 }
390 pub fn build(self) -> anyhow::Result<AccountingModule> {
394 let db_pool = self.db_pool
395 .ok_or_else(|| anyhow::anyhow!("Database pool not configured"))?;
396
397 let account_repository = Arc::new(AccountRepository::new(db_pool.clone()));
399 let account_service = Arc::new(AccountService::with_repository(account_repository.clone()));
400
401 let accounting_post_repository = Arc::new(AccountingPostRepository::new(db_pool.clone()));
403 let accounting_post_service = Arc::new(AccountingPostService::with_repository(accounting_post_repository.clone()));
404
405 let cost_center_repository = Arc::new(CostCenterRepository::new(db_pool.clone()));
407 let cost_center_service = Arc::new(CostCenterService::with_repository(cost_center_repository.clone()));
408
409 let emv_qr_config_repository = Arc::new(EmvQrConfigRepository::new(db_pool.clone()));
411 let emv_qr_config_service = Arc::new(EmvQrConfigService::with_repository(emv_qr_config_repository.clone()));
412
413 let bank_check_sequence_repository = Arc::new(BankCheckSequenceRepository::new(db_pool.clone()));
415 let bank_check_sequence_service = Arc::new(BankCheckSequenceService::with_repository(bank_check_sequence_repository.clone()));
416
417 let printed_check_repository = Arc::new(PrintedCheckRepository::new(db_pool.clone()));
419 let printed_check_service = Arc::new(PrintedCheckService::with_repository(printed_check_repository.clone()));
420
421 let tax_tag_repair_run_repository = Arc::new(TaxTagRepairRunRepository::new(db_pool.clone()));
423 let tax_tag_repair_run_service = Arc::new(TaxTagRepairRunService::with_repository(tax_tag_repair_run_repository.clone()));
424
425 let financial_statement_repository = Arc::new(FinancialStatementRepository::new(db_pool.clone()));
427 let financial_statement_service = Arc::new(FinancialStatementService::with_repository(financial_statement_repository.clone()));
428
429 let fiscal_period_repository = Arc::new(FiscalPeriodRepository::new(db_pool.clone()));
431 let fiscal_period_service = Arc::new(FiscalPeriodService::with_repository(fiscal_period_repository.clone()));
432
433 let journal_repository = Arc::new(JournalRepository::new(db_pool.clone()));
435 let journal_service = Arc::new(JournalService::with_repository(journal_repository.clone()));
436
437 let journal_line_repository = Arc::new(JournalLineRepository::new(db_pool.clone()));
439 let journal_line_service = Arc::new(JournalLineService::with_repository(journal_line_repository.clone()));
440
441 let ledger_repository = Arc::new(LedgerRepository::new(db_pool.clone()));
443 let ledger_service = Arc::new(LedgerService::with_repository(ledger_repository.clone()));
444
445 let reconciliation_repository = Arc::new(ReconciliationRepository::new(db_pool.clone()));
447 let reconciliation_service = Arc::new(ReconciliationService::with_repository(reconciliation_repository.clone()));
448
449 let reconciliation_item_repository = Arc::new(ReconciliationItemRepository::new(db_pool.clone()));
451 let reconciliation_item_service = Arc::new(ReconciliationItemService::with_repository(reconciliation_item_repository.clone()));
452
453 let full_reconcile_repository = Arc::new(FullReconcileRepository::new(db_pool.clone()));
455 let full_reconcile_service = Arc::new(FullReconcileService::with_repository(full_reconcile_repository.clone()));
456
457 let partial_reconcile_repository = Arc::new(PartialReconcileRepository::new(db_pool.clone()));
459 let partial_reconcile_service = Arc::new(PartialReconcileService::with_repository(partial_reconcile_repository.clone()));
460
461 let reconcile_graph_repository = std::sync::Arc::new(
465 crate::infrastructure::persistence::reconcile_graph_repository::SqlxReconcileGraphRepository::new(),
466 );
467 let reconcile_posting_repository = std::sync::Arc::new(
468 crate::infrastructure::persistence::posting_repository::SqlxPostingRepository::new(
469 db_pool.clone(),
470 ),
471 );
472 let reconcile_write_service = std::sync::Arc::new(
473 crate::application::service::reconcile_write_service::ReconcileWriteService::new(
474 reconcile_graph_repository,
475 reconcile_posting_repository,
476 db_pool.clone(),
477 None,
478 )
479 .with_deferred_tax_if_set(self.deferred_tax.clone()),
480 );
481 let chart_install_service = std::sync::Arc::new(
484 crate::application::service::chart_install_service::ChartInstallService::new(
485 std::sync::Arc::new(
486 crate::infrastructure::persistence::chart_install_repository::SqlxChartInstallRepository::new(),
487 ),
488 db_pool.clone(),
489 self.chart_datasets,
490 ),
491 );
492 let reporting_service = std::sync::Arc::new(
494 crate::application::service::reporting_service::ReportingService::new(
495 std::sync::Arc::new(
496 crate::infrastructure::persistence::reporting_repository::SqlxReportingRepository::new(
497 db_pool.clone(),
498 ),
499 ),
500 ),
501 );
502 let check_printing_service = std::sync::Arc::new(
505 crate::application::service::check_printing_service::CheckPrintingService::new(
506 db_pool.clone(),
507 ),
508 );
509 let emv_qr_service = std::sync::Arc::new(
511 crate::application::service::emv_qr_service::EmvQrService::new(db_pool.clone()),
512 );
513 let tax_tag_repair_service = std::sync::Arc::new(
515 crate::application::service::tax_tag_repair_service::TaxTagRepairService::new(
516 db_pool.clone(),
517 ),
518 );
519 Ok(AccountingModule {
522 account_service,
523 accounting_post_service,
524 cost_center_service,
525 emv_qr_config_service,
526 bank_check_sequence_service,
527 printed_check_service,
528 tax_tag_repair_run_service,
529 financial_statement_service,
530 fiscal_period_service,
531 journal_service,
532 journal_line_service,
533 ledger_service,
534 reconciliation_service,
535 reconciliation_item_service,
536 full_reconcile_service,
537 partial_reconcile_service,
538 db_pool,
540 reconcile_write_service,
541 deferred_tax: self.deferred_tax,
542 budget_control: self.budget_control,
543 chart_install_service,
544 reporting_service,
545 check_printing_service,
546 emv_qr_service,
547 tax_tag_repair_service,
548 })
550 }
551}
552
553impl Default for AccountingModuleBuilder {
554 fn default() -> Self {
555 Self::new()
556 }
557}