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::CompensationChangeService;
36pub use application::service::PayrollEntryService;
37pub use application::service::SalarySlipService;
38pub use application::service::SalarySlipLineService;
39pub use application::service::SalaryStructureService;
40pub use application::service::SalaryComponentService;
41
42pub mod request_pool;
47pub use application::service::{
52 bpjs_kesehatan, bpjs_ketenagakerjaan, compute_statutory, overtime_pay, pph21, pph21_ter, thr,
53 AccountingPostEnvelope, ComputedSlipRequest, EmployeeStatutory, EmployeeStatutoryInputs,
54 GlPostAck, GlPostLine, GlPostRejected, GlPostSink, LoggingSink, NewComponent, NewPayrollEntry,
55 NewSalarySlip, NewStructure, OvertimeInputs, PayrollError, PayrollEvent, PayrollEventError,
56 PayrollEventSink, PayrollPayable, PayrollPosted, PayrollWriteService, PoolEmployeeStatutoryInputs,
57 PoolOvertimeInputs, PostOutcome, Pph21Method, RemitAck, RemitOutcome, RemittanceInstruction,
58 RemittanceSeamError, RemittanceSink, StatutoryAccounts, StatutoryConfig, StatutoryError,
59 UnwiredGlSink, UnwiredRemittance,
60};
61pub use presentation::http::create_guarded_payroll_routes;
62use std::sync::Arc;
64use axum::Router;
65use sqlx::PgPool;
66
67pub struct PayrollModule {
80 pub(crate) compensation_change_service: Arc<CompensationChangeService>,
81 pub(crate) payroll_entry_service: Arc<PayrollEntryService>,
82 pub(crate) salary_slip_service: Arc<SalarySlipService>,
83 pub(crate) salary_slip_line_service: Arc<SalarySlipLineService>,
84 pub(crate) salary_structure_service: Arc<SalaryStructureService>,
85 pub(crate) salary_component_service: Arc<SalaryComponentService>,
86 pub(crate) payroll_write_service: Arc<PayrollWriteService>,
90 }
92
93impl PayrollModule {
94 pub fn builder() -> PayrollModuleBuilder {
96 PayrollModuleBuilder::new()
97 }
98
99 pub fn all_crud_routes(&self) -> Router {
105 use presentation::http::{
106 create_compensation_change_read_routes,
107 create_payroll_entry_routes,
108 create_salary_slip_routes,
109 create_salary_slip_line_routes,
110 create_salary_structure_routes,
111 create_salary_component_routes,
112 };
113
114 Router::new()
115 .merge(create_compensation_change_read_routes(self.compensation_change_service.clone()))
116 .merge(create_payroll_entry_routes(self.payroll_entry_service.clone()))
117 .merge(create_salary_slip_routes(self.salary_slip_service.clone()))
118 .merge(create_salary_slip_line_routes(self.salary_slip_line_service.clone()))
119 .merge(create_salary_structure_routes(self.salary_structure_service.clone()))
120 .merge(create_salary_component_routes(self.salary_component_service.clone()))
121 }
122
123 #[deprecated(note = "mounts unvalidated generic CRUD; prefer readonly_routes() + validated writes, or all_crud_routes() for the full/unguarded surface")]
129 pub fn routes(&self) -> Router {
130 self.all_crud_routes()
131 }
132
133 pub fn readonly_routes(&self) -> Router {
139 use presentation::http::{
140 create_compensation_change_read_routes,
141 create_payroll_entry_read_routes,
142 create_salary_slip_read_routes,
143 create_salary_slip_line_read_routes,
144 create_salary_structure_read_routes,
145 create_salary_component_read_routes,
146 };
147
148 Router::new()
149 .merge(create_compensation_change_read_routes(self.compensation_change_service.clone()))
150 .merge(create_payroll_entry_read_routes(self.payroll_entry_service.clone()))
151 .merge(create_salary_slip_read_routes(self.salary_slip_service.clone()))
152 .merge(create_salary_slip_line_read_routes(self.salary_slip_line_service.clone()))
153 .merge(create_salary_structure_read_routes(self.salary_structure_service.clone()))
154 .merge(create_salary_component_read_routes(self.salary_component_service.clone()))
155 }
156
157 pub fn payroll_write_service(&self) -> Arc<PayrollWriteService> {
160 self.payroll_write_service.clone()
161 }
162
163 pub fn with_payroll_write_service(mut self, svc: Arc<PayrollWriteService>) -> Self {
179 self.payroll_write_service = svc;
180 self
181 }
182 }
184
185pub struct PayrollModuleBuilder {
187 db_pool: Option<PgPool>,
188}
189
190impl PayrollModuleBuilder {
191 pub fn new() -> Self {
193 Self {
194 db_pool: None,
195 }
196 }
197
198 pub fn with_database(mut self, pool: PgPool) -> Self {
200 self.db_pool = Some(pool);
201 self
202 }
203
204 pub fn build(self) -> anyhow::Result<PayrollModule> {
209 let db_pool = self.db_pool
210 .ok_or_else(|| anyhow::anyhow!("Database pool not configured"))?;
211
212 let compensation_change_repository = Arc::new(CompensationChangeRepository::new(db_pool.clone()));
214 let compensation_change_service = Arc::new(CompensationChangeService::with_repository(compensation_change_repository.clone()));
215
216 let payroll_entry_repository = Arc::new(PayrollEntryRepository::new(db_pool.clone()));
218 let payroll_entry_service = Arc::new(PayrollEntryService::with_repository(payroll_entry_repository.clone()));
219
220 let salary_slip_repository = Arc::new(SalarySlipRepository::new(db_pool.clone()));
222 let salary_slip_service = Arc::new(SalarySlipService::with_repository(salary_slip_repository.clone()));
223
224 let salary_slip_line_repository = Arc::new(SalarySlipLineRepository::new(db_pool.clone()));
226 let salary_slip_line_service = Arc::new(SalarySlipLineService::with_repository(salary_slip_line_repository.clone()));
227
228 let salary_structure_repository = Arc::new(SalaryStructureRepository::new(db_pool.clone()));
230 let salary_structure_service = Arc::new(SalaryStructureService::with_repository(salary_structure_repository.clone()));
231
232 let salary_component_repository = Arc::new(SalaryComponentRepository::new(db_pool.clone()));
234 let salary_component_service = Arc::new(SalaryComponentService::with_repository(salary_component_repository.clone()));
235
236 let payroll_write_service = Arc::new(PayrollWriteService::new(db_pool.clone()));
241 Ok(PayrollModule {
244 compensation_change_service,
245 payroll_entry_service,
246 salary_slip_service,
247 salary_slip_line_service,
248 salary_structure_service,
249 salary_component_service,
250 payroll_write_service,
252 })
254 }
255}
256
257impl Default for PayrollModuleBuilder {
258 fn default() -> Self {
259 Self::new()
260 }
261}