Skip to main content

PayrollWriteService

Struct PayrollWriteService 

Source
pub struct PayrollWriteService { /* private fields */ }

Implementations§

Source§

impl PayrollWriteService

Source

pub fn new(pool: PgPool) -> Self

Source

pub fn with_overtime_inputs(self, inputs: Box<dyn OvertimeInputs>) -> Self

Override where overtime hours come from (default: the pool read mirroring attendance’s export).

Source

pub fn set_timesheet_inputs(&self, inputs: Arc<dyn ApprovedTimesheetInputs>)

Wire the approved-timesheet input port (the composing app’s adapter when it wants the SQL in one place; the pool default reads the timesheet tables directly under the fence).

Source

pub fn with_employee_inputs( self, inputs: Box<dyn EmployeeStatutoryInputs>, ) -> Self

Override where employee statutory facts come from (default: the pool read mirroring the employee module’s export).

Source

pub fn with_gl_sink(self, sink: Arc<dyn GlPostSink>) -> Self

Override the GL-posting seam (default UnwiredGlSink — post refuses with gl_seam_unwired).

Source

pub fn with_event_sink(self, sink: Arc<dyn PayrollEventSink>) -> Self

Override the domain-event sink (default LoggingSink). A durable composition stages into an outbox here.

Source

pub fn with_remit_sink(self, sink: Arc<dyn RemittanceSink>) -> Self

Override the remittance seam (default UnwiredRemittance — remit refuses with remittance_seam_unwired).

Source

pub async fn post_run( &self, run_id: Uuid, posting_date: NaiveDate, ) -> Result<PostOutcome, PayrollError>

Post through the module-held GL + event seams — the composition-root convenience over Self::post_payroll_entry (which stays public for callers supplying their own sinks, e.g. tests driving a real accounting adapter).

Source

pub async fn remit_run( &self, run_id: Uuid, ) -> Result<RemitOutcome, PayrollError>

Remit through the module-held remittance seam — the composition-root convenience over Self::remit_payroll_entry.

Source

pub async fn create_structure( &self, s: NewStructure, ) -> Result<Uuid, PayrollError>

Define a salary structure with its earning/deduction components.

Source

pub async fn create_payroll_entry( &self, e: NewPayrollEntry, ) -> Result<Uuid, PayrollError>

Open a payroll run for a period (draft). Unique per (org unit, year, month) once the composing service’s tenancy decorator has re-declared the run unique org-scoped.

Source

pub async fn add_salary_slip( &self, run_id: Uuid, s: NewSalarySlip, ) -> Result<Uuid, PayrollError>

Add an employee’s slip to a DRAFT run. Earnings come from the structure, prorated by unpaid days (gross = Σ earning · (working − unpaid)/working); fixed + supplied statutory deductions subtract. net = gross − deductions and must be non-negative.

Source

pub async fn add_computed_salary_slip( &self, r: ComputedSlipRequest, ) -> Result<Uuid, PayrollError>

Build one employee’s slip end-to-end: period → effective statutory params → employee facts → TER/bracket dispatch → overtime pay → the same Self::add_salary_slip write path a manual caller uses. The statutory base is the structure’s un-prorated monthly earning total (the salary being paid); overtime pay rides in as an ordinary earning line so gross stays balanced through the existing journal.

Source

pub async fn process_payroll_entry( &self, run_id: Uuid, ) -> Result<(), PayrollError>

Roll the run’s slips up into its totals and move draft → processed (ready to post).

Source

pub async fn render_slip_pdf( &self, slip_id: Uuid, ) -> Result<Vec<u8>, PayrollError>

Post the processed run to the GL — the 8th producer. Builds ONE balanced posting (Dr Salary Expense (gross) · Cr Salary Payable (net) · Cr Σ deduction-account), drives the GlPostSink (idempotent per run), then transition-gates processed → posted with the journal. Posts at most once. Emits PayrollPosted. Render one slip as a PDF (#553). Published-run gated like the self-service read: a slip on a draft or processed run is an internal draft, not a promise to the employee.

Source

pub async fn cancel_payroll_entry( &self, run_id: Uuid, ) -> Result<bool, PayrollError>

Cancel a run that has not left draft (#605): the month opens for a fresh run, the slips go with it. Only draft may cancel (posted history is immutable — reverse, don’t delete); idempotent on an already-cancelled row.

Source

pub async fn post_payroll_entry( &self, run_id: Uuid, posting_date: NaiveDate, sink: &dyn GlPostSink, events: &dyn PayrollEventSink, ) -> Result<PostOutcome, PayrollError>

Source

pub async fn remit_payroll_entry( &self, run_id: Uuid, sink: &dyn RemittanceSink, ) -> Result<RemitOutcome, PayrollError>

Remit a posted run’s payables — one instruction per deduction account, each carrying the stable payroll_remittance:{company}:{run}:{account} idempotency key so retries dedup at the sink (the company segment is the legacy tenancy twin echo, ADR-0029 — stable per unit under a composing service, nil undecorated). Requires posted (an unposted run has no settled obligations to pay). Payee resolution is the composing host’s adapter, never payroll’s.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more