Pay at Close jobs still send unpaid SMS and "not paid" action flows when work order shows PAC

Objective

  • Stop clients from receiving unpaid / "No Pay" SMS and other automations tied to Paid is false when the work order already shows Pay at Close (PAC) and staff expect payment to be arranged.
  • Align action flow behavior with how teams interpret PAC on the payments list vs the job-level Paid flag used by conditions.

Background

  • Production example (FHI): Inspection 1008591123 — payment shows PAC, but the client received "No Pay" texts/notifications.
  • Symptom: Work order Payments shows Pay at Close (often Paid / Signed on the PAC row from ISN status), while automations keyed on Paid → is false ("order not paid") still run (SMS, email, reminders).
  • Root cause (code review):
  • Action flow condition Paid is false maps to inspection.paid (attributePathResolver.ts, conditionsResolver.ts, builder in templatingData.ts).
  • inspection.paid is set in syncTotalsOnInspection (syncTotalsOnInspections.ts) only when balance ≤ $0.01; pending pay_at_close payments contribute $0 to totalPaid.
  • On inspection payments changes, inspectionStream.ts calls syncTotalsOnInspection without await, then immediately flowEventTriggerer('payment_created', …) — flows can evaluate paid: false even right after PAC activity.
  • payment_created fires when a pending PAC row is created (isnPayments.ts), not only when the job is fully paid.
  • UI mismatch: ServicesPayments.tsx can show PAC as Paid/Signed from payment/ISN status while inspection.paid remains false; client portal shows Pending Payment until inspection.paid is true (JobAccordion.tsx).

Steps to reproduce

  1. Configure an action flow on Payment created (or follow-up/reminders) with condition Paid → is false (unpaid / "No Pay" SMS or email).
  2. On a job, client selects Pay at Close (FlexFund/ISN) so the work order shows a Pay at Close payment line.
  3. Observe the flow still runs while inspection.paid is false (common when PAC is pending, or due to sync timing right after PAC create/complete).

Narrower repro: Client starts PAC → pending payment created → payment_created fires immediately → Paid is false passes → unpaid SMS sent while staff see PAC on the WO.

Scope

Backend (required)

  • attik-backend/src/events/streamHandlers/inspectionStream.tsawait syncTotalsOnInspection before enqueueing payment_created (or re-fetch inspection after sync in the flow worker before evaluateConditions).
  • attik-backend/src/util/functions/forecast/syncTotalsOnInspections.tspaid / totalPaid rules for pending vs completed PAC.
  • attik-backend/src/routes/isnPayments.ts — PAC create (pending payment).
  • attik-backend/src/routes/webhooks/flexfund/flexfundWebhook.ts — PAC complete (awaits sync today; stream may still race).
  • attik-backend/src/util/functions/isn/isnPayAtCloseOrderTotal.ts — PAC amount toward totalPaid when completed.
  • attik-backend/src/util/functions/actionFlows/handleEventTriggerdByBull.ts — condition evaluation timing vs populated inspection snapshot.
  • Product decision needed: Treat pending PAC as "payment arranged" for some conditions (new attribute) or do not fire payment_created on pending PAC create — use an event when PAC completes / when inspection.paid becomes true.
  • Tests: tests/unit/payment.pac.test.ts and flow condition tests — completed PAC → inspection.paid === truePaid is false actions filtered; pending PAC behavior matches chosen product rule.

Frontend (supporting / clarity)

  • attik-frontend/src/components/conditions/templatingData.tsPaid boolean condition labeling (clarify vs PAC row status).
  • attik-frontend/src/app/tools/inspections/[id]/components/ServicesPayments.tsx — PAC display vs job Paid flag.
  • attik-frontend/src/app/client/job/[slug]/components/JobAccordion.tsx — portal Pending Payment vs Paid chip.

Investigation outcomes (acceptance)

  • [ ] On 1008591123 (or clone): confirm PAC pending vs completed, inspection.paid, remainingBalance, and which flow action (event + Paid is false) sent the "No Pay" SMS.
  • [ ] Fix: After completed PAC with $0 balance, inspection.paid is true before payment_created actions evaluate (or those actions do not run for settled PAC).
  • [ ] Fix: Product rule documented for pending PAC (no unpaid harassment vs intentional reminders).
  • [ ] Regression test(s) committed.

References

  • Example inspection 1008591123 (FHI)
  • attik-backend/src/events/streamHandlers/inspectionStream.ts
  • attik-backend/src/util/functions/forecast/syncTotalsOnInspections.ts
  • attik-backend/src/util/functions/actionFlows/attributePathResolver.ts
  • attik-backend/src/routes/isnPayments.ts
  • attik-backend/src/routes/webhooks/flexfund/flexfundWebhook.ts
  • attik-frontend/src/components/conditions/templatingData.ts

Please authenticate to join the conversation.

Upvoters
Status

Planned

Board
🏠

Main App

Date

10 days ago

Author

Linear

Subscribe to post

Get notified by email when there are changes.