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
28#[path = "lib.ext.rs"]
30mod lib_ext;
31pub use lib_ext::*;
32#[allow(dead_code)]
34pub(crate) type ThisModule = AccountingModule;
35#[allow(dead_code)]
36pub(crate) type ThisModuleBuilder = AccountingModuleBuilder;
37
38pub use domain::entity::*;
40
41pub use infrastructure::persistence::*;
43
44pub use application::service::AccountService;
46pub use application::service::AccountingPostService;
47pub use application::service::CostCenterService;
48pub use application::service::EmvQrConfigService;
49pub use application::service::BankCheckSequenceService;
50pub use application::service::PrintedCheckService;
51pub use application::service::TaxTagRepairRunService;
52pub use application::service::FinancialStatementService;
53pub use application::service::FiscalPeriodService;
54pub use application::service::JournalService;
55pub use application::service::JournalLineService;
56pub use application::service::LedgerService;
57pub use application::service::ReconciliationService;
58pub use application::service::ReconciliationItemService;
59pub use application::service::FullReconcileService;
60pub use application::service::PartialReconcileService;
61
62pub use application::workflows::*;
64
65use std::sync::Arc;
66use axum::Router;
67use sqlx::PgPool;
68
69pub struct AccountingModule {
82 pub(crate) account_service: Arc<AccountService>,
83 pub(crate) accounting_post_service: Arc<AccountingPostService>,
84 pub(crate) cost_center_service: Arc<CostCenterService>,
85 pub(crate) emv_qr_config_service: Arc<EmvQrConfigService>,
86 pub(crate) bank_check_sequence_service: Arc<BankCheckSequenceService>,
87 pub(crate) printed_check_service: Arc<PrintedCheckService>,
88 pub(crate) tax_tag_repair_run_service: Arc<TaxTagRepairRunService>,
89 pub(crate) financial_statement_service: Arc<FinancialStatementService>,
90 pub(crate) fiscal_period_service: Arc<FiscalPeriodService>,
91 pub(crate) journal_service: Arc<JournalService>,
92 pub(crate) journal_line_service: Arc<JournalLineService>,
93 pub(crate) ledger_service: Arc<LedgerService>,
94 pub(crate) reconciliation_service: Arc<ReconciliationService>,
95 pub(crate) reconciliation_item_service: Arc<ReconciliationItemService>,
96 pub(crate) full_reconcile_service: Arc<FullReconcileService>,
97 pub(crate) partial_reconcile_service: Arc<PartialReconcileService>,
98 pub(crate) ext: ModuleExt,
100}
101
102impl std::ops::Deref for AccountingModule {
103 type Target = ModuleExt;
104 fn deref(&self) -> &Self::Target {
105 &self.ext
106 }
107}
108
109impl std::ops::DerefMut for AccountingModule {
110 fn deref_mut(&mut self) -> &mut Self::Target {
111 &mut self.ext
112 }
113}
114
115#[allow(dead_code)]
117pub(crate) struct ModuleParts<'a> {
118 pub(crate) db_pool: &'a PgPool,
119 pub(crate) account_service: &'a Arc<AccountService>,
120 pub(crate) account_repository: &'a Arc<AccountRepository>,
121 pub(crate) accounting_post_service: &'a Arc<AccountingPostService>,
122 pub(crate) accounting_post_repository: &'a Arc<AccountingPostRepository>,
123 pub(crate) cost_center_service: &'a Arc<CostCenterService>,
124 pub(crate) cost_center_repository: &'a Arc<CostCenterRepository>,
125 pub(crate) emv_qr_config_service: &'a Arc<EmvQrConfigService>,
126 pub(crate) emv_qr_config_repository: &'a Arc<EmvQrConfigRepository>,
127 pub(crate) bank_check_sequence_service: &'a Arc<BankCheckSequenceService>,
128 pub(crate) bank_check_sequence_repository: &'a Arc<BankCheckSequenceRepository>,
129 pub(crate) printed_check_service: &'a Arc<PrintedCheckService>,
130 pub(crate) printed_check_repository: &'a Arc<PrintedCheckRepository>,
131 pub(crate) tax_tag_repair_run_service: &'a Arc<TaxTagRepairRunService>,
132 pub(crate) tax_tag_repair_run_repository: &'a Arc<TaxTagRepairRunRepository>,
133 pub(crate) financial_statement_service: &'a Arc<FinancialStatementService>,
134 pub(crate) financial_statement_repository: &'a Arc<FinancialStatementRepository>,
135 pub(crate) fiscal_period_service: &'a Arc<FiscalPeriodService>,
136 pub(crate) fiscal_period_repository: &'a Arc<FiscalPeriodRepository>,
137 pub(crate) journal_service: &'a Arc<JournalService>,
138 pub(crate) journal_repository: &'a Arc<JournalRepository>,
139 pub(crate) journal_line_service: &'a Arc<JournalLineService>,
140 pub(crate) journal_line_repository: &'a Arc<JournalLineRepository>,
141 pub(crate) ledger_service: &'a Arc<LedgerService>,
142 pub(crate) ledger_repository: &'a Arc<LedgerRepository>,
143 pub(crate) reconciliation_service: &'a Arc<ReconciliationService>,
144 pub(crate) reconciliation_repository: &'a Arc<ReconciliationRepository>,
145 pub(crate) reconciliation_item_service: &'a Arc<ReconciliationItemService>,
146 pub(crate) reconciliation_item_repository: &'a Arc<ReconciliationItemRepository>,
147 pub(crate) full_reconcile_service: &'a Arc<FullReconcileService>,
148 pub(crate) full_reconcile_repository: &'a Arc<FullReconcileRepository>,
149 pub(crate) partial_reconcile_service: &'a Arc<PartialReconcileService>,
150 pub(crate) partial_reconcile_repository: &'a Arc<PartialReconcileRepository>,
151}
152
153impl AccountingModule {
154 pub fn builder() -> AccountingModuleBuilder {
156 AccountingModuleBuilder::new()
157 }
158
159 pub fn all_crud_routes(&self) -> Router {
165 use presentation::http::{
166 create_account_routes,
167 create_accounting_post_routes,
168 create_cost_center_routes,
169 create_emv_qr_config_routes,
170 create_bank_check_sequence_routes,
171 create_printed_check_routes,
172 create_tax_tag_repair_run_routes,
173 create_financial_statement_routes,
174 create_fiscal_period_read_routes,
175 create_journal_routes,
176 create_journal_line_routes,
177 create_ledger_routes,
178 create_reconciliation_routes,
179 create_reconciliation_item_routes,
180 create_full_reconcile_routes,
181 create_partial_reconcile_routes,
182 };
183
184 Router::new()
185 .merge(create_account_routes(self.account_service.clone()))
186 .merge(create_accounting_post_routes(self.accounting_post_service.clone()))
187 .merge(create_cost_center_routes(self.cost_center_service.clone()))
188 .merge(create_emv_qr_config_routes(self.emv_qr_config_service.clone()))
189 .merge(create_bank_check_sequence_routes(self.bank_check_sequence_service.clone()))
190 .merge(create_printed_check_routes(self.printed_check_service.clone()))
191 .merge(create_tax_tag_repair_run_routes(self.tax_tag_repair_run_service.clone()))
192 .merge(create_financial_statement_routes(self.financial_statement_service.clone()))
193 .merge(create_fiscal_period_read_routes(self.fiscal_period_service.clone()))
197 .merge(create_journal_routes(self.journal_service.clone()))
198 .merge(create_journal_line_routes(self.journal_line_service.clone()))
199 .merge(create_ledger_routes(self.ledger_service.clone()))
200 .merge(create_reconciliation_routes(self.reconciliation_service.clone()))
201 .merge(create_reconciliation_item_routes(self.reconciliation_item_service.clone()))
202 .merge(create_full_reconcile_routes(self.full_reconcile_service.clone()))
203 .merge(create_partial_reconcile_routes(self.partial_reconcile_service.clone()))
204 }
205
206 #[deprecated(note = "mounts unvalidated generic CRUD; prefer readonly_routes() + validated writes, or all_crud_routes() for the full/unguarded surface")]
212 pub fn routes(&self) -> Router {
213 self.all_crud_routes()
214 }
215
216 pub fn readonly_routes(&self) -> Router {
222 use presentation::http::{
223 create_account_read_routes,
224 create_accounting_post_read_routes,
225 create_cost_center_read_routes,
226 create_emv_qr_config_read_routes,
227 create_bank_check_sequence_read_routes,
228 create_printed_check_read_routes,
229 create_tax_tag_repair_run_read_routes,
230 create_financial_statement_read_routes,
231 create_fiscal_period_read_routes,
232 create_journal_read_routes,
233 create_journal_line_read_routes,
234 create_ledger_read_routes,
235 create_reconciliation_read_routes,
236 create_reconciliation_item_read_routes,
237 create_full_reconcile_read_routes,
238 create_partial_reconcile_read_routes,
239 };
240
241 Router::new()
242 .merge(create_account_read_routes(self.account_service.clone()))
243 .merge(create_accounting_post_read_routes(self.accounting_post_service.clone()))
244 .merge(create_cost_center_read_routes(self.cost_center_service.clone()))
245 .merge(create_emv_qr_config_read_routes(self.emv_qr_config_service.clone()))
246 .merge(create_bank_check_sequence_read_routes(self.bank_check_sequence_service.clone()))
247 .merge(create_printed_check_read_routes(self.printed_check_service.clone()))
248 .merge(create_tax_tag_repair_run_read_routes(self.tax_tag_repair_run_service.clone()))
249 .merge(create_financial_statement_read_routes(self.financial_statement_service.clone()))
250 .merge(create_fiscal_period_read_routes(self.fiscal_period_service.clone()))
251 .merge(create_journal_read_routes(self.journal_service.clone()))
252 .merge(create_journal_line_read_routes(self.journal_line_service.clone()))
253 .merge(create_ledger_read_routes(self.ledger_service.clone()))
254 .merge(create_reconciliation_read_routes(self.reconciliation_service.clone()))
255 .merge(create_reconciliation_item_read_routes(self.reconciliation_item_service.clone()))
256 .merge(create_full_reconcile_read_routes(self.full_reconcile_service.clone()))
257 .merge(create_partial_reconcile_read_routes(self.partial_reconcile_service.clone()))
258 }
259
260}
261
262pub struct AccountingModuleBuilder {
264 db_pool: Option<PgPool>,
265 ext: ModuleBuilderExt,
267}
268
269impl std::ops::Deref for AccountingModuleBuilder {
270 type Target = ModuleBuilderExt;
271 fn deref(&self) -> &Self::Target {
272 &self.ext
273 }
274}
275
276impl std::ops::DerefMut for AccountingModuleBuilder {
277 fn deref_mut(&mut self) -> &mut Self::Target {
278 &mut self.ext
279 }
280}
281
282impl AccountingModuleBuilder {
283 pub fn new() -> Self {
285 Self {
286 db_pool: None,
287 ext: Default::default(),
288 }
289 }
290
291 pub fn with_database(mut self, pool: PgPool) -> Self {
293 self.db_pool = Some(pool);
294 self
295 }
296
297
298 pub fn build(self) -> anyhow::Result<AccountingModule> {
300 let db_pool = self.db_pool
301 .ok_or_else(|| anyhow::anyhow!("Database pool not configured"))?;
302
303 let account_repository = Arc::new(AccountRepository::new(db_pool.clone()));
305 let account_service = Arc::new(AccountService::with_repository(account_repository.clone()).with_guard(Arc::new(crate::application::service::AccountRowRules)));
306
307 let accounting_post_repository = Arc::new(AccountingPostRepository::new(db_pool.clone()));
309 let accounting_post_service = Arc::new(AccountingPostService::with_repository(accounting_post_repository.clone()).with_guard(Arc::new(crate::application::service::AccountingPostRowRules)));
310
311 let cost_center_repository = Arc::new(CostCenterRepository::new(db_pool.clone()));
313 let cost_center_service = Arc::new(CostCenterService::with_repository(cost_center_repository.clone()).with_guard(Arc::new(crate::application::service::CostCenterRowRules)));
314
315 let emv_qr_config_repository = Arc::new(EmvQrConfigRepository::new(db_pool.clone()));
317 let emv_qr_config_service = Arc::new(EmvQrConfigService::with_repository(emv_qr_config_repository.clone()).with_guard(Arc::new(crate::application::service::EmvQrConfigRowRules)));
318
319 let bank_check_sequence_repository = Arc::new(BankCheckSequenceRepository::new(db_pool.clone()));
321 let bank_check_sequence_service = Arc::new(BankCheckSequenceService::with_repository(bank_check_sequence_repository.clone()).with_guard(Arc::new(crate::application::service::BankCheckSequenceRowRules)));
322
323 let printed_check_repository = Arc::new(PrintedCheckRepository::new(db_pool.clone()));
325 let printed_check_service = Arc::new(PrintedCheckService::with_repository(printed_check_repository.clone()).with_guard(Arc::new(crate::application::service::PrintedCheckRowRules)));
326
327 let tax_tag_repair_run_repository = Arc::new(TaxTagRepairRunRepository::new(db_pool.clone()));
329 let tax_tag_repair_run_service = Arc::new(TaxTagRepairRunService::with_repository(tax_tag_repair_run_repository.clone()).with_guard(Arc::new(crate::application::service::TaxTagRepairRunRowRules)));
330
331 let financial_statement_repository = Arc::new(FinancialStatementRepository::new(db_pool.clone()));
333 let financial_statement_service = Arc::new(FinancialStatementService::with_repository(financial_statement_repository.clone()).with_guard(Arc::new(crate::application::service::FinancialStatementRowRules)));
334
335 let fiscal_period_repository = Arc::new(FiscalPeriodRepository::new(db_pool.clone()));
337 let fiscal_period_service = Arc::new(FiscalPeriodService::with_repository(fiscal_period_repository.clone()).with_guard(Arc::new(crate::application::service::FiscalPeriodRowRules)));
338
339 let journal_repository = Arc::new(JournalRepository::new(db_pool.clone()));
341 let journal_service = Arc::new(JournalService::with_repository(journal_repository.clone()).with_guard(Arc::new(crate::application::service::JournalRowRules)));
342
343 let journal_line_repository = Arc::new(JournalLineRepository::new(db_pool.clone()));
345 let journal_line_service = Arc::new(JournalLineService::with_repository(journal_line_repository.clone()).with_guard(Arc::new(crate::application::service::JournalLineRowRules)));
346
347 let ledger_repository = Arc::new(LedgerRepository::new(db_pool.clone()));
349 let ledger_service = Arc::new(LedgerService::with_repository(ledger_repository.clone()).with_guard(Arc::new(crate::application::service::LedgerRowRules)));
350
351 let reconciliation_repository = Arc::new(ReconciliationRepository::new(db_pool.clone()));
353 let reconciliation_service = Arc::new(ReconciliationService::with_repository(reconciliation_repository.clone()).with_guard(Arc::new(crate::application::service::ReconciliationRowRules)));
354
355 let reconciliation_item_repository = Arc::new(ReconciliationItemRepository::new(db_pool.clone()));
357 let reconciliation_item_service = Arc::new(ReconciliationItemService::with_repository(reconciliation_item_repository.clone()).with_guard(Arc::new(crate::application::service::ReconciliationItemRowRules)));
358
359 let full_reconcile_repository = Arc::new(FullReconcileRepository::new(db_pool.clone()));
361 let full_reconcile_service = Arc::new(FullReconcileService::with_repository(full_reconcile_repository.clone()));
362
363 let partial_reconcile_repository = Arc::new(PartialReconcileRepository::new(db_pool.clone()));
365 let partial_reconcile_service = Arc::new(PartialReconcileService::with_repository(partial_reconcile_repository.clone()).with_guard(Arc::new(crate::application::service::PartialReconcileRowRules)));
366
367
368 let ext = self.ext.build(&ModuleParts {
370 db_pool: &db_pool,
371 account_service: &account_service,
372 account_repository: &account_repository,
373 accounting_post_service: &accounting_post_service,
374 accounting_post_repository: &accounting_post_repository,
375 cost_center_service: &cost_center_service,
376 cost_center_repository: &cost_center_repository,
377 emv_qr_config_service: &emv_qr_config_service,
378 emv_qr_config_repository: &emv_qr_config_repository,
379 bank_check_sequence_service: &bank_check_sequence_service,
380 bank_check_sequence_repository: &bank_check_sequence_repository,
381 printed_check_service: &printed_check_service,
382 printed_check_repository: &printed_check_repository,
383 tax_tag_repair_run_service: &tax_tag_repair_run_service,
384 tax_tag_repair_run_repository: &tax_tag_repair_run_repository,
385 financial_statement_service: &financial_statement_service,
386 financial_statement_repository: &financial_statement_repository,
387 fiscal_period_service: &fiscal_period_service,
388 fiscal_period_repository: &fiscal_period_repository,
389 journal_service: &journal_service,
390 journal_repository: &journal_repository,
391 journal_line_service: &journal_line_service,
392 journal_line_repository: &journal_line_repository,
393 ledger_service: &ledger_service,
394 ledger_repository: &ledger_repository,
395 reconciliation_service: &reconciliation_service,
396 reconciliation_repository: &reconciliation_repository,
397 reconciliation_item_service: &reconciliation_item_service,
398 reconciliation_item_repository: &reconciliation_item_repository,
399 full_reconcile_service: &full_reconcile_service,
400 full_reconcile_repository: &full_reconcile_repository,
401 partial_reconcile_service: &partial_reconcile_service,
402 partial_reconcile_repository: &partial_reconcile_repository,
403 })?;
404
405 Ok(AccountingModule {
406 account_service,
407 accounting_post_service,
408 cost_center_service,
409 emv_qr_config_service,
410 bank_check_sequence_service,
411 printed_check_service,
412 tax_tag_repair_run_service,
413 financial_statement_service,
414 fiscal_period_service,
415 journal_service,
416 journal_line_service,
417 ledger_service,
418 reconciliation_service,
419 reconciliation_item_service,
420 full_reconcile_service,
421 partial_reconcile_service,
422 ext,
423 })
424 }
425}
426
427impl Default for AccountingModuleBuilder {
428 fn default() -> Self {
429 Self::new()
430 }
431}