Bug: Flat-fee payroll can be skipped for some inspectors when service permissions or event-linked charges differ

Objective

  • Restore consistent flat-fee payroll behavior so the same service pays the same way for inspectors when there are no custom payout overrides.
  • Make it clear why a flat-fee payout is skipped when payroll is driven by service eligibility, assignments, or event-linked charge handling.

Background

  • Product feedback indicates that some inspectors in SWF receive correct flat-fee payouts for services like termite, SLE, mold sampling, pool inspection, and leak assessment, while other inspectors do not for the same services.
  • The reported pattern is that percentage-based payouts appear correct, flat-fee payouts are the ones missing, and the payout configuration is intended to be the same for all inspectors.
  • Current payroll logic contains service-level and event-level gates that can legitimately zero out or suppress flat-fee payout for one inspector while another inspector is paid correctly on the same service. That makes this behavior difficult to diagnose from the payroll UI alone.

Scope

Backend

  • Payroll calculation for inspection charges lives in attik-backend/src/util/functions/payroll/dataFunc.ts. Charge-level pay is only calculated when the charge remains eligible for the inspection-level path. If a linked event exists for the charge, the code marks isPrimaryInspectorCompleted false and skips charge-level payout for that charge. Flat-fee payout is then selected from custom flat rate, service flat rate, modifier flat-rate addition, or commission fallback.
  • The same file also requires the inspector to be enabled for the service before charge-level flat-fee pay is applied. The canPerformService check is based on inspector.services.includes(serviceId), so two inspectors on the same company can receive different results if their allowed service lists differ even when the service payout settings are the same.
  • Event-level payroll is also handled in attik-backend/src/util/functions/payroll/dataFunc.ts. When a charge is suppressed because of linked events, the expected payout path moves to the event calculation branch. Any mismatch between charge/event linkage, event assignment, or service eligibility can therefore present as a missing flat-fee payout.
  • Payroll aggregation and population are assembled in attik-backend/src/routes/payroll.ts. That route populates inspections, charges, services, events, discount code behavior, and payroll modifier additions before passing the data into sortInspectionsByInspector().
  • Inspector service eligibility comes from attik-backend/src/models/inspectorSchema.ts, where each inspector has a services array. Service payout settings come from attik-backend/src/models/serviceSchema.ts, including flatRate, flatRateType, flatRateAsPrimary, and flatRateAsPrimaryType.

Decision needed

  • Whether flat-fee services that have linked events should continue to suppress charge-level payout entirely, or whether certain flat-fee service types should still pay at the inspection-charge level even when events exist.
  • Whether payroll should continue to rely on inspector.services as a strict eligibility gate for payment, or whether missing eligibility should be surfaced more clearly as a data/configuration problem in payroll output.

References

  • Payroll charge and event calculation: attik-backend/src/util/functions/payroll/dataFunc.ts
  • Payroll aggregation route: attik-backend/src/routes/payroll.ts
  • Inspector service eligibility: attik-backend/src/models/inspectorSchema.ts
  • Service flat-rate fields: attik-backend/src/models/serviceSchema.ts

Please authenticate to join the conversation.

Upvoters
Status

Canceled

Board
πŸ’‘

New Features

Date

17 days ago

Author

Linear

Subscribe to post

Get notified by email when there are changes.