Cancelled with billable Cancellation service lines — they are independent conceptsCancelledCancelled (cancelled banner shown; top chip may still show Published because published report status takes precedence in the workorder header). Invoice FHI624 has a single Cancellation-type line "Same Day Cancelation - HI NOT Done" at $125.00, fully paid ($340.52 captured, $211.14 refunded, $0 balance). Invoice and payment did not sync to QuickBooks solely because the WO is cancelled — not because the invoice is empty or unsettledinspection.status !== 'confirmed': queueQuickbooksSync.ts (queueQuickbooksInvoiceSync, queueQuickbooksInvoiceSyncFromInspection) and upsertQuickbooksInvoice.ts (processQuickbooksInvoiceJob)inspectionStream.ts calls queueQuickbooksInvoiceDelete using invoiceNumberqueueQuickbooksSync.ts (queueQuickbooksPaymentSync)resolveQbPaymentSyncAction → sync_payment_and_invoice, but invoice workers still skip non-confirmed inspectionsQuickbooks.tsx (canSyncInvoice requires status === 'confirmed'; subtext: "Cancelled—invoice sync off; payments can sync")qbChargeLineItems.ts / buildQbInvoiceLineItems.ts (no special-case skip for Cancellation service type today)Locked
CancelledjobCreationType === 'attik' (existing integration scope)Open
total > 0, balance >= 0 with at least one charge line, only when a Cancellation-type service is present, or any non-zero invoice regardless of line types?queueQuickbooksInvoiceDelete still run (removing a previously synced invoice), or should delete be suppressed / replaced with upsert when net billable revenue exists?sync_payment_and_invoice) once the status gate is fixed?Backend (attik-backend)
src/util/functions/quickbooks/queueQuickbooksSync.ts — invoice sync enqueue requires status === 'confirmed' today; payment sync allows confirmed | cancelledsrc/events/subscribers/quickbooksIntegration/upsertQuickbooksInvoice.ts — processQuickbooksInvoiceJob hard-skips non-confirmed inspections before QB API callssrc/events/streamHandlers/inspectionStream.ts — on cancel: queueQuickbooksInvoiceDelete; on confirm/charge/reschedule: queueQuickbooksInvoiceSyncFromInspectionsrc/events/streamHandlers/chargeStream.ts — charge insert/update triggers invoice sync (still subject to confirmed gate in queue helper)src/events/streamHandlers/paymentStream.ts — payment insert/update triggers payment sync; refund policy in qbPaymentSyncPolicy.ts may queue invoice sync that is then blockedsrc/util/functions/quickbooks/buildQbInvoiceLineItems.ts / qbChargeLineItems.ts — charge lines map via _serviceId.quickbooks.id; verify Cancellation services have correct QB item mapping per brand (data/config, not code branch today)src/routes/quickbooks.ts — manual POST /sync-invoice/:inspectionId endpoint (no status check at route level; worker skip applies)Frontend (attik-frontend)
src/app/tools/inspections/[id]/components/integrations/Quickbooks.tsx — canSyncInvoice and cancelled subtext; expectedQbInvoiceTotal for balance comparisonsrc/app/tools/inspections/[id]/components/InspectionWorkorderShell.tsx — cancelled banner vs PropertyStatusChip showing published when inspection.published (orthogonal to QB sync; explains FHI624 header confusion but out of scope unless separately fixed)Out of scope (unless expanded)
status === 'cancelled'FHI624 — cancelled WO, Cancellation fee line, paid zero balancequeueQuickbooksSync.ts, upsertQuickbooksInvoice.ts, Quickbooks.tsxisn/historicalImportPayments.ts (isIsnSameDayCancellationCatalogFeeName)Please authenticate to join the conversation.
Planned
Main App
About 5 hours ago
Linear
Get notified by email when there are changes.
Planned
Main App
About 5 hours ago
Linear
Get notified by email when there are changes.