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;
27pub use domain::entity::*;
32
33pub use infrastructure::persistence::*;
35
36pub use application::service::AccountService;
38pub use application::service::AccountingPostService;
39pub use application::service::CostCenterService;
40pub use application::service::EmvQrConfigService;
41pub use application::service::BankCheckSequenceService;
42pub use application::service::PrintedCheckService;
43pub use application::service::TaxTagRepairRunService;
44pub use application::service::FinancialStatementService;
45pub use application::service::FiscalPeriodService;
46pub use application::service::JournalService;
47pub use application::service::JournalLineService;
48pub use application::service::LedgerService;
49pub use application::service::ReconciliationService;
50pub use application::service::ReconciliationItemService;
51pub use application::service::FullReconcileService;
52pub use application::service::PartialReconcileService;
53
54pub use application::validator::{ValidationError, ValidationResult};
56
57pub use application::workflows::*;
59
60use std::sync::Arc;
61use axum::Router;
62use sqlx::PgPool;
63
64pub struct AccountingModule {
77 pub(crate) account_service: Arc<AccountService>,
78 pub(crate) accounting_post_service: Arc<AccountingPostService>,
79 pub(crate) cost_center_service: Arc<CostCenterService>,
80 pub(crate) emv_qr_config_service: Arc<EmvQrConfigService>,
81 pub(crate) bank_check_sequence_service: Arc<BankCheckSequenceService>,
82 pub(crate) printed_check_service: Arc<PrintedCheckService>,
83 pub(crate) tax_tag_repair_run_service: Arc<TaxTagRepairRunService>,
84 pub(crate) financial_statement_service: Arc<FinancialStatementService>,
85 pub(crate) fiscal_period_service: Arc<FiscalPeriodService>,
86 pub(crate) journal_service: Arc<JournalService>,
87 pub(crate) journal_line_service: Arc<JournalLineService>,
88 pub(crate) ledger_service: Arc<LedgerService>,
89 pub(crate) reconciliation_service: Arc<ReconciliationService>,
90 pub(crate) reconciliation_item_service: Arc<ReconciliationItemService>,
91 pub(crate) full_reconcile_service: Arc<FullReconcileService>,
92 pub(crate) partial_reconcile_service: Arc<PartialReconcileService>,
93 pub(crate) db_pool: PgPool,
95 pub(crate) reconcile_write_service:
96 Arc<crate::application::service::reconcile_write_service::ReconcileWriteService>,
97 pub(crate) check_printing_service:
100 Arc<crate::application::service::check_printing_service::CheckPrintingService>,
101 pub(crate) emv_qr_service:
104 Arc<crate::application::service::emv_qr_service::EmvQrService>,
105 pub(crate) tax_tag_repair_service:
107 Arc<crate::application::service::tax_tag_repair_service::TaxTagRepairService>,
108 pub(crate) deferred_tax: Option<Arc<dyn crate::domain::repositories::DeferredTaxLookup>>,
111 pub(crate) budget_control: Option<Arc<dyn crate::domain::repositories::BudgetControlPort>>,
115 pub(crate) chart_install_service:
117 Arc<crate::application::service::chart_install_service::ChartInstallService>,
118 pub(crate) reporting_service:
120 Arc<crate::application::service::reporting_service::ReportingService>,
121 }
123
124impl AccountingModule {
125 pub fn builder() -> AccountingModuleBuilder {
127 AccountingModuleBuilder::new()
128 }
129
130 pub fn all_crud_routes(&self) -> Router {
136 use presentation::http::{
137 create_account_routes,
138 create_accounting_post_routes,
139 create_cost_center_routes,
140 create_emv_qr_config_routes,
141 create_bank_check_sequence_routes,
142 create_printed_check_routes,
143 create_tax_tag_repair_run_routes,
144 create_financial_statement_routes,
145 create_fiscal_period_read_routes,
146 create_journal_routes,
147 create_journal_line_routes,
148 create_ledger_routes,
149 create_reconciliation_routes,
150 create_reconciliation_item_routes,
151 create_full_reconcile_routes,
152 create_partial_reconcile_routes,
153 };
154
155 Router::new()
156 .merge(create_account_routes(self.account_service.clone()))
157 .merge(create_accounting_post_routes(self.accounting_post_service.clone()))
158 .merge(create_cost_center_routes(self.cost_center_service.clone()))
159 .merge(create_emv_qr_config_routes(self.emv_qr_config_service.clone()))
160 .merge(create_bank_check_sequence_routes(self.bank_check_sequence_service.clone()))
161 .merge(create_printed_check_routes(self.printed_check_service.clone()))
162 .merge(create_tax_tag_repair_run_routes(self.tax_tag_repair_run_service.clone()))
163 .merge(create_financial_statement_routes(self.financial_statement_service.clone()))
164 .merge(create_fiscal_period_read_routes(self.fiscal_period_service.clone()))
168 .merge(create_journal_routes(self.journal_service.clone()))
169 .merge(create_journal_line_routes(self.journal_line_service.clone()))
170 .merge(create_ledger_routes(self.ledger_service.clone()))
171 .merge(create_reconciliation_routes(self.reconciliation_service.clone()))
172 .merge(create_reconciliation_item_routes(self.reconciliation_item_service.clone()))
173 .merge(create_full_reconcile_routes(self.full_reconcile_service.clone()))
174 .merge(create_partial_reconcile_routes(self.partial_reconcile_service.clone()))
175 }
176
177 #[deprecated(note = "mounts unvalidated generic CRUD; prefer readonly_routes() + validated writes, or all_crud_routes() for the full/unguarded surface")]
183 pub fn routes(&self) -> Router {
184 self.all_crud_routes()
185 }
186
187 pub fn readonly_routes(&self) -> Router {
193 use presentation::http::{
194 create_account_read_routes,
195 create_accounting_post_read_routes,
196 create_cost_center_read_routes,
197 create_emv_qr_config_read_routes,
198 create_bank_check_sequence_read_routes,
199 create_printed_check_read_routes,
200 create_tax_tag_repair_run_read_routes,
201 create_financial_statement_read_routes,
202 create_fiscal_period_read_routes,
203 create_journal_read_routes,
204 create_journal_line_read_routes,
205 create_ledger_read_routes,
206 create_reconciliation_read_routes,
207 create_reconciliation_item_read_routes,
208 create_full_reconcile_read_routes,
209 create_partial_reconcile_read_routes,
210 };
211
212 Router::new()
213 .merge(create_account_read_routes(self.account_service.clone()))
214 .merge(create_accounting_post_read_routes(self.accounting_post_service.clone()))
215 .merge(create_cost_center_read_routes(self.cost_center_service.clone()))
216 .merge(create_emv_qr_config_read_routes(self.emv_qr_config_service.clone()))
217 .merge(create_bank_check_sequence_read_routes(self.bank_check_sequence_service.clone()))
218 .merge(create_printed_check_read_routes(self.printed_check_service.clone()))
219 .merge(create_tax_tag_repair_run_read_routes(self.tax_tag_repair_run_service.clone()))
220 .merge(create_financial_statement_read_routes(self.financial_statement_service.clone()))
221 .merge(create_fiscal_period_read_routes(self.fiscal_period_service.clone()))
222 .merge(create_journal_read_routes(self.journal_service.clone()))
223 .merge(create_journal_line_read_routes(self.journal_line_service.clone()))
224 .merge(create_ledger_read_routes(self.ledger_service.clone()))
225 .merge(create_reconciliation_read_routes(self.reconciliation_service.clone()))
226 .merge(create_reconciliation_item_read_routes(self.reconciliation_item_service.clone()))
227 .merge(create_full_reconcile_read_routes(self.full_reconcile_service.clone()))
228 .merge(create_partial_reconcile_read_routes(self.partial_reconcile_service.clone()))
229 }
230
231 pub fn budget_control(
238 &self,
239 ) -> Option<Arc<dyn crate::domain::repositories::BudgetControlPort>> {
240 self.budget_control.clone()
241 }
242
243 pub fn reporting_service(
246 &self,
247 ) -> std::sync::Arc<crate::application::service::reporting_service::ReportingService> {
248 self.reporting_service.clone()
249 }
250
251 pub fn reconcile_write_service(
255 &self,
256 ) -> std::sync::Arc<crate::application::service::reconcile_write_service::ReconcileWriteService>
257 {
258 self.reconcile_write_service.clone()
259 }
260
261 pub fn reconcile_write_service_with_exchange_account(
266 &self,
267 exchange_account_id: uuid::Uuid,
268 ) -> std::sync::Arc<crate::application::service::reconcile_write_service::ReconcileWriteService>
269 {
270 std::sync::Arc::new(
271 crate::application::service::reconcile_write_service::ReconcileWriteService::new(
272 std::sync::Arc::new(
273 crate::infrastructure::persistence::reconcile_graph_repository::SqlxReconcileGraphRepository::new(),
274 ),
275 std::sync::Arc::new(
276 crate::infrastructure::persistence::posting_repository::SqlxPostingRepository::new(
277 self.db_pool.clone(),
278 ),
279 ),
280 self.db_pool.clone(),
281 Some(exchange_account_id),
282 )
283 .with_deferred_tax_if_set(self.deferred_tax.clone()),
284 )
285 }
286
287 pub fn chart_install_service(
292 &self,
293 ) -> std::sync::Arc<crate::application::service::chart_install_service::ChartInstallService>
294 {
295 self.chart_install_service.clone()
296 }
297
298 pub fn check_printing_service(
302 &self,
303 ) -> std::sync::Arc<crate::application::service::check_printing_service::CheckPrintingService>
304 {
305 self.check_printing_service.clone()
306 }
307
308 pub fn emv_qr_service(
311 &self,
312 ) -> std::sync::Arc<crate::application::service::emv_qr_service::EmvQrService> {
313 self.emv_qr_service.clone()
314 }
315
316 pub fn tax_tag_repair_service(
320 &self,
321 ) -> std::sync::Arc<crate::application::service::tax_tag_repair_service::TaxTagRepairService>
322 {
323 self.tax_tag_repair_service.clone()
324 }
325 }
327
328pub struct AccountingModuleBuilder {
330 db_pool: Option<PgPool>,
331 deferred_tax: Option<Arc<dyn crate::domain::repositories::DeferredTaxLookup>>,
333 budget_control: Option<Arc<dyn crate::domain::repositories::BudgetControlPort>>,
334 chart_datasets: Vec<Arc<crate::domain::chart_dataset::ChartDataset>>,
335 }
337
338impl AccountingModuleBuilder {
339 pub fn new() -> Self {
341 Self {
342 db_pool: None,
343 deferred_tax: None,
345 budget_control: None,
346 chart_datasets: Vec::new(),
347 }
349 }
350
351 pub fn with_database(mut self, pool: PgPool) -> Self {
353 self.db_pool = Some(pool);
354 self
355 }
356
357 pub fn with_chart_dataset(
363 mut self,
364 dataset: Arc<crate::domain::chart_dataset::ChartDataset>,
365 ) -> Self {
366 self.chart_datasets.push(dataset);
367 self
368 }
369
370 pub fn with_deferred_tax(
375 mut self,
376 port: Arc<dyn crate::domain::repositories::DeferredTaxLookup>,
377 ) -> Self {
378 self.deferred_tax = Some(port);
379 self
380 }
381
382 pub fn with_budget_control(
389 mut self,
390 port: Arc<dyn crate::domain::repositories::BudgetControlPort>,
391 ) -> Self {
392 self.budget_control = Some(port);
393 self
394 }
395 pub fn build(self) -> anyhow::Result<AccountingModule> {
399 let db_pool = self.db_pool
400 .ok_or_else(|| anyhow::anyhow!("Database pool not configured"))?;
401
402 let account_repository = Arc::new(AccountRepository::new(db_pool.clone()));
404 let account_service = Arc::new(AccountService::with_repository(account_repository.clone()));
405
406 let accounting_post_repository = Arc::new(AccountingPostRepository::new(db_pool.clone()));
408 let accounting_post_service = Arc::new(AccountingPostService::with_repository(accounting_post_repository.clone()));
409
410 let cost_center_repository = Arc::new(CostCenterRepository::new(db_pool.clone()));
412 let cost_center_service = Arc::new(CostCenterService::with_repository(cost_center_repository.clone()));
413
414 let emv_qr_config_repository = Arc::new(EmvQrConfigRepository::new(db_pool.clone()));
416 let emv_qr_config_service = Arc::new(EmvQrConfigService::with_repository(emv_qr_config_repository.clone()));
417
418 let bank_check_sequence_repository = Arc::new(BankCheckSequenceRepository::new(db_pool.clone()));
420 let bank_check_sequence_service = Arc::new(BankCheckSequenceService::with_repository(bank_check_sequence_repository.clone()));
421
422 let printed_check_repository = Arc::new(PrintedCheckRepository::new(db_pool.clone()));
424 let printed_check_service = Arc::new(PrintedCheckService::with_repository(printed_check_repository.clone()));
425
426 let tax_tag_repair_run_repository = Arc::new(TaxTagRepairRunRepository::new(db_pool.clone()));
428 let tax_tag_repair_run_service = Arc::new(TaxTagRepairRunService::with_repository(tax_tag_repair_run_repository.clone()));
429
430 let financial_statement_repository = Arc::new(FinancialStatementRepository::new(db_pool.clone()));
432 let financial_statement_service = Arc::new(FinancialStatementService::with_repository(financial_statement_repository.clone()));
433
434 let fiscal_period_repository = Arc::new(FiscalPeriodRepository::new(db_pool.clone()));
436 let fiscal_period_service = Arc::new(FiscalPeriodService::with_repository(fiscal_period_repository.clone()));
437
438 let journal_repository = Arc::new(JournalRepository::new(db_pool.clone()));
440 let journal_service = Arc::new(JournalService::with_repository(journal_repository.clone()));
441
442 let journal_line_repository = Arc::new(JournalLineRepository::new(db_pool.clone()));
444 let journal_line_service = Arc::new(JournalLineService::with_repository(journal_line_repository.clone()));
445
446 let ledger_repository = Arc::new(LedgerRepository::new(db_pool.clone()));
448 let ledger_service = Arc::new(LedgerService::with_repository(ledger_repository.clone()));
449
450 let reconciliation_repository = Arc::new(ReconciliationRepository::new(db_pool.clone()));
452 let reconciliation_service = Arc::new(ReconciliationService::with_repository(reconciliation_repository.clone()));
453
454 let reconciliation_item_repository = Arc::new(ReconciliationItemRepository::new(db_pool.clone()));
456 let reconciliation_item_service = Arc::new(ReconciliationItemService::with_repository(reconciliation_item_repository.clone()));
457
458 let full_reconcile_repository = Arc::new(FullReconcileRepository::new(db_pool.clone()));
460 let full_reconcile_service = Arc::new(FullReconcileService::with_repository(full_reconcile_repository.clone()));
461
462 let partial_reconcile_repository = Arc::new(PartialReconcileRepository::new(db_pool.clone()));
464 let partial_reconcile_service = Arc::new(PartialReconcileService::with_repository(partial_reconcile_repository.clone()));
465
466 let reconcile_graph_repository = std::sync::Arc::new(
470 crate::infrastructure::persistence::reconcile_graph_repository::SqlxReconcileGraphRepository::new(),
471 );
472 let reconcile_posting_repository = std::sync::Arc::new(
473 crate::infrastructure::persistence::posting_repository::SqlxPostingRepository::new(
474 db_pool.clone(),
475 ),
476 );
477 let reconcile_write_service = std::sync::Arc::new(
478 crate::application::service::reconcile_write_service::ReconcileWriteService::new(
479 reconcile_graph_repository,
480 reconcile_posting_repository,
481 db_pool.clone(),
482 None,
483 )
484 .with_deferred_tax_if_set(self.deferred_tax.clone()),
485 );
486 let chart_install_service = std::sync::Arc::new(
489 crate::application::service::chart_install_service::ChartInstallService::new(
490 std::sync::Arc::new(
491 crate::infrastructure::persistence::chart_install_repository::SqlxChartInstallRepository::new(),
492 ),
493 db_pool.clone(),
494 self.chart_datasets,
495 ),
496 );
497 let reporting_service = std::sync::Arc::new(
499 crate::application::service::reporting_service::ReportingService::new(
500 std::sync::Arc::new(
501 crate::infrastructure::persistence::reporting_repository::SqlxReportingRepository::new(
502 db_pool.clone(),
503 ),
504 ),
505 ),
506 );
507 let check_printing_service = std::sync::Arc::new(
510 crate::application::service::check_printing_service::CheckPrintingService::new(
511 db_pool.clone(),
512 ),
513 );
514 let emv_qr_service = std::sync::Arc::new(
516 crate::application::service::emv_qr_service::EmvQrService::new(db_pool.clone()),
517 );
518 let tax_tag_repair_service = std::sync::Arc::new(
520 crate::application::service::tax_tag_repair_service::TaxTagRepairService::new(
521 db_pool.clone(),
522 ),
523 );
524 Ok(AccountingModule {
527 account_service,
528 accounting_post_service,
529 cost_center_service,
530 emv_qr_config_service,
531 bank_check_sequence_service,
532 printed_check_service,
533 tax_tag_repair_run_service,
534 financial_statement_service,
535 fiscal_period_service,
536 journal_service,
537 journal_line_service,
538 ledger_service,
539 reconciliation_service,
540 reconciliation_item_service,
541 full_reconcile_service,
542 partial_reconcile_service,
543 db_pool,
545 reconcile_write_service,
546 deferred_tax: self.deferred_tax,
547 budget_control: self.budget_control,
548 chart_install_service,
549 reporting_service,
550 check_printing_service,
551 emv_qr_service,
552 tax_tag_repair_service,
553 })
555 }
556}
557
558impl Default for AccountingModuleBuilder {
559 fn default() -> Self {
560 Self::new()
561 }
562}