← 25. Finance Management

Chunks — 25. Finance Management

The FRD markdown is the source of truth; these chunks are the derived retrieval index used to give the test-case generator only the relevant slices. Rebuilt automatically when the FRD is saved.

509 chunks · ~84,262 tokens

#1
(intro)
~6 tok
☑️ Billing > Invoices Tab
#2
**Finances Billing module - Invoices Tab FRD**
~12 tok
# **Finances Billing module - Invoices Tab FRD**
#3
**Finances Billing module - Invoices Tab FRD** > **1\. Module Overview**
~200 tok
## **1\. Module Overview**

*   **Module Name:** Billing > Invoices Tab
*   **Purpose:** The Invoices Tab within the Billing submodule serves as the central hub for managing all client invoices across the agency. It provides a comprehensive view of invoice statuses, payment schedules, and associated transactions, and enables agency owners to track payment collection progress on a per-project basis.
*   **Business Goal:** Enable agency owners to efficiently manage client billing by providing visibility into invoice statuses, payment schedules, and financial health. The module ensures streamlined payment collection, accurate financial tracking per project, and seamless integration with external accounting systems (QuickBooks) to maintain financial integrity and reduce administrative overhead.
#4
**Finances Billing module - Invoices Tab FRD** > **2\. User Roles & Permissions**
~14 tok
## **2\. User Roles & Permissions**

Refer - Click Here
#5
**Finances Billing module - Invoices Tab FRD** > **3\. User Flow**
~294 tok
## **3\. User Flow**

**Navigation Path:** Sidebar → Finances → Billing → Invoices Tab

**Primary User Flow - Viewing and Managing Invoices:**

1.  **Access Billing Module:** User navigates to the Finances section and selects Billing.
2.  **Land on Invoices Tab:** System displays the Invoices tab as default with "All" sub-tab selected.
3.  **View Invoice List:** User sees a table of active invoices sorted by next payment date (overdue first).
4.  **Filter by Brand:** User selects brand from the dropdown to filter invoices.
5.  **Search:** User enters search terms to find specific invoices.
6.  **Expand Invoice Details:** User clicks the expand arrow to view transactions inline.
7.  **Perform Actions:** User accesses the three-dot menu for View Details, Download PDF, or Deactivate.
8.  **View Deactivated:** User switches to the Deactivated sub-tab to reactivate invoices.

**Alternative Flow - Empty State Handling:**

1.  User navigates to the Billing module.
2.  System checks prerequisites (Stripe, Brands, Projects, Invoices).
3.  If missing, the system displays an appropriate empty state with action prompts.
4.  User follows guided actions to complete setup.
#6
**Finances Billing module - Invoices Tab FRD** > **4\. Functional Logic**
~82 tok
## **4\. Functional Logic**

**4.1 Empty State Management**

The system performs a structured, priority-based empty state evaluation to ensure all required prerequisites are completed before the user can access the Billing → Invoices tab.

Only one empty state is displayed at a time based on the highest applicable condition.
#7
**Finances Billing module - Invoices Tab FRD** > **4\. Functional Logic** >
~1 tok
###
#8
**Finances Billing module - Invoices Tab FRD** > **4\. Functional Logic** > **Priority Order of Empty State Checks**
~636 tok
### **Priority Order of Empty State Checks**

**4.1.1 No Brands Created (Highest Priority)**

*   **Condition:** The user has not created any brand under the agency.
*   **System Behavior:**
    *   Displays an empty state with the message: **“Create a brand to organize your projects and billing.”**
    *   Shows a CTA button: **“Setup Brand”**
    *   **CTA Action:** Opens the brand creation workflow (Brand Setup wizard → Step 1).

**4.1.2 No Stripe Account Connected**

*   **Condition:** Brands exist, but the user has not connected a Stripe account for payment processing.
*   **System Behavior:**
    *   Displays an empty state with the message: **“Connect your Stripe account to start collecting payments.”**
    *   Shows a CTA button: **“Connect Stripe”**
    *   **CTA Action:** Redirects the user to: **Settings → Business & Payment Details → Stripe Connection**

**4.1.3 No Projects Created**

*   **Condition:** At least one brand exists and Stripe is connected, but the user has not created any projects.
*   **System Behavior:**
    *   Displays an empty state with the message: **“Create a project to begin invoicing clients.”**
    *   Shows a CTA button: **“Create Project”**
    *   **CTA Action:** Opens the project creation workflow (Project → Create New).

**4.1.4 No Invoices Created**

*   **Condition:** Brands exist, Stripe is connected, and at least one project exists, but no invoices have been created.
*   **System Behavior:**
    *   Displays an empty state with the message: **“No invoices found. Invoices appear when proposals are accepted or created manually.”**
    *   Shows a CTA button: **“Go to Projects”**
    *   **CTA Action:** Navigates to the **Projects module**.

**Business Rules**

*   The system evaluates empty states in **strict priority order** (4.1.1 → 4.1.2 → 4.1.3 → 4.1.4). Only the highest applicable empty state is shown.
*   If **no brand exists**, all subsequent checks are skipped.
*   When any empty state is active:
    *   The **Brand Filter dropdown** is disabled.
    *   The invoice list table remains hidden.
*   When all prerequisites are satisfied, the invoice list becomes visible.

**4.2 Invoice List Display**

**Default Sort Order:**

1.  **Primary:** Overdue invoices appear first.
2.  **Secondary:** Next payment date ascending (nearest first).
3.  **Tertiary:** Invoice ID descending (newest first).

**Pagination:**

*   Default: 10 rows per page
*   Options: 10, 25, 50, 100
*   Display: "1-10 of X" format
*   Persists when switching between All/Deactivated tabs
#9
**Finances Billing module - Invoices Tab FRD** > **4.3 Invoice Status Logic**
~219 tok
## **4.3 Invoice Status Logic**

Invoice status is automatically calculated based on the collective status of all associated transactions.

**Status**

**Trigger Condition**

**Unpaid**

All transactions "Unpaid" and none overdue

**Partially Paid**

At least one "Paid" AND at least one "Unpaid"/"Processing" (no overdue)

**Paid**

All transactions "Paid"

**Overdue**

At least one transaction "Overdue" (due date passed without payment)

**Partially Refunded**

At least one transaction refunded but not all

**Refunded**

All paid transactions fully refunded

**Deactivated**

Manually deactivated by admin

**Status Priority Rules:**

1.  Deactivated overrides all other statuses.
2.  Overdue takes precedence over Partially Paid or Unpaid.
3.  Refunded only applies when ALL collected payments returned.
4.  Status updates in real-time as transaction statuses change.
#10
**Finances Billing module - Invoices Tab FRD** > **4.4 Invoice-to-Transaction Grouping**
~181 tok
## **4.4 Invoice-to-Transaction Grouping**

**Relationship:**

Each invoice has a one-to-many relationship with transactions. Every scheduled payment creates a corresponding transaction.

**Expand/Collapse Behavior:**

*   **Collapsed (Default):** Only invoice row visible with summary.
*   **Expanded:** All transactions displayed inline below invoice.
*   **Visual:** Down arrow collapsed, Up arrow expanded.
*   **Transaction Display:** Indented rows with Payment Date, Amount, Status, Actions.

**Transaction Status Badges:**

*   **Paid:** Green badge
*   **Unpaid:** Orange/Yellow badge
*   **Processing:** Blue badge (ACH 4-5 days)
*   **Overdue:** Red badge
*   **Failed:** Dark Red badge
*   **Refunded:** Gray badge
#11
**Finances Billing module - Invoices Tab FRD** > **4.5 Payment Schedule Logic**
~234 tok
## **4.5 Payment Schedule Logic**

**Automatic Invoice Creation (from Proposal):**

1.  When proposal accepted, system automatically generates invoice.
2.  Invoice inherits exact payment schedule from proposal (same dates, amounts, installments).
3.  Each scheduled payment becomes a transaction.
4.  Invoice automatically linked to same project as proposal.

**Payment Schedule Rules:**

*   Minimum 1 scheduled payment per invoice.
*   No maximum limit on installments.
*   Only fixed-split payments supported (no custom partial amounts).
*   Sum of payments must equal total invoice amount.
*   Admin can adjust schedule after creation (dates, split amounts).

**Next Payment Date Calculation:**

*   System identifies earliest "Unpaid" or "Overdue" transaction.
*   If overdue exists, earliest overdue date displayed.
*   If no unpaid transactions remain, displays "-" or "Complete."
*   Format: "Mon DD, YYYY" (e.g., "Oct 5, 2024").
#12
**Finances Billing module - Invoices Tab FRD** > **4.6 Filtering and Search Functionality**
~197 tok
## **4.6 Filtering and Search Functionality**

**Brand Filtering:**

*   **Location:** Top right dropdown labeled "All Brands."
*   **Options:** "All Brands" (default) + all active brands.
*   **Behavior:** Filters to invoices for projects under selected brand.
*   **Persistence:** Persists only within current tab; switching to Transactions resets it.
*   **Update:** Table refreshes immediately on selection.

**Search Functionality:**

*   **Location:** Search bar next to brand filter.
*   **Searchable Fields:**

\- Invoice ID (e.g., "#INV00004")

\- Client name (partial match)

\- Project name (partial match)

*   **Type:** Case-insensitive, partial match (contains).
*   **Real-time:** Results filter as user types (300ms debounce).
*   **Clear:** X button to clear search field.
#13
**Finances Billing module - Invoices Tab FRD** > **4.7 Invoice Deactivation and Reactivation**
~301 tok
## **4.7 Invoice Deactivation and Reactivation**

**Deactivation Eligibility:**

*   **Can deactivate:** Unpaid, Partially Paid, or Overdue invoices.
*   **Cannot deactivate:** Paid, Refunded, Partially Refunded, or invoices with "Processing" transactions.
*   **Reason:** Prevents financial inconsistencies during active payments.

**Impact of Deactivation:**

1.  **Payment Collection Blocked:** No payments can be collected.
2.  **Transactions Hidden:** All transactions hidden from Transactions tab.
3.  **No Workflow Blocking:** Other workflows function normally.
4.  **Tab Movement:** Invoice moves to Deactivated tab.
5.  **Status Update:** Status changes to "Deactivated."
6.  **Audit Trail:** Action logged with timestamp and user.
7.  **Statuses Preserved:** Transaction statuses remain unchanged internally.

**Reactivation Logic:**

1.  **Access:** "Reactivate" button in Deactivated tab.
2.  **Data Restoration:** All data restores exactly as before.
3.  **Status Recalculation:** Status recalculated (may become Overdue).
4.  **Transactions Visible:** Transactions reappear in Transactions tab.
5.  **Invoice Returns:** Returns to All tab.
6.  **Audit Trail:** Reactivation action logged.
#14
**Finances Billing module - Invoices Tab FRD** > **4.8 Invoice Actions Menu**
~125 tok
## **4.8 Invoice Actions Menu**

**Actions in All Tab:**

1.  **View Details:** Opens detailed view with Invoice ID, Client info, Line items, Payment schedule, Transaction history.
2.  **Download PDF:** Generates branded PDF with line items, taxes, payment schedule. File: "Invoice\_\[ID\]\_\[Client\].pdf"
3.  **Deactivate Invoice:** Confirmation dialog required. Disabled if Processing transactions exist.

**Actions in Deactivated Tab:**

*   View Details
*   Download PDF
*   Reactivate Invoice
#15
**Finances Billing module - Invoices Tab FRD** > **4.9 Project Linking Logic**
~177 tok
## **4.9 Project Linking Logic**

**Core Rules:**

*   Every invoice belongs to exactly one project (mandatory).
*   Transactions inherit the same project as their invoice.
*   Project's client automatically becomes invoice owner.
*   Projects under brands establish filtering structure.

**Project Determines:**

*   Client association
*   Brand association (for filtering)
*   Visibility and access permissions
*   Revenue attribution

**Multi-Project Clients:**

*   Single client can have multiple projects (Wedding, Engagement, etc.).
*   Each project generates separate invoice(s).
*   Billing records maintained per project, not aggregated.
*   Client appears multiple times with different projects.
#16
**Finances Billing module - Invoices Tab FRD** > **4.10 Impact on Other Modules**
~227 tok
## **4.10 Impact on Other Modules**

**Dashboard:**

*   Outstanding invoices count reflects active invoices only.
*   Revenue tracking includes only Paid transactions.
*   Overdue alerts display prominently.

**QuickBooks Sync:**

*   **CRITICAL:** Only "Paid" transactions sync to QuickBooks.
*   Unpaid, Processing, Failed, Overdue NOT synced.
*   Refunds trigger reversal entries.
*   Deactivated invoice transactions excluded.

**Profit & Loss:**

*   Revenue includes only Paid transactions.
*   Refunds appear as adjustments.
*   Project-level profitability tied to payments.

**Proposals Module:**

*   Accepted proposals auto-generate invoices.
*   Payment schedule inherited.
*   Proposal status updates to "Accepted."

**Client Portal:**

*   Clients view invoices and payment history.
*   Deactivated invoices hidden from client view.
*   Payment buttons disabled for deactivated/paid invoices.
#17
**5\. Field Details & Validations**
~161 tok
# **5\. Field Details & Validations**

**Table Structure:**

**Column**

**Data Displayed**

**Sorting**

Expand/Collapse

Arrow icon for transaction list

Not sortable

Next Payment Date

Date of next scheduled payment

Sortable (Default: ascending, overdue first)

Invoice ID

Unique identifier (#INV00004)

Sortable

Client

Client avatar and full name

Sortable (alphabetically)

Amount

Total invoice amount

Sortable (numerical)

Payments

Total scheduled payments count

Sortable (numerical)

Status

Invoice status badge

Not sortable

Project

Associated project name

Sortable (alphabetically)

Actions

Three-dot menu

Not sortable
#18
**5\. Field Details & Validations** > **5.1 Invoice List Table Fields**
~147 tok
## **5.1 Invoice List Table Fields**

**Field Name**

**Type**

**Format**

**Validation**

Next Payment Date

Date

"Mon DD, YYYY"

System-calculated, read-only

Invoice ID

Auto-generated

"#INVXXXXX"

Unique, sequential, immutable

Client Name

Text + Avatar

"\[Avatar\] Full Name"

Inherited from project, required

Amount

Currency

"$X,XXX.XX"

Must be > $0, two decimals

Payments Count

Integer

Number (e.g., "3")

Minimum 1, no maximum

Status Badge

Badge

Colored badge with text

System-calculated, read-only

Project Name

Text

Full project name

Required, immutable link
#19
**5\. Field Details & Validations** > **5.2 Search and Filter Fields**
~73 tok
## **5.2 Search and Filter Fields**

**Field**

**Type**

**Format**

**Validation**

Search Bar

Text Input

Placeholder text

No character limit, 300ms debounce

Brand Filter

Dropdown

Default: "All Brands"

Single selection

Rows Per Page

Dropdown

Default: "10"

Options: 10, 25, 50, 100
#20
**6\. Error Message Handling**
~222 tok
# **6\. Error Message Handling**

**Scenario**

**Trigger**

**Message**

**Type**

No Search Results

Query returns zero matches

"No invoices found matching your search criteria."

Info

Deactivate Blocked

Processing transaction exists

"Cannot deactivate. Payments are processing."

Error

Deactivate Confirm

User clicks Deactivate

"Are you sure? Payments cannot be collected until reactivated."

Warning

Deactivate Success

Successful deactivation

"Invoice #INVXXXXX deactivated successfully."

Success

Reactivate Success

Successful reactivation

"Invoice reactivated. Payments can now be collected."

Success

PDF Download Fail

Generation fails

"Failed to generate PDF. Please try again."

Error

Network Error

API request fails

"Unable to load. Check your connection."

Error

Stripe Not Connected

No Stripe account

"Connect Stripe to start collecting payments."

Info
#21
**7\. Edge Cases & Special Scenarios**
~225 tok
# **7\. Edge Cases & Special Scenarios**

**Scenario**

**Expected Behavior**

All transactions Processing

Status shows "Partially Paid". Deactivation blocked.

Transaction becomes Overdue while deactivated

Updates internally. On reactivation, invoice shows Overdue.

Client has invoices across multiple brands

Brand filter shows only invoices for selected brand's projects.

Partial refund on transaction

Invoice becomes "Partially Refunded". QuickBooks receives reversal.

Search for deactivated invoice in All tab

Returns no results. User must switch to Deactivated tab.

Project deletion with existing invoice

Blocked if unpaid invoices exist.

Very long client/project name

Truncated with ellipsis. Full name on hover.

Invoice has 100+ transactions

Virtualized list with scroll for performance.

Brand is deleted

Invoices remain visible via "All Brands". Brand removed from dropdown.
#22
**8\. Acceptance Criteria**
~231 tok
# **8\. Acceptance Criteria**

**Core Functionality:**

*   Users can view all active invoices in sortable, paginated table.
*   Invoice status auto-calculates based on transaction statuses.
*   Users can expand/collapse invoices to view transactions inline.
*   Brand filtering works correctly for projects under selected brand.
*   Search returns results for Invoice ID, Client name, or Project name.

**Deactivation/Reactivation:**

*   Users can deactivate Unpaid, Partially Paid, or Overdue invoices.
*   Deactivation blocked for Processing transactions.
*   Deactivated invoices appear only in Deactivated tab.
*   Reactivation restores all data and recalculates status.
*   Audit trail logs all deactivation/reactivation actions.

**Integration:**

*   Only Paid transactions sync to QuickBooks.
*   Dashboard widgets reflect accurate counts and statuses.
*   Project linking maintains data integrity across modules.
#23
**9\. Dependencies**
~159 tok
# **9\. Dependencies**

**Module/System**

**Type**

**Impact if Unavailable**

Stripe Payment Gateway

Integration

Cannot collect payments. Empty state displayed.

Projects Module

Data Dependency

Cannot create/link invoices. Project names may fail.

Clients Module

Data Dependency

Client info unavailable. No names/avatars.

Proposals Module

Integration

Auto-generation from proposals fails.

QuickBooks Integration

Integration

Paid transactions not synced. Manual reconciliation needed.

Authentication Service

Security

Users cannot access module.

Audit Trail Service

Service

Actions not logged. Compliance compromised.
#24
**10\. References**
~20 tok
# **10\. References**

**Design Files:**

*   Figma/Sketch link - \[To be added\]
#25
**10\. References** >
~1 tok
##
#26
**10\. References** > **Deprecated—--------------**
~8 tok
## **Deprecated—--------------**
#27
**10\. References** > **4\. Field Details & Validations**
~351 tok
## **4\. Field Details & Validations**

**Field Name**

**Type**

**Required**

**Validation Rules**

Next Payment Date

Date

Yes

Must be a valid date format, auto-calculated from the package schedule, the breakdown of the split payment will shuffle, and the nearest payment date will be at the top

Invoice ID

Alpha numeric

Yes

Auto-generated: "INV" + sequential number for main invoice, append "-1", "-2" etc. for split payments

Client Name

Text

Yes

Client’s profile image with the client name from the client module

Amount

Currency

Yes

Must be a positive number, formatted to 2 decimal places. The 1st row will consist of the sum of the total invoice value autopopulated from the package selected

Payment Splits

Number

No

An integer showing the total number of payment splits based on the package’s payment terms (shown in the primary row).  

Each line split displays the split amount” status row by row.

Payment Status

Text

Yes

Values: Unpaid, Processing, Paid, Overdue, Failed, Refund

“Deactivated” status

Payment Status  
only visible in the

Text

Conditional(only visible in the deactivated tab )

“Deactivated” status on the primary row for the deactivated invoices,

Reactivate tab

CTA

Conditional(only visible in the deactivated tab )

It can reactivate and move the invoice to the “All” sub-tab of invoices

Project Name

Text

Yes

Links to the associated project
#28
**10\. References** > **5\. Success Message Handling**
~84 tok
## **5\. Success Message Handling**

**Validation Scenario**

**Success Message**

Invoice PDF downloaded

"Invoice PDF downloaded successfully."

Invoice link copied

"Invoice link copied to clipboard."

Invoice deactivated

"Invoice has been deactivated successfully."

Invoice reactivated

"Invoice has been reactivated successfully."
#29
**10\. References** > **6\. Error Message Handling**
~175 tok
## **6\. Error Message Handling**

**Field**

**Validation Scenario**

**Error Message**

General

Network connection failed

"Unable to load invoices. Please check your connection and try again."

General

Server timeout

"Request timed out. Please refresh and try again."

Invoice Actions

PDF generation failed

"Unable to generate PDF. Please try again later."

Invoice Actions

Print job failed

"Unable to print invoice. Please check the printer connection."

Brand Filter

No results found

"No invoices found for the selected brand."

Deactivation

Action failed

"Unable to deactivate invoice. Please try again."

Reactivation

Action failed

"Unable to reactivate invoice. Please try again."
#30
**10\. References** > **8\. Edge Cases**
~135 tok
## **8\. Edge Cases**

**Scenario**

**Expected Behavior**

Payment status changes from Paid to Refund

System maintains payment history, updates current status, and preserves previous status in the invoice record

Large number of payment splits (>10)

System handles gracefully with scroll or pagination within the expanded view

Brand filter returns no results

Display an empty state with clear messaging and an option to clear the filter

PDF generation for large invoices

System shows loading indicator, generates PDF asynchronously
#31
**10\. References** > **11\. Dependencies**
~105 tok
## **11\. Dependencies**

**Module/System**

**Impact if Unavailable**

Packages Module

Cannot auto-generate invoices if there are no proposals

Project Management

Cannot link invoices to projects, PM role restrictions fail

Client Management

Cannot display client information and profiles

Payment Gateway

Cannot process payment status updates

Proposal System

Cannot auto-generate invoices from signed proposals
#32
**10\. References** > **12\. References**
~43 tok
## **12\. References**

*   [Figma](https://www.figma.com/design/ej0kxwP45mDKmZCZfAJ5O8/Pixally?node-id=10266-199694&p=f&t=zwu2sP7PfuQvqJ8I-0)

☑️ Billing > Transactions Tab
#33
**Functional Requirements Document (FRD) - Transactions Tab**
~16 tok
# **Functional Requirements Document (FRD) - Transactions Tab**
#34
**Functional Requirements Document (FRD) - Transactions Tab** > **1\. Module Overview**
~182 tok
## **1\. Module Overview**

*   **Module Name:** Billing → Transactions Tab
*   **Purpose:** The Transactions tab provides a centralized, status-driven view of all payment schedule items (transactions) across client invoices. It enables agency owners and financial administrators to monitor payment lifecycles, track failed payments, manage overdue collections, process refunds, and maintain QuickBooks synchronization from a single interface.
*   **Business Goal:** To give agencies complete visibility and control over their payment collection pipeline, reduce revenue leakage through proactive overdue management, streamline refund processing, and ensure accurate financial record-keeping across integrated accounting systems.
#35
**Functional Requirements Document (FRD) - Transactions Tab** > **2\. User Roles & Permissions**
~14 tok
## **2\. User Roles & Permissions**

Refer- Click Here
#36
**Functional Requirements Document (FRD) - Transactions Tab** >
~1 tok
##
#37
**Functional Requirements Document (FRD) - Transactions Tab** > **3\. User Flow**
~356 tok
## **3\. User Flow**

**Navigation Path:** Main Menu → Finances → Billing → Transactions Tab

**Step-by-Step Flow:**

1.  User clicks "Finances" in the left navigation menu, which expands to show sub-options.
2.  User clicks "Billing" to access the Billing module.
3.  System displays the Billing page with two primary tabs: "Invoices" and "Transactions."
4.  User clicks the "Transactions" button (highlighted/active state).
5.  System displays the Transactions view with six sub-tabs: Unpaid, Processing, Paid, Overdue, Failed, Refunds.
6.  By default, system loads the "Unpaid" sub-tab showing all unpaid transactions.
7.  User can switch between sub-tabs to view transactions filtered by status.
8.  User can apply additional filters using the Brand dropdown, search bar, or Filters panel.
9.  User can sort columns by clicking column headers.
10.  User can perform actions via the Actions menu (three-dot icon) on each transaction row.
11.  For specific sub-tabs (Overdue), user can click dedicated action buttons (Remind) directly in the row.

**Alternative Flows:**

*   **Direct Navigation via URL:** User can access specific sub-tabs directly via URL parameters
*   **Cross-Module Navigation:** User clicks on Invoice ID in the transaction row to navigate to the Invoice detail view.
*   **Filter-First Approach:** User opens the Filters panel first, applies filters, then browses sub-tabs with filters persisted.
#38
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#39
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Functional Logic** > **4.1 Page Layout & Common Elements**
~529 tok
### **4.1 Page Layout & Common Elements**

**Overview:** The Transactions tab shares a consistent layout across all six sub-tabs while adapting specific columns and actions based on transaction status.

**Common Header Elements:**

*   **Page Title:** "Billing" (persistent across Invoices and Transactions tabs)
*   **Tab Switcher:** Two buttons - "Invoices" (outline style) and "Transactions" (filled/active style)
*   **Brand Dropdown:** Single-select dropdown defaulting to "All Brands," positioned top-right
*   **Search Bar:** Text input for searching across Invoice ID, Client name, and Project name
*   **Filter Icon:** Opens the Filters slideout panel

**Sub-Tab Navigation:**

*   Horizontal tab bar with six status tabs: Unpaid | Processing | Paid | Overdue | Failed | Refunds
*   Active tab displays with underline indicator
*   Tab badges showing count of transactions (optional based on configuration)

**Common Table Structure:**

*   Sortable column headers (indicated by ↓ icon)
*   Client column displays avatar + full name
*   Amount column shows dollar value with "X of Y" indicator (e.g., "1 of 2" for payment schedule position)
*   Status column displays colored badge (varies by sub-tab)
*   Project column shows linked project name
*   Actions column contains three-dot menu for row actions

**Pagination:**

*   "Rows per page" dropdown: Options 10, 25, 50, 100
*   Default: 25 rows per page
*   Page indicator: "1-4 of 4" format
*   Previous/Next navigation arrows

**Empty State (No Transactions Exist):** When there are no transactions in the system at all (not just filtered results), the Transactions tab displays:

*   Centered illustration/icon representing transactions or payments
*   Heading: "No transactions yet"
*   Subtext: "Transactions will appear here once you create invoices with payment schedules"
*   Call-to-action button: "Create Invoice" (links to Invoice creation flow)

This empty state appears when the agency has not yet created any invoices with payment schedules. Once invoices are created, individual sub-tabs will show their own status-specific empty states.
#40
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Functional Logic** > **4.2 Unpaid Sub-Tab**
~368 tok
### **4.2 Unpaid Sub-Tab**

**Overview:** Displays all transactions that have not yet been paid and are not yet overdue.

**Entry Criteria:** Transaction status = "Unpaid" AND payment\_due\_date ≥ current\_date

**Displayed Columns:**

1.  Payment Date (sortable) - The scheduled payment due date
2.  Invoice ID (sortable) - Format: #INVXXXXX
3.  Client (sortable) - Avatar + Full Name
4.  Amount (sortable) - Dollar amount + payment schedule position
5.  Status (sortable) - "Unpaid" badge (gray/neutral color)
6.  Project (sortable) - Project name
7.  Actions - Three-dot menu

**Default Sort:** Payment Date ascending (earliest due dates first)

**Available Actions (Three-dot menu):**

*   View Details → Opens transaction/invoice detail view
*   Copy Invoice Link → Copies client payment portal URL to clipboard
*   Download PDF → Downloads invoice PDF
*   Print Invoice → Opens print dialog for invoice
*   Mark as Paid → Opens manual payment recording dialog

**Business Rules:**

*   Transactions automatically move to Overdue sub-tab when payment\_due\_date < current\_date (scheduled job runs at midnight in agency's timezone).
*   Transactions move to Processing when client initiates payment via Stripe.
*   Transactions from deactivated invoices are hidden from this view.
*   Display shows only active invoice transactions.

**Empty State:**

*   Message: "No unpaid transactions"
*   Subtext: "All scheduled payments have been processed or are not yet due"
#41
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Functional Logic** > **4.3 Processing Sub-Tab**
~403 tok
### **4.3 Processing Sub-Tab**

**Overview:** Displays transactions where payment has been initiated but not yet confirmed by Stripe (ACH transfers, 3D Secure authentication pending).

**Entry Criteria:** Transaction status = "Processing"

**Displayed Columns:**

1.  Payment Date (sortable) - Original scheduled payment due date
2.  Charged (sortable) - Date and time payment was initiated (Format: "January 20, 2025" + "5:48 PM")
3.  Invoice ID (sortable) - Format: #INVXXXXX
4.  Client (sortable) - Avatar + Full Name
5.  Amount (sortable) - Dollar amount + payment schedule position
6.  Status (sortable) - "Processing" badge (yellow/amber color)
7.  Project (sortable) - Project name
8.  Actions - Three-dot menu

**Default Sort:** Charged date descending (most recent first)

**Available Actions (Three-dot menu):**

*   View Details → Opens transaction detail view
*   Copy Invoice Link → Copies payment URL to clipboard
*   Download PDF → Downloads invoice PDF
*   Print Invoice → Opens print dialog

**Business Rules:**

*   Status transitions via Stripe webhooks only (no manual intervention).
*   Processing → Paid: When Stripe confirms successful payment
*   Processing → Failed: When Stripe returns failure
*   Typical processing duration: ACH (3-5 business days), 3D Secure (minutes to hours).
*   System stores timestamp when payment enters Processing state.
*   These are one-time payments; system will not automatically retry failed payments.

**Empty State:**

*   Message: "No payments currently processing"
*   Subtext: "Payments typically process within 3-5 business days for ACH transfers"
#42
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Functional Logic** > **4.4 Paid Sub-Tab**
~547 tok
### **4.4 Paid Sub-Tab**

**Overview:** Displays all successfully completed transactions with payment confirmation, fee details, and QuickBooks sync status.

**Entry Criteria:** Transaction status = "Paid"

**Displayed Columns:**

1.  Payment Date (sortable) - Original scheduled payment due date
2.  Deposited (sortable) - Date and time payment was confirmed (Format: "January 20, 2025" + "5:48 PM")
3.  Invoice ID (sortable) - Format: #INVXXXXX
4.  Client (sortable) - Avatar + Full Name
5.  Amount (sortable) - Dollar amount + info icon (ⓘ) + payment schedule position
6.  Status (sortable) - "Paid" badge (green color)
7.  QuickBooks Icon - Sync status indicator
8.  Project (sortable) - Project name
9.  Actions - Three-dot menu

**Amount Info Tooltip (on ⓘ hover):**

*   Transaction Method: \[Credit Card / ACH Transfer / Manual – Cash / Manual – Bank Transfer / etc.\]
*   Amount: $XXX.XX
*   Fee: $XX.XX (Stripe + Pixally platform fee, only for online payments)

**QuickBooks Sync Status Icons:**

*   Green QB icon: Successfully synced
*   Gray QB icon with red cross: Sync failed (manual retry available)
*   No icon: QuickBooks integration not enabled

**Default Sort:** Deposited date descending (most recent first)

**Available Actions (Three-dot menu):**

*   View Details → Opens transaction detail view
*   Sync with QuickBooks → Manual sync trigger (shown only if sync failed or pending)
*   Copy Invoice Link → Copies payment confirmation URL
*   Download PDF → Downloads receipt/invoice PDF
*   Print Invoice → Opens print dialog
*   Refund → Opens refund initiation dialog

**Business Rules:**

*   Paid transactions trigger automatic QuickBooks sync immediately when integration is enabled.
*   Timestamp stored when payment is confirmed.
*   Payment method and transaction fees stored for reporting.
*   Paid transactions can only transition to Refunded or Partially Refunded status.
*   Manual payments marked as "Manual – \[Method\]" in transaction method field.
*   Only one refund allowed per transaction (full or partial).

**Empty State:**

*   Message: "No paid transactions yet"
*   Subtext: "Completed payments will appear here with their receipt details"
#43
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Functional Logic** > **4.5 Overdue Sub-Tab**
~584 tok
### **4.5 Overdue Sub-Tab**

**Overview:** Displays transactions where the payment due date has passed without successful payment, enabling proactive collection management.

**Entry Criteria:** (Transaction status = "Unpaid" OR Transaction status = "Failed") AND payment\_due\_date < current\_date

**Displayed Columns:**

1.  Payment Date (sortable) - Original scheduled payment due date (past date)
2.  Invoice ID (sortable) - Format: #INVXXXXX
3.  Client (sortable) - Avatar + Full Name
4.  Amount (sortable) - Dollar amount + payment schedule position
5.  Status (sortable) - "Overdue" badge (red/coral color)
6.  Project (sortable) - Project name
7.  Remind Button - Dedicated action button
8.  Actions - Three-dot menu

**Remind Button Behavior:**

_Normal State (clickable):_

*   Button text: "Remind"
*   Tooltip on hover: "No reminders sent" OR "Reminders sent: X \\n Last Reminded: \[Date/Time\]"
*   Click action: Sends reminder email immediately

_Disabled State (within 24h cooldown):_

*   Button text: "Remind" (grayed out)
*   Tooltip on hover: "Reminders sent: X \\n Last Reminded: \[Date/Time\] \\n ⓘ You will be able to send next reminder after 24h after last one."
*   No click action available

**Default Sort:** Payment Date ascending (oldest overdue first)

**Available Actions (Three-dot menu):**

*   View Details → Opens transaction detail view
*   Send Payment Link → Emails payment link to client
*   Copy Invoice Link → Copies payment URL to clipboard
*   Download PDF → Downloads invoice PDF
*   Print Invoice → Opens print dialog
*   Mark as Paid → Opens manual payment recording dialog

**Business Rules:**

*   System automatically moves transactions to Overdue via scheduled job (runs at midnight in agency's timezone).
*   Both Unpaid and Failed transactions appear here if overdue.
*   Reminder cooldown: Minimum 24 hours between reminders per transaction.
*   No maximum limit on reminder count.
*   Each reminder increments reminder\_count and updates last\_reminded\_at timestamp.
*   Reminder email uses system-wide template containing: Invoice details, amount due, days overdue, payment link.
*   All reminder actions logged in audit trail with user and timestamp.

**Empty State:**

*   Message: "No overdue transactions"
*   Subtext: "Great! All payments are current or have been collected"
#44
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Functional Logic** > **4.6 Failed Sub-Tab**
~516 tok
### **4.6 Failed Sub-Tab**

**Overview:** Displays transactions where payment processing failed, showing failure reasons from Stripe for troubleshooting and retry.

**Entry Criteria:** Transaction status = "Failed"

**Displayed Columns:**

1.  Payment Date (sortable) - Original scheduled payment due date
2.  Failed Date (sortable) - Date and time of failure + Failure Reason (Format: "January 20, 2025" + "Card Declined")
3.  Invoice ID (sortable) - Format: #INVXXXXX
4.  Client (sortable) - Avatar + Full Name
5.  Amount (sortable) - Dollar amount + payment schedule position
6.  Status (sortable) - "Failed" badge (red color with border)
7.  Project (sortable) - Project name
8.  Actions - Three-dot menu

**Failure Reasons (from Stripe):**

*   Card Declined
*   Invalid Card Details
*   Insufficient Funds
*   Payment Blocked
*   Expired Card
*   Authentication Failed
*   Network Error
*   Processing Error

**Default Sort:** Failed Date descending (most recent failures first)

**Available Actions (Three-dot menu):**

*   View Details → Opens transaction detail view with full error information
*   Notify Client → Sends failure notification email with reason and retry instructions
*   Send Payment Link → Sends new payment link for retry
*   Copy Invoice Link → Copies payment URL to clipboard
*   Download PDF → Downloads invoice PDF
*   Print Invoice → Opens print dialog

**Business Rules:**

*   Failure reason stored directly from Stripe webhook response.
*   Failed transactions that pass their due date also appear in Overdue sub-tab.
*   Failed timestamp and failure reason stored for each failure.
*   Client can retry payment via sent link, which creates new Processing transaction.
*   Multiple failure attempts tracked in transaction history.
*   Transaction remains in Failed tab until client retries and status changes to Processing or Paid.
*   System does not automatically retry failed payments (one-time payment model).

**Empty State:**

*   Message: "No failed transactions"
*   Subtext: "All payment attempts have been successful"
#45
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Functional Logic** > **4.7 Refunds Sub-Tab**
~588 tok
### **4.7 Refunds Sub-Tab**

**Overview:** Displays transactions that have been fully or partially refunded, with refund amounts and reasons.

**Entry Criteria:** Transaction status = "Refunded" OR Transaction status = "Partially Refunded"

**Displayed Columns:**

1.  Payment Date (sortable) - Original scheduled payment due date
2.  Invoice ID (sortable) - Format: #INVXXXXX
3.  Client (sortable) - Avatar + Full Name
4.  Amount (sortable) - Net amount after refund (with strikethrough for original if different) + refund info icon
5.  Status (sortable) - "Refunded" badge (purple color) OR "Partially Refunded" badge
6.  QuickBooks Icon - Refund sync status (with circular arrow indicator)
7.  Project (sortable) - Project name
8.  Actions - Three-dot menu

**Amount Display Logic:**

*   Full Refund: Shows refunded amount (e.g., "$100.00")
*   Partial Refund: Shows net amount (e.g., "$80.00" with tooltip showing original $100.00, refunded $20.00)

**Refund Info Tooltip (on amount hover):**

*   Original Amount: $XXX.XX
*   Refunded Amount: $XX.XX
*   Net Paid Amount: $XXX.XX (for partial refunds)
*   Refund Reason: \[User-entered reason text\]

**QuickBooks Refund Indicator:**

*   Circular arrow icon showing refund has been synced to QuickBooks
*   Gray icon with red cross if sync failed

**Default Sort:** Payment Date descending (most recent refunds first)

**Available Actions (Three-dot menu):**

*   View Details → Opens refund transaction detail view
*   Sync with QuickBooks → Manual sync for failed refund sync
*   Download PDF → Downloads refund receipt
*   Print Receipt → Opens print dialog for refund receipt

**Business Rules:**

*   Refunds can only be initiated from Paid transactions.
*   Partial refunds require amount ≤ original paid amount.
*   Refund reason is required (free text field).
*   Only one refund allowed per transaction (no subsequent refunds on partially refunded transactions).
*   Refunds processed through Stripe API for online payments.
*   Manual payment refunds require manual tracking only.
*   System stores: original\_amount, refunded\_amount, net\_paid\_amount, refund\_reason, refunded\_at.
*   All refund actions logged in audit trail with user and timestamp.

**Empty State:**

*   Message: "No refunded transactions"
*   Subtext: "Refund history will appear here when refunds are processed"
#46
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Functional Logic** > **4.8 Transaction Status Lifecycle**
~453 tok
### **4.8 Transaction Status Lifecycle**

**Overview:** Defines all valid status transitions and the triggers that cause them.

**Status Values:**

1.  Unpaid - Initial state, awaiting payment
2.  Processing - Payment initiated, awaiting confirmation
3.  Paid - Payment successfully completed
4.  Overdue - Payment due date passed (Unpaid or Failed)
5.  Failed - Payment attempt unsuccessful
6.  Refunded - Full refund processed
7.  Partially Refunded - Partial refund processed

**Transition Matrix:**

**From Status**

**To Status**

**Trigger**

**Automation**

Unpaid

Processing

Client initiates payment via Stripe

Automatic (Stripe webhook)

Unpaid

Paid

User marks as paid manually

Manual action

Unpaid

Overdue

Payment due date passes

Automatic (scheduled job at midnight in agency timezone)

Processing

Paid

Stripe confirms payment

Automatic (Stripe webhook)

Processing

Failed

Stripe returns failure

Automatic (Stripe webhook)

Failed

Processing

Client retries payment

Automatic (Stripe webhook)

Failed

Paid

User marks as paid manually

Manual action

Failed

Overdue

Already past due date

Display logic (appears in both tabs)

Paid

Refunded

User initiates full refund

Manual action + Stripe API

Paid

Partially Refunded

User initiates partial refund

Manual action + Stripe API

Overdue

Processing

Client initiates late payment

Automatic (Stripe webhook)

Overdue

Paid

User marks as paid manually

Manual action

**Invalid Transitions:**

*   Processing → Unpaid (cannot reverse payment initiation)
*   Paid → Unpaid (cannot unpay completed payment)
*   Refunded → Paid (cannot unrefund)
*   Partially Refunded → Paid (refund is permanent)
*   Partially Refunded → Refunded (only one refund allowed per transaction)
*   Any status → Processing (only Stripe can set this)
#47
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Functional Logic** > **4.9 Stripe Integration & Webhook Processing**
~354 tok
### **4.9 Stripe Integration & Webhook Processing**

**Overview:** All online payments are processed through Stripe, with transaction statuses updated via webhooks.

**Transaction Creation:**

*   When an invoice is created with a payment schedule, the system creates individual transaction records for each scheduled payment.
*   Each transaction is linked to: Invoice ID, Project ID, Client ID, Brand ID.
*   Initial status: Unpaid
*   Payment amount and due date set from invoice payment schedule.
*   Each transaction shows independently based on its own status (e.g., for invoice with 3 payments, one could be Paid while others remain Unpaid).

**Stripe Payment Flow:**

1.  **Payment Initiation:**
    *   Client clicks payment link in email or client portal.
    *   System creates Stripe PaymentIntent with transaction metadata.
    *   Transaction status → Processing.
2.  **Data Synchronized from Stripe:**
    *   Transaction ID (Stripe PaymentIntent ID)
    *   Payment method type (card, ach\_debit)
    *   Last 4 digits of payment method
    *   Processing fees (Stripe fees + Pixally platform fee)
    *   Failure codes and decline reasons
    *   Refund transaction IDs

**Fee Calculation:**

*   Stripe fee: Standard Stripe rates (e.g., 2.9% + $0.30 for cards)
*   Pixally platform fee: Configurable percentage (set at account level)
*   Total fee stored
*   Displayed in the Paid tab amount tooltip
#48
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Functional Logic** > **4.10 Reminder Logic (Overdue Management)**
~407 tok
### **4.10 Reminder Logic (Overdue Management)**

**Overview:** Enables systematic follow-up on overdue payments with email reminders and tracking.

**Reminder Initiation:**

*   User clicks "Remind" button on overdue transaction row.
*   System checks cooldown period (24-hour minimum).
*   If allowed, sends reminder email immediately.

**Reminder Email Content (System-Wide Template):**

*   Subject: "Payment Reminder: Invoice #\[INVOICE\_ID\] - \[PROJECT\_NAME\]"
*   Body includes:
    *   Client name greeting
    *   Invoice number and project name
    *   Original payment due date
    *   Number of days overdue
    *   Amount due
    *   Direct payment link (secure, pre-authenticated)
    *   Agency contact information
    *   Professional, non-aggressive tone

**Tracking Data:**

*   Reminder Count: Integer tracking total reminders sent
*   Last Reminded at: Timestamp of most recent reminder
*   Stored at transaction level
*   History log maintained for audit purposes (accessible to admin users)
*   Audit trail records: user who sent reminder, timestamp, client email

**Cooldown Logic:**

*   Minimum 24 hours between reminders.
*   Calculation: current\_time - last\_reminded\_at ≥ 24 hours.
*   If within cooldown: Button disabled, tooltip shows countdown.
*   No maximum limit on reminders (agency discretion).
*   Exactly at 24-hour mark, button becomes enabled.

**Reminder Button States:**

*   **Never Reminded:** Enabled, tooltip "No reminders sent"
*   **Reminded + Cooldown Expired:** Enabled, tooltip shows history
*   **Reminded + Within Cooldown:** Disabled, tooltip shows restriction message
#49
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Functional Logic** > **4.11 Refund Processing Logic**
~485 tok
### **4.11 Refund Processing Logic**

**Overview:** Supports both full and partial refunds with complete audit trail and accounting integration.

**Refund Initiation Points:**

1.  Transactions → Paid tab → Actions menu → Refund
2.  Invoice detail view → Transaction section → Refund action

**Full Refund Process:**

1.  User clicks "Refund" from Paid transaction.
2.  System displays refund dialog:
    *   Original amount: $XXX.XX (read-only)
    *   Refund amount: \[pre-filled with full amount\]
    *   Refund reason: \[required text field\]
    *   Confirm/Cancel buttons
3.  User enters reason and confirms.
4.  For online payments: System calls Stripe Refund API.
5.  For manual payments: System records refund locally only.
6.  Transaction status → Refunded.
7.  Refund data stored: original\_amount, refunded\_amount = original\_amount, net\_paid\_amount = 0, refund\_reason, refunded\_at.
8.  QuickBooks sync triggered immediately (if enabled).
9.  Audit trail records: user, timestamp, amounts, reason.

**Partial Refund Process:**

1.  Same initiation as full refund.
2.  User modifies refund amount to less than original.
3.  Validation: Refund amount must be > 0 and ≤ original amount.
4.  Transaction status → Partially Refunded.
5.  Only one refund allowed - cannot add more refunds to a partially refunded transaction.

**Invoice Impact:**

*   **Full Refund of All Transactions:** Invoice status → Refunded.
*   **Partial Refund (invoice still fully paid):** Invoice status remains Paid, displays "Refunded $X" indicator.
*   **Partial Refund (creating outstanding balance):** Invoice status updates based on remaining balance rules.

**QuickBooks Sync:**

*   Full refunds create credit memo in QuickBooks.
*   Partial refunds adjust payment record with memo.
*   Sync happens immediately upon refund processing.
*   Failed sync shows error indicator, allows manual retry.
*   Refund reason synced as memo/note field.
#50
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Functional Logic** > **4.12 Manual Payment Recording**
~360 tok
### **4.12 Manual Payment Recording**

**Overview:** Allows agencies to record offline payments (cash, check, bank transfer) that occur outside Stripe.

**Initiation:**

*   From Unpaid or Overdue transaction → Actions → "Mark as Paid"

**Manual Payment Dialog:**

*   Payment Method dropdown:
    *   Manual – Cash
    *   Manual – Check
    *   Manual – Bank Transfer
    *   Manual – Wire Transfer
    *   Manual – Other
*   Payment Date: Date picker (defaults to current date)
*   Reference Number: Optional text field (check number, wire reference, etc.)
*   Notes: Optional text field for additional context
*   Confirm/Cancel buttons

**Processing:**

1.  User fills out dialog and confirms.
2.  Transaction status → Paid.
3.  Payment method stored as selected option.
4.  No fees calculated (no Stripe processing).
5.  Reference number and notes stored for audit.
6.  QuickBooks sync triggered immediately with manual payment type.
7.  Audit trail records: user, timestamp, payment details.

**Display in Paid Tab:**

*   Amount tooltip shows "Transaction Method: Manual – \[Method\]"
*   Fee field shows "$0.00" or "N/A"
*   Reference number visible in transaction detail view

**Restrictions:**

*   Only users with appropriate permissions can mark as paid.
*   Cannot be reversed once marked (must process as refund if needed).
*   Payment date cannot be in the future.
*   Audit log records user who marked payment and timestamp.
#51
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Functional Logic** > **4.13 QuickBooks Synchronization**
~380 tok
### **4.13 QuickBooks Synchronization**

**Overview:** Automatically syncs paid transactions and refunds to QuickBooks Online immediately when integration is enabled.

**Auto-Sync Triggers:**

*   Transaction status changes to Paid (payment received) - synced immediately.
*   Refund is processed (full or partial) - synced immediately.

**Sync Data Mapping:**

*   Transaction → QuickBooks Payment
*   Invoice linkage maintained
*   Payment method recorded
*   Fees recorded as expenses (optional configuration)
*   Refund → QuickBooks Credit Memo or Payment Adjustment

**Sync Status Indicators:**

_In Paid Tab:_

*   ✅ Green QB icon: Successfully synced, click shows sync timestamp
*   ❌ Gray QB icon with red cross: Sync failed
*   No icon: QuickBooks not integrated

_In Refunds Tab:_

*   🔄 Circular arrow icon: Refund synced
*   ❌ Red cross: Refund sync failed

**Failed Sync Handling:**

1.  System attempts sync immediately upon status change.
2.  If fails (network error, QB API error, auth issue), mark as failed.
3.  Error details logged for troubleshooting.
4.  User sees failed indicator in Actions column.
5.  Actions menu shows "Sync with QuickBooks" option.
6.  User clicks to retry sync manually.
7.  On success, icon updates to success state.

**Error Scenarios:**

*   Authentication expired: Prompt to re-authenticate QB connection
*   Duplicate transaction: Skip with warning logged
*   QB API timeout: Retry with exponential backoff
*   Data mapping error: Log specific field issue for support
#52
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Functional Logic** > **4.14 Filters Panel**
~512 tok
### **4.14 Filters Panel**

**Overview:** Comprehensive filtering system that applies across all sub-tabs.

**Filter Panel Access:**

*   Click filter icon (funnel) in top-right header area.
*   Panel slides out from right side.
*   Filters persist when switching between sub-tabs.

**Available Filters:**

1.  **Date Issued:**
    *   Type: Date picker
    *   Format: Calendar popup with date selection
    *   Filters on invoice issue date
    *   Clear button to reset
2.  **Payment Due Date:**
    *   Type: Date picker
    *   Format: Calendar popup with date selection
    *   Filters on transaction payment due date
    *   Clear button to reset
3.  **Brand:**
    *   Type: Single-select dropdown
    *   Default: "All Brands"
    *   Options: List of all brands in account
    *   Filters transactions by brand association
4.  **Amount:**
    *   Type: Range slider with min/max inputs
    *   Format: Min ()\[input\]—Max() \[input\] — Max ( )\[input\]—Max() \[input\]
    *   Visual slider for quick adjustment
    *   Scale markers shown below slider
    *   Filters transactions within dollar range
5.  **Client:**
    *   Type: Multi-select with search
    *   Search box for client name lookup (minimum 2 characters)
    *   Scrollable list with checkboxes
    *   Client avatars displayed next to names
    *   Filters to show only selected clients
6.  **Project:**
    *   Type: Multi-select with search
    *   Search box for project name lookup (minimum 2 characters)
    *   Scrollable list with checkboxes
    *   Filters to show only selected projects

**Filter Actions:**

*   **Reset Icon (↻):** Top-right of panel, clears all filters
*   **Apply Button:** Applies selected filters (if separate apply needed)
*   **Auto-Apply:** Filters may apply in real-time as changed (configuration option)

**Filter Persistence:**

*   Filters remain active when switching sub-tabs.
*   Filter state shown via "Active Filters" indicator.
*   Filters reset on page refresh (session-based).
*   Clear all option removes all active filters.
#53
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Functional Logic** > **4.15 Sorting Logic**
~242 tok
### **4.15 Sorting Logic**

**Overview:** Enables column-based sorting with persistence across sub-tab navigation.

**Sortable Columns (varies by sub-tab):**

*   Payment Date
*   Charged / Deposited / Failed Date (status-specific)
*   Invoice ID
*   Client
*   Amount
*   Status
*   Project

**Sort Behavior:**

*   Click column header to sort ascending.
*   Click again to sort descending.
*   Sort indicator (↓) shows current sort column and direction.
*   Only one column sorted at a time.
*   Default sort varies by sub-tab (defined in each sub-tab section).

**Sort Persistence:**

*   Sort order maintained when switching sub-tabs.
*   Reset to default when page is refreshed.
*   Sort state not saved in user preferences (session-only).

**Sort Logic for Data Types:**

*   Dates: Chronological/reverse chronological
*   Text (Client, Project, Invoice ID): Alphabetical A-Z / Z-A
*   Amount: Numeric low-high / high-low
*   Status: Alphabetical by status name
#54
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Functional Logic** > **4.16 Search Functionality**
~173 tok
### **4.16 Search Functionality**

**Overview:** Global search bar for quick transaction lookup.

**Search Scope:**

*   Invoice ID (exact and partial match)
*   Client Name (partial match, case-insensitive)
*   Project Name (partial match, case-insensitive)

**Search Behavior:**

*   Real-time filtering as user types (debounced 300ms).
*   Minimum 2 characters required to trigger search.
*   Searches within currently active sub-tab only.
*   Combined with other active filters.
*   Clear button (X) to reset search.

**Search Results Display:**

*   Table updates to show only matching transactions.
*   Row count updates in pagination.
*   "No results found" empty state if no matches.
#55
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Functional Logic** > **4.17 Project/Client/Brand Linkage**
~186 tok
### **4.17 Project/Client/Brand Linkage**

**Overview:** Every transaction maintains hierarchical relationships for organizational context.

**Data Hierarchy:**

Brand

└─ Client

└─ Project

└─ Invoice

└─ Transaction (Payment Schedule Item)

**Navigation Capabilities:**

*   Click Invoice ID → Navigate to Invoice detail view
*   Click Project name → Navigate to Project detail view
*   Click Client name → Navigate to Client profile (optional)
*   All navigation opens in same window (back button functional)

**Filtering by Linkage:**

*   Brand dropdown filters all transactions by brand.
*   Filters panel allows Client and Project multi-select.
*   Hierarchical filtering: Selecting client shows only their projects in Project filter.
#56
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Functional Logic** > **4.18 Interaction with Invoices Module**
~368 tok
### **4.18 Interaction with Invoices Module**

**Overview:** Transactions are integral to invoice lifecycle, with bidirectional impact on statuses and totals.

**Invoice Status Impact from Transactions:**

**Transaction Status Change**

**Invoice Status Impact**

All transactions Paid

Invoice → Paid

All transactions Refunded

Invoice → Refunded

Some transactions Paid, some Unpaid

Invoice → Partially Paid

Partial refund on Paid invoice (no outstanding)

Invoice remains Paid, shows "Refunded $X"

Transaction becomes Overdue

Invoice may show "Overdue" indicator

**Invoice Total Calculations:**

*   Invoice total = Sum of all transaction amounts.
*   Paid amount = Sum of Paid transaction amounts - Refunded amounts.
*   Outstanding = Invoice total - Paid amount.
*   Refunded indicator = Sum of all refunded amounts.

**Deactivated Invoice Behavior:**

*   When invoice is deactivated (soft delete), all its transactions are hidden from Transactions tab.
*   Transactions are not deleted, just filtered from view.
*   Reactivating invoice makes transactions visible again.
*   Deactivated invoice transactions don't count in totals/reports.

**Cross-Module Actions:**

*   Refund initiated from Invoice detail → Updates Transaction status in Transactions tab.
*   Payment marked as paid from Transactions tab → Updates Invoice status and amounts.
*   Invoice edited (schedule changed) → Transactions updated accordingly (with restrictions on Paid transactions).
#57
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Functional Logic** > **4.19 Email & Notification Triggers**
~351 tok
### **4.19 Email & Notification Triggers**

**Overview:** System-generated emails triggered by transaction events.

**Email Types:**

1.  **Overdue Reminder Email:**
    *   Trigger: User clicks "Remind" button
    *   Recipient: Client primary email
    *   Template: System-wide (not customizable per brand)
    *   Content: Invoice details, amount due, days overdue, payment link
    *   Throttle: 24-hour minimum between sends
2.  **Failed Payment Notification:**
    *   Trigger: User clicks "Notify Client" from Failed tab
    *   Recipient: Client primary email
    *   Content: Failure reason, retry instructions, payment link
    *   No automatic sending (user-initiated only)
3.  **Payment Link Resend:**
    *   Trigger: User clicks "Send Payment Link"
    *   Recipient: Client primary email
    *   Content: Original payment link with invoice details
    *   Available from: Failed and Overdue tabs
4.  **Refund Confirmation:**
    *   Trigger: Refund successfully processed
    *   Recipient: Client primary email (optional, configurable)
    *   Content: Refund amount, reason, updated invoice balance
    *   Automatic if email notifications enabled

**Notification Logging:**

*   All sent emails logged with timestamp.
*   Delivery status tracked (sent, delivered, bounced, opened).
*   Accessible in transaction detail view and audit trail.
*   Audit trail accessible to admin users.
#58
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Functional Logic** > **4.20 Audit Trail**
~203 tok
### **4.20 Audit Trail**

**Overview:** Comprehensive logging of all user actions on transactions for accountability and compliance.

**Logged Actions:**

*   Mark as Paid (manual payment recording)
*   Refund initiation (full or partial)
*   Reminder sent
*   QuickBooks sync attempts (manual retries)
*   Status changes (with source: manual vs webhook)

**Audit Entry Data:**

*   Timestamp (UTC with timezone conversion for display)
*   User ID and name who performed action
*   Action type
*   Previous value (if applicable)
*   New value
*   Additional context (e.g., refund reason, payment method)
*   IP address (optional for security)

**Access:**

*   Visible to admin users in transaction detail view
*   Exportable for compliance reporting
*   Retained according to data retention policy (configurable)
#59
**Functional Requirements Document (FRD) - Transactions Tab** > **5\. Field Details & Validations**
~10 tok
## **5\. Field Details & Validations**
#60
**Functional Requirements Document (FRD) - Transactions Tab** > **5\. Field Details & Validations** > **5.1 Transaction Table Fields**
~300 tok
### **5.1 Transaction Table Fields**

**Field Name**

**Field Type**

**Display Format**

**Validation Rules**

Payment Date

Date Display

"January 20, 2025"

Required, valid date

Charged (Processing)

DateTime Display

"January 20, 2025" + "5:48 PM"

Required when status = Processing

Deposited (Paid)

DateTime Display

"January 20, 2025" + "5:48 PM"

Required when status = Paid

Failed Date (Failed)

DateTime + Text

"January 20, 2025" + "Card Declined"

Required when status = Failed

Invoice ID

Text Link

"#INV00004"

Required, format #INV\[5 digits\], clickable

Client

Avatar + Text

\[Avatar\] "Judy Whales"

Required, display name from Client record

Amount

Currency + Info

"$250.00" + ⓘ + "1 of 2"

Required, positive decimal, two decimal places

Status

Badge

Colored badge with status text

Required, must be valid status value

Project

Text Link

"Jadon & Monika Wedding"

Required, from linked Project record

Actions

Icon Menu

Three-dot vertical menu

System-generated based on status

Remind Button

Button

"Remind" text button

Only on Overdue tab, respects cooldown

QuickBooks Icon

Icon

QB logo with status indicator

Only on Paid/Refunds tabs when QB integrated
#61
**Functional Requirements Document (FRD) - Transactions Tab** > **5\. Field Details & Validations** > **5.2 Manual Payment Dialog Fields**
~110 tok
### **5.2 Manual Payment Dialog Fields**

**Field Name**

**Field Type**

**Display Format**

**Validation Rules**

Payment Method

Dropdown

Single-select list

Required, must select from predefined options

Payment Date

Date Picker

"mm/dd/yyyy" with calendar

Required, cannot be future date

Reference Number

Text Input

Alphanumeric text

Optional, max 50 characters

Notes

Text Area

Multi-line text

Optional, max 500 characters
#62
**Functional Requirements Document (FRD) - Transactions Tab** > **5\. Field Details & Validations** > **5.3 Refund Dialog Fields**
~94 tok
### **5.3 Refund Dialog Fields**

**Field Name**

**Field Type**

**Display Format**

**Validation Rules**

Original Amount

Read-only Text

"$250.00"

Display only, non-editable

Refund Amount

Currency Input

"$" + numeric input

Required, > 0, ≤ original amount, two decimal places

Refund Reason

Text Area

Multi-line text

Required, min 10 characters, max 500 characters
#63
**Functional Requirements Document (FRD) - Transactions Tab** > **5\. Field Details & Validations** > **5.4 Filter Panel Fields**
~197 tok
### **5.4 Filter Panel Fields**

**Field Name**

**Field Type**

**Display Format**

**Validation Rules**

Date Issued

Date Picker

Calendar with "Select Date" placeholder

Optional, valid date

Payment Due Date

Date Picker

Calendar with "Select Date" placeholder

Optional, valid date

Brand

Dropdown

"All Brands" default, single-select

Optional, valid brand from list

Amount Min

Number Input

Dollar amount with slider

Optional, ≥ 0, ≤ Max value

Amount Max

Number Input

Dollar amount with slider

Optional, ≥ Min value

Client

Multi-select with Search

Checkboxes with avatars and names

Optional, valid clients from list, min 2 chars for search

Project

Multi-select with Search

Checkboxes with project names

Optional, valid projects from list, min 2 chars for search
#64
**Functional Requirements Document (FRD) - Transactions Tab** > **6\. Error Messages & Notifications**
~516 tok
## **6\. Error Messages & Notifications**

**Field/Action**

**Validation Scenario**

**Error/Success Message**

**Type**

Refund Amount

Exceeds original amount

"Refund amount cannot exceed the original payment of $\[amount\]"

Error

Refund Amount

Zero or negative

"Please enter a valid refund amount greater than $0"

Error

Refund Reason

Empty or too short

"Please provide a refund reason (minimum 10 characters)"

Error

Refund Processing

Stripe API error

"Refund could not be processed. Please try again or contact support."

Error

Refund Success

Successful refund

"Refund of $\[amount\] has been processed successfully"

Success

QuickBooks Sync

Authentication failed

"QuickBooks authentication expired. Please reconnect your QuickBooks account."

Error

QuickBooks Sync

Sync failed

"Failed to sync transaction to QuickBooks. Click to retry."

Error

QuickBooks Sync

Sync successful

"Transaction synced to QuickBooks successfully"

Success

Manual Payment

Future date selected

"Payment date cannot be in the future"

Error

Manual Payment

No method selected

"Please select a payment method"

Error

Manual Payment Success

Payment recorded

"Payment of $\[amount\] has been recorded successfully"

Success

Reminder

Within 24h cooldown

"You will be able to send next reminder after 24h after last one."

Info (tooltip)

Reminder

Client has no email

"Client email address not configured"

Error

Reminder Sent

Email dispatched

"Reminder email sent to \[client email\]"

Success

Reminder Failed

Email delivery failed

"Failed to send reminder. Please check client email address."

Error

Search

No results

"No transactions found matching '\[search term\]'"

Info

Search

Too few characters

"Please enter at least 2 characters to search"

Info

Filter

No results

"No transactions match the selected filters"

Info

Network Error

Connection lost

"Connection lost. Please check your internet and try again."

Error

Stripe Webhook

Processing error

"Payment status update pending. Please refresh in a few minutes."

Warning
#65
**Functional Requirements Document (FRD) - Transactions Tab** >
~1 tok
##
#66
**Functional Requirements Document (FRD) - Transactions Tab** >
~1 tok
##
#67
**Functional Requirements Document (FRD) - Transactions Tab** > **7\. Edge Cases & Special Scenarios**
~637 tok
## **7\. Edge Cases & Special Scenarios**

**Scenario**

**Expected Behavior**

Transaction becomes overdue during user session

Transaction remains in Unpaid tab until midnight scheduled job runs; real-time update not required

Client pays while transaction is in Processing state

Stripe webhook updates status; if user viewing Processing tab, refresh shows transaction moved to Paid

Multiple refunds on same transaction

System prevents - once Refunded/Partially Refunded, no further refunds allowed

Partial refund equals full amount

System treats as full refund, status → Refunded

QuickBooks disconnected after paid transaction

Transaction marked as "sync failed", manual retry available after QB reconnected

Invoice deactivated with Processing transactions

Processing transactions hidden; if payment completes via Stripe, transaction updated but remains hidden until invoice reactivated

Reminder sent exactly 24h ago

Button becomes enabled; edge case at 24:00:00 mark should enable

Client has no email address

Remind button shows error: "Client email address not configured", button disabled

Zero-amount transaction (rare)

Display as "$0.00", all actions available except refund

Currency mismatch

System enforces single currency per account; edge case handled by validation at invoice creation

Duplicate webhook received

Idempotency key prevents duplicate status changes; webhook logged but no action taken

User closes browser during refund processing

Refund continues server-side; status updated on next page load

Filter returns > 10,000 results

Pagination handles efficiently; warning shown if export attempted

Browser timezone differs from server

All times displayed in user's local timezone (converted from UTC storage)

Refund processed but Stripe reverses it

Rare scenario - would require manual correction; audit log maintained

Payment method changes during Processing

Not possible - method locked when PaymentIntent created

Client account deleted with outstanding transactions

Transactions remain viewable; client shows as "\[Deleted Client\]"

Project deleted with transactions

Transactions remain; project shows as "\[Deleted Project\]"

Brand deleted/deactivated

Brand filter excludes; existing transactions remain but may be filtered out

Failed transaction retried successfully

Transaction moves from Failed tab to Processing, then to Paid; original failure history preserved in audit trail

Search with 1 character

No search performed; tooltip shows "Please enter at least 2 characters to search"
#68
**Functional Requirements Document (FRD) - Transactions Tab** > **8\. Test Cases Reference**
~8 tok
## **8\. Test Cases Reference**
#69
**Functional Requirements Document (FRD) - Transactions Tab** > **9\. Acceptance Criteria**
~495 tok
## **9\. Acceptance Criteria**

*   Users can view transactions filtered by status across six sub-tabs, with each tab displaying appropriate columns and actions.
*   System automatically updates transaction status based on Stripe webhook events without manual intervention.
*   Users can send overdue reminders with 24-hour cooldown enforcement, and system tracks reminder count and last sent timestamp.
*   Users can process full and partial refunds with required reason, and system allows only one refund per transaction.
*   Users can mark transactions as paid manually with payment method selection, and system records offline payment details.
*   Filters panel allows multi-criteria filtering by date, brand, amount range, client, and project, with filters persisting across sub-tabs.
*   Column sorting functions correctly for all sortable fields, with sort order maintained during sub-tab navigation.
*   Search functionality requires minimum 2 characters and returns real-time results matching invoice ID, client name, or project name.
*   QuickBooks integration automatically syncs paid transactions and refunds immediately upon status change, with failed sync indicator and manual retry option.
*   Transactions from deactivated invoices are hidden from all views and become visible upon reactivation.
*   All error messages display appropriately for validation failures, network errors, and integration issues.
*   Empty states provide clear messaging when no transactions exist for selected status or filter combination.
*   Pagination correctly handles large datasets with configurable rows per page (10, 25, 50, 100).
*   Overdue status transitions occur automatically via scheduled job running at midnight in agency's timezone.
*   All user actions (mark as paid, refund, reminder sent, QB sync retries) are logged in audit trail accessible to admin users.
*   Failed transactions remain in Failed tab until client retries and status changes to Processing or Paid.
#70
**Functional Requirements Document (FRD) - Transactions Tab** > **10\. Dependencies**
~321 tok
## **10\. Dependencies**

**Module/System**

**Dependency Type**

**Impact if Unavailable**

Stripe Payment Gateway

Integration

Online payments cannot be processed, webhook updates fail, no automatic status transitions

QuickBooks Online API

Integration

Automatic accounting sync fails, manual recording required, potential reconciliation issues

Invoices Module

Data Dependency

Cannot create transactions without invoices, invoice-transaction linkage broken

Client Management Module

Data Dependency

Cannot display client information, reminders fail without client email

Projects Module

Data Dependency

Cannot display project information, filtering by project unavailable

Brands Module

Data Dependency

Brand filtering unavailable, transaction-brand association broken

Email Service (SendGrid/SES)

Service Dependency

Reminder emails fail to send, payment notifications not delivered

Authentication Service

Security Dependency

Users cannot access module, permission checks fail

Database Service

Infrastructure

Complete module failure, no data retrieval or updates

Cron/Scheduler Service

Service Dependency

Overdue status transitions don't occur automatically at midnight

Audit Logging Service

Service Dependency

User actions not tracked, compliance issues
#71
**Functional Requirements Document (FRD) - Transactions Tab** > **11\. References**
~29 tok
## **11\. References**

*   **Design Files:** Figma/Sketch link - \[Provided screenshots cover UI specifications\]
#72
**Functional Requirements Document (FRD) - Transactions Tab** >
~1 tok
##
#73
**Functional Requirements Document (FRD) - Transactions Tab** > **Deprecated —---------------------------------**
~13 tok
## **Deprecated —---------------------------------**
#74
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Status-Specific Field Details & Validations**
~14 tok
## **4\. Status-Specific Field Details & Validations**
#75
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Status-Specific Field Details & Validations** > **4.1 Unpaid Status Tab Fields**
~188 tok
### **4.1 Unpaid Status Tab Fields**

**Field Name**

**Type**

**Validation Rules**

Payment Date

Date

Valid date format, the payment date is fetched from the package

Invoice ID

Text

Format: INV + number + sequence (e.g., INV0004, INV0004-1)  
Unique identifier for transaction  

Client

Text with Profile

Links to client profile, displays name with profile image  
  
The client who signed the package will be displayed here

Amount

Currency with Split Info

Positive number, with  
  
Payment amount with split details shows installment notation (e.g., "2 of 3")

Status

Static Text

Always displays "Unpaid"

Project

Text

Links to the associated project

Actions

Kebab Menu

View Details, Copy Invoice Link, Download PDF, Print Invoice
#76
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Status-Specific Field Details & Validations** > **4.2 Processing Status Tab Fields**
~197 tok
### **4.2 Processing Status Tab Fields**

**Field Name**

**Type**

**Validation Rules**

Payment Date

Date

Original payment due date  
  
Valid date format, original due date

Charged Date

DateTime

Auto-populated by Stripe when payment is initiated

Invoice ID

Text

Format: INV + number + sequence (e.g., INV0004-1)  
  
Unique identifier for transaction

Client

Text with Profile

Links to client profile, displays name with profile image  
  
The client who signed the package will be displayed here

Amount

Currency with Split Info

Positive number, shows installment notation (e.g., "1 of 2")

Status

Static Text

Always displays "Processing"

Project

Text

Links to the associated project

Actions

Kebab Menu

View Details, Copy Invoice Link, Download PDF, Print Invoice
#77
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Status-Specific Field Details & Validations** > **4.3 Paid Status Tab Fields**
~298 tok
### **4.3 Paid Status Tab Fields**

**Field Name**

**Type**

**Validation Rules**

Payment Date

Date

Original payment due date  
  
Valid date format, original due date

Deposited Date

DateTime

Date payment received in the agency account  
  
Auto-updated by Stripe, manually adjustable

Invoice ID

Text

Format: INV + number + sequence (e.g., INV0004-2)  
Unique identifier for transaction

Client

Text with Profile

Links to client profile, displays name with profile image  
  
Primary client who signs the proposal

Amount

Currency with Hover Details

Positive number, detailed split info on hover  
  
Payment amount with detailed breakdown  
  
On the tooltip, details like payment method, amount, and free can be seen

Stripe and Pixally Fees

QuickBooks Sync

Icon

Synchronization status with QuickBooks  
  
Green tick (synced) or red cross (not synced)  
  
Can be manually synced via action in the kebab menu, in case it is not automatically synced

Status

Static Text

Always displays "Paid"

Project

Text

Links to the associated project

Actions

Kebab Menu

View Details, Sync with QuickBooks (if not synced), Copy Invoice Link, Download PDF, Print Invoice, Refund
#78
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Status-Specific Field Details & Validations** > **4.4 Overdue Status Tab Fields**
~180 tok
### **4.4 Overdue Status Tab Fields**

**Field Name**

**Type**

**Validation Rules**

Payment Date

Date

Original payment due date  
  
Valid date format, original due date

Invoice ID

Text

Format: INV + number + sequence (e.g., INV0004-3)

Client

Text with Profile

Links to client profile, displays name with profile image

Amount

Currency

Outstanding payment amount  
  
Positive number, payment amount due

Status

Static Text

Always displays "Overdue"

Project

Text

Links to the associated project

Reminder

Button with Hover Info

Send a reminder email to the client  
  
Shows reminder count and last sent date on hover

Actions

Kebab Menu

View Details, Copy Invoice Link, Download PDF, Print Invoice
#79
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Status-Specific Field Details & Validations** >
~1 tok
###
#80
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Status-Specific Field Details & Validations** >
~1 tok
###
#81
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Status-Specific Field Details & Validations** > **4.5 Failed Status Tab Fields**
~196 tok
### **4.5 Failed Status Tab Fields**

**Field Name**

**Type**

**Validation Rules**

Payment Date

Date

Original payment due date  
  
Valid date format, original due date

Failed Date

DateTime with Reason

Date and reason for payment failure  
  
Auto-populated by Stripe with failure reason

Invoice ID

Text

Unique identifier for transaction  
  
Format: INV + number + sequence (e.g., INV0004-1)

Client

Text with Profile

Links to client profile, displays name with profile image

Amount

Currency with Split Status

Payment amount with split details  
  
A positive number shows split information

Status

Static Text

Always displays "Failed"

Project

Text

Links to the associated project

Actions

Kebab Menu

View Details, Copy Invoice Link, Download PDF, Print Invoice
#82
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Status-Specific Field Details & Validations** > **4.6 Refunds Status Tab Fields**
~155 tok
### **4.6 Refunds Status Tab Fields**

**Field Name**

**Type**

**Validation Rules**

Payment Date

Date

Original payment due date  
  
Valid date format, original due date

Invoice ID

Text

Unique identifier for transaction  
  
Format: INV + number + sequence (e.g., INV0004-2)

Client

Text with Profile

Links to client profile, displays name with profile image

Amount

Currency

Full refund amount  
  
Positive number, refunded amount

Status

Static Text

Always displays "Refunded"

Project

Text

Links to associated project

Actions

Kebab Menu

View Details, Copy Invoice Link, Download PDF, Print Invoice
#83
**Functional Requirements Document (FRD) - Transactions Tab** > **4\. Status-Specific Field Details & Validations** >
~1 tok
###
#84
**Functional Requirements Document (FRD) - Transactions Tab** > **5\. Success Message Handling**
~96 tok
## **5\. Success Message Handling**

**Validation Scenario**

**Success Message**

Reminder email sent successfully

"Payment reminder sent successfully."

QuickBooks synchronization completed- manual

"Transaction synced with QuickBooks successfully."

Refund processing completed

"Refund processed successfully."

Invoice link copied

"Transaction invoice link copied to clipboard."
#85
**Functional Requirements Document (FRD) - Transactions Tab** > **6\. Error Message Handling**
~221 tok
## **6\. Error Message Handling**

**Field**

**Validation Scenario**

**Error Message**

QuickBooks Integration

Sync connection failed

"QuickBooks synchronization failed. Please check integration settings and try again"

QuickBooks Integration

Authentication expired

"QuickBooks authentication expired. Please reconnect your account"

Refund Processing

Refund processing failed

"Unable to process refund. Please contact payment support or try again later."

Refund Processing

Transaction not eligible

"This transaction is not eligible for refund. Please contact support."

Status Management

Invalid status transition

"Invalid status change. Please verify the transaction's current status."

Filter Validations

Invalid date range

"End date must be after start date"

Filter Validations

Invalid amount range

"The maximum amount must be greater than the minimum amount."
#86
**Functional Requirements Document (FRD) - Transactions Tab** >
~1 tok
##
#87
**Functional Requirements Document (FRD) - Transactions Tab** > **8\. Edge Cases**
~366 tok
## **8\. Edge Cases**

**Scenario**

**Expected Behavior**

Client initiates multiple failed payment attempts

Each failure attempt is tracked with a separate failed date and reason, and final successful payment updates to Paid status with complete failure history preserved

QuickBooks sync repeatedly fails for a specific transaction

Red cross indicator persists, manual retry available indefinitely, sync status does not affect other transaction functionality

Multiple reminder emails sent within short timeframe

All reminders tracked and sent without frequency restrictions, complete communication history maintained

Manual status change from Unpaid directly to Paid

Status updates immediately, deposited date field becomes available for manual entry, and bypasses normal processing flow

Refund initiated for the transaction with pending QuickBooks sync

Refund processes normally, sync status transfers to the refunded transaction record

Large volume of transactions exceeding pagination limits

System maintains filter state across all pages, and pagination applies to filtered results

Client retries failed payment multiple times before success

All failure attempts are preserved in the transaction history, and successful payment updates the existing transaction rather than creating a duplicate

Network interruption during transaction status update

System provides clear error messaging, allows immediate retry, and maintains data consistency
#88
**Functional Requirements Document (FRD) - Transactions Tab** > **11\. Dependencies**
~174 tok
## **11\. Dependencies**

**Module/System**

**Impact if Unavailable**

Stripe Payment Gateway

Cannot process payments, status updates fail, no failure notifications

QuickBooks Integration

Sync functionality unavailable, accounting reconciliation fails

Email Service Provider

Reminder emails cannot be sent, client failure notifications fail

Billing Module

Cannot access invoice data, transaction creation fails

Project Management Module

Cannot link transactions to projects, PM access restrictions fail

Client Management Module

Cannot display client information, reminder email delivery fails

Authentication System

Role-based access control fails, user permissions cannot be enforced
#89
**Functional Requirements Document (FRD) - Transactions Tab** > **12\. References**
~14 tok
## **12\. References**

*   Figma

☑️ Contractor Invoices
#90
**Functional Requirements Document (FRD) - Contractor Invoices Module**
~57 tok
# **Functional Requirements Document (FRD) - Contractor Invoices Module**

**Document Version:** 1.1  
**Created Date:** December 23, 2025  
**Last Updated:** July 14, 2026  
**Module Location:** Finances → Contractor Invoices
#91
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **1\. Module Overview**
~323 tok
## **1\. Module Overview**

**Module Name:** Contractor Invoices

**Purpose:** The Contractor Invoices module enables agency owners and admins to view, manage, and process payments for invoices submitted by contractors for work completed on specific project events. Contractors upload invoices through the Contractor Portal, and agencies can pay via Stripe, ACH bank transfer, or record manual offline payments.

**Business Goals:**

*   Streamline contractor payment workflows by centralizing all invoice management in one location.  
    
*   Provide real-time visibility into invoice statuses across Unpaid, Overdue, Processing, Paid, and Failed states.  
    
*   Enable flexible payment options through online ACH transfers and manual payment recording.  
    
*   Track discrepancies between agreed contractor fees and invoiced amounts to prevent overpayments.  
    
*   Automatically identify overdue invoices based on contractor-set due dates to ensure timely payments.  
    
*   Synchronize contractor payments with QuickBooks as expenses for accurate financial reporting.  
    
*   Provide transparent fee breakdown for online payments to help agencies understand total costs.  
    
*   Reduce payment processing time and improve contractor satisfaction through timely payments.
#92
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **2\. User Roles & Permissions**
~202 tok
## **2\. User Roles & Permissions**

**Role**

**View Invoices**

**Pay (Stripe ACH)**

**Mark as Paid**

**Retry Payment**

**View Invoice PDF**

**Download Invoice**

**Sync QuickBooks**

Agency Owner

✅

✅

✅

✅

✅

✅

✅

Agency Admin

✅

❌

✅

❌

✅

✅

✅

**Role Descriptions:**

*   **Agency Owner:** Has full access to all contractor invoice functionalities including initiating online ACH payments via Stripe, retrying failed payments, marking invoices as paid manually, viewing and downloading invoice PDFs, and triggering QuickBooks sync.  
    
*   **Agency Admin:** Can view all contractor invoices, mark invoices as paid manually using offline payment methods, view and download invoice PDFs, and trigger QuickBooks sync. Agency Admins cannot initiate online ACH payouts or retry failed payments.
#93
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **3\. User Flow**
~797 tok
## **3\. User Flow**

**3.1** The user navigates to the Finances section from the left sidebar menu and clicks on Contractor Invoices.

**3.2** The system loads the Contractor Invoices module and displays the Unpaid tab by default with all unpaid and overdue invoices listed.

**3.3** If no invoices have been submitted by contractors, the system displays an empty state with the message "No contractor invoices yet" and secondary text "The Invoices will appear here once the contractors submit invoices."

**3.4** The user can switch between Unpaid, Processing, Paid, and Failed tabs by clicking on the respective tab headers.

**3.5** The system displays the invoice list for the selected tab with columns appropriate to that tab's context.

**3.6** The user observes invoices with "Overdue" status badge (red) in the Unpaid tab for invoices whose due date has passed without payment.

**3.7** The user clicks the expand arrow on any invoice row to view the Expected Contractor Payment details including the agreed fee, total amount invoiced, and any discrepancy.

**3.8** The system expands the row inline and displays the Expected Contractor Payment amount, Amount Invoiced by Contractor, and Discrepancy (if applicable).

**3.9** The user clicks the filter icon to open the Filters panel.

**3.10** The system displays the Filters panel with Date Issued, Brand, Contractor, and Project filter options.

**3.11** The user selects filter values and the system immediately filters the invoice list based on the selected criteria.

**3.12** The user clicks the "Pay" button on an unpaid or overdue invoice row (Agency Owner only).

**3.13** The system opens the "Pay Contractor" modal displaying contractor details, project name, issue date, Expected Contractor Payment, Amount Invoiced by Contractor, Discrepancy (if applicable), an editable Amount field pre-filled with the invoice amount, and the Stripe fee breakdown.

**3.14** The system displays the fee breakdown showing the Amount (payment to contractor), Fee (Stripe transaction fee), and implied total that the agency will be charged.

**3.15** If the agency has not connected their Stripe account or added a payment method, the system displays "No payment method set up" with the message "To pay your contractor, you'll need to add a payment method first." and an "Add Payment Method" button.

**3.16** If the contractor has not set up their bank account, the system displays a message "You can't process the payment as the contractor does not have their bank account set up to receive the payment. Please ask the contractor to add their bank account."

**3.17** If both agency and contractor payment methods are configured, the system displays the agency's linked bank account details with account name and last 4 digits.

**3.18** The user reviews the payment details including the Stripe fee, optionally modifies the amount (which triggers fee recalculation), and clicks "Pay Contractor" to initiate the ACH transfer.

**3.19** The system initiates the Stripe ACH payout and moves the invoice from Unpaid/Overdue to Processing status.

**3.20** The user clicks the "Mark as Paid" button on an unpaid or overdue invoice row.
#94
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **3\. User Flow**
~721 tok
**3.21** The system opens the "Mark as Paid" modal with confirmation text "You are about to mark this invoice as paid. Do you want to continue?", contractor details, Expected Contractor Payment, Amount Invoiced by Contractor, Discrepancy (if applicable), editable Amount field, Payment Method dropdown, and optional Note field.

**3.22** The system does not display any fee breakdown in the Mark as Paid modal since manual payments do not incur Stripe fees.

**3.23** The user selects a payment method from the dropdown (Cash, Check, Zelle, PayPal, Venmo, Google Pay, or Apple Pay), optionally enters a note, and clicks "Mark as Paid".

**3.24** The system moves the invoice directly from Unpaid/Overdue to Paid status and records the manual payment details.

**3.25** The user clicks the "View Invoice" button on any invoice row.

**3.26** The system opens a PDF viewer popup displaying the uploaded invoice document with Print, Download, and zoom controls.

**3.27** The user clicks the 3-dot overflow menu on any invoice row.

**3.28** The system displays menu options: View Invoice, Sync with QuickBooks (if not synced or sync failed), and Download Invoice.

**3.29** The user clicks "Retry Payment" icon on a failed invoice row (Agency Owner only).

**3.30** The system initiates a new ACH payout attempt and moves the invoice from Failed back to Processing status.

**3.31** The system receives a Stripe webhook confirming successful payout and moves the invoice from Processing to Paid status.

**3.32** The system receives a Stripe webhook indicating payout failure and moves the invoice from Processing to Failed status, storing the failure reason.

**3.33** The user clicks on a Project name link in the invoice list.

**3.34** The system navigates the user to the Project details page.

**3.35** The user enters a search term in the search bar.

**3.36** The system filters the invoice list to show invoices matching the search term against Contractor Name, Project Name, or Amount.

**3.37** The user clicks a column header to sort the invoice list.

**3.38** The system sorts the invoice list by the selected column in ascending or descending order.

**3.39** The user hovers over the info icon (ⓘ) next to the amount in the Paid tab to view the fee breakdown.

**3.40** The system displays a tooltip showing Transaction Method, Amount paid to contractor, and Fee charged by Stripe.

**3.41** The user clicks the QuickBooks sync icon on a Paid invoice.

**3.42** The system displays a tooltip showing the sync status ("Synced: \[Date\] at \[Time\]", "Not synced yet. Press QuickBooks icon to sync this transaction.", or "Sync failed. Press to retry.").

**3.43** If sync is pending or failed, the user clicks the icon and the system initiates a sync to QuickBooks.

**3.44** The system creates or updates the corresponding expense entry in QuickBooks upon successful sync.
#95
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#96
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.1 Navigation & Entry Points**
~166 tok
### **4.1 Navigation & Entry Points**

*   The Contractor Invoices module is accessible from the left sidebar under Finances → Contractor Invoices.  
    
*   The module can also be accessed contextually from Project details or Event details pages where contractor invoice links may be present.  
    
*   When the user navigates to the module, the system loads the Unpaid tab by default.  
    
*   The system displays a Brand dropdown filter in the header set to "All Brands" by default.  
    
*   The system displays a search bar in the header for quick invoice lookup.  
    
*   The system displays a filter icon button that opens the advanced Filters panel.
#97
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.2 Empty State Logic**
~112 tok
### **4.2 Empty State Logic**

*   If no invoices have been submitted by contractors across the entire system, the system displays the message "No invoices yet" with secondary text "The Invoices will appear here once the contractors submit invoices."  
    
*   Empty states are displayed only after data loading is complete to prevent UI flicker.  
    
*   Filters remain accessible during empty states to allow users to adjust filter criteria.
#98
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.3 Tab-Level Empty States**
~111 tok
### **4.3 Tab-Level Empty States**

*   If invoices exist in the system but the Unpaid tab has no entries, the system displays "No unpaid invoices found."  
    
*   If the Processing tab has no entries, the system displays "No invoices are currently processing."  
    
*   If the Paid tab has no entries, the system displays "No paid invoices found."  
    
*   If the Failed tab has no entries, the system displays "No failed invoices found."
#99
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.4 Filter-Induced Empty State**
~78 tok
### **4.4 Filter-Induced Empty State**

*   If the user applies filters that return zero results, the system displays the message "No invoices match your selected filters." with a "Clear Filters" CTA.  
    
*   Clicking "Clear Filters" resets all filter values to their defaults and refreshes the invoice list.
#100
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.5 Invoice Status Definitions**
~244 tok
### **4.5 Invoice Status Definitions**

*   **Unpaid:** The invoice has been uploaded by the contractor, the due date has not yet passed, and no payment attempt has been initiated (no ACH payout, no manual "Mark as Paid").  
    
*   **Overdue:** The invoice has been uploaded by the contractor, the due date set by the contractor has passed, and no payment has been processed or initiated. Overdue invoices are displayed within the Unpaid tab with a red "Overdue" status badge.  
    
*   **Processing:** A Stripe ACH payout has been initiated to the contractor's bank account and final confirmation is pending from Stripe (typically 3-5 business days).  
    
*   **Paid:** The ACH payout was successfully completed based on Stripe webhook confirmation, OR the agency used "Mark as Paid" to record a manual offline payment.  
    
*   **Failed:** The ACH payout failed due to a bank or Stripe error such as insufficient funds, blocked transaction, or invalid account details.
#101
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.6 Overdue Status Logic**
~283 tok
### **4.6 Overdue Status Logic**

*   The contractor sets the due date when uploading an invoice through the Contractor Portal.  
    
*   The system automatically monitors all unpaid invoices and compares the current date against each invoice's due date.  
    
*   When the current date exceeds the invoice's due date and the invoice has not been paid or is not in Processing status, the system automatically changes the invoice status from Unpaid to Overdue.  
    
*   The Overdue status change is performed by a background scheduled task that runs daily.  
    
*   Overdue invoices are displayed within the Unpaid tab alongside Unpaid invoices, distinguished by a red "Overdue" badge.  
    
*   There is no separate tab or filter specifically for Overdue invoices; they appear mixed with Unpaid invoices in the Unpaid tab.  
    
*   When an agency owner receives a notification that an invoice has become overdue, they can take action to pay the contractor promptly.  
    
*   Overdue invoices can be paid using either the "Pay" (Stripe ACH) or "Mark as Paid" (manual) methods, following the same flows as Unpaid invoices.
#102
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.7 Status Transitions**
~280 tok
### **4.7 Status Transitions**

*   **Unpaid → Overdue:** Occurs automatically when the current date exceeds the invoice's due date and no payment has been initiated.  
    
*   **Unpaid → Processing:** Occurs when the agency owner clicks "Pay" and confirms the online ACH payment via Stripe.  
    
*   **Unpaid → Paid:** Occurs when an agency user clicks "Mark as Paid" and confirms a manual offline payment method.  
    
*   **Overdue → Processing:** Occurs when the agency owner clicks "Pay" on an overdue invoice and confirms the online ACH payment via Stripe.  
    
*   **Overdue → Paid:** Occurs when an agency user clicks "Mark as Paid" on an overdue invoice and confirms a manual offline payment method.  
    
*   **Processing → Paid:** Occurs when Stripe webhook confirms successful ACH payout completion.  
    
*   **Processing → Failed:** Occurs when Stripe webhook returns a failure response.  
    
*   **Failed → Processing:** Occurs when the agency owner uses "Retry Payment" to initiate a new payout attempt for the same invoice.  
    
*   No other status transitions are permitted by the system.
#103
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.8 List View & Tab Structure**
~9 tok
### **4.8 List View & Tab Structure**
#104
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.8 List View & Tab Structure** > **4.8.1 Unpaid Tab Columns**
~174 tok
#### **4.8.1 Unpaid Tab Columns**

*   Contractor (with avatar and name). A green checkmark badge appears on the avatar when the contractor has completed Stripe payout setup; hovering the badge shows the tooltip “Stripe setup complete.” No badge is shown when setup is incomplete (see Section 4.28).  
    
*   Issued (date the invoice was submitted)  
    
*   Due Date (date set by contractor for payment)  
    
*   Status (displays "Unpaid" or "Overdue" badge; Overdue is displayed in red)  
    
*   Project (project name with event name and event color dot below)  
    
*   Amount (invoice amount in currency format)  
    
*   Actions (Pay, Mark as Paid, View Invoice buttons, 3-dot menu)
#105
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.8 List View & Tab Structure** > **4.8.2 Processing Tab Columns**
~205 tok
#### **4.8.2 Processing Tab Columns**

*   Contractor (with avatar and name). A green checkmark badge appears on the avatar when the contractor has completed Stripe payout setup; hovering the badge shows the tooltip “Stripe setup complete.” No badge is shown when setup is incomplete (see Section 4.28).  
    
*   Issued (date the invoice was submitted)  
    
*   Paid (date the payment was initiated)  
    
*   Paid Amount (the amount paid to the contractor, shown with an info icon (ⓘ) that displays the fee breakdown on hover — see Section 4.15)  
    
*   Payment Method (displays "Bank Transfer" for ACH or manual method name)  
    
*   Status (always displays "Processing" badge)  
    
*   Project (project name with event name and event color dot below)  
    
*   Actions (View Invoice button, 3-dot menu)
#106
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.8 List View & Tab Structure** > **4.8.3 Paid Tab Columns**
~220 tok
#### **4.8.3 Paid Tab Columns**

*   Contractor (with avatar and name). A green checkmark badge appears on the avatar when the contractor has completed Stripe payout setup; hovering the badge shows the tooltip “Stripe setup complete.” No badge is shown when setup is incomplete (see Section 4.28).  
    
*   Issued (date the invoice was submitted)  
    
*   Paid (date the payment was completed)  
    
*   Payment Method (displays "Bank Transfer" for ACH or manual method name)  
    
*   Status (always displays "Paid" badge)  
    
*   Project (project name with event name and event color dot below)  
    
*   Paid Amount (the amount paid to the contractor, shown with an info icon (ⓘ) that displays the fee breakdown on hover — see Section 4.15)  
    
*   QuickBooks Sync Icon (displays sync status)  
    
*   Actions (View Invoice button, QuickBooks Sync, 3-dot menu)
#107
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.8 List View & Tab Structure** > **4.8.4 Failed Tab Columns**
~134 tok
#### **4.8.4 Failed Tab Columns**

*   Contractor (with avatar and name). The Stripe setup badge is not displayed on the Failed tab (see Section 4.28).  
    
*   Issued (date the invoice was submitted)  
    
*   Failed Date (date and failure reason below)  
    
*   Payment Method (displays "Bank Transfer" or last attempted method)  
    
*   Status (always displays "Failed" badge in red)  
    
*   Project (project name with event name and event color dot below)  
    
*   Actions (View Invoice, Retry Payment icon, 3-dot menu)
#108
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.9 Expandable Row Logic**
~191 tok
### **4.9 Expandable Row Logic**

*   Each invoice row in the Unpaid tab has an expand/collapse arrow on the left side.  
    
*   When the user clicks the expand arrow, the row expands inline to display additional payment context.  
    
*   The expanded section displays: Expected Contractor Payment (the agreed contractor fee for the event), Amount Invoiced by Contractor (cumulative total of all invoices submitted by this contractor for this event), and Discrepancy (if applicable) showing the difference when invoiced amount exceeds the expected payment.  
    
*   The discrepancy value is displayed only when the Amount Invoiced exceeds the Expected Contractor Payment.  
    
*   Clicking the expand arrow again collapses the row back to its default state.
#109
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.10 Contractor Fee Tracking & Overage Warning**
~207 tok
### **4.10 Contractor Fee Tracking & Overage Warning**

*   Each contractor has an agreed fee per event that is set when the agency assigns the contractor to the event.  
    
*   The system tracks the cumulative total of all invoices submitted by a contractor for a specific event.  
    
*   The system does NOT block invoices that exceed the assigned contractor fee.  
    
*   When the total invoiced amount exceeds the assigned contractor fee, the system displays the discrepancy amount in the expanded row view.  
    
*   The discrepancy warning is also displayed in the Pay Contractor modal and Mark as Paid modal to alert the agency before processing payment.  
    
*   The agency can proceed with payment even when a discrepancy exists, as there may be valid reasons such as scope changes or extended event duration.
#110
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.11 Pay Contractor Modal (Online Payment)**
~13 tok
### **4.11 Pay Contractor Modal (Online Payment)**
#111
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.11 Pay Contractor Modal (Online Payment)**
~800 tok
*   The Pay Contractor modal opens when an Agency Owner clicks the "Pay" button on an unpaid or overdue invoice.  
    
*   The modal header displays "Pay Contractor" with a close (X) button.  
    
*   The Contractor section displays the contractor's avatar, name, linked project name, and issue date.  
    
*   A "View Invoice" link is displayed to allow the user to view the PDF without closing the modal.  
    
*   The modal displays Expected Contractor Payment, Amount Invoiced by Contractor, and Discrepancy (if applicable) as read-only informational fields.  
    
*   When the contractor has submitted more than one invoice for the same contractor and event/project, the modal displays an itemized breakdown listing all of those invoices instead of a single amount.  
    
*   The specific invoice on which the action was clicked is pinned to the top of the breakdown list regardless of its own status; the remaining invoices are listed below it sorted by status in the order Unpaid → Processing → Failed → Paid.  
    
*   Each row in the breakdown shows the invoice description, invoice number, issued date, status badge, a “View” link to open that invoice’s PDF, and the invoice amount. A Total Invoiced value (with invoice count) and the Discrepancy (if applicable) are shown below the list.  
    
*   The Amount field is pre-filled with the sum of all non-Paid invoices (Unpaid, Processing, and Failed) shown in the breakdown — not the full total invoiced and not only the pinned invoice. Invoices already in Paid status are displayed in the breakdown for context but are excluded from the default payable amount to prevent accidental duplicate payment. The field remains editable to allow partial payments or manual adjustment.  
    
*   If the contractor has only a single invoice for the event/project, the modal displays that single invoice inline with no breakdown list, and the Amount field is pre-filled with that invoice’s amount (unchanged behavior).  
    
*   The system fetches the current Stripe ACH transaction fee percentage dynamically from the Stripe API when the modal opens.  
    
*   The modal displays a fee breakdown section showing: Amount (the payment that will be sent to the contractor), and Fee (the Stripe transaction fee that the agency will bear).  
    
*   The total amount the agency will be charged equals the Amount plus the Fee.  
    
*   When the user edits the Amount field, the system automatically recalculates the Stripe Fee in real-time based on the new amount.  
    
*   If the contractor has not set up their bank account, the modal displays "You can't process the payment as the contractor does not have their bank account set up to receive the payment. Please ask the contractor to add their bank account." and the Pay Contractor button is disabled.  
    
*   If the agency has not set up their payment method, the modal displays "No payment method set up" with the message "To pay your contractor, you'll need to add a payment method first." and an "Add Payment Method" button that redirects to Stripe Financial Connections.  
    
*   If both payment methods are configured, the modal displays the agency's connected bank account w
#112
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.11 Pay Contractor Modal (Online Payment)**
~142 tok
ith company name and last 4 digits of the account number, along with an edit icon to change the payment method.  
    
*   The Cancel button closes the modal without any changes.  
    
*   The Pay Contractor button should validate that both the agency and contractor payment methods are configured and the amount field has a valid value.  
    
*   Clicking Pay Contractor initiates the Stripe ACH payout (charging the agency the Amount plus Fee) and closes the modal.  
    
*   The contractor receives the full Amount; the Fee is deducted from the agency's payment.
#113
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.12 Stripe Transaction Fee Logic**
~279 tok
### **4.12 Stripe Transaction Fee Logic**

*   For all online payments via Stripe ACH, the agency bears the Stripe transaction fees.  
    
*   The Stripe fee percentage is fetched dynamically from the Stripe API and may vary (e.g., 1.8% for ACH).  
    
*   The fee is calculated as: Fee = Amount × (Stripe Fee Percentage / 100).  
    
*   The total charge to the agency is: Total = Amount + Fee.  
    
*   Example: If Amount = $100.00 and Stripe Fee = 1.8%, then Fee = $1.80 and Total = $101.80.  
    
*   The fee breakdown is displayed in the Pay Contractor modal before payment initiation.  
    
*   The fee breakdown is visible in the Paid tab via an info icon (ⓘ) tooltip showing Transaction Method, Amount, and Fee.  
    
*   The fee breakdown is also included in transaction history reports.  
    
*   Stripe fees are only charged when a payment is successful; failed payment attempts do not incur fees.  
    
*   When retrying a failed payment, the Stripe fee will be charged only if the retry attempt is successful.  
    
*   Manual payments recorded via "Mark as Paid" do not incur any Stripe fees.
#114
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.13 Mark as Paid Modal (Manual Payment)**
~694 tok
### **4.13 Mark as Paid Modal (Manual Payment)**

*   The Mark as Paid modal opens when an agency user clicks the "Mark as Paid" button on an unpaid or overdue invoice.  
    
*   The modal header displays "Mark as Paid" with a close (X) button.  
    
*   The modal displays confirmation text: "You are about to mark this invoice as paid. Do you want to continue?"  
    
*   The Contractor section displays the contractor's avatar, name, linked project name, and issue date.  
    
*   A "View Invoice" link is displayed to allow the user to view the PDF without closing the modal.  
    
*   The modal displays Expected Contractor Payment, Amount Invoiced by Contractor, and Discrepancy (if applicable) as read-only informational fields.  
    
*   When the contractor has submitted more than one invoice for the same contractor and event/project, the modal displays an itemized breakdown listing all of those invoices instead of a single amount.  
    
*   The specific invoice on which the action was clicked is pinned to the top of the breakdown list regardless of its own status; the remaining invoices are listed below it sorted by status in the order Unpaid → Processing → Failed → Paid.  
    
*   Each row in the breakdown shows the invoice description, invoice number, issued date, status badge, a “View” link to open that invoice’s PDF, and the invoice amount. A Total Invoiced value (with invoice count) and the Discrepancy (if applicable) are shown below the list.  
    
*   The Amount field is pre-filled with the sum of all non-Paid invoices (Unpaid, Processing, and Failed) shown in the breakdown; invoices already in Paid status are shown for context but excluded from the default amount to prevent accidental duplicate payment. The field remains editable.  
    
*   If the contractor has only a single invoice for the event/project, the modal displays that single invoice inline with no breakdown list, and the Amount field is pre-filled with that invoice’s amount (unchanged behavior).  
    
*   No fee breakdown is displayed since manual payments do not incur Stripe fees.  
    
*   The Payment Method dropdown is required and contains options: Cash, Check, Zelle, PayPal, Venmo, Google Pay, Apple Pay.  
    
*   The Note field is optional and allows the agency to record internal notes about the payment (maximum 1000 characters).  
    
*   The Note field content is visible only to agency owner and team members, not to the contractor.  
    
*   The Cancel button closes the modal without any changes.  
    
*   The Mark as Paid button should validate that a payment method is selected and the amount field has a valid value.  
    
*   Clicking Mark as Paid records the manual payment, moves the invoice to Paid status, and closes the modal.
#115
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.14 View Invoice Functionality**
~139 tok
### **4.14 View Invoice Functionality**

*   Clicking the "View Invoice" button opens a full-screen PDF viewer popup.  
    
*   The popup header displays the invoice filename in the format "\[Contractor Name\] - \[Project Name\] (\[Issue Date\]).pdf".  
    
*   The popup header includes Print, Download, zoom out (-), zoom percentage dropdown, and zoom in (+) controls.  
    
*   A back arrow in the top-left allows the user to close the popup and return to the invoice list.  
    
*   The PDF viewer displays the contractor-uploaded invoice document.
#116
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.15 Paid Amount Column & Fee Breakdown Tooltip (Processing & Paid Tabs)**
~272 tok
### **4.15 Paid Amount Column & Fee Breakdown Tooltip (Processing & Paid Tabs)**

*   A “Paid Amount” column appears on both the Processing and Paid tabs, showing the amount paid to the contractor with an info icon (ⓘ) next to it. This column is additive and does not replace the Paid (date) column.  
    
*   Hovering over the info icon displays a tooltip with the fee breakdown.  
    
*   For online payments (Stripe ACH / Bank Transfer), the tooltip shows: Paid Amount (the payment sent to the contractor), Stripe Fees (the Stripe transaction fee), and Net Paid (the total cost to the agency, equal to Paid Amount plus Stripe Fees).  
    
*   For manual payments (Cash, Check, Zelle, PayPal, Venmo, Google Pay, Apple Pay), the tooltip shows only the Transaction Method and Paid Amount; the Stripe Fees and Net Paid lines are omitted because no Stripe fee is charged.  
    
*   The Paid Amount column and its tooltip behave identically on the Processing and Paid tabs for consistency.  
    
*   The tooltip also displays the installment information if applicable (e.g., "1 of 2").
#117
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.16 Failed Payment & Retry Logic**
~200 tok
### **4.16 Failed Payment & Retry Logic**

*   When an ACH payout fails, the system stores the failure reason received from Stripe.  
    
*   The Failed tab displays the failure date and failure reason below each failed invoice (e.g., "Card Declined", "Invalid Card Details", "Insufficient Funds", "Payment Blocked").  
    
*   The Retry Payment action is available only to Agency Owners.  
    
*   Clicking the Retry Payment icon initiates a new Stripe ACH payout attempt for the same invoice.  
    
*   Upon retry, the invoice status changes from Failed to Processing.  
    
*   Stripe fees are not charged for failed payment attempts; fees are only charged if the retry is successful.  
    
*   The subsequent Stripe webhook will determine whether the invoice moves to Paid or back to Failed.
#118
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.17 Invoice Payment Status Icon**
~335 tok
### **4.17 Invoice Payment Status Icon**

*   When a contractor's invoice is paid or marked as paid by the agency, the invoice payment status icon reflects the updated status  
    
*   The invoice icon visually indicates the payment status of a contractor's invoice  
    
*   The icon fill state updates automatically when the agency marks payments  
    
*   **Icon States:  
    **
*   **Unpaid  
    **
    *   Icon appears empty (outline only)  
        
    *   No payment has been made against the invoice  
        
*   **Partial Payment  
    **
    *   Icon appears half-filled  
        
    *   Agency has made a partial payment  
        
    *   Remaining balance is pending  
        
*   **Fully Paid  
    **
    *   Icon appears completely filled  
        
    *   Full invoice amount has been paid by the agency  
        
*   **Modules Impacted:  
    **
    *   Calendar List View - Invoice icon displayed alongside each event entry  
        
    *   Event Details > Contractors Tab - Invoice icon shown for each assigned contractor  
        
    *   Project Listing - Invoice icon visible in the project list view  
        
    *   Event Listing - Invoice icon displayed for each event row  
        
    *   Contractor Portal > Event Listing  
        
    *   Contractor Portal > Event Details> Contractor’s tab
#119
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.18 Filters Panel Logic**
~344 tok
### **4.18 Filters Panel Logic**

*   The Filters panel is accessed by clicking the filter icon in the header.  
    
*   A refresh icon at the top of the panel resets all filters to default values.  
    
*   **Date Issued Filter:** A date picker allowing the user to select a specific date or date range.  
    
*   **Brand Filter:** A single-select dropdown defaulting to "All Brands" that filters invoices by the brand associated with the project.  
    
*   **Contractor Filter:** A multi-select list with search functionality allowing the user to select one or more contractors.  
    
*   **Project Filter:** A multi-select list with search functionality allowing the user to select one or more projects.  
    
*   When a Brand is selected, the Project filter list is scoped to show only projects belonging to that brand.  
    
*   When a Brand is selected, the Contractor filter list is scoped to show only contractors assigned to events within that brand.  
    
*   Filters apply across all four status tabs (Unpaid, Processing, Paid, Failed).  
    
*   Filter selections persist when switching between status tabs until manually cleared.  
    
*   Applying filters immediately refreshes the invoice list without requiring a separate "Apply" action.  
    
*   There is no dedicated filter for Overdue status; Overdue invoices are viewed within the Unpaid tab.
#120
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.19 Search Functionality**
~95 tok
### **4.19 Search Functionality**

*   The search bar in the header allows quick lookup of invoices.  
    
*   Search matches against Contractor Name, Project Name, and Amount.  
    
*   Search results are displayed in real-time as the user types.  
    
*   Search works in conjunction with applied filters.  
    
*   Clearing the search field restores the full filtered list.
#121
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.20 Sorting Logic**
~152 tok
### **4.20 Sorting Logic**

*   All column headers with a down arrow (↓) are sortable.  
    
*   Clicking a sortable column header sorts the list by that column in ascending order.  
    
*   Clicking the same column header again toggles to descending order.  
    
*   Sortable columns include: Contractor, Issued, Due Date (Unpaid tab), Paid (where applicable), Payment Method (where applicable), Status, Project, Amount.  
    
*   Default sort order is by Issued date in descending order (most recent first).  
    
*   Sorting preferences persist while navigating between tabs within the same session.
#122
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.21 Pagination Logic**
~91 tok
### **4.21 Pagination Logic**

*   The invoice list supports pagination with a "Rows per page" dropdown (default: 10).  
    
*   Available options for rows per page are: 10, 25, 50.  
    
*   The pagination footer displays the current range (e.g., "1-4 of 4") and navigation arrows.  
    
*   Pagination state resets when switching tabs or applying new filters.
#123
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.22 Project & Event Linkage**
~129 tok
### **4.22 Project & Event Linkage**

*   Every Contractor Invoice is mandatorily linked to a specific Event.  
    
*   Every Event is mandatorily linked to a Project.  
    
*   Every Project is mandatorily linked to a Brand.  
    
*   The Project column displays the project name with the event name and event color dot displayed below.  
    
*   Clicking on the Project name navigates the user to the Project details page.  
    
*   Multiple invoices can exist for the same contractor and event combination.
#124
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.23 3-Dot Overflow Menu Actions**
~88 tok
### **4.23 3-Dot Overflow Menu Actions**

*   **View Invoice:** Opens the PDF viewer popup to display the uploaded invoice document.  
    
*   **Sync with QuickBooks:** Displayed only if the invoice is not synced or sync has failed; triggers a manual sync to QuickBooks.  
    
*   **Download Invoice:** Downloads the invoice PDF to the user's device.
#125
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.24 QuickBooks Integration**
~236 tok
### **4.24 QuickBooks Integration**

*   Contractor payments (both online ACH and manual) sync to QuickBooks as expenses.  
    
*   When an invoice status becomes Paid, the system creates or updates the corresponding expense entry in QuickBooks.  
    
*   The QuickBooks sync icon displays one of three states: Synced successfully, Sync failed, Sync pending.  
    
*   Hovering over the sync icon displays a tooltip with status details (e.g., "Synced: Aug 20, 2025 at 7:00pm" or "Not synced yet. Press QuickBooks icon to sync this transaction.").  
    
*   If sync fails, the user can click the icon to manually retry the sync.  
    
*   Data mapping: Contractor maps to Vendor in QuickBooks, Project maps to Class/Job, payment amount maps to expense amount, and Stripe fee (if applicable) is recorded separately or as part of the expense.  
    
*   If the agency has not connected their QuickBooks account, the sync icon is not displayed.
#126
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.25 Stripe Connect Integration**
~212 tok
### **4.25 Stripe Connect Integration**

*   Pixally maintains a master Stripe account with both agencies and contractors as connected accounts.  
    
*   When an agency invites a contractor to Pixally for the first time, the system creates a Stripe Connect account for the contractor under Pixally's master account.  
    
*   Contractors complete the Stripe onboarding process only once, even if invited by multiple agencies.  
    
*   Each agency that wants to pay a contractor must set up a customer profile and payment method within the contractor's Stripe account.  
    
*   If a contractor is already associated with another agency on Pixally, they do not need to complete onboarding again.  
    
*   For ACH payouts to succeed, both the agency's funding bank account and the contractor's payout bank account must be configured in Stripe.
#127
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.26 Notifications & Emails**
~263 tok
### **4.26 Notifications & Emails**

*   **Payment Success (to Contractor):** When a contractor payment is successfully processed (either via ACH or marked as paid manually), the system sends an email notification and an in-app notification to the contractor confirming the payment.  
    
*   **Payment Failed (to Agency Owner):** When an ACH payout fails, the system sends an email notification to the agency owner with the failure reason.  
    
*   **New Invoice Submitted (to Agency):** When a contractor submits a new invoice, the system sends an in-app notification to agency users.  
    
*   **Invoice Overdue (to Agency Owner):** When an invoice's due date passes and the invoice becomes Overdue, the system sends a notification to the agency owner alerting them of the overdue invoice.  
    
*   **Invoice Overage Warning:** The warning is displayed only in the UI (Pay Contractor modal and Mark as Paid modal) when the agency attempts to pay an invoice that exceeds the expected contractor fee; no email notification is sent for overage.
#128
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.27 Audit Trail**
~127 tok
### **4.27 Audit Trail**

*   The system maintains an audit trail for all payment-related actions.  
    
*   Logged actions include: Invoice submitted, Invoice became overdue, Payment initiated, Payment completed, Payment failed, Payment retried, Invoice marked as paid, QuickBooks sync attempted, QuickBooks sync completed, QuickBooks sync failed.  
    
*   Each audit entry captures the action timestamp, user who performed the action, and relevant details including fee information for online payments.
#129
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.28 Contractor Stripe Setup Indicator**
~375 tok
### **4.28 Contractor Stripe Setup Indicator**

*   Purpose: give agency owners and admins at-a-glance visibility into which contractors have completed their Stripe payout setup, without opening the Pay Contractor modal.  
    
*   A small green checkmark badge is overlaid on the contractor’s avatar in the list view.  
    
*   On hover, the badge shows the tooltip “Stripe setup complete.”  
    
*   The badge appears only when the contractor’s Stripe payout setup is complete. When setup is incomplete, no badge is shown — the absence of the badge implies incomplete setup, and no separate “not set up” icon or state is used.  
    
*   The badge is displayed on the Unpaid, Processing, and Paid tabs only.  
    
*   The badge is not displayed on the Failed tab.  
    
*   The badge appears strictly on the main list-view rows (the Contractor column avatar). It does not appear on the contractor avatar inside the Pay Contractor modal, the Mark as Paid modal, or the Filters panel contractor list.  
    
*   The indicator is informational only and does not gate or restrict any action; Pay and Mark as Paid remain governed by the existing payment-method validation logic (see Section 4.11 and Section 5).  
    
*   If a contractor completes Stripe setup after invoices already exist, the badge appears on the next data refresh across the applicable tabs (Unpaid, Processing, Paid). If a contractor’s setup later becomes invalid or disconnected, the badge is removed on the next data refresh.
#130
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **5\. Field Details & Validations**
~682 tok
## **5\. Field Details & Validations**

**Field Name**

**Field Type**

**Validation Rules**

Contractor Name

Text (Display)

Read-only; pulled from contractor profile

Contractor Avatar

Image (Display)

Read-only; pulled from contractor profile

Issued Date

Date (Display)

Read-only; set when contractor submits invoice; Format: MMM D, YYYY

Due Date

Date (Display)

Read-only; set by contractor when uploading invoice; Format: MMM D, YYYY

Paid Date

Date (Display)

Read-only; set when payment completes; Format: MMM D, YYYY

Failed Date

Date (Display)

Read-only; set when payment fails; Format: Month D, YYYY

Status

Badge (Display)

Read-only; system-managed; Values: Unpaid (default), Overdue (red), Processing, Paid, Failed (red)

Project Name

Text (Link)

Read-only; clickable to navigate to project details

Event Name

Text (Display)

Read-only; displayed with event color dot below project name

Invoice Amount

Currency (Display)

Read-only; set by contractor; Format: $X,XXX.XX

Expected Contractor Payment

Currency (Display)

Read-only; pulled from contractor assignment on event

Amount Invoiced by Contractor

Currency (Display)

Read-only; cumulative sum of all invoices for contractor-event

Discrepancy

Currency (Display)

Read-only; calculated as (Amount Invoiced - Expected Payment) when positive

Payment Amount

Currency (Input)

Required; Numeric only; Must be greater than $0.00; Pre-filled with the sum of non-Paid invoices in the breakdown (Unpaid, Processing, Failed) when multiple invoices exist, otherwise the single invoice amount; editable; Format: $X,XXX.XX

Stripe Fee

Currency (Display)

Read-only; calculated dynamically as Amount × Stripe Fee Percentage; Format: $X.XX

Stripe Fee Percentage

Percentage (System)

Fetched dynamically from Stripe API; typically 1.8% for ACH

Total Charge

Currency (Display)

Read-only; calculated as Payment Amount + Stripe Fee; Format: $X,XXX.XX

Payment Method (Manual)

Dropdown (Select)

Required for Mark as Paid; Options: Cash, Check, Zelle, PayPal, Venmo, Google Pay, Apple Pay

Note

Text Area (Input)

Optional; Maximum 1000 characters; Internal use only

Failure Reason

Text (Display)

Read-only; populated from Stripe webhook response

QuickBooks Sync Status

Icon (Display)

Read-only; States: Synced, Failed, Pending

Search Query

Text (Input)

Optional; Matches against Contractor Name, Project Name, Amount

Date Issued Filter

Date Picker

Optional; Accepts single date or date range

Brand Filter

Dropdown (Single-select)

Optional; Default: All Brands

Contractor Filter

Multi-select List

Optional; Searchable; Multiple selections allowed

Project Filter

Multi-select List

Optional; Searchable; Scoped to selected brand
#131
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **6\. Success Message Handling**
~332 tok
## **6\. Success Message Handling**

**Operation**

**Success Message**

**Trigger Condition**

**Post-Success Action**

Pay Contractor (ACH)

"Payment initiated successfully. The contractor will receive funds within 3-5 business days."

User clicks "Pay Contractor" and ACH payout is initiated

Modal closes; Invoice moves to Processing tab; List refreshes

Mark as Paid

"Invoice marked as paid successfully."

User clicks "Mark as Paid" with valid payment method selected

Modal closes; Invoice moves to Paid tab; List refreshes

Retry Payment

"Payment retry initiated. Processing will complete within 3-5 business days."

User clicks Retry Payment icon on failed invoice

Invoice moves to Processing tab; List refreshes

QuickBooks Sync

"Successfully synced with QuickBooks."

Manual or automatic sync completes successfully

Sync icon updates to "Synced" state; Tooltip shows sync timestamp

Download Invoice

"Invoice downloaded successfully."

User clicks Download Invoice from 3-dot menu

PDF file downloads to user's device

Filters Applied

(No toast message - list updates silently)

User selects filter values

Invoice list refreshes to show filtered results

Filters Cleared

"Filters cleared."

User clicks "Clear Filters" or refresh icon

All filters reset to defaults; List shows all invoices for current tab
#132
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **7\. Error Message Handling**
~798 tok
## **7\. Error Message Handling**

**Error Scenario**

**Error Message**

**Trigger Condition**

**Required Action**

Agency Payment Method Not Set Up

"No payment method set up. To pay your contractor, you'll need to add a payment method first."

Agency clicks Pay but has not connected Stripe or added payment method

Click "Add Payment Method" to configure Stripe Financial Connections

Contractor Bank Account Not Set Up

"You can't process the payment as the contractor does not have their bank account set up to receive the payment. Please ask the contractor to add their bank account."

Agency clicks Pay but contractor has not completed Stripe onboarding

Contact contractor to complete bank account setup in Contractor Portal

Payment Amount Invalid

"Please enter a valid payment amount greater than $0.00."

User enters zero, negative, or non-numeric value in Amount field

Enter a valid positive numeric amount

Payment Amount Exceeds Limit

"Payment amount exceeds the maximum allowed limit."

User enters amount exceeding Stripe ACH limit

Enter an amount within the allowed limit

Payment Method Required

"Please select a payment method to continue."

User clicks Mark as Paid without selecting payment method

Select a payment method from the dropdown

Stripe Fee Fetch Failed

"Unable to calculate transaction fees. Please try again."

System fails to fetch Stripe fee percentage from API

Close modal and try again; Contact support if issue persists

ACH Payout Failed - Insufficient Funds

"Payment failed: Insufficient funds in the source account."

Stripe webhook returns insufficient funds error

Verify agency bank account balance and retry payment

ACH Payout Failed - Invalid Account

"Payment failed: Invalid bank account details."

Stripe webhook returns invalid account error

Contractor must update bank account details

ACH Payout Failed - Account Blocked

"Payment failed: The recipient's bank account is blocked."

Stripe webhook returns blocked account error

Contractor must resolve issue with their bank

ACH Payout Failed - Card Declined

"Payment failed: Card declined by the bank."

Stripe webhook returns card declined error

Verify payment details and retry

QuickBooks Sync Failed

"Failed to sync with QuickBooks. Click to retry."

QuickBooks API returns error during sync

Click sync icon to retry; If persistent, verify QuickBooks connection

QuickBooks Not Connected

"Connect your QuickBooks account to sync contractor payments."

User attempts sync but QuickBooks is not connected

Navigate to Settings → Integrations to connect QuickBooks

Search No Results

"No invoices found matching your search."

Search query returns no matching invoices

Modify search term or clear search

Filter No Results

"No invoices match your selected filters."

Applied filters return zero results

Adjust filter criteria or click "Clear Filters"

Note Exceeds Character Limit

"Note cannot exceed 1000 characters."

User enters more than 1000 characters in Note field

Reduce note content to 1000 characters or less

Network Error

"Unable to complete the request. Please check your connection and try again."

Network connectivity issue during any operation
#133
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **7\. Error Message Handling**
~45 tok
Check internet connection and retry the action

Session Expired

"Your session has expired. Please log in again."

User session times out during operation

Log in again to continue
#134
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **8\. Edge Cases**
~791 tok
## **8\. Edge Cases**

**Edge Case**

**System Behavior**

Contractor submits multiple invoices for the same event

The system accepts all invoices and displays them as separate line items; Amount Invoiced by Contractor shows cumulative total. When Pay or Mark as Paid is clicked, the modal lists all invoices for that contractor-event with the selected invoice pinned on top and the remaining invoices sorted by status, and the Amount field defaults to the sum of the non-Paid invoices only (already-Paid invoices are shown for context but excluded to prevent duplicate payment).

Total invoiced amount exceeds agreed contractor fee

The system displays a discrepancy warning but does not block payment; Agency can proceed with payment

Agency attempts to pay more than invoice amount

The system allows overpayment as the Amount field is editable; Stripe fee is calculated on the new amount

Agency pays partial amount

The system processes the partial payment with fee calculated on partial amount; Invoice status changes based on payment flow; Original invoice amount remains unchanged for reference

Invoice due date passes without payment

System automatically changes status from Unpaid to Overdue; Agency owner receives notification

Invoice due date is set to past date by contractor

System immediately marks invoice as Overdue upon submission

Payment initiated on same day as due date

Invoice remains Unpaid (not Overdue) until end of due date; If payment processing extends past due date, status depends on payment completion

Stripe webhook delayed beyond 5 business days

Invoice remains in Processing status until webhook is received; No timeout mechanism auto-fails the payment

Stripe webhook received out of order

The system processes webhooks based on event timestamp, not receipt order

Stripe fee percentage changes during modal session

Fee is calculated at time of payment initiation using the rate fetched when modal opened; Real-time rate changes don't affect in-progress modals

User switches tabs while payment is processing

The invoice correctly appears in Processing tab; Original tab updates upon return

User applies filters then switches tabs

Filter selections persist across tab switches within the same session

Brand with no projects is selected in filter

Project filter shows empty list; Contractor filter shows empty list

Contractor is removed from event after submitting invoice

Existing invoices remain visible and can still be paid; New invoices cannot be submitted

Project is deactivated after invoice submission

Existing invoices remain visible and can still be processed; Project name displays with deactivated indicator

Multiple users attempt to pay same invoice simultaneously

First successful payment request is processed; Subsequent attempts fail with "Invoice already processing" error

QuickBooks sync fails due to disconnection

Sync icon shows failed state; User can reconnect QuickBooks and retry sync

Agency disconnects Stripe account with invoices in Processing

Processing invoices continue through Stripe; New payments cannot be initiated until reconnection

Contractor has multiple bank accounts
#135
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **8\. Edge Cases**
~245 tok
The system uses the default payout bank account set in contractor's Stripe Connect account

PDF invoice file is corrupted or cannot be rendered

System displays error "Unable to load invoice. Please contact support." with option to download file directly

User opens Pay modal for invoice that was just paid by another user

Modal displays current status and refreshes; Shows message "This invoice has already been paid."

Internet disconnects during payment confirmation

System displays network error; User should check Processing tab to verify if payment was initiated

Note field contains special characters

System accepts all UTF-8 characters including emojis; Properly escapes for storage

Amount field receives paste with currency symbol

System strips non-numeric characters except decimal point; Validates resulting number; Recalculates fee

Stripe API unavailable when fetching fee

Modal displays error message; Pay Contractor button disabled until fee can be fetched
#136
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **9\. Acceptance Criteria**
~8 tok
## **9\. Acceptance Criteria**
#137
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **9\. Acceptance Criteria** > **9.1 Navigation & Access**
~93 tok
### **9.1 Navigation & Access**

*   Users can access Contractor Invoices from Finances menu in left sidebar.  
    
*   Unpaid tab is displayed by default when module loads.  
    
*   All four status tabs (Unpaid, Processing, Paid, Failed) are visible and clickable.  
    
*   Brand dropdown filter defaults to "All Brands" and shows all brands the user has access to.
#138
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **9\. Acceptance Criteria** > **9.2 Empty States**
~77 tok
### **9.2 Empty States**

*   System displays "No contractor invoices yet" with secondary text when no invoices exist.  
    
*   Tab-level empty states display when no invoices exist for specific status.  
    
*   Filter-induced empty state displays with Clear Filters option when filters return no results.
#139
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **9\. Acceptance Criteria** > **9.3 Invoice List Display**
~158 tok
### **9.3 Invoice List Display**

*   Invoice rows display correct columns for each tab type.  
    
*   Unpaid tab displays both Unpaid and Overdue invoices with appropriate status badges.  
    
*   Overdue status is displayed with a red badge.  
    
*   Due Date column is visible in the Unpaid tab.  
    
*   Expandable rows show Expected Contractor Payment, Amount Invoiced, and Discrepancy.  
    
*   Project column shows project name with event name and color dot below.  
    
*   Status badges display correct color and text for each status.  
    
*   Pagination controls work correctly with configurable rows per page.
#140
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **9\. Acceptance Criteria** > **9.4 Overdue Logic**
~84 tok
### **9.4 Overdue Logic**

*   Invoices automatically transition from Unpaid to Overdue when due date passes.  
    
*   Agency owner receives notification when invoice becomes overdue.  
    
*   Overdue invoices can be paid via Pay or Mark as Paid methods.  
    
*   Overdue invoices appear within the Unpaid tab (no separate tab).
#141
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **9\. Acceptance Criteria** > **9.5 Pay Contractor Flow**
~183 tok
### **9.5 Pay Contractor Flow**

*   Pay button is visible only to Agency Owners.  
    
*   Pay Contractor modal displays all required information fields including fee breakdown.  
    
*   Stripe fee is fetched dynamically and displayed in the modal.  
    
*   Fee recalculates automatically when Amount field is edited.  
    
*   Modal shows appropriate message when agency payment method is not configured.  
    
*   Modal shows appropriate message when contractor bank account is not configured.  
    
*   Amount field is pre-filled and editable.  
    
*   Pay Contractor button initiates Stripe ACH payout with total charge (Amount + Fee).  
    
*   Invoice moves to Processing status after successful payment initiation.
#142
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **9\. Acceptance Criteria** > **9.6 Mark as Paid Flow**
~121 tok
### **9.6 Mark as Paid Flow**

*   Mark as Paid button is visible to both Agency Owners and Agency Admins.  
    
*   Modal displays a confirmation message and all required fields.  
    
*   No fee breakdown is displayed for manual payments.  
    
*   Payment Method dropdown shows all seven options (Cash, Check, Zelle, PayPal, Venmo, Google Pay, Apple Pay).  
    
*   Note field accepts up to 1000 characters.  
    
*   Invoice moves directly to Paid status after confirmation.
#143
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **9\. Acceptance Criteria** > **9.7 Paid Tab Fee Display**
~65 tok
### **9.7 Paid Tab Fee Display**

*   Paid invoices from online payments display info icon (ⓘ) next to amount.  
    
*   Hovering over info icon shows tooltip with Transaction Method, Amount, and Fee.  
    
*   Manually paid invoices do not display info icon.
#144
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **9\. Acceptance Criteria** > **9.8 Failed Payment & Retry**
~84 tok
### **9.8 Failed Payment & Retry**

*   Failed invoices display failure date and reason.  
    
*   Retry Payment icon is visible only to Agency Owners.  
    
*   Retry initiates new ACH payout attempt.  
    
*   Stripe fees are only charged on successful retry.  
    
*   Invoice moves to Processing status after retry initiation.
#145
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **9\. Acceptance Criteria** > **9.9 Filters & Search**
~99 tok
### **9.9 Filters & Search**

*   All filter types function correctly (Date, Brand, Contractor, Project).  
    
*   Project filter scopes to selected Brand.  
    
*   Contractor filter scopes to selected Brand.  
    
*   Filters persist across tab switches.  
    
*   Search matches against Contractor Name, Project Name, and Amount.  
    
*   Clear Filters resets all filters to defaults.
#146
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **9\. Acceptance Criteria** > **9.10 Sorting**
~53 tok
### **9.10 Sorting**

*   All designated columns are sortable including Due Date in Unpaid tab.  
    
*   Sort order toggles between ascending and descending.  
    
*   Sort preferences persist within session.
#147
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **9\. Acceptance Criteria** > **9.11 QuickBooks Integration**
~68 tok
### **9.11 QuickBooks Integration**

*   Sync icon displays correct state (Synced, Failed, Pending).  
    
*   Tooltip shows sync status details on hover.  
    
*   Manual sync triggers successfully when clicked.  
    
*   Paid invoices sync to QuickBooks as expenses.
#148
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **9\. Acceptance Criteria** > **9.12 Notifications**
~82 tok
### **9.12 Notifications**

*   Contractor receives email and in-app notification on successful payment.  
    
*   Agency owner receives email notification on failed payment.  
    
*   Agency receives in-app notification when new invoice is submitted.  
    
*   Agency owner receives notification when invoice becomes overdue.
#149
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **9\. Acceptance Criteria** > **9.13 View & Download Invoice**
~51 tok
### **9.13 View & Download Invoice**

*   View Invoice opens PDF viewer popup.  
    
*   PDF viewer has Print, Download, and zoom controls.  
    
*   Download Invoice downloads PDF file to user's device.
#150
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **10\. Manual Test Cases**
~64 tok
## **10\. Manual Test Cases**

Test cases are documented in a separate Excel file for import into test management tools.

**Refer:** [<u>Click Here</u>](https://docs.google.com/spreadsheets/d/1XG6d-HIZbultzZs2f2joNP_I0UMGyFD4FFf5980cOXU/edit?usp=drive_link)
#151
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **11\. Dependencies**
~468 tok
## **11\. Dependencies**

**Dependency Type**

**Dependency Name**

**Description**

**Impact if Unavailable**

Internal Module

Brands

Brand creation and management

Invoices cannot be linked to projects/events

Internal Module

Projects

Project creation and linking

Invoices cannot be associated with projects

Internal Module

Events

Event creation within projects

Invoices cannot be linked to specific events

Internal Module

Contractor Management

Contractor profiles and event assignment

Cannot assign contractors or receive invoices

Internal Module

Contractor Portal

Interface for contractors to submit invoices with due dates

Invoices cannot be created by contractors

External Service

Stripe Connect

Payment processing for ACH payouts

Online payments cannot be processed; Mark as Paid still available

External Service

Stripe Financial Connections

Bank account linking for agencies

Agencies cannot add payment methods for ACH

External Service

Stripe Webhooks

Payment status updates

Payment status stuck in Processing; Manual verification required

External Service

Stripe Pricing API

Dynamic fee percentage retrieval

Fee cannot be calculated; Online payment blocked until resolved

External Service

QuickBooks API

Expense synchronization

Expense entries not created; Manual accounting required

Configuration

Agency Stripe Account

Agency's connected Stripe account

Cannot initiate ACH payments

Configuration

Contractor Stripe Account

Contractor's Stripe Connect account

Cannot receive ACH payments

Configuration

Agency Payment Method

Linked bank account for fund source

Cannot initiate ACH payments

Configuration

Contractor Bank Account

Linked bank account for payout

Cannot receive ACH payments

Background Service

Overdue Status Scheduler

Daily job to update invoice statuses

Invoices won't auto-transition to Overdue
#152
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **12\. References**
~45 tok
## **12\. References**

Please refer- [<u>Click Here</u>](https://www.figma.com/design/ej0kxwP45mDKmZCZfAJ5O8/Pixally?node-id=29141-24236&t=7RQKgcJBUkbtY4aT-0)

View detail invoice
#153
**Functional Requirements Document (FRD) — Invoice Details View**
~17 tok
# **Functional Requirements Document (FRD) — Invoice Details View**
#154
**Functional Requirements Document (FRD) — Invoice Details View** > **1\. Module Overview**
~247 tok
## **1\. Module Overview**

*   **Module Name:** Billing → Invoice Details View  
    
*   **Purpose:** The Invoice Details View provides a complete, single-screen representation of an individual invoice — including line items, taxes, discounts, payment schedule, payment activity, payout activity, refund activity, and contextual metadata (client, project, brand). It is the central interface for viewing, editing, sharing, refunding, deactivating, or deleting an invoice and for tracking the lifecycle of every scheduled payment within it.  
    
*   **Business Goal:** Give agency owners and financial administrators a single source of truth for every invoice in the system. Reduce errors caused by stale or partial information by surfacing real-time payment and payout state, enable controlled in-place edits that preserve financial integrity once payments are collected, and centralize all invoice-level actions (edit, share, refund, deactivate, delete) into one auditable surface.
#155
**Functional Requirements Document (FRD) — Invoice Details View** > **2\. User Roles & Permissions**
~14 tok
## **2\. User Roles & Permissions**

Refer — Click Here
#156
**Functional Requirements Document (FRD) — Invoice Details View** > **3\. User Flow**
~551 tok
## **3\. User Flow**

**Navigation Paths:**

There are two entry points to the Invoice Details View:

**Path A — From Billing:**

1.  User clicks "Finances" in the left navigation menu.
2.  User clicks "Billing."
3.  System displays the Billing page with the Invoices tab active by default.
4.  User locates the desired invoice row and clicks the three-dot Actions menu.
5.  User clicks "View Details."
6.  System opens the Invoice Details View for the selected invoice.

**Path B — From Project:**

1.  User navigates to a project from the Projects module.
2.  User opens the Invoice section/tab within the project.
3.  User clicks "View Invoice" on a specific invoice.
4.  System navigates the user to the Invoice Details View for that invoice (deep-linked).

**Primary User Flow (after landing on Invoice Details View):**

1.  User reviews invoice header (Invoice ID + status badge).
2.  User reviews the Items section (line items, optional groupings, quantity, unit, price, per-item tax toggle).
3.  User reviews calculated summary (Subtotal, Discount, Tax, Total Amount).
4.  User reviews Payment Terms and the schedule of payments with their individual statuses.
5.  User reviews the right-side Details panel (Net Total, Gross Total, Paid, Unpaid, Issued On, Next Payment, From, Bill To, Project & Event, Activity).
6.  User uses the Activity payment selector to inspect Payment, Payout, and Refund activity for a specific scheduled payment.
7.  User clicks "Actions" to perform any invoice-level action (Copy Invoice Link, Edit Invoice, Download PDF, Print Invoice, Refund, Deactivate Invoice, Delete Invoice).

**Alternative Flows:**

*   **Edit Mode Entry:** User clicks Actions → Edit Invoice → System navigates to the Invoice Editor where the "Actions" button is replaced by "Update & Notify Client."
*   **Back Navigation:** User clicks the back arrow next to the invoice ID to return to the Billing → Invoices list (or to the originating project if Path B was used).
*   **Send Reminder:** For invoices with an unpaid next payment, user clicks "Send Reminder" in the Activity panel to send a reminder email immediately (governed by the 24-hour cooldown rule defined in the Transactions FRD).
#157
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#158
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic** > **4.1 Page Layout & Empty State**
~371 tok
### **4.1 Page Layout & Empty State**

**Overview:** The Invoice Details View is rendered as a two-column layout with a persistent header. There is no empty state for the page itself — if no invoice exists at the URL/ID, the system shows a "404 — Page not found" state with a CTA to return to Billing.

**Header (top bar):**

*   Back arrow (←)
*   Page title: "Invoice Details: #INVXXXXX"
*   Status badge (right of title) — see Section 4.2
*   "Actions" dropdown button (right-aligned) — see Section 4.10
*   In Edit mode: the "Actions" button is replaced by "Update & Notify Client" — see Section 4.12

**Left Column — Invoice Body :**

1.  Items section (with line items, grouping headers, per-item tax toggle)
2.  Subtotal, Add Discount, Tax, Total Amount summary block
3.  Payment Terms section (schedule table with Amount, Due Date, Payment Date, Payment ID, Status, row actions in edit mode)

**Right Column — Details Panel :**

1.  Details card (Net Total, Gross Total, Paid, Unpaid, Issued On, Next Payment, From, Bill To)
2.  Project & Event card (Project link, Event and Date, Brand)
3.  Activity card (Payment selector + activity timelines + Send Reminder CTA)

**Default State on Load:** Read-only view with the most recent or upcoming scheduled payment auto-selected in the Activity selector.

**Invoice-Not-Found State:**

*   Heading: "Invoice not found"
*   Subtext: "This invoice may have been deleted or you may not have access to it."
*   CTA: "Back to Billing"
#159
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic** > **4.2 Invoice Status Display (Header Badge)**
~268 tok
### **4.2 Invoice Status Display (Header Badge)**

**Overview:** The status badge next to the Invoice ID communicates the current consolidated state of the invoice. It is derived from the underlying transaction states (per the logic defined in the Invoices Tab FRD) and is mapped to a compact display label.

**Status Badge Mapping:**

**Underlying Invoice Status**

**Display Badge**

Unpaid

In Progress

Partially Paid

In Progress

Overdue

In Progress

Paid

Paid

Partially Refunded

In progress

Refunded

Refund

Deactivated

Deactivated

**Business Rules:**

*   The badge is read-only and system-calculated.
*   The badge updates in real time as underlying transactions transition state via Stripe webhooks or manual actions.
*   The badge controls which Actions are available (see Section 4.10) and whether the invoice body is editable (see Section 4.18).
*   Overdue is surfaced primarily at the payment-row level inside Payment Terms; at the invoice level, an overdue invoice shows "In Progress" with the affected payment row showing an "Overdue" status pill.
#160
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic** > **4.3 Items Section**
~403 tok
### **4.3 Items Section**

**Overview:** Displays all line items grouped logically (e.g., Wedding, Rehearsal Dinner, Instagram Photo as standalone). Each line item shows description, optional sub-bullets, quantity, unit, price, and a per-item tax toggle.

**Per-Item Fields Displayed:**

*   **Item Name** (text)
*   **Description / sub-bullets** (text list — e.g., "10 hours of photoshooting", "Basic Retouch", "1 Photographer")
*   **Qty** (numeric, optional display)
*   **Unit** (text, optional display — e.g., hours, sessions)
*   **Price** (currency, e.g., "$450")
*   **Tax Toggle** (per item — when ON, this item's price is included in the tax base)

**Grouping Headers:**

*   Items can be visually grouped under a section header (e.g., "WEDDING," "REHEARSAL DINNER").
*   Grouping is set during invoice creation and is preserved here in read-only display.

**"Add New Item" Link:**

*   Visible **only in Edit mode** (Section 4.12). In read-only view this control is hidden.
*   In Edit mode (Mode A), clicking "Add New Item" opens an inline new-item row.
*   In Edit mode (Mode B), it adds a new line item that will generate additional unpaid balance.

**Business Rules:**

*   In read-only view, items are not editable.
*   When an invoice is fully Paid, items are locked even in edit mode (Edit Invoice is not available for Paid status — see Section 4.10).
*   When an invoice is Partially Paid, line items that correspond to already-collected payments are locked and visually indicated; new items can still be added.
*   Tax toggle reflects the saved state and is not interactive in read-only mode.
#161
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic** > **4.4 Subtotal, Discount, Tax, Total Amount**
~361 tok
### **4.4 Subtotal, Discount, Tax, Total Amount**

**Overview:** Auto-calculated summary block beneath the Items section.

**Fields:**

*   **Subtotal** — Sum of all line item prices (Qty × Unit Price summed across items). Read-only, system-calculated.
*   **Add Discount** — Link/control to apply or edit a discount. Visible as "Add Discount" if no discount is applied, else shows discount value (e.g., "−$50.00") with an edit affordance in Edit mode.
*   **Tax** — Displays as "X% Tax" or "$X Tax" (Fixed mode) or "Auto-Tax" (Stripe Tax mode). Shows "0.0% Tax" when no tax has been configured. Tax amount displayed on the right (e.g., "$42.50").
*   **Total Amount** — Subtotal − Discount + Tax = Total Amount. Read-only, system-calculated, bold styling.

**Pencil/Edit Icons:**

*   The pencil icon next to Tax and the Add Discount control are visible **only in Edit mode**. In read-only view these controls are hidden.

**Calculation Logic:**

*   **Subtotal** = Σ (item.qty × item.unit\_price) for all items.
*   **Taxable Subtotal** = Σ (item.qty × item.unit\_price) for items where tax\_toggle = true.
*   **Tax Amount** depends on tax type (see Section 4.5).
*   **Discount** is subtracted from Subtotal before tax (when tax is percentage-based, tax applies to discounted subtotal). When tax is Fixed, discount and tax are independent.
*   **Total Amount** = Subtotal − Discount + Tax. Cannot be negative; see validation in Section 5.
#162
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic** > **4.5 Edit Tax Modal**
~655 tok
### **4.5 Edit Tax Modal**

**Overview:** Triggered from the pencil icon next to the Tax row in Edit mode. Allows the user to set or change the tax mechanism for the invoice.

**Modal Title:** "Edit Tax"

**Tax Type Selector (Three Tabs):**

1.  **Percentage** — User enters a percentage value (e.g., "8.5"). Tax = Taxable Subtotal × (percentage / 100).
2.  **Fixed** — User enters a flat dollar amount (e.g., "$100"). Tax = entered amount, regardless of taxable subtotal. Not distributed across items.
3.  **Auto-Tax Calculation** — Powered by Stripe Tax. Automatically applies sales tax based on client location, product/service category, and other Stripe Tax inputs. Requires Stripe Tax to be enabled at the account level.

**Field Behavior:**

*   **Amount Field:**
    *   In Percentage mode: numeric input with "%" suffix indicator.
    *   In Fixed mode: numeric input with "$" suffix indicator.
    *   In Auto-Tax Calculation mode: amount field is hidden; an info card explains the behavior.

**Auto-Tax Calculation Info Card Copy:** "Auto-Tax Calculation powered by Stripe helps you apply sales tax automatically based on your client's location, product type, or service category — no manual input needed. While it's a helpful starting point and often accurate, we're not accountants and can't guarantee its correctness. Ultimately, it's your responsibility to ensure the right amount of tax is collected and remitted."

**Auto-Tax Availability:**

*   If Stripe Tax is **not enabled** on the connected Stripe account, the "Auto-Tax Calc..." tab is rendered **disabled** with a tooltip: "Enable Stripe Tax in your Stripe dashboard to use Auto-Tax Calculation."
*   The other two tabs (Percentage, Fixed) remain available.

**Modal Buttons:**

*   **Remove Tax** (secondary, left) — Sets tax to 0/none on the invoice. Closes the modal. Visible only when a tax is already configured.
*   **Cancel** (secondary, right) — Discards changes, closes modal.
*   **Save** (primary, right) — Validates and applies the tax. Closes the modal.

**Business Rules:**

*   The tax mechanism is invoice-level (one tax setting per invoice).
*   The per-item Tax toggle controls which items are included in the tax base; the modal does not control that.
*   Tax can be edited on Unpaid, Partially Paid, and Overdue invoices.
*   Tax editing is disabled when invoice is Paid, Partially Refunded, Refunded, or Deactivated.
*   Changing tax recalculates totals immediately on Save. Already-paid transaction amounts are not affected; the recalculated Total only impacts the unpaid balance and future transactions (see Section 4.18).
#163
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic** > **4.6 Add / Edit Discount**
~225 tok
### **4.6 Add / Edit Discount**

**Overview:** Allows applying a discount that reduces the invoice subtotal.

**Trigger:** "Add Discount" link in Edit mode (link converts to discount value with pencil affordance once applied).

**Discount Behavior:**

*   Discount can be entered as a fixed dollar amount and percentage based.
*   Discount is subtracted from Subtotal before tax (for Percentage tax mode).
*   Discount can be removed/edited in Edit mode while invoice is Unpaid, Partially Paid, or Overdue.

**Business Rules:**

*   Discount value cannot make the Total Amount negative. Validation prevents Save if Subtotal − Discount + Tax < 0.
*   On a Partially Paid invoice, discount edits can reduce only the **unpaid balance**; they cannot retroactively reduce already-collected payments. If the new Total would be less than the already-paid amount, Save is blocked with a validation message.
#164
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic** > **4.7 Payment Terms Section**
~552 tok
### **4.7 Payment Terms Section**

**Overview:** Displays the schedule of payments derived from the invoice — when and how the client pays.

**Section Header Elements:**

*   Title: "Payment Terms"
*   Subtitle: "Specify when and how you will be paid"
*   **Save as Preset** (button, Edit mode only) — Saves the current payment schedule as a reusable preset.
*   **Apply Preset** (dropdown, Edit mode only) — Applies an existing preset to the current invoice's schedule.

**Table Columns:**

**Column**

**Description**

Amount

Dollar amount of this scheduled payment

Due Date

Scheduled payment due date

Payment Date

Actual date payment was completed (blank for unpaid rows)

Payment ID

Stripe payment identifier once charged (blank for unpaid rows)

Status

Row-level transaction status pill (Paid, Processing, Overdue, Failed, Unpaid, Due)

Row Actions (Edit mode only)

Edit (pencil) and Delete (trash) icons

**Row-Level Status Pills:**

**Status**

**Pill Color**

**Meaning**

Paid

Green

Payment confirmed by Stripe (or marked paid manually)

Processing

Blue/Cyan

Payment initiated, awaiting Stripe confirmation

Overdue

Red/Coral

Due date passed without successful payment

Failed

Red outline

Stripe returned a failure

Unpaid

Gray

Scheduled, due date not yet reached

Due

Yellow/Amber

Currently due (today or imminently — UI emphasis variant of Unpaid)

**Add Payment Link:**

*   Visible **only in Edit mode**.
*   Clicking adds a new payment row at the bottom of the schedule with empty Amount and Due Date inputs.

**Business Rules:**

*   In read-only view, the table is purely informational; no row actions are visible.
*   In Edit mode:
    *   Paid, Processing, and Failed rows are **locked** — pencil and trash icons are disabled with a tooltip ("Cannot edit a payment that has been processed").
    *   Unpaid and Overdue rows are editable (amount, due date) and deletable.
    *   The sum of all payment row amounts must equal Total Amount on Save. If not, validation blocks Save with a clear message.
*   The Payment ID column auto-populates from Stripe once the payment is initiated/completed.
*   The Payment Date column auto-populates from Stripe on successful payment.
#165
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic** > **4.8 Details Panel (Right Column)**
~340 tok
### **4.8 Details Panel (Right Column)**

**Overview:** Snapshot of invoice metadata, financial summary, and relationships.

**Details Card Fields:**

**Field**

**Description**

Net Total

Invoice total before any refunds, equal to Total Amount

Gross Total

Invoice total including any post-issuance changes (typically same as Net Total unless adjusted)

Paid

Total amount collected to date (sum of Paid transaction amounts)

Unpaid

Remaining balance (Net Total − Paid). Displayed in red/coral when > 0

Issued On

Date the invoice was first published/sent

Next Payment

Due date of the next upcoming scheduled payment (or "—" if all paid)

From

Agency information block (name, email, business name)

Bill To

Client information block (name, email)

**Project & Event Card Fields:**

**Field**

**Description**

Project

Project name with a "Project Details" link/button to navigate to the project

Event and Date

Event name and date (e.g., "Wedding (Sat, October 5, 2024)")

Brand

Brand under which the invoice was issued

**Business Rules:**

*   All fields are read-only on the Details Panel.
*   Project Details link navigates to the Projects module → project page.
*   Client name in Bill To is a link to the Client profile (if Client Management module supports it).
*   Paid and Unpaid values update in real time as transaction statuses change.
#166
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic** > **4.9 Activity Section**
~184 tok
### **4.9 Activity Section**

**Overview:** Granular, per-payment activity log showing the full lifecycle of each scheduled payment across three categories — Payment, Payout, and Refund. The Activity section is scoped to the payment selected in the dropdown.

**Activity Payment Selector:**

*   Dropdown at the top of the Activity card (e.g., "Payment 2: Sep 20, 2025").
*   Lists all scheduled payments in chronological order with their date.
*   Default selection: the most recent payment with activity, or the next upcoming payment if no activity yet exists.
*   Switching the selection swaps the displayed timelines.

**Three Timeline Sections (rendered conditionally — only shown if at least one event exists in that category):**
#167
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic** > **4.9 Activity Section** > **4.9.1 Payment Activity Timeline**
~247 tok
#### **4.9.1 Payment Activity Timeline**

Displays the full lifecycle of payment attempts for the selected scheduled payment, including retries.

**States (in chronological order, retries reset the cycle):**

**State**

**Color**

**Description / Trigger**

Initiated

Blue

Client started a payment attempt (Stripe PaymentIntent created)

Requires Action

Amber

3D Secure authentication requested

Processing

Purple

Shown for ACH / bank account payments awaiting clearance

Failed

Red

Card declined or other failure — customer retried, cycle restarts from Initiated

Successful

Green (filled)

Payment confirmed by Stripe

**Header Right-Aligned Info:** Card type and last 4 (e.g., "Card · Visa •••• 4242").

**Display Rules:**

*   Full retry history is preserved — each cycle appended in chronological order.
*   A horizontal divider separates retry cycles for visual clarity.
*   The currently-active state (latest) is displayed with a filled dot; prior states use outlined dots.
#168
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic** > **4.9 Activity Section** > **4.9.2 Payout Activity Timeline**
~208 tok
#### **4.9.2 Payout Activity Timeline**

Displays the lifecycle of funds moving from Stripe to the agency's connected bank account for the selected payment.

**States:**

**State**

**Color**

**Description / Trigger**

Payout Initiated

Blue

Triggered by payout.created Stripe webhook

Deposit In Progress

Amber

Triggered by payout.updated with status: in\_transit

Deposited

Green (filled)

Triggered by payout.paid

Deposit Failed

Red

Shown only when payout.failed is received

**Header Right-Aligned Info:** Wallet → Bank reference (e.g., "Wallet → Bank •••• 6789").

**Display Rules:**

*   Payout Activity is shown only after the corresponding Payment Activity reaches "Successful."
*   If a payout fails, the system surfaces the failure but does not automatically retry — the failure flows in via Stripe webhook only.
#169
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic** > **4.9 Activity Section** > **4.9.3 Refund Activity Timeline**
~236 tok
#### **4.9.3 Refund Activity Timeline**

Displays the lifecycle of refunds initiated against the selected payment.

**States (Partial and Full refund flows shown in chronological order):**

**State**

**Color**

**Description / Trigger**

Partial Refund In Progress

Amber

Refund initiated for an amount less than the full payment

Partial Refund Failed

Red

Stripe returned failure on the partial refund

Partially Refunded

Green (filled)

Partial refund successfully returned to client

Refund In Progress

Amber

Full refund initiated

Refund Failed

Red

Stripe returned failure on the full refund

Refunded

Green (filled)

Full refund successfully returned

**Header Right-Aligned Info:** "Initiated by agency."

**Display Rules:**

*   Refund Activity is rendered only if at least one refund has been initiated for the selected payment.
*   All refund attempts (in-progress, failed, successful) are preserved for audit and visibility.
#170
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic** > **4.9 Activity Section** > **4.9.4 Send Reminder CTA**
~89 tok
#### **4.9.4 Send Reminder CTA**

Below the timelines, the "Send Reminder" button is visible when:

*   The selected payment is in Unpaid, Overdue, or Failed state.
*   The 24-hour reminder cooldown (per Transactions FRD §4.10) has elapsed.

Disabled with tooltip when within cooldown: "You will be able to send the next reminder 24h after the last one."
#171
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic** > **4.10 Actions Menu (Status-Driven)**
~420 tok
### **4.10 Actions Menu (Status-Driven)**

**Overview:** The Actions dropdown in the header surfaces all invoice-level actions. Available actions vary by invoice status. Destructive actions ("Deactivate Invoice", "Delete Invoice") are visually distinguished (red text).

**Action Availability Matrix:**

**Action**

**Unpaid (In Progress)**

**Partially Paid (In Progress)**

**Overdue (In Progress)**

**Paid**

**Partially Refunded (Refund)**

**Refunded (Refund)**

**Deactivated**

Copy Invoice Link

✓

✓

✓

✓

✓

✓

✗

Edit Invoice

✓

✓

✓

✗

✗

✗

✗

Download PDF

✓

✓

✓

✓

✓

✓

✓

Print Invoice

✓

✓

✓

✓

✓

✓

✓

Refund

✗

✓

✓ (if any paid txn exists)

✓

✓

✗

✗

Deactivate Invoice

✓

✓

✓

✗

✗

✗

✗

Delete Invoice

✓ (if no payment history)

✗

✓ (if no payment history)

✗

✗

✗

✓ (if no payment history)

**Action-Specific Rules:**

*   **Copy Invoice Link:** Hidden for Deactivated invoices because the link is invalidated on deactivation.
*   **Edit Invoice:** Hidden for Paid, Partially Refunded, Refunded, and Deactivated invoices. Available for Partially Paid with restricted scope (see Section 4.12 Mode B).
*   **Refund:** Only available when at least one underlying transaction is in Paid state (i.e., there are funds to refund). Hidden for Refunded (no remaining refundable balance) and Deactivated.
*   **Deactivate Invoice:** Hidden for Paid (deactivation is meant to stop future collection — irrelevant when fully paid).
*   **Delete Invoice:** Allowed only when zero payments have been collected (no transactions in Processing, Paid, Failed, or Refunded state). Available for Unpaid and Deactivated invoices that have no payment history.
#172
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic** > **4.11 Copy Invoice Link (Share Link Modal)**
~343 tok
### **4.11 Copy Invoice Link (Share Link Modal)**

**Overview:** Generates and shares a tokenized link that, when opened by an authenticated client associated with the project, renders the invoice and allows payment.

**Modal Title:** "Share Link"

**Modal Copy:** "This link can be shared with all clients associated with this project."

**Modal Body:**

*   **Public Link** label
*   Read-only text input pre-filled with the tokenized URL (e.g., https://www.pixally.com/document/v2?token=a79d963c593584b7906aa7bc1387...)
*   **Copy Link** button (right of the input) — copies the URL to clipboard, shows toast "Invoice link copied to clipboard."

**Modal Footer:**

*   **Done** (primary) — closes the modal.

**Business Rules:**

*   The link is **token-based and requires client authentication** (client must be logged in as a recipient associated with this project).
*   When the authenticated client opens the link, they see the invoice in client-portal mode and can pay outstanding scheduled payments.
*   The link is **invalidated** when the invoice is Deactivated or Deleted. Opening a stale link displays an error page: "This invoice is no longer available."
*   No time-based expiry — the link remains valid as long as the invoice is active.
*   The link is consistent across multiple "Copy Invoice Link" actions (it's the same token, not regenerated each time).
#173
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic** > **4.12 Edit Invoice Flow**
~140 tok
### **4.12 Edit Invoice Flow**

**Overview:** Edit Invoice takes the user from the read-only Invoice Details View to the Invoice Editor — the same builder UI used during invoice creation (Image 15 layout). The editor is gated by an editability mode that depends on the invoice's current state.

**Entry Point:** Actions → Edit Invoice.

**Editor Header Differences vs. Detail View:**

*   The "Actions" button in the top-right is **replaced** by an "Update & Notify Client" button.
*   The back arrow remains and triggers the unsaved-changes check (see below).
#174
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic** > **4.12 Edit Invoice Flow** > **4.12.1 Mode A — Full Edit (Unpaid invoice with no payment history)**
~185 tok
#### **4.12.1 Mode A — Full Edit (Unpaid invoice with no payment history)**

**Eligibility:** Invoice status = Unpaid AND no transactions have ever entered Processing, Paid, Failed, or Refunded state.

**Editable Surface:**

*   All line items (add, edit, delete, reorder)
*   Quantity, Unit, Price for each item
*   Per-item Tax toggle
*   Tax (type and amount via Edit Tax modal)
*   Discount (add, edit, remove)
*   Payment Terms (add, edit, delete rows; change amounts and due dates)
*   Save as Preset / Apply Preset for payment terms

**Save Behavior:** On "Update & Notify Client," all transactions are regenerated from the new payment schedule, the invoice version increments, and the client is sent an updated email notification.
#175
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic** > **4.12 Edit Invoice Flow** > **4.12.2 Mode B — Restricted Edit (Partially Paid or Overdue invoice)**
~322 tok
#### **4.12.2 Mode B — Restricted Edit (Partially Paid or Overdue invoice)**

**Eligibility:** Invoice status = Partially Paid OR Overdue AND at least one transaction has been Paid/Processing/Failed/Refunded.

**Locked Elements (visually indicated, non-interactive):**

*   Line items that correspond to already-collected payments
*   Payment Terms rows with status Paid, Processing, or Failed (pencil and trash icons disabled with tooltip)
*   Already-collected payment amounts

**Editable Elements:**

*   Tax (type and amount — applies to recalculation of unpaid balance only)
*   Discount (add, edit, remove — cannot make Total Amount less than already-paid sum)
*   New line items can be added (which generate additional unpaid balance / new payment rows)
*   Unpaid and Overdue payment rows (amount, due date)
*   New payment rows can be added via "Add Payment"

**Validation on Save:**

*   New Total Amount ≥ Sum of already-paid amounts — otherwise Save is blocked.
*   Sum of Payment Term row amounts = Total Amount — otherwise Save is blocked.
*   Total Amount > 0 — otherwise Save is blocked.

**Save Behavior:** Only unpaid/new transactions are regenerated; existing Paid/Processing/Failed transactions are preserved unchanged. The client is sent an updated email notification.
#176
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic** > **4.12 Edit Invoice Flow** > **4.12.3 Update & Notify Client Button**
~230 tok
#### **4.12.3 Update & Notify Client Button**

**Button States:**

*   **Disabled (default on entry):** No changes have been made. Tooltip: "Make a change to update this invoice."
*   **Enabled:** At least one field has been modified vs. the saved version.

**Click Behavior:**

*   System validates all fields and constraints (see Section 5 and Section 6).
*   If valid, system saves changes, regenerates affected transactions, and **directly sends** an email notification to the client with a link to the updated invoice. No additional confirmation step.
*   On success, system returns the user to the Invoice Details View (now reflecting the saved changes) with a success toast: "Invoice updated and client notified."

**Autosave:**

*   Changes are autosaved as draft as the user edits (debounced).
*   The "Changes applied to file" modal explicitly references this autosave: "Your changes were saved automatically."
#177
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic** > **4.12 Edit Invoice Flow** > **4.12.4 Unsaved Changes — Back Navigation Modal**
~314 tok
#### **4.12.4 Unsaved Changes — Back Navigation Modal**

**Trigger:** While in Edit mode, user clicks the back arrow (or attempts to navigate away) with unsaved changes that have not yet been published via "Update & Notify Client."

**Modal Title:** "Changes applied to file"

**Modal Body:**

*   "Your changes were saved automatically."
*   Warning callout (icon + yellow background): "Updating will publish the latest version and send your client an email notification. Otherwise they'll still see the previous one."

**Modal Buttons:**

*   **Exit without updating** (secondary) — User leaves the editor; draft remains saved internally but client is **not** notified and continues to see the previous published version.
*   **Update & Notify Client** (primary) — Equivalent to clicking the header CTA: publishes and notifies, then exits.

**Business Rules:**

*   The draft is preserved across sessions. The next time the user opens Edit Invoice, the draft state is restored.
*   Drafts do not affect the read-only Invoice Details View shown to the agency or the client; both continue to see the last published version until "Update & Notify Client" is clicked.
*   If the invoice is deactivated or deleted while a draft exists, the draft is discarded.
#178
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic** > **4.13 Download PDF**
~176 tok
### **4.13 Download PDF**

**Overview:** Generates a PDF representation of the invoice and triggers a download.

**Behavior:**

*   On click, system generates the latest published version of the invoice as a PDF.
*   PDF includes: header (logo, invoice ID, status), line items with grouping, totals, payment terms, agency and client info, payment IDs for paid transactions.
*   Download begins automatically; filename format: Invoice\_#INVXXXXX.pdf.

**Business Rules:**

*   Available across all statuses including Deactivated (for record-keeping).
*   PDF generation is asynchronous; a loading indicator displays during generation.
*   On failure, user sees the PDF failure error message (Section 6).
#179
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic** > **4.14 Print Invoice**
~81 tok
### **4.14 Print Invoice**

**Overview:** Opens the browser's print dialog with a print-optimized rendering of the invoice.

**Behavior:**

*   On click, system opens a print-friendly view in a new tab/dialog.
*   Print stylesheet hides navigation, action buttons, and interactive controls.
*   Available across all statuses.
#180
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic** > **4.15 Refund Flow**
~540 tok
### **4.15 Refund Flow**

**Overview:** Initiates a refund of a paid amount back to the client through Stripe. Funds are returned to the original payment method.

**Trigger:** Actions → Refund.

**Modal Title:** "Refund Invoice"

**Modal Top Note (yellow callout):** "Note: When you issue a refund, the processing fees from the original payment are not returned by Stripe. The refunded amount will come out of your balance in full."

**Modal Body Copy:** "We'll send the money back to **{ClientName}** via Stripe, directly to the original payment method. Enter the amount and an optional note. Refunds typically take 5–10 business days to appear in the client's account."

**Modal Fields:**

*   **Amount** (currency input)
    *   Pre-filled with a default suggested value or left blank.
    *   Helper text below: "Up to **${maxRefund}** available to refund."
    *   maxRefund = sum of paid amounts − sum of already-refunded amounts across all transactions on this invoice.
*   **Note** (multi-line text area, optional)
    *   Free-form internal note (e.g., "Refunding the overpayment by customer").

**Modal Buttons:**

*   **Cancel** (secondary)
*   **Process Refund** (primary)

**Business Rules:**

*   If the connected Stripe account does not have sufficient balance for the refund, Stripe returns an error; system surfaces the failure message.
*   Refund amount can be partial or full (up to maxRefund).
*   Multiple partial refunds are allowed on the same invoice as long as cumulative refunded amount ≤ total paid amount.
*   On success:
    *   Stripe initiates the refund (state: Refund In Progress or Partial Refund In Progress in the Refund Activity timeline).
    *   Invoice status updates: Paid → Partially Refunded (if partial) or Refunded (if full), Partially Refunded → Refunded if cumulative refunds now cover all paid amounts.
    *   Refund Activity timeline reflects the new state.
*   If multiple paid transactions exist, the system applies the refund against transactions in chronological order (oldest first) unless future logic dictates otherwise.
*   Refunds are logged in the audit trail with user, timestamp, amount, and note.
#181
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic** > **4.16 Deactivate Invoice Flow**
~394 tok
### **4.16 Deactivate Invoice Flow**

**Overview:** Marks the invoice as inactive — prevents the client from making any further payments and locks the invoice from edits.

**Trigger:** Actions → Deactivate Invoice.

**Modal Title:** "Deactivate Invoice"

**Modal Warning Banner (yellow):** "Warning: Deactivating This Invoice Will Stop All Payments."

**Modal Body Copy:**

"Before deactivating this invoice, please make sure you've issued any necessary refunds manually. Deactivating an invoice will:

*   Prevent the client from making any future payments
*   Stop all automated reminders
*   Lock the invoice from further editing unless reactivated

Refunds are not processed automatically. If any amount needs to be returned to the client, please complete the refund through your payment processor before deactivating."

**Modal Buttons:**

*   **Cancel** (secondary)
*   **Yes, Deactivate Invoice** (primary, destructive styling)

**Business Rules:**

*   Deactivation is not allowed when any transaction is in Processing state (the existing block from the Invoices Tab FRD applies). System shows the error: "Cannot deactivate. Payments are processing."
*   On success:
    *   Invoice status → Deactivated.
    *   All unpaid/overdue scheduled payments are halted (no further reminders, no payment portal access).
    *   Public invoice link is invalidated.
    *   Client can no longer view or pay the invoice via the link.
    *   Invoice moves to the "Deactivated" tab in the Billing → Invoices list.
    *   Audit trail logs the deactivation event (user, timestamp).
#182
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic** > **4.17 Delete Invoice Flow**
~366 tok
### **4.17 Delete Invoice Flow**

**Overview:** Permanently removes the invoice and all associated data. Allowed only when no payments have been collected.

**Trigger:** Actions → Delete Invoice.

**Modal Title:** "Delete Invoice"

**Modal Body Copy:**

"This action will permanently delete the invoice and all associated data, including:

*   Line items
*   Payment terms
*   History and activity logs

This cannot be undone."

**Modal Warning Banner (yellow):** "If any payments have been made toward this invoice, you must void or deactivate it instead to preserve financial records. Invoices with payments cannot be deleted."

**Modal Buttons:**

*   **Cancel** (secondary)
*   **Yes, Delete Invoice** (primary, destructive styling)

**Business Rules:**

*   Delete is allowed only when zero transactions on this invoice have ever been in Processing, Paid, Failed, or Refunded state.
*   If any payment history exists, the "Yes, Delete Invoice" button is disabled and a tooltip explains why; alternatively, the action is hidden from the Actions menu entirely (per Section 4.10).
*   On success:
    *   Invoice and all associated data are removed from active storage.
    *   The public link is invalidated.
    *   The deletion is logged in the audit trail (user, timestamp, invoice ID) for compliance, even though the underlying record is removed.
    *   User is redirected to the Billing → Invoices list with a success toast: "Invoice deleted successfully."
#183
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic** > **4.18 Read-Only vs. Editable State Logic**
~374 tok
### **4.18 Read-Only vs. Editable State Logic**

**Overview:** The Invoice Details View has a strict separation between read-only display and the Edit mode (Invoice Editor). The page itself is **always read-only**. Inline controls such as the Tax pencil, Discount edit, "Add New Item," "Add Payment," and row-level pencil/trash icons appear **only** in Edit mode.

**State Determination on Page Load:**

1.  System fetches the invoice and computes its consolidated status (per Invoices Tab FRD §4.3).
2.  System renders the page in read-only mode by default.
3.  If the user clicks Actions → Edit Invoice (and the action is allowed per Section 4.10), system navigates to the Invoice Editor in Mode A or Mode B based on payment history.

**Locking Rules in Edit Mode (Mode B specifically):**

**Element**

**Locked When**

Line item (any field)

The item is fully covered by collected payments

Payment row (amount, due date, delete)

Row status is Paid, Processing, or Failed

Total Amount reduction below paid sum

Always blocked — cannot make Net Total less than already-collected funds

Currency

Always locked (currency is fixed per brand/project)

**Tax & Discount on Partial Payment:**

*   Editing tax recalculates Total. The new Total must remain ≥ already-paid amount.
*   Editing discount recalculates Total. The new Total must remain ≥ already-paid amount AND > 0.
*   If the user attempts a change that would violate either rule, Save is blocked with a specific error (see Section 6).
#184
**Functional Requirements Document (FRD) — Invoice Details View** > **4\. Functional Logic** > **4.19 Impact**
~407 tok
### **4.19 Impact**

**Cross-Module and Downstream Impact of Actions on the Invoice Details View:**

*   **Edit Invoice → Update & Notify Client:  
    **
    *   Triggers regeneration of unpaid transactions in the Billing → Transactions tab.
    *   Sends an email notification to the client via the Email Service Provider.
    *   Updates the Next Payment Date displayed in the Invoices list.
    *   Logs the event in the audit trail.
    *   QuickBooks: only paid transactions remain synced; unpaid-side edits do not trigger sync.
*   **Refund:  
    **
    *   Triggers Stripe refund API.
    *   Updates underlying transaction(s) to Refunded or Partially Refunded.
    *   Updates invoice-level status accordingly.
    *   Updates Refund Activity timeline.
    *   QuickBooks: pushes a reversal entry for the refunded amount (per Transactions FRD).
    *   Updates Paid and Unpaid amounts in the Details panel.
*   **Deactivate:  
    **
    *   Marks invoice as Deactivated.
    *   Moves invoice to the Deactivated sub-tab in the Billing → Invoices list.
    *   Invalidates the public link.
    *   Removes the invoice from the client portal.
    *   Stops automated reminders.
    *   Does not affect already-paid transactions or their QuickBooks sync state.
*   **Delete:  
    **
    *   Permanently removes the invoice record.
    *   Removes the invoice from the Billing → Invoices list (All and Deactivated sub-tabs).
    *   Invalidates the public link.
    *   Logs the deletion in the audit trail.
*   **Copy Invoice Link:  
    **
    *   No state change on the invoice. Audit trail optionally logs the action.
#185
**Functional Requirements Document (FRD) — Invoice Details View** > **5\. Field Details & Validations**
~10 tok
## **5\. Field Details & Validations**
#186
**Functional Requirements Document (FRD) — Invoice Details View** > **5\. Field Details & Validations** > **5.1 Header Fields**
~54 tok
### **5.1 Header Fields**

**Field**

**Type**

**Format**

**Validation**

Invoice ID

Auto-generated

"#INVXXXXX"

Read-only, unique, immutable

Status Badge

System-calculated

Colored pill (see §4.2)

Read-only
#187
**Functional Requirements Document (FRD) — Invoice Details View** > **5\. Field Details & Validations** > **5.2 Items Section Fields**
~104 tok
### **5.2 Items Section Fields**

**Field**

**Type**

**Format**

**Validation**

Item Name

Text

Free text

Required, max 200 chars

Description

Multi-line text

Free text (bulleted)

Optional

Qty

Numeric

Positive integer or decimal

Must be > 0

Unit

Text

Free text (e.g., "hours")

Optional

Unit Price

Currency

"$X,XXX.XX"

Must be ≥ 0, two decimals

Per-Item Tax Toggle

Boolean

On/Off

Default: Off
#188
**Functional Requirements Document (FRD) — Invoice Details View** > **5\. Field Details & Validations** > **5.3 Summary Fields**
~115 tok
### **5.3 Summary Fields**

**Field**

**Type**

**Format**

**Validation**

Subtotal

Currency

"$X,XXX.XX"

System-calculated, read-only

Discount

Currency

"−$X,XXX.XX"

Optional; ≥ 0; ≤ Subtotal + Tax

Tax (Percentage)

Numeric

"X.X %"

≥ 0; max 100

Tax (Fixed)

Currency

"$X,XXX.XX"

≥ 0

Tax (Auto-Tax)

System-calculated

"$X,XXX.XX"

Pulled from Stripe Tax

Total Amount

Currency

"$X,XXX.XX"

System-calculated; must be > 0 on Save in Edit mode
#189
**Functional Requirements Document (FRD) — Invoice Details View** > **5\. Field Details & Validations** > **5.4 Payment Terms Fields**
~114 tok
### **5.4 Payment Terms Fields**

**Field**

**Type**

**Format**

**Validation**

Amount

Currency

"$X,XXX.XX"

\> 0; row-level. Sum of all rows must = Total Amount

Due Date

Date

"Mon DD, YYYY"

Valid date; must be ≥ Issued On date

Payment Date

Date

"Mon DD, YYYY"

Read-only; auto-populated from Stripe on payment

Payment ID

Text

Stripe ID format

Read-only; auto-populated from Stripe

Status

System pill

See §4.7 status pill table

Read-only
#190
**Functional Requirements Document (FRD) — Invoice Details View** > **5\. Field Details & Validations** > **5.5 Details Panel Fields**
~159 tok
### **5.5 Details Panel Fields**

**Field**

**Type**

**Format**

**Validation**

Net Total

Currency

"$X,XXX.XX"

Read-only, equals Total Amount

Gross Total

Currency

"$X,XXX.XX"

Read-only

Paid

Currency

"$X,XXX.XX"

Read-only, sum of paid transactions

Unpaid

Currency

"$X,XXX.XX"

Read-only, Net Total − Paid

Issued On

Date

"Mon DD, YYYY"

Read-only

Next Payment

Date

"Mon DD, YYYY" or "—"

Read-only

From

Text block

Multi-line

Read-only

Bill To

Text block

Multi-line

Read-only

Project

Text + Link

Project name

Read-only link

Event and Date

Text

Free text

Read-only

Brand

Text

Brand name

Read-only
#191
**Functional Requirements Document (FRD) — Invoice Details View** > **5\. Field Details & Validations** > **5.6 Edit Tax Modal Fields**
~92 tok
### **5.6 Edit Tax Modal Fields**

**Field**

**Type**

**Format**

**Validation**

Tax Type

Segmented tabs

Percentage / Fixed / Auto-Tax Calc

One required selection

Amount (Percentage)

Numeric

"%" suffix

≥ 0; ≤ 100; up to 2 decimals

Amount (Fixed)

Currency

"$" suffix

≥ 0; up to 2 decimals

Amount (Auto-Tax)

N/A

Not user-editable

Hidden; Stripe-driven
#192
**Functional Requirements Document (FRD) — Invoice Details View** > **5\. Field Details & Validations** > **5.7 Refund Modal Fields**
~50 tok
### **5.7 Refund Modal Fields**

**Field**

**Type**

**Format**

**Validation**

Amount

Currency

"$" prefix

\> 0; ≤ maxRefund; up to 2 decimals

Note

Text area

Free text

Optional; max 500 chars
#193
**Functional Requirements Document (FRD) — Invoice Details View** > **5\. Field Details & Validations** > **5.8 Share Link Modal Fields**
~38 tok
### **5.8 Share Link Modal Fields**

**Field**

**Type**

**Format**

**Validation**

Public Link

Read-only text

Tokenized URL

Read-only; copy-only
#194
**Functional Requirements Document (FRD) — Invoice Details View** > **6\. Error Message Handling**
~798 tok
## **6\. Error Message Handling**

**Scenario**

**Trigger**

**Message**

**Type**

Invoice not found

URL or ID invalid

"Invoice not found. It may have been deleted or you don't have access."

Error

Network failure on load

API timeout

"Unable to load invoice. Please check your connection and try again."

Error

Edit blocked — Paid status

User somehow accesses Edit

"Paid invoices cannot be edited."

Error

Edit Save — total below paid sum

Mode B Save

"Total Amount cannot be less than the amount already collected (${paidSum})."

Error

Edit Save — payment rows don't sum to Total

Mode B Save

"Payment Terms total (${rowSum}) must equal the Invoice Total (${total})."

Error

Edit Save — Total ≤ 0

Mode A or B Save

"Invoice Total must be greater than $0."

Error

Edit Save — Discount exceeds Subtotal + Tax

Discount input

"Discount cannot make the Total Amount negative."

Error

Tax Save — Percentage out of range

Edit Tax modal

"Tax percentage must be between 0 and 100."

Error

Tax Save — Fixed amount invalid

Edit Tax modal

"Tax amount must be a positive number."

Error

Auto-Tax disabled

Auto-Tax tab clicked while Stripe Tax off

"Enable Stripe Tax in your Stripe dashboard to use Auto-Tax Calculation."

Tooltip

Refund — amount exceeds max

Process Refund click

"Refund amount cannot exceed the available refund balance (${maxRefund})."

Error

Refund — Stripe failure

Process Refund click

"Unable to process refund. Please try again or contact support."

Error

Refund — insufficient Stripe balance

Process Refund click

"Your Stripe balance is insufficient for this refund. Please top up and try again."

Error

Deactivate blocked — Processing payment

Deactivate confirm

"Cannot deactivate. Payments are processing."

Error

Delete blocked — payment history exists

Delete confirm

"Invoices with payment history cannot be deleted. Please deactivate instead."

Error

Copy link copy failure

Browser permission

"Unable to copy link. Please copy it manually."

Error

PDF generation failure

Download PDF click

"Unable to generate PDF. Please try again."

Error

Print dialog failure

Print Invoice click

"Unable to open print dialog. Please check your browser settings."

Error

Reminder cooldown active

Send Reminder click

"You will be able to send the next reminder 24h after the last one."

Tooltip

Edit conflict — last write wins

Concurrent edit detected

"Another user has updated this invoice. Your latest save has been applied."

Warning

Update & Notify — email send failure

Save in Edit mode

"Invoice updated, but we couldn't send the notification email. Please retry from Actions."

Warning

Stale share link opened by client

Client clicks invalidated link

"This invoice is no longer available."

Info (client-facing)

**Success Messages:**

**Scenario**

**Message**

Invoice link copied

"Invoice link copied to clipboard."

Invoice updated and client notified

"Invoice updated and client notified."

Tax updated

"Tax updated successfully."

Discount applied

"Discount applied successfully."

Refund processed

"Refund initiated. The amount will appear in the client's account in 5–10 business days."

Invoice deactivated
#195
**Functional Requirements Document (FRD) — Invoice Details View** > **6\. Error Message Handling**
~51 tok
"Invoice #INVXXXXX deactivated successfully."

Invoice deleted

"Invoice deleted successfully."

PDF downloaded

"Invoice PDF downloaded successfully."

Reminder sent

"Payment reminder sent successfully."
#196
**Functional Requirements Document (FRD) — Invoice Details View** > **7\. Edge Cases**
~793 tok
## **7\. Edge Cases**

**Scenario**

**Expected Behavior**

Invoice has no payment schedule yet (draft)

Page renders normally; Payment Terms section shows "Add Payment" prompt in Edit mode; Activity section shows no timelines.

Activity selector shows a payment with no activity yet

Timelines render as empty (or hidden); only the selector and Send Reminder (if applicable) are visible.

User selects a payment in Activity that has been deleted in Edit mode

Selector falls back to the next available payment; previously-selected payment is removed from the dropdown.

Invoice status changes while user is viewing (e.g., client just paid)

Page updates in real time (websocket/polling); status badge, Paid/Unpaid totals, and Payment Terms row update without full reload.

Two users edit the same invoice concurrently

Last-write-wins. The user whose save lands second sees the warning "Another user has updated this invoice. Your latest save has been applied." Their changes overwrite the prior save.

User tries to edit tax on a fully Paid invoice

Edit Invoice action is hidden entirely; tax cannot be modified post-full-payment.

User tries to delete a payment row that is Paid

Trash icon is disabled with tooltip "Cannot delete a payment that has been processed."

Discount makes Total = 0

Save blocked: "Invoice Total must be greater than $0."

Refund amount equals full paid balance

Invoice status transitions to Refunded; subsequent Refund action is hidden.

Multiple partial refunds across the same payment

Each refund attempt logged in the Refund Activity timeline; cumulative refunded amount tracked; further refunds blocked once cumulative = paid total.

Auto-Tax Calculation returns a different value on recalculation

Tax field updates automatically; user notified via toast "Tax recalculated by Stripe Tax."

Stripe Tax becomes disabled after an invoice was configured with Auto-Tax

The saved tax value is preserved on the invoice; in Edit mode, the Auto-Tax tab is disabled and the user must choose Percentage or Fixed to make changes.

Client tries to pay an invoice that has just been deactivated

Public link returns "This invoice is no longer available." Any in-flight payment attempt is allowed to complete (Stripe will not cancel mid-flight), and the resulting transaction is recorded.

Invoice has 50+ payment rows

Payment Terms table renders with scroll; no virtualization required at this scale.

Activity timeline has very long retry history

Timeline scrolls vertically within its card; dividers separate retry cycles.

User exits edit mode via browser back button (not in-app back arrow)

Browser-native "Leave site?" prompt is triggered; draft remains saved (autosaved) so user can resume later.

User opens Edit Invoice with an existing draft

Editor restores the draft state with a banner: "You have unpublished changes. Update & Notify Client when ready."

Invoice deletion happens while user has it open in another tab

The other tab shows "Invoice not found" on next interaction.

Brand or Project linked to the invoice is deleted

Invoice remains intact; the Project/Brand link in the Details panel shows "—" or "Deleted Project."
#197
**Functional Requirements Document (FRD) — Invoice Details View** > **7\. Edge Cases**
~160 tok
Send Reminder click while the next payment becomes Paid mid-action

System validates state at click time; if already Paid, returns "This payment has already been collected."

Refund initiated while a payout for that payment is still In Progress

Refund is queued at Stripe level (per Stripe behavior); state shown as Refund In Progress until Stripe processes.

User attempts to add a payment row that would push schedule beyond Total Amount

Validation on Save: "Payment Terms total exceeds Invoice Total."

User changes tax type from Percentage to Fixed (or vice versa)

Amount field resets; new value required before Save can be enabled.
#198
**Functional Requirements Document (FRD) — Invoice Details View** > **8\. Acceptance Criteria**
~618 tok
## **8\. Acceptance Criteria**

**Core Functionality:**

*   Users can open the Invoice Details View from both the Billing module and from within a Project.
*   The status badge correctly maps invoice status to the four display states (In Progress, Paid, Refund, Deactivated).
*   All read-only fields (Items, Summary, Payment Terms, Details, Activity) render accurately based on real-time data.

**Activity Section:**

*   The Activity selector defaults to the most recent or next upcoming payment.
*   Switching the selector swaps the three timeline sections correctly.
*   Payment, Payout, and Refund timelines render only when at least one event exists in that category.
*   Retry cycles in Payment Activity are preserved and visually separated.

**Actions:**

*   The Actions menu shows exactly the actions permitted by the invoice's current status (per §4.10 matrix).
*   Destructive actions (Deactivate, Delete) are visually distinguished.

**Edit Flow:**

*   Edit Invoice from Actions navigates to the Invoice Editor in Mode A or Mode B based on payment history.
*   In edit mode, "Actions" is replaced by "Update & Notify Client."
*   "Update & Notify Client" is disabled until at least one field is changed.
*   Back navigation with unsaved changes triggers the "Changes applied to file" modal.
*   "Update & Notify Client" sends the client an email directly on click.
*   Mode B correctly locks paid line items and paid payment rows.
*   Save is blocked when Total would fall below already-paid sum.

**Modals:**

*   Copy Invoice Link modal shows a tokenized link and copy-to-clipboard works.
*   Refund modal validates amount against maxRefund and submits to Stripe.
*   Deactivate modal blocks deactivation when a Processing payment exists.
*   Delete modal blocks deletion when payment history exists.
*   Edit Tax modal supports Percentage, Fixed, and Auto-Tax Calculation modes with correct field visibility.

**Real-Time and Audit:**

*   Status changes from upstream events (Stripe webhooks, manual marking) reflect immediately in the view.
*   All actions (edit, refund, deactivate, delete, reminder sent) are logged in the audit trail with user and timestamp.

**Integrations:**

*   Stripe refunds, webhooks, and Stripe Tax (when enabled) function correctly through the view.
*   QuickBooks sync state is preserved across edits (only paid transactions sync; refunds push reversals).
*   Client notification emails are sent on Update & Notify Client.
#199
**Functional Requirements Document (FRD) — Invoice Details View** > **9\. Dependencies**
~344 tok
## **9\. Dependencies**

**Module/System**

**Type**

**Impact if Unavailable**

Billing → Invoices Tab

Data Dependency

Cannot reach Invoice Details via Path A; cannot return on back navigation.

Billing → Transactions Tab

Data Dependency

Transaction data and statuses cannot be displayed; Activity timelines render empty.

Projects Module

Data Dependency

Path B navigation broken; Project Details link non-functional; Project/Event card shows "—".

Clients Module

Data Dependency

Bill To block and refund recipient name cannot be displayed.

Brands Module

Data Dependency

Brand label in Project & Event card cannot be displayed.

Stripe Payment Gateway

Integration

Payment/Payout activity timelines cannot update; Refund cannot be processed.

Stripe Tax

Integration

Auto-Tax Calculation option disabled with tooltip.

QuickBooks Integration

Integration

Sync indicators on Paid transactions unavailable; refund reversals not pushed.

Email Service Provider

Integration

"Update & Notify Client" cannot send notification email; reminder emails fail.

Authentication Service

Security

User cannot access the page; client cannot open public link.

Audit Trail Service

Service

Actions not logged; compliance impacted.

PDF Generation Service

Service

Download PDF fails with error.

File Storage / CDN

Service

Avatars, logos, and other assets fail to render.
#200
**Functional Requirements Document (FRD) — Invoice Details View** > **10\. References**
~17 tok
## **10\. References**

Invoices

**Refer - Click Here**

Deprecated
#201
**Functional Requirements Document (FRD) - Paid Invoice Detail View**
~18 tok
# **Functional Requirements Document (FRD) - Paid Invoice Detail View**
#202
**Functional Requirements Document (FRD) - Paid Invoice Detail View** > **1\. Overview**
~66 tok
## **1\. Overview**

Paid Invoice Detail View  
**Purpose:** Display a comprehensive read-only view of paid invoices with limited action capabilities  
**Business Goal:** Provide complete invoice information for reference and enable essential post-payment actions
#203
**Functional Requirements Document (FRD) - Paid Invoice Detail View** > **2\. User Roles & Permissions**
~65 tok
## **2\. User Roles & Permissions**

**Role**

**Access Level**

Agency Owner

Full access to all paid invoice details and actions

Admin

Full access to all paid invoice details and actions

Project Manager

Access only to paid invoices for assigned projects
#204
**Functional Requirements Document (FRD) - Paid Invoice Detail View** > **3\. User Flow**
~88 tok
## **3\. User Flow**

1.  User navigates to the paid invoice from the billing list or the direct link
2.  System displays read-only invoice detail view
3.  User reviews invoice information and payment history
4.  User can perform limited actions: Download PDF, Print, Copy Link, and Refund.
5.  The system maintains an audit trail of actions performed
#205
**Functional Requirements Document (FRD) - Paid Invoice Detail View** > **4\. Display Sections**
~7 tok
## **4\. Display Sections**
#206
**Functional Requirements Document (FRD) - Paid Invoice Detail View** > **4\. Display Sections** > **4.1 Invoice Header**
~60 tok
### **4.1 Invoice Header**

**Field**

**Type**

**Description**

Invoice Number

Text

Format: #INV00004

Status Badge

Visual Indicator

Green "Paid" badge

Action CTA

Action Button

Copy invoice link, download PDF, Print invoice, Refund
#207
**Functional Requirements Document (FRD) - Paid Invoice Detail View** > **4\. Display Sections** > **4.2 Items Section (Read-Only)**
~119 tok
### **4.2 Items Section (Read-Only)**

**Field**

**Description**

Service Description

Item name and details

Quantity

Service quantity

Unit Price

Price Unit

Package Line item listing

Event-wise details of the line items

A La Carte item Listing

Ad on items/events’ listing

Subtotal

Sum of all line items and add-ons

Tax Percentage

Applied tax rate (only applies if not 0)

Tax Amount

Calculated tax amount(only applies if not 0)

Total Amount

Final invoice total
#208
**Functional Requirements Document (FRD) - Paid Invoice Detail View** > **4\. Display Sections** > **4.3 Payment Terms Section (Read-Only)**
~83 tok
### **4.3 Payment Terms Section (Read-Only)**

**Field**

**Description**

Payment Amount

Individual payment amount

Due Date

Original payment due date as per the package or manual added

Payment Date

Actual payment completion date

Payment ID

Unique payment reference- auto-fetched from

Payment Status

"Paid" status indicator
#209
**Functional Requirements Document (FRD) - Paid Invoice Detail View** > **4\. Display Sections** >
~1 tok
###
#210
**Functional Requirements Document (FRD) - Paid Invoice Detail View** > **4\. Display Sections** >
~1 tok
###
#211
**Functional Requirements Document (FRD) - Paid Invoice Detail View** > **4\. Display Sections** > **4.4 Right Sidebar Information**
~232 tok
### **4.4 Right Sidebar Information**

**Invoice Details**

*   Net Total - This is the amount after deductions (like taxes, insurance, or other withholdings).
*   Gross Total - This is the total amount before any deductions.
*   Paid- Money already received or settled.
*   Unpaid-Money that is still outstanding (not yet received or settled). In case of a paid document the unpaid amount will be by default zero
*   Issued on - date of invoice issued

**Action CTA:**

*   Copy invoice link: Creates a shareable link to the invoice
*   Download PDF : Lets you save the invoice as a PDF file on your computer.
*   Print Invoice: Sends the invoice to your printer for a paper copy.
*   Refund: will move the invoice to the refund tab.

**Project & Event Panel:**

*   Project name and link
*   Event details and dates
*   Brand association

**Activity Panel:**

*   Payment timeline
*   Status change history
*   User action logs
#212
**Functional Requirements Document (FRD) - Paid Invoice Detail View** > **5\. Success Messages**
~40 tok
## **5\. Success Messages**

**Action**

**Success Message**

PDF Download

"Invoice PDF downloaded successfully."

Copy Link

"Invoice link copied to clipboard"
#213
**Functional Requirements Document (FRD) - Paid Invoice Detail View** >
~1 tok
##
#214
**Functional Requirements Document (FRD) - Paid Invoice Detail View** >
~1 tok
##
#215
**Functional Requirements Document (FRD) - Paid Invoice Detail View** > **6\. Error Messages**
~50 tok
## **6\. Error Messages**

**Scenario**

**Error Message**

PDF Generation Failed

"Unable to generate PDF. Please try again"

Refund Process Failed

"Unable to process refund. Please contact support"
#216
**Functional Requirements Document (FRD) - Paid Invoice Detail View** > **7\. Functional Logic**
~7 tok
## **7\. Functional Logic**
#217
**Functional Requirements Document (FRD) - Paid Invoice Detail View** > **7\. Functional Logic** > **Read-Only Enforcement**
~48 tok
### **Read-Only Enforcement**

*   All invoice data is displayed as non-editable text
*   No form fields or input controls available
*   Financial calculations are displayed but not modifiable
#218
**Functional Requirements Document (FRD) - Paid Invoice Detail View** > **7\. Functional Logic** > **Action Restrictions**
~45 tok
### **Action Restrictions**

*   Refund and actions limited to Owner/Admin roles
*   PM users can only view invoices for assigned projects
*   All actions maintain an audit trail
#219
**Functional Requirements Document (FRD) - Paid Invoice Detail View** > **7\. Functional Logic** > **Data Display Rules**
~50 tok
### **Data Display Rules**

*   Currency values formatted with proper symbols and decimals
*   Dates displayed in consistent format (MMM DD, YYYY)
*   Payment status clearly indicated with visual cues
#220
**Functional Requirements Document (FRD) - Paid Invoice Detail View** > **8\. Acceptance Criteria**
~121 tok
## **8\. Acceptance Criteria**

*   Invoice displays all line items, totals, and payment information in read-only format
*   Payment history shows a complete transaction timeline
*   All monetary values are formatted consistently with currency symbols
*   Limited actions (Download, Print, Copy Link, Refund) function correctly
*   The activity timeline shows chronological payment and status progression
*   Visual status indicators clearly show "Paid" state throughout the interface
#221
**Functional Requirements Document (FRD) - Paid Invoice Detail View** >
~1 tok
##
#222
**Functional Requirements Document (FRD) - Paid Invoice Detail View** >
~1 tok
##
#223
**Functional Requirements Document (FRD) - Paid Invoice Detail View** > **9\. Dependencies**
~89 tok
## **9\. Dependencies**

**System**

**Dependency Type**

**Impact if Unavailable**

Billing Module

Data Source

Cannot display invoice information

Payment Processing

Status Data

Payment history unavailable

Project Management

Reference Data

Project details cannot be displayed

PDF Generation Service

File Export

Download PDF functionality fails
#224
**Functional Requirements Document (FRD) - Invoice details**
~16 tok
# **Functional Requirements Document (FRD) - Invoice details**
#225
**Functional Requirements Document (FRD) - Invoice details** > **1\. Overview**
~92 tok
## **1\. Overview**

  
**Purpose:** Comprehensive invoice viewing, editing, and management interface with line item modifications, payment term adjustments, and status tracking capabilities  
**Business Goal:** Provide complete invoice lifecycle management with flexible editing, automated calculations, payment processing integration, and comprehensive audit tracking
#226
**Functional Requirements Document (FRD) - Invoice details** > **2\. User Roles & Permissions**
~152 tok
## **2\. User Roles & Permissions**

**Role**

**Description**

**Key Permissions**

Agency Owner

Business owner with full financial control

Full access: view, edit, delete, refund, activate/deactivate all invoices, manage payment terms, tax settings

Admin

System administrator with operational control

Full access: view, edit, delete, refund, activate/deactivate all invoices, manage payment terms, tax settings

Project Manager (PM)

Project-specific management role

Limited access: view invoices for assigned projects only, edit/delete permissions are available but no refund access is with the PM
#227
**Functional Requirements Document (FRD) - Invoice details** > **3\. Invoice Status Management**
~9 tok
## **3\. Invoice Status Management**
#228
**Functional Requirements Document (FRD) - Invoice details** > **3\. Invoice Status Management** > **3.1 Client-to-Agency Invoice Statuses**
~117 tok
### **3.1 Client-to-Agency Invoice Statuses**

**Status**

**Description**

**Trigger**

**Editable**

Unpaid

Payment not yet initiated

Manual/Default

Yes

Processing

Payment initiated, pending completion

Stripe automatic

No

Paid

Payment successfully completed

Stripe automatic

No

Overdue

Payment is past due date

Automatic (date-based)

Yes

Failed

Payment processing failed

Stripe automatic

No

Refunded

Payment refunded to client

Manual/Stripe

Yes
#229
**Functional Requirements Document (FRD) - Invoice details** > **3\. Invoice Status Management** > **3.2 Agency-to-Contractor Invoice Statuses**
~94 tok
### **3.2 Agency-to-Contractor Invoice Statuses**

**Status**

**Description**

**Trigger**

**Editable**

Unpaid

Payment has not yet been made to the contractor

Default

Yes

Processing

Payment initiated to the contractor

Stripe automatic

No

Paid

Payment completed to the contractor

Stripe automatic

No

Failed

Payment to the contractor failed

Stripe automatic

Yes
#230
**Functional Requirements Document (FRD) - Invoice details** > **4\. User Flow**
~5 tok
## **4\. User Flow**
#231
**Functional Requirements Document (FRD) - Invoice details** > **4\. User Flow** > **Primary Flow - Invoice Detail Management:**
~150 tok
### **Primary Flow - Invoice Detail Management:**

1.  **Invoice Access:** User navigates to the invoice detail from the billing list or a direct link
2.  **Status Review:** User views current invoice status and financial summary
3.  **Content Management:** User reviews/edits line items, applies discounts, and manages tax settings
4.  **Payment Terms:** User modifies payment schedules, adds new payment terms
5.  **Actions Execution:** User performs available actions based on invoice status and permissions
6.  **Activity Tracking:** System logs all changes and updates in the activity timeline
#232
**Functional Requirements Document (FRD) - Invoice details** > **5\. Field Details & Validations**
~10 tok
## **5\. Field Details & Validations**
#233
**Functional Requirements Document (FRD) - Invoice details** > **5\. Field Details & Validations** > **5.1 Invoice Header Information**
~89 tok
### **5.1 Invoice Header Information**

**Field Name**

**Required**

**Validation Rules**

**Description**

Invoice Number

Yes

Auto-generated, format: #INV00004

Unique invoice identifier

Status Badge

Yes

Auto-updated based on payment status

Current invoice status display

Actions Button

Yes

Role-based action availability

Available actions menu
#234
**Functional Requirements Document (FRD) - Invoice details** > **5\. Field Details & Validations** > **5.2 Financial Summary Fields**
~199 tok
### **5.2 Financial Summary Fields**

**Field Name**

**Type**

**Required**

**Validation Rules**

Gross Total

Currency

Yes

Calculated from line items, the full invoice amount before deductions.

Net Total

Currency

Yes

The total amount due after all deductions (e.g., taxes, discounts).

Paid Amount

Currency

Yes

Sum of completed payments  
  
The invoice marked as settled, either automatically when payment is processed or manually.

Unpaid Amount

Currency

Yes

Invoice not yet settled; may become overdue after the due date.

Issued On

Date

Yes

Date of the invoice issused

Next Payment

Date

Yes

Date of next payment if there is any

From

Name and email ID

Yes

From the billing name and the email ID

Bill To

Name and email ID

Yes

To the billing name and the email ID
#235
**Functional Requirements Document (FRD) - Invoice details** > **5\. Field Details & Validations** >
~1 tok
###
#236
**Functional Requirements Document (FRD) - Invoice details** > **5\. Field Details & Validations** >
~1 tok
###
#237
**Functional Requirements Document (FRD) - Invoice details** > **5\. Field Details & Validations** >
~1 tok
###
#238
**Functional Requirements Document (FRD) - Invoice details** > **5\. Field Details & Validations** >
~1 tok
###
#239
**Functional Requirements Document (FRD) - Invoice details** > **5\. Field Details & Validations** >
~1 tok
###
#240
**Functional Requirements Document (FRD) - Invoice details** > **5\. Field Details & Validations** > **5.3 Line Item Fields**
~144 tok
### **5.3 Line Item Fields**

**Field Name**

**Type**

**Required**

**Validation Rules**

**Description**

Item Name

Text

Yes

From the package catalogue or custom entry

Service/product description

Quantity

Number

Yes

Must be > 0, decimal allowed

Item quantity

Unit Price

Currency

Yes

Must be > 0

Price per unit

Line Total

Currency

Yes

Calculated: Quantity × Unit Price

Total for line item

Tax Toggle

Boolean

No

Per-item tax application

Tax inclusion for specific item

Item Description

Text

No

Optional detailed description

Additional item details
#241
**Functional Requirements Document (FRD) - Invoice details** > **5\. Field Details & Validations** > **5.4 Payment Terms Fields**
~138 tok
### **5.4 Payment Terms Fields**

**Field Name**

**Type**

**Required**

**Validation Rules**

**Description**

Payment Amount

Currency

Yes

Must be > 0, total must equal Net Total

Individual payment amount

Due Date

Date

Yes

Cannot be past date for new payments

Payment due date

Payment Date

Date

Conditional

Set when payment is completed

Actual payment date

Payment ID

Text

Conditional

Auto-generated for completed payments

Payment reference

Payment Status

Text

Yes

Unpaid/Processing/Paid/Failed/Overdue

Current payment status
#242
**Functional Requirements Document (FRD) - Invoice details** > **5\. Field Details & Validations** >
~1 tok
###
#243
**Functional Requirements Document (FRD) - Invoice details** > **5\. Field Details & Validations** >
~1 tok
###
#244
**Functional Requirements Document (FRD) - Invoice details** > **5\. Field Details & Validations** > **5.5 Contact Information, Project & event details and Activity**
~129 tok
### **5.5 Contact Information, Project & event details and Activity**

**Field Name**

**Required**

**Validation Rules**

**Description**

Project Name

Yes

Links to the project management module

Associated project

Event Date

Yes

Primary event date from the project

Event scheduling information

Brand

Yes

Brand association

Brand identification

Payment activity

Yes

All the payment status flow will be there

Send Reminder

Conditional

Send an email reminder for the client to pay the overdue invoice
#245
**Functional Requirements Document (FRD) - Invoice details** > **6\. Popup Specifications**
~8 tok
## **6\. Popup Specifications**
#246
**Functional Requirements Document (FRD) - Invoice details** > **6\. Popup Specifications** > **6.1 Add Payment Popup**
~141 tok
### **6.1 Add Payment Popup**

**Field Name**

**Type**

**Required**

**Validation Rules**

**Description**

Date Type

Dropdown

Yes

Smart Date, Custom Date options

Payment date calculation method

Days Before

Number

Conditional

1-365 days

Days before project date

Payment Type

Radio Buttons

Yes

Custom, Percentage, Equal Payment

Payment calculation method

Custom Amount

Currency

Conditional

Must be > 0 when Custom selected

Specific payment amount

Percentage

Percentage

Conditional

1-100% when Percentage selected

Percentage of total amount
#247
**Functional Requirements Document (FRD) - Invoice details** > **6\. Popup Specifications** > **6.2 Edit Discount Popup**
~89 tok
### **6.2 Edit Discount Popup**

**Field Name**

**Type**

**Required**

**Validation Rules**

**Description**

Discount Type

Radio Buttons

Yes

Percentage or Fixed amount

Discount calculation method

Amount

Number

Yes

Must be > 0, percentage ≤ 100%

Discount value

Remove Discount

Button

No

Removes all applied discounts

Discount removal option
#248
**Functional Requirements Document (FRD) - Invoice details** > **6\. Popup Specifications** > **6.3 Apply Tax Popup**
~95 tok
### **6.3 Apply Tax Popup**

**Field Name**

**Type**

**Required**

**Validation Rules**

**Description**

Tax Type

Radio Buttons

Yes

Percentage, Fixed, Auto-Tax Calculation

Tax calculation method

Amount

Number

Conditional

Must be ≥ 0

Tax rate or fixed amount

Auto-Tax Calc

Selection

Conditional

Based on client location and service type

Automatic tax calculation
#249
**Functional Requirements Document (FRD) - Invoice details** > **6\. Popup Specifications** > **6.4 Delete Invoice Popup**
~125 tok
### **6.4 Delete Invoice Popup**

**Field Name**

**Type**

**Required**

**Validation Rules**

**Description**

Warning Message

Text

Yes

"This action will permanently delete the invoice and all associated data"

Deletion warning

Data Impact List

Text

Yes

Line items, Payment terms, History and activity logs

What will be deleted

Payment Warning

Text

Conditional

Shown if payments exist

Warning about paid invoices

Confirmation

Button

Yes

"Yes, Delete Invoice"

Deletion confirmation
#250
**Functional Requirements Document (FRD) - Invoice details** > **6\. Popup Specifications** > **6.5 Deactivate Invoice Popup**
~121 tok
### **6.5 Deactivate Invoice Popup**

**Field Name**

**Type**

**Required**

**Validation Rules**

**Description**

Warning Message

Text

Yes

"Warning: Deactivating This Invoice Will Stop All Payments"

Deactivation warning

Impact Description

Text

Yes

Lists effects of deactivation

Consequences explanation

Refund Notice

Text

Yes

Manual refund requirement notice

Refund process information

Confirmation

Button

Yes

"Yes, Deactivate Invoice"

Deactivation confirmation
#251
**Functional Requirements Document (FRD) - Invoice details** > **6\. Popup Specifications** > **6.6 Refund Invoice Popup**
~122 tok
### **6.6 Refund Invoice Popup**

**Field Name**

**Type**

**Required**

**Validation Rules**

**Description**

Refund Notice

Text

Yes

Processing fee and timing information

Refund process details

Recipient

Text

Yes

Client name for refund

Refund recipient

Amount

Currency

Yes

Must be ≤ total refundable amount

Refund amount

Available Amount

Text

Yes

Shows maximum refundable amount

Refund limit display

Note

Text Area

No

Optional refund reason

Refund explanation
#252
**Functional Requirements Document (FRD) - Invoice details** > **7\. Success Message Handling**
~142 tok
## **7\. Success Message Handling**

**Validation Scenario**

**Success Message**

Invoice updated successfully

"Invoice has been updated successfully."

Payment term added

"Payment term added successfully."

Discount applied

"Discount applied successfully."

Tax settings updated

"Tax settings updated successfully."

Payment processed

"Payment processed successfully."

Invoice deactivated

"Invoice has been deactivated successfully."

Invoice deleted

"Invoice has been deleted permanently."

Refund processed

"Refund of $\[amount\] initiated successfully."
#253
**Functional Requirements Document (FRD) - Invoice details** > **8\. Error Message Handling**
~133 tok
## **8\. Error Message Handling**

**Field**

**Validation Scenario**

**Error Message**

Payment Terms

Invalid payment distribution

"Payment terms must equal invoice total amount"

Discount

Discount exceeds invoice total

"Discount cannot exceed invoice total amount"

Date Validation

Invalid due date

"Due date cannot be in the past"

Amount Validation

Invalid payment amount

"Payment amount must be greater than $0"

System Integration

Stripe connection failure

"Payment processing unavailable. Please try again later"
#254
**Functional Requirements Document (FRD) - Invoice details** > **9\. Functional Logic**
~7 tok
## **9\. Functional Logic**
#255
**Functional Requirements Document (FRD) - Invoice details** > **9\. Functional Logic** > **Invoice Editing Rules**
~128 tok
### **Invoice Editing Rules**

*   **Paid Invoice Restrictions:** Once any payment is completed, invoice cannot be edited
*   **Line Item Modifications:** Adding/editing line items automatically recalculates totals and adjusts unpaid payment terms proportionally
*   **Tax Toggle Logic:** Tax can be applied/removed to entire invoice or individual line items, automatically recalculating totals
*   **Discount Application:** Only one discount can be applied per invoice, either percentage-based or fixed amount
#256
**Functional Requirements Document (FRD) - Invoice details** > **9\. Functional Logic** > **Payment Term Management**
~135 tok
### **Payment Term Management**

*   **Automatic Adjustment:** When invoice total changes, unpaid payment terms adjust proportionally while maintaining paid amounts
*   **Overpayment Handling:** If line item changes result in paid amount exceeding new total, system displays warning and requires manual refund processing
*   **Payment Addition:** New payment terms can be added, automatically redistributing unpaid amounts across all payment dates
*   **Date Validation:** Payment due dates cannot be set in the past for new payment terms
#257
**Functional Requirements Document (FRD) - Invoice details** > **9\. Functional Logic** > **Tax Calculation Logic**
~113 tok
### **Tax Calculation Logic**

*   **Auto-Tax Calculation:** System automatically applies correct tax based on client location and service type when enabled
*   **Manual Override:** Users can override automatic tax calculations with custom rates or fixed amounts
*   **Line Item Tax:** Tax can be applied at individual line item level or invoice level
*   **Tax Toggle:** Tax can be completely removed from invoice, updating all calculations accordingly
#258
**Functional Requirements Document (FRD) - Invoice details** > **9\. Functional Logic** > **Activity Tracking Logic**
~113 tok
### **Activity Tracking Logic**

*   **Comprehensive Logging:** All invoice actions logged with timestamps: creation, editing, payments, status changes, user actions
*   **User Attribution:** Every activity entry includes user identification and role information
*   **Permanent History:** Activity logs maintained indefinitely for audit and compliance purposes
*   **Real-Time Updates:** Activity timeline updates immediately when actions are performed
#259
**Functional Requirements Document (FRD) - Invoice details** > **9\. Functional Logic** > **Integration Logic**
~108 tok
### **Integration Logic**

*   **Stripe Integration:** All payment processing, status updates, and refunds handled through Stripe API
*   **Project Module Integration:** Project details link directly to project management module
*   **Package Catalog Integration:** Line item additions pull from existing package and A La Carte catalogs
*   **Preset System:** Payment term presets can be saved and applied across multiple invoices
#260
**Functional Requirements Document (FRD) - Invoice details** > **10\. Edge Cases**
~342 tok
## **10\. Edge Cases**

**Scenario**

**Expected Behavior**

Overpayment due to line item reduction

Display warning message, require manual refund processing before allowing changes

Multiple simultaneous edits

Last save wins, notify users of conflicts, provide option to refresh and retry

Payment processing during invoice edit

Lock invoice editing until payment processing completes

Discount exceeding invoice total

Prevent application, show validation error, suggest maximum discount amount

Tax toggle on individual items with invoice-level tax

Item-level tax takes precedence, calculate accordingly

Payment term deletion with existing payments

Prevent deletion of payment terms with completed payments

Preset application over existing payment terms

Replace existing unpaid terms, preserve paid terms, recalculate totals

Network interruption during save

Auto-save draft changes, restore on reconnection, validate data integrity

Client location change affecting auto-tax

Prompt user to recalculate tax, apply new rates if confirmed

Large invoice with many line items

Implement pagination for line items, maintain performance

Concurrent payment and refund processing

Queue operations, process sequentially, update status accordingly

Invoice deletion with partial payments

Prevent deletion, require deactivation instead, provide refund guidance
#261
**Functional Requirements Document (FRD) - Invoice details** > **11\. Test Cases**
~6 tok
## **11\. Test Cases**
#262
**Functional Requirements Document (FRD) - Invoice details** > **12\. Acceptance Criteria**
~396 tok
## **12\. Acceptance Criteria**

*   **Role-Based Access Control:** PM users can only view invoices for assigned projects, Owner/Admin have full edit access
*   **Status Management:** Invoice statuses update automatically via Stripe integration and manually as appropriate
*   **Line Item Flexibility:** Users can add, edit, and remove line items with automatic total recalculation
*   **Tax Management:** Tax toggle works at invoice and line item levels with accurate calculations
*   **Payment Term Control:** Payment terms can be added, modified, and adjusted with proper validation
*   **Discount Functionality:** Single discount application per invoice with percentage or fixed amount options
*   **Edit Restrictions:** Paid invoices cannot be edited, appropriate restrictions enforced
*   **Overpayment Protection:** System prevents line item changes that would create overpayment situations
*   **Integration Reliability:** Stripe integration handles all payment processing and status updates
*   **Activity Tracking:** Complete audit trail maintained for all invoice actions and changes
*   **Preset Management:** Payment term presets can be saved and applied efficiently
*   **Action Availability:** All actions (edit, delete, refund, etc.) available based on invoice status and user permissions
*   **Data Validation:** All financial calculations accurate and validated before saving
*   **Error Handling:** Comprehensive error messaging for validation failures and system issues
*   **Performance:** Interface remains responsive with large invoices and multiple line items
#263
**Functional Requirements Document (FRD) - Invoice details** > **13\. Dependencies**
~201 tok
## **13\. Dependencies**

**Module/System**

**Dependency Type**

**Impact if Unavailable**

Stripe Payment Gateway

Critical Integration

Payment processing, status updates, and refunds fail

Package Management

Data Dependency

Cannot add line items from package catalog

Project Management

Reference Dependency

Project details link non-functional, project association fails

Authentication System

Security Dependency

Role-based access control fails

Billing Module

Parent Dependency

Cannot access invoice data or navigate back to billing list

Activity Logging System

Audit Dependency

Activity tracking fails, compliance issues

Tax Calculation Service

Functional Dependency

Auto-tax calculation unavailable

Email Service

Communication Dependency

Invoice notifications and reminders fail
#264
**Functional Requirements Document (FRD) - Invoice details** > **14\. Future Enhancements**
~8 tok
## **14\. Future Enhancements**
#265
**Functional Requirements Document (FRD) - Invoice details** > **14\. Future Enhancements** > **14.1 Advanced Features**
~87 tok
### **14.1 Advanced Features**

*   **Version Control:** Track invoice versions and allow rollback to previous versions
*   **Approval Workflow:** Multi-level approval process for large invoice modifications
*   **Bulk Operations:** Batch invoice operations for multiple invoices
*   **Template Management:** Custom invoice templates with branding
#266
**Functional Requirements Document (FRD) - Invoice details** > **14\. Future Enhancements** > **14.2 Integration Expansions**
~93 tok
### **14.2 Integration Expansions**

*   **Multi-Currency Support:** Handle international clients with currency conversion
*   **Advanced Tax Management:** Complex tax scenarios with multiple jurisdictions
*   **Document Management:** Attach supporting documents and contracts to invoices
*   **API Access:** RESTful API for third-party integrations and custom reporting
#267
**Functional Requirements Document (FRD) - Invoice details** > **15\. References**
~11 tok
## **15\. References**

*   Figma

Expense
#268
**Finance Management — Expenses Management Module (FRD)**
~15 tok
# **Finance Management — Expenses Management Module (FRD)**
#269
**Finance Management — Expenses Management Module (FRD)** > **1\. Module Overview**
~142 tok
## **1\. Module Overview**

**Module Name:** Expenses Management Module (Sub-module within Finance Management)

**Purpose:** Record, manage, and track all outgoing monetary expenses of the company with COGS/OPEX classification, brand and project association, contractor/editor payee tracking, and automated QuickBooks integration.

**Business Goal:** Provide centralized expense management with an OPEX-vs-COGS tabbed view, detailed categorization, project-linked cost attribution (COGS), contractor and editor payment tracking, and per-row QuickBooks sync visibility.
#270
**Finance Management — Expenses Management Module (FRD)** > **2\. User Roles & Permissions**
~241 tok
## **2\. User Roles & Permissions**

**Role**

**Add**

**Edit**

**Delete**

**View**

Agency Owner

Any expense (COGS or OPEX)

Any expense

Any expense — **except Stripe/ACH-paid entries, which are never deletable**

All expenses

Admin

Any expense (COGS or OPEX)

Any expense

**Only entries they added themselves** (never Stripe/ACH-paid)

All expenses

Project Manager (PM)

**COGS only, for assigned projects** (cannot add OPEX)

Only entries they created themselves, within assigned projects

Only entries they created themselves, within assigned projects (never Stripe/ACH-paid)

Own assigned-project expenses; can view OPEX read-only

**Note (flagged for confirmation):** Admin permissions are intentionally asymmetric — Admin can **edit any** expense but can **delete only their own** manual entries. Confirm this is intended and not meant to be symmetric.

**Note:** "Project owner" in stakeholder notes is treated as the **Project Manager (PM)** role.
#271
**Finance Management — Expenses Management Module (FRD)** > **3\. User Flow**
~5 tok
## **3\. User Flow**
#272
**Finance Management — Expenses Management Module (FRD)** > **3\. User Flow** > **Primary Flow — Expense Management**
~305 tok
### **Primary Flow — Expense Management**

1.  **Module Access:** User navigates to Finance Management → Expenses.
2.  **Tab Selection:** User lands on the **All** tab by default and can switch between **All | OPEX | COGS** (each showing a live count).
3.  **Expense Listing:** System displays the expense table. On **All** and **COGS**, columns are Date, Amount, Category (with a COGS/OPEX badge), Brand, Project, Payee, Notes, and Action. On **OPEX**, the Project and Payee columns are hidden.
4.  **Filter Application:** User applies filters (brand, date range, price range, notes/category search) and, on the **All** and **COGS** tabs only, the "Only show amount paid to Contractor" toggle. Filters and search persist when switching tabs.
5.  **Expense Actions:** Based on permissions, the user can add, edit, or delete expenses, and manually re-sync an entry with QuickBooks.
6.  **QuickBooks Integration:** When the integration is on the plan and connected, every expense syncs to QuickBooks by default and each row shows a Synced / Not synced indicator with manual re-sync from the kebab. The indicator is hidden when the integration isn't on the plan and greyed when on plan but not connected (see §4.11, §10.1).
#273
**Finance Management — Expenses Management Module (FRD)** > **3\. User Flow** > **Secondary Flow — Add New Expense**
~246 tok
### **Secondary Flow — Add New Expense**

1.  **Add Expense:** User clicks the "Add Expense" button (available from every tab).
2.  **Type Selection:** The expense type defaults to **OPEX** from all tabs. Agency Owner and Admin can switch to COGS. **Project Managers are offered COGS only** (they cannot create OPEX), so COGS is pre-selected for them.
3.  **Category Selection:** User selects from the predefined category list for the chosen type.
4.  **Form Completion:** User fills the required fields. For COGS, brand is required and project is auto-fetched when the entry originates from a project, or optional when added manually. OPEX has no project field.
5.  **Payee Selection (COGS):** For payee-based COGS categories (e.g., Contractor), the user selects the relevant contractor; the selected name appears in the Payee column.
6.  **Submission:** System validates data and creates the expense record.
7.  **Auto-Sync:** System syncs the new expense to QuickBooks by default.
#274
**Finance Management — Expenses Management Module (FRD)** > **3\. User Flow** > **Tertiary Flow — Delete / Void**
~167 tok
### **Tertiary Flow — Delete / Void**

1.  **Delete Attempt:** A permitted user clicks the delete icon on a deletable row (Stripe/ACH-paid entries show a greyed-out, non-clickable delete icon).
2.  **Local Deletion:** The entry is hard-deleted from the CRM (row disappears, excluded from all totals).
3.  **QuickBooks Void:** If the entry was synced, it is **voided** in QuickBooks. If QuickBooks is not connected (or the entry was never synced), no QuickBooks action occurs.
4.  **Source Reversion:** If the entry was an editor payment (from Post Production) or a manually marked-as-paid contractor payment, deleting it reverts the source status back to **unpaid**.
#275
**Finance Management — Expenses Management Module (FRD)** > **3\. User Flow** > **Quaternary Flow — QuickBooks Sync Management**
~123 tok
### **Quaternary Flow — QuickBooks Sync Management**

1.  **Auto-Sync:** The system syncs new/modified expenses to QuickBooks by default.
2.  **Sync Indicator:** When connected, each row shows Synced (green) or Not synced (grey); hidden when the integration isn't on the plan; greyed for all rows when on plan but not connected (see §10.1).
3.  **Manual Re-Sync:** When connected, the user opens the row's kebab (three-dot) menu and selects "Sync with QuickBooks" to sync a Not-synced entry.
#276
**Finance Management — Expenses Management Module (FRD)** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#277
**Finance Management — Expenses Management Module (FRD)** > **4\. Functional Logic** > **4.1 Empty State (Initial Behavior)**
~111 tok
### **4.1 Empty State (Initial Behavior)**

*   When no rows match the current tab, search, filters, brand, or toggle — or when no expenses exist at all — the table area shows a **single global empty-state message** (see Section 6). The filter/search/tab controls and the toolbar "Add Expense" button remain visible and enabled at all times.
*   The empty state never blocks adding an expense; permitted users can always add from the toolbar.
#278
**Finance Management — Expenses Management Module (FRD)** > **4\. Functional Logic** > **4.2 Expense Tabs (All | OPEX | COGS)**
~165 tok
### **4.2 Expense Tabs (All | OPEX | COGS)**

*   Three tabs group expenses by type: **All**, **OPEX**, **COGS**. Each tab displays a live count of its records.
*   **All** is the default tab and shows every expense; rows carry a COGS/OPEX badge in the Category cell, and OPEX rows render "–" in the Project and Payee columns.
*   **OPEX** and **COGS** tabs constrain the list to that type. Search, brand filter, price/date filters, and (where applicable) the contractor toggle operate within the active tab's scope and **persist across tab switches**.
*   Selecting a tab does not clear active filters or search terms; they re-apply within the new tab's scope.
#279
**Finance Management — Expenses Management Module (FRD)** > **4\. Functional Logic** > **4.3 Expense Type & Category Logic**
~209 tok
### **4.3 Expense Type & Category Logic**

*   **COGS and Editor/Contractor placement:** Contractor payments and editor payments are **COGS** (moved from OPEX). COGS categories include Contractor plus production-related categories such as Second Shooter, Editing Services, Equipment Rental, and Album & Print Production.
*   **OPEX scope:** OPEX now covers operating costs only (e.g., Business Insurance, Legal Fees, Utilities, CRM / Project Management Software, Studio Lease, Paid Advertising, Bank / Payment Processor Fees). **OPEX no longer has a contractor field.**
*   **Type→Category filtering:** Selecting COGS shows only COGS categories; selecting OPEX shows only OPEX categories.
*   **Contractor category logic:** When a payee-based COGS category (e.g., Contractor) is selected, the contractor/payee selection becomes required.
#280
**Finance Management — Expenses Management Module (FRD)** > **4\. Functional Logic** > **4.4 Table Columns & Behavior**
~227 tok
### **4.4 Table Columns & Behavior**

*   **All & COGS tabs:** Date, Amount, Category (with COGS/OPEX badge), Brand, **Project**, **Payee**, Notes, Action.
*   **OPEX tab:** Date, Amount, Category, Brand, Notes, Action — the **Project and Payee columns are hidden entirely** (not blank).
*   **Project column:** Clickable — navigates through to the linked project. Present on All & COGS; "–" for OPEX rows shown on the All tab.
*   **Payee column:** A single generic column showing the contractor/editor/vendor name where one applies; blank ("–") when there is no named payee. **Plain text, not clickable** (for now).
*   **Action column:** Contains the QuickBooks sync indicator (Synced / Not synced — hidden entirely when QuickBooks integration is not on the subscription plan; see §4.11 and §10.1), an edit icon, a delete icon, and a kebab (three-dot) menu with "View Details" and "Sync with QuickBooks."
#281
**Finance Management — Expenses Management Module (FRD)** > **4\. Functional Logic** > **4.5 Project Assignment Logic**
~129 tok
### **4.5 Project Assignment Logic**

*   Project applies to **COGS only**. When a COGS entry originates from a project, the project is **auto-fetched** and populated on every such entry; when added manually, the project field is **optional**.
*   **PM scoping:** PMs can only select/add against their assigned projects. Because OPEX has no project to scope by, **PMs cannot add OPEX** (they may view OPEX read-only).
*   Agency Owner and Admin can leave the manual COGS project field empty for company-wide costs.
#282
**Finance Management — Expenses Management Module (FRD)** > **4\. Functional Logic** > **4.6 Payee Logic (Contractor vs. Editor)**
~176 tok
### **4.6 Payee Logic (Contractor vs. Editor)**

*   **Contractors and editors are distinct entities**, both surfaced through the single Payee column.
*   **Contractor payments:** Paid **directly via Stripe/ACH**, or **manually marked as paid**. Stripe/ACH-paid contractor entries are non-deletable; manually marked-as-paid contractor entries are deletable.
*   **Editor payments:** Editors **cannot be paid directly from the system**; they are **marked as paid from Post Production**, which creates the expense entry. Such entries are deletable, and deletion reverts the editor to unpaid in Post Production.
*   Failed payments never create an expense entry, so there is no failed-payment row to handle.
#283
**Finance Management — Expenses Management Module (FRD)** > **4\. Functional Logic** > **4.7 Add Expense & Type Pre-selection**
~99 tok
### **4.7 Add Expense & Type Pre-selection**

*   The **Add Expense** action is available from every tab; on submission it defaults the expense type to **OPEX** regardless of the active tab.
*   Agency Owner and Admin may switch the type to COGS in the form.
*   **Project Managers** are offered **COGS only** (they cannot create OPEX), so COGS is pre-selected and OPEX is unavailable for them.
#284
**Finance Management — Expenses Management Module (FRD)** > **4\. Functional Logic** > **4.8 Brand Association Logic**
~67 tok
### **4.8 Brand Association Logic**

*   All expenses can be associated with any brand or "All Brands," with no type-based brand restrictions.
*   The list defaults to "All Brands" unless the user selects a specific brand; the brand filter is available on every tab.
#285
**Finance Management — Expenses Management Module (FRD)** > **4\. Functional Logic** > **4.9 Delete Logic & Rules**
~295 tok
### **4.9 Delete Logic & Rules**

*   **Non-deletable:** Stripe/ACH-paid entries can never be deleted; their delete icon is **greyed out and non-clickable, with an explanatory tooltip**.
*   **Deletable:** Any COGS or OPEX entry that was **manually marked as paid** (or otherwise not paid through Stripe/ACH) can be deleted, subject to role permissions.
*   **Local behavior:** Deletion is a **hard delete** in the CRM — the row disappears and is excluded from all totals and rollups.
*   **QuickBooks behavior:** If the entry was synced, deletion **voids** it in QuickBooks. If QuickBooks is not connected (or the entry was never synced), no QuickBooks action is taken.
*   **Source reversion:** Deleting an editor payment reverts it to unpaid in Post Production; deleting a manually marked-as-paid contractor payment reverts the paid status at its source.
*   **Role scope:** Agency Owner can delete any (deletable) entry. Admin and PM can delete only entries they added themselves (PM further limited to assigned projects). System-generated entries (editor payments from Post Production, project-fetched contractor entries) are therefore **deletable only by the Agency Owner**.
#286
**Finance Management — Expenses Management Module (FRD)** > **4\. Functional Logic** > **4.10 Edit Logic**
~73 tok
### **4.10 Edit Logic**

*   **Role scope:** Agency Owner and Admin can edit any expense; PMs can edit only entries they created themselves within their assigned projects.
*   **Stripe/ACH-paid entries are editable** (delete is the only locked action for them); edits propagate to QuickBooks.
#287
**Finance Management — Expenses Management Module (FRD)** > **4\. Functional Logic** > **4.11 QuickBooks Integration & Sync Indicator Logic**
~335 tok
### **4.11 QuickBooks Integration & Sync Indicator Logic**

*   **Icon visibility (plan-gated):** The sync indicator appears **only when QuickBooks integration is part of the account's subscription plan**. If the integration is **not on the plan, the icon is hidden entirely** for every row.
*   **Connection state (when the integration is on the plan):**
    *   **On plan but not connected** (never integrated) → the icon shows for all rows but is **greyed / Not synced** (nothing can sync yet).
    *   **Connected** → the icon reflects each entry's sync status: **green "Synced"** once the entry has synced, **greyed "Not synced"** until it has.
    *   **Previously connected, then disconnected** → the icon reverts to **greyed / Not synced** for all rows until QuickBooks is reconnected.
*   **Sync by default:** When connected, every expense — including manually added ones — syncs to QuickBooks by default.
*   **Edits sync / Delete voids:** When connected, editing an expense (including a Stripe/ACH-paid one) updates the corresponding QuickBooks record, and deleting a synced expense voids it (see 4.9).
*   **Manual re-sync:** When connected, a Not-synced entry can be re-synced from the row's kebab menu via "Sync with QuickBooks." When not connected — or when the integration is not on the plan — manual re-sync is unavailable.
#288
**Finance Management — Expenses Management Module (FRD)** > **4\. Functional Logic** > **4.12 Price Range Filter Logic**
~144 tok
### **4.12 Price Range Filter Logic**

*   **System-derived Min/Max:** The system calculates the minimum from the lowest expense amount and the maximum from the highest, updating dynamically as the dataset changes.
*   **User interaction:** The user drags the range slider between the system-defined Min and Max to filter the list.
*   **Display:** The Min ($) and Max ($) labels above the slider are informational, read-only values reflecting the current dataset range.
*   **Removal of Event Types Filter:** The Event Types dropdown has been removed from the filter panel.
#289
**Finance Management — Expenses Management Module (FRD)** > **4\. Functional Logic** > **4.13 Impact**
~207 tok
### **4.13 Impact**

*   **Accounting sync:** Creates and edits propagate to QuickBooks by default; deletes void the synced record, keeping external accounting aligned. If QuickBooks is disconnected, entries simply carry no QuickBooks record.
*   **Financial classification:** Moving contractor and editor costs into COGS changes how those amounts roll into COGS-vs-OPEX reporting and profitability views, so tab/type accuracy directly affects those figures.
*   **Cross-module status:** Deleting an editor or manually-paid contractor payment reverts the paid status at its source (Post Production / contractor record), so Finance deletions have downstream effects.
*   **Brand & project rollups:** Project-linked COGS attributes costs to the correct project and brand; hard-deleted entries drop out of those rollups immediately.
#290
**Finance Management — Expenses Management Module (FRD)** > **5\. Field Details & Validations**
~10 tok
## **5\. Field Details & Validations**
#291
**Finance Management — Expenses Management Module (FRD)** > **5\. Field Details & Validations** > **5.1 Expense Form Fields**
~207 tok
### **5.1 Expense Form Fields**

**Field Name**

**Required**

**Validation Rules**

Date

Yes

The date of payment.

Amount

Yes

Total amount paid. Must be numeric and > 0, formatted to 2 decimal places.

Category

Yes

The category the payment was made in (scoped to the selected type).

Payee

Conditional

Required for payee-based COGS categories (e.g., Contractor); shows the contractor/editor/vendor name.

Notes

Yes

Maximum 250 characters.

QuickBooks sync indicator

Conditional

Shown only when QuickBooks integration is on the subscription plan. States: green "Synced" / greyed "Not synced" (greyed for all rows when on plan but not connected or later disconnected). Re-sync via the row kebab when connected. See §10.1.

Actions

Yes

Sync indicator, edit, delete, and kebab ("View Details", "Sync with QuickBooks").
#292
**Finance Management — Expenses Management Module (FRD)** > **5\. Field Details & Validations** > **5.2 COGS (Cost of Goods Sold) Form Fields**
~149 tok
### **5.2 COGS (Cost of Goods Sold) Form Fields**

**Field Group**

**Details**

Select Category

Drop-down auto-populated with COGS values (Contractor, Second Shooter, Editing Services, Equipment Rental, Album & Print Production, etc.).

Select Brand

Drop-down; brand values auto-populate. Required.

Select Project

Auto-fetched when the entry originates from a project; optional when added manually.

Select Contractor / Payee

Required for payee-based categories (e.g., Contractor); populates the Payee column.

Date

Date picker.

Amount

Numeric value only.

Notes (Optional)

Text field.
#293
**Finance Management — Expenses Management Module (FRD)** > **5\. Field Details & Validations** > **5.3 OPEX (Operating Expenses) Form Fields**
~130 tok
### **5.3 OPEX (Operating Expenses) Form Fields**

**Field Group**

**Details**

Select Brand

Drop-down; brand values auto-populate.

Select Category

Drop-down auto-populated with OPEX values (Business Insurance, Legal Fees, Utilities, CRM / Project Management Software, Studio Lease, Paid Advertising, Bank / Payment Processor Fees, etc.).

Date

Date picker.

Amount

Numeric value only.

Notes

Text field.

**Removed from OPEX:** the Select Contractor field and any project field. Contractors/editors are now COGS.
#294
**Finance Management — Expenses Management Module (FRD)** > **5\. Field Details & Validations** > **5.4 Table Columns by Tab**
~83 tok
### **5.4 Table Columns by Tab**

**Column**

**All**

**COGS**

**OPEX**

Date

✓

✓

✓

Amount

✓

✓

✓

Category (with COGS/OPEX badge)

✓

✓

✓

Brand

✓

✓

✓

Project (clickable)

✓ ("–" for OPEX rows)

✓

Hidden

Payee (plain text)

✓ ("–" when none)

✓

Hidden

Notes

✓

✓

✓

Action (sync / edit / delete / kebab)

✓

✓

✓
#295
**Finance Management — Expenses Management Module (FRD)** > **5\. Field Details & Validations** > **5.5 Filter & Toolbar Fields**
~169 tok
### **5.5 Filter & Toolbar Fields**

**Field Name**

**Type**

**Rules / Availability**

Tabs (All / OPEX / COGS)

Tab control

Default All; live counts; filters/search persist across tabs.

Contractor Toggle

Toggle Switch

"Only show amount paid to Contractor." **Shown on All and COGS tabs only; hidden on OPEX.**

Brand Filter

Dropdown

Filter by brand; "All Brands" default. Available on all tabs.

Date Filter

Date Range

Start date ≤ end date; valid date format.

Price Range

Number Range

Filter by amount range (Min $0 – Max $200+); system-derived min/max.

Notes/Category Search

Text Input

Real-time search within notes and categories, scoped to the active tab.
#296
**Finance Management — Expenses Management Module (FRD)** > **6\. Empty State Handling**
~177 tok
## **6\. Empty State Handling**

All empty conditions render a **single global message** (informational, not an error). Controls and the toolbar "Add Expense" button remain available.

**Message:** "No expenses match these filters." **Sub-text:** "Try widening the date range, or clear the filters to see everything."

**Trigger scenarios (all show the message above):**

1.  Notes/category search returns no matching results.
2.  Applied filters (date range, price range, brand) return no matching results.
3.  "Only show amount paid to Contractor" toggle returns no data.
4.  Selected brand has no expense records.
5.  Active tab (OPEX or COGS) has no records.
6.  No expense records exist in the system.
#297
**Finance Management — Expenses Management Module (FRD)** > **7\. Success Message Handling**
~112 tok
## **7\. Success Message Handling**

**Scenario**

**Success Message**

Expense created successfully

"Expense has been added successfully."

Expense updated successfully

"Expense details have been updated successfully."

Expense deleted successfully

"Expense has been deleted successfully."

Expense deleted while synced

"Expense has been deleted and voided in QuickBooks."

Manual re-sync successful

"Expense has been synced with QuickBooks."
#298
**Finance Management — Expenses Management Module (FRD)** > **8\. Error Message Handling**
~216 tok
## **8\. Error Message Handling**

**Field / Action**

**Scenario**

**Message**

Expense Type

Not selected

"Please select expense type (COGS or OPEX)."

Category

Not selected

"Please select a category."

Brand

Not selected

"Please select a brand."

Project

Not selected (when required on a project-originated COGS entry)

"Please select a project from your assigned projects."

Payee / Contractor

Not selected when required

"Please select a contractor for this expense."

Date

Invalid or empty

"Please select a valid date."

Amount

Invalid or ≤ 0

"Please enter a valid expense amount greater than $0."

Amount

Non-numeric

"Please enter a valid numeric amount."

Notes

Exceeds 250 characters

"Notes cannot exceed 250 characters."

Delete (blocked)

Stripe/ACH-paid entry

Delete icon greyed out with tooltip: "Stripe-paid entries can't be deleted."
#299
**Finance Management — Expenses Management Module (FRD)** > **9\. Edge Cases**
~381 tok
## **9\. Edge Cases**

**Scenario**

**Expected Behavior**

Delete a Stripe/ACH-paid entry

Not permitted; delete icon greyed out with tooltip. Entry remains editable.

Delete a synced entry

Hard-delete locally; void the corresponding record in QuickBooks.

Delete when QuickBooks disconnected / entry never synced

Hard-delete locally; no QuickBooks action.

Delete an editor payment (from Post Production)

Reverts the editor to unpaid in Post Production.

Delete a manually marked-as-paid contractor payment

Reverts the paid status at its source.

Admin/PM attempts to delete a system-generated entry they didn't add

Not permitted; only the Agency Owner can delete system-generated entries.

PM attempts to add OPEX

Not permitted; OPEX is unavailable in Add Expense for PMs (they may view OPEX read-only).

Category selection with no matching contractor

If a contractor is required but none are available, show "No contractors available."

Switching tabs with active filters/search

Filters and search persist and re-apply within the new tab's scope.

QuickBooks integration not on the subscription plan

Sync indicator is hidden on every row; no sync/void occurs; kebab "Sync with QuickBooks" is unavailable.

On plan but QuickBooks not connected (never integrated)

Indicator shown greyed "Not synced" on all rows; manual re-sync unavailable until connected.

QuickBooks previously connected, then disconnected

Indicator reverts to greyed "Not synced" on all rows; entries stop syncing/voiding until reconnected.
#300
**Finance Management — Expenses Management Module (FRD)** > **10\. QuickBooks Integration Specifications**
~12 tok
## **10\. QuickBooks Integration Specifications**
#301
**Finance Management — Expenses Management Module (FRD)** > **10\. QuickBooks Integration Specifications** > **10.1 Sync Indicator States (plan- and connection-gated)**
~198 tok
### **10.1 Sync Indicator States (plan- and connection-gated)**

**Subscription / Connection State**

**Icon Visibility**

**Icon State**

**Notes**

QuickBooks integration **not on the subscription plan**

**Hidden** — no icon on any row

—

The Action column shows no sync indicator at all.

On plan, **not connected** (never integrated)

Shown

Greyed "Not synced" (all rows)

Nothing syncs until QuickBooks is connected.

On plan, **connected** — entry has synced

Shown

Green "Synced"

Entry is synchronized with QuickBooks.

On plan, **connected** — entry not yet synced

Shown

Greyed "Not synced"

Re-sync via the row kebab → "Sync with QuickBooks."

On plan, **previously connected then disconnected**

Shown

Greyed "Not synced" (all rows)

Reconnect QuickBooks to resume syncing.
#302
**Finance Management — Expenses Management Module (FRD)** > **10\. QuickBooks Integration Specifications** > **10.2 Sync Behavior**
~138 tok
### **10.2 Sync Behavior**

*   When connected, every expense (including manual) syncs to QuickBooks by default.
*   When connected, edits update the QuickBooks record; deletes void the QuickBooks record.
*   When the integration is **not on the plan**, no sync indicator is shown and no QuickBooks records are created, updated, or voided.
*   When on the plan but **not connected** (never integrated, or later disconnected), the indicator shows greyed "Not synced," manual re-sync is unavailable, and no records are created or voided until reconnected.
#303
**Finance Management — Expenses Management Module (FRD)** > **11\. Acceptance Criteria**
~428 tok
## **11\. Acceptance Criteria**

*   **Tabs:** All | OPEX | COGS render with live counts; All is default; filters/search persist across tabs and scope to the active tab.
*   **Columns:** Project and Payee appear on All & COGS and are hidden on OPEX; Project is clickable to the project; Payee is plain text; OPEX rows on the All tab show "–" for Project/Payee.
*   **Reclassification:** Contractor and editor costs are COGS; OPEX has no contractor/project fields.
*   **Add Expense:** Defaults to OPEX from all tabs for Owner/Admin; PMs are offered COGS only.
*   **Project logic:** Project auto-fetches for project-originated COGS entries and is optional for manual COGS; PMs cannot add OPEX.
*   **Delete rules:** Stripe/ACH-paid entries are non-deletable (greyed icon + tooltip); manually paid entries are deletable; deletion is a local hard delete and voids the entry in QuickBooks when synced; deletion reverts the source (Post Production / contractor) to unpaid.
*   **Permissions:** Owner deletes any deletable entry; Admin/PM delete only their own manual entries (PM within assigned projects); Owner/Admin edit any entry; PM edits own within assigned projects.
*   **Sync indicator:** Hidden when QuickBooks integration is not on the subscription plan; greyed "Not synced" when on plan but not connected (or later disconnected); green "Synced" / greyed "Not synced" per entry when connected. Manual re-sync from the kebab is available only when connected; every expense syncs by default when connected.
*   **Empty state:** A single global message appears for all empty/no-result conditions with controls remaining accessible.
*   **Validation:** Required-field validations and messages work as specified.
#304
**Finance Management — Expenses Management Module (FRD)** > **12\. Dependencies**
~174 tok
## **12\. Dependencies**

**Module / System**

**Impact if Unavailable**

Brands Management

Cannot associate/filter expenses by brand.

Contractor Management

Cannot select contractors for COGS payee categories.

Project Management

Cannot auto-fetch/assign projects to COGS; PM project scoping fails.

Post Production

Editor payments (marked as paid) cannot flow in; delete-to-unpaid reversion cannot reflect.

Stripe / ACH Payment Processing

Direct contractor payments cannot be processed; non-deletable rule cannot be enforced.

QuickBooks Integration

Sync/void unavailable; manual reconciliation required.

Authentication System

Role-based add/edit/delete permissions cannot be enforced.
#305
**Finance Management — Expenses Management Module (FRD)** > **13\. References**
~57 tok
## **13\. References**

*   [Figma](https://www.figma.com/design/ej0kxwP45mDKmZCZfAJ5O8/Pixally?node-id=28823-122672&t=ShhIDg0jGuZ3l3Li-0)
*   UI reference screenshots (All / OPEX / COGS tab states) provided by the product team.
#306
**Finance Management — Expenses Management Module (FRD)** > **Open Items (to confirm)**
~86 tok
## **Open Items (to confirm)**

*   **Add Expense pre-selection (TBD → proposed resolved):** Defaults to OPEX from all tabs; for PMs (no OPEX), COGS is pre-selected. Confirm this reconciliation.
*   **Admin edit/delete asymmetry:** Admin edits any but deletes only own — confirm intended.

Quickbooks

**Refer - Click Here**

☑️ Profit and Loss
#307
**Functional Requirements Document (FRD) - Profit and Loss Module**
~17 tok
# **Functional Requirements Document (FRD) - Profit and Loss Module**
#308
**Functional Requirements Document (FRD) - Profit and Loss Module** > **1\. Module Overview**
~124 tok
## **1\. Module Overview**

**Module Name:** Profit and Loss Module (Sub-module within Finance Management)  
**Purpose:** Provide comprehensive financial insights by tracking income, expenses, and profit trends across different time periods with visual analytics and detailed reporting capabilities  
**Business Goal:** Enable data-driven financial decision making, monitor business performance trends, and provide stakeholders with clear visibility into agency profitability and financial health
#309
**Functional Requirements Document (FRD) - Profit and Loss Module** > **2\. User Roles & Permissions**
~151 tok
## **2\. User Roles & Permissions**

**Role**

**Description**

**Key Permissions**

Agency Owner

Business owner with full financial oversight

Full access to all financial data, can view/configure filters, export reports Excel, and print summaries

Admin

System administrator with financial access

Full access to all financial data, can view/configure filters, export reports Excel, and print summaries

Project Manager (PM)

Project-specific management role

Limited access to financial data only for assigned projects, project-specific profit/loss calculations, and restricted export capabilities
#310
**Functional Requirements Document (FRD) - Profit and Loss Module** > **3\. User Flow**
~5 tok
## **3\. User Flow**
#311
**Functional Requirements Document (FRD) - Profit and Loss Module** > **3\. User Flow** > **Primary Flow - Financial Analytics Review:**
~193 tok
### **Primary Flow - Financial Analytics Review:**

1.  **Module Access:** User navigates to Finance Management → Profit and Loss
2.  **Time Period Selection:** User selects date filter from preset options or custom range (defaults to "Last Month")
3.  **Analytics Review:** System displays Profit & Loss analytics with KPI cards (Profit, Income, Expenses) and trend chart
4.  **Chart Interaction:** User can click on chart points to view detailed breakdowns for specific time periods
5.  **Summary Analysis:** User scrolls to view the detailed Summary section with project-level breakdowns
6.  **Data Export:** User can print a summary or export data in Excel formats
7.  **Project Drill-down:** User can expand/collapse individual project details in the summary section
#312
**Functional Requirements Document (FRD) - Profit and Loss Module** > **3\. User Flow** > **Secondary Flow - Custom Date Range Selection:**
~104 tok
### **Secondary Flow - Custom Date Range Selection:**

1.  **Custom Range Selection:** User clicks "Custom Range" from the date filter dropdown
2.  **Calendar Interface:** Dual calendar picker opens, showing start and end date selection
3.  **Date Validation:** System validates selected date range and updates analytics
4.  **Data Refresh:** All charts, KPIs, and summary data refresh based on the selected period
#313
**Functional Requirements Document (FRD) - Profit and Loss Module** > **3\. User Flow** > **Tertiary Flow - Project-Specific Analysis (PM Users):**
~87 tok
### **Tertiary Flow - Project-Specific Analysis (PM Users):**

1.  **Restricted Access:** PM users see only assigned project financial data
2.  **Project Filtering:** The System automatically filters all financial metrics to assigned projects only
3.  **Limited Export:** PM users have restricted export capabilities for assigned project data only
#314
**Functional Requirements Document (FRD) - Profit and Loss Module** > **4\. Field Details & Validations**
~10 tok
## **4\. Field Details & Validations**
#315
**Functional Requirements Document (FRD) - Profit and Loss Module** > **4\. Field Details & Validations** > **4.1 Date Filter Configuration**
~290 tok
### **4.1 Date Filter Configuration**

**Field Name**

**Type**

**Required**

**Validation Rules**

**Description**

Time Filter

Dropdown

Yes

Must select from preset options or valid custom range

Date period for financial analysis

Custom Start Date

Date

Conditional

Must be valid past date, cannot be a future date

Start date for custom range selection

Custom End Date

Date

Conditional

Must be ≥ start date, cannot be a future date

End date for custom range selection

**Preset Filter Options:**

*   **Custom Range**: Pick any start and end date you want.
*   **Today**: Shows only today’s data.
*   **This Week to Date**: From the start of this week up to today.
*   **This Month to Date**: From the start of this month up to today.
*   **This Quarter to Date**: From the start of this quarter (3-month period) up to today.
*   **This Year to Date**: From January 1 (or start of the financial year) up to today.
*   **Last Week**: Data from the full previous week.
*   **Last Month (Default)**: Data from the full previous month.
*   **Last Quarter**: Data from the full previous quarter.
*   **Last Year**: Data from the full previous year.
#316
**Functional Requirements Document (FRD) - Profit and Loss Module** > **4\. Field Details & Validations** > **4.2 Financial KPI Fields**
~247 tok
### **4.2 Financial KPI Fields**

**Field Name**

**Type**

**Required**

**Validation Rules**

**Description**

**Calculation Source**

Total Profit

Currency

Yes

Calculated field, can be negative

Net profit for selected period

Income - Total Expenses

Total Income

Currency

Yes

Must be ≥ 0, sum of all incoming revenue

All incoming money from clients

Client Payments (Billing Module)

Total Expenses

Currency

Yes

Must be ≥ 0, sum of all outgoing costs

All outgoing money flow

Contractor Payments + COGS + OPEX

Profit Percentage Change

Percentage

Conditional

Comparison with same period last year

Year-over-year profit change

Current Period vs Previous Year

Income Percentage Change

Percentage

Conditional

Comparison with same period last year

Year-over-year income change

Current Period vs Previous Year

Expense Percentage Change

Percentage

Conditional

Comparison with same period last year

Year-over-year expense change

Current Period vs Previous Year
#317
**Functional Requirements Document (FRD) - Profit and Loss Module** > **4\. Field Details & Validations** > **4.3 Summary Breakdown
~9 tok
### **4.3 Summary Breakdown  
  
**
#318
**Functional Requirements Document (FRD) - Profit and Loss Module** > **4\. Field Details & Validations** > **Category**
~4 tok
### **Category**
#319
**Functional Requirements Document (FRD) - Profit and Loss Module** > **4\. Field Details & Validations** > **Definition**
~5 tok
### **Definition**
#320
**Functional Requirements Document (FRD) - Profit and Loss Module** > **4\. Field Details & Validations** > Total Income
~4 tok
### Total Income
#321
**Functional Requirements Document (FRD) - Profit and Loss Module** > **4\. Field Details & Validations** > Money earned from business activities (excluding sales tax). With breakdown entries supporting the sum total figure
~30 tok
### Money earned from business activities (excluding sales tax). With breakdown entries supporting the sum total figure
#322
**Functional Requirements Document (FRD) - Profit and Loss Module** > **4\. Field Details & Validations** > Cost of Goods Sold (COGS)
~7 tok
### Cost of Goods Sold (COGS)
#323
**Functional Requirements Document (FRD) - Profit and Loss Module** > **4\. Field Details & Validations** > Direct costs of making or delivering what was sold.
~28 tok
### Direct costs of making or delivering what was sold.  
With breakdown entries supporting the sum total figure
#324
**Functional Requirements Document (FRD) - Profit and Loss Module** > **4\. Field Details & Validations** > Gross Profit
~4 tok
### Gross Profit
#325
**Functional Requirements Document (FRD) - Profit and Loss Module** > **4\. Field Details & Validations** > Income left after subtracting COGS.
~24 tok
### Income left after subtracting COGS.  
With breakdown entries supporting the sum total figure
#326
**Functional Requirements Document (FRD) - Profit and Loss Module** > **4\. Field Details & Validations** > Total Expenses
~5 tok
### Total Expenses
#327
**Functional Requirements Document (FRD) - Profit and Loss Module** > **4\. Field Details & Validations** > All other business costs, not including COGS.
~27 tok
### All other business costs, not including COGS.  
With breakdown entries supporting the sum total figure
#328
**Functional Requirements Document (FRD) - Profit and Loss Module** > **4\. Field Details & Validations** > Net Profit (Loss)
~5 tok
### Net Profit (Loss)
#329
**Functional Requirements Document (FRD) - Profit and Loss Module** > **4\. Field Details & Validations** > Final result after subtracting expenses from gross profit.
~30 tok
### Final result after subtracting expenses from gross profit.  
With breakdown entries supporting the sum total figure
#330
**Functional Requirements Document (FRD) - Profit and Loss Module** > **4\. Field Details & Validations** >
~1 tok
###
#331
**Functional Requirements Document (FRD) - Profit and Loss Module** > **4\. Field Details & Validations** > Categories can expand/collapse → first row = total, inside rows = details.
~20 tok
### Categories can expand/collapse → first row = total, inside rows = details.
#332
**Functional Requirements Document (FRD) - Profit and Loss Module** > **4\. Field Details & Validations** > Totals and breakdowns depend on the date filter selected.
~15 tok
### Totals and breakdowns depend on the date filter selected.
#333
**Functional Requirements Document (FRD) - Profit and Loss Module** > **4\. Field Details & Validations** > Output can be exported/printed in Excel in the same format.
~16 tok
### Output can be exported/printed in Excel in the same format.
#334
**Functional Requirements Document (FRD) - Profit and Loss Module** > **5\. Success Message Handling**
~37 tok
## **5\. Success Message Handling**

**Validation Scenario**

**Success Message**

Excel export completed

"Financial data exported successfully."
#335
**Functional Requirements Document (FRD) - Profit and Loss Module** > **6\. Error Message Handling**
~93 tok
## **6\. Error Message Handling**

**Field**

**Validation Scenario**

**Error Message**

Date Selection

Future date selected

"Cannot select future dates for financial reporting."

Date Range

End date before start date

"End date must be after start date."

Data Loading

No financial data for the selected period

"No financial data available for the selected period."
#336
**Functional Requirements Document (FRD) - Profit and Loss Module** > **7\. Functional Logic**
~7 tok
## **7\. Functional Logic**
#337
**Functional Requirements Document (FRD) - Profit and Loss Module** > **7\. Functional Logic** > **Financial Calculation Engine**
~163 tok
### **Financial Calculation Engine**

*   **Profit Calculation:** Total Income - Total Expenses (including contractor payments, COGS, and operational expenses)
*   **Year-over-Year Comparison:** Compare the selected period with the same period in previous year, display "N/A" if no previous year data exists
*   **Project-Level Calculations:** Individual project profit/loss calculated from project-specific income and allocated expenses
*   **Real-Time Updates:** Financial data updated via batch processing every hour when source data changes
*   **Currency Precision:** All financial calculations maintained to 2 decimal places with proper rounding
#338
**Functional Requirements Document (FRD) - Profit and Loss Module** > **7\. Functional Logic** > **Chart Visualization Logic**
~163 tok
### **Chart Visualization Logic**

*   **Time Granularity Adjustment:** Chart automatically adjusts granularity based on selected time period (daily for weeks, weekly for months, monthly for quarters/years)
*   **Multi-Metric Display:** Users can toggle between Profit only (default) or Profit + Income + Expenses view
*   **Interactive Data Points:** Clicking chart points reveals detailed financial breakdown for specific time periods
*   **Trend Analysis:** Chart displays trend lines for selected metrics with appropriate scaling and formatting
*   **Performance Optimization:** Loading indicators displayed for datasets exceeding 500 data points
#339
**Functional Requirements Document (FRD) - Profit and Loss Module** > **7\. Functional Logic** > **Data Source Integration**
~126 tok
### **Data Source Integration**

*   **Income Sources:** All incoming money from clients via Billing/Client Invoices module
*   **Expense Sources:**
    *   Contractor payments from Contractor Invoices module
    *   Cost of Goods Sold from direct project expenses
    *   Operational expenses from Expenses module
*   **Data Synchronization:** Data refreshes on page refresh to maintain current financial information
*   **Data Validation:** Cross-module validation to ensure financial data consistency
#340
**Functional Requirements Document (FRD) - Profit and Loss Module** > **7\. Functional Logic** > **Access Control and Filtering**
~105 tok
### **Access Control and Filtering**

*   **Role-Based Data Access:** PM users see only financial data for assigned projects
*   **Project-Specific Calculations:** PM role calculations limited to the assigned project scope
*   **Full Company View:** Agency Owner and Admin see aggregated company-wide financial data
*   **Dynamic Filtering:** All charts, KPIs, and summaries automatically filter based on user permissions
#341
**Functional Requirements Document (FRD) - Profit and Loss Module** > **8\. Edge Cases**
~172 tok
## **8\. Edge Cases**

**Scenario**

**Expected Behavior**

No financial data for the selected period

Display "No data available" message with option to select a different period

Year-over-year comparison with no previous year data

Show "N/A" instead of percentage change to avoid misleading metrics

Very large dataset (2+ years of daily data)

Implement pagination for the summary section (50+ projects), show loading indicators, and warn the user of a large export

Custom date range exceeding the maximum recommended period

Display a warning message about the potential performance impact

Export process interrupted or failed

Provide a retry option with a detailed error message
#342
**Functional Requirements Document (FRD) - Profit and Loss Module** > **9\. Chart and Visualization Specifications**
~12 tok
## **9\. Chart and Visualization Specifications**
#343
**Functional Requirements Document (FRD) - Profit and Loss Module** > **9\. Chart and Visualization Specifications** > **9.1 Main Financial Trend Chart**
~166 tok
### **9.1 Main Financial Trend Chart**

**Feature**

**Specification**

**Description**

Chart Type

Multi-line chart

Primary visualization for financial trends

Default View

Profit line only

Single metric view for clarity

Toggle Option

Profit + Income + Expenses

Three-line view for comprehensive analysis

Interactive Points

Click for detailed breakdown

Drill-down capability for specific periods

Y-Axis

Currency formatting

Proper dollar formatting with appropriate scaling

X-Axis

Time period labels

Clear date/time labels based on granularity

Color Scheme

Profit (Blue), Income (Green), Expenses (Red)

Consistent color coding across interface
#344
**Functional Requirements Document (FRD) - Profit and Loss Module** > **9\. Chart and Visualization Specifications** > **9.2 KPI Cards Layout**
~53 tok
### **9.2 KPI Cards Layout**

**Metric**

**Features**

Profit

Amount, percentage change, trend indicator

Income

Amount, percentage change, trend indicator

Expenses

Amount, percentage change, trend indicator
#345
**Functional Requirements Document (FRD) - Profit and Loss Module** > **10\. Test Cases**
~6 tok
## **10\. Test Cases**
#346
**Functional Requirements Document (FRD) - Profit and Loss Module** > **11\. Acceptance Criteria**
~420 tok
## **11\. Acceptance Criteria**

*   **Role-Based Access Control:** PM users restricted to assigned project financial data only, Owner/Admin sees full company financials
*   **Date Filter Functionality:** All preset options and custom date ranges work correctly with proper validation
*   **Financial Calculation Accuracy:** Profit = Income - Expenses calculations are accurate across all time periods and user roles
*   **Year-over-Year Comparisons:** Percentage changes calculated correctly, "N/A" displayed when no previous year data exists
*   **Chart Visualization:** An Interactive chart displays financial trends with appropriate granularity and user interaction capabilities
*   **Summary Section:** Project-level breakdown with expand/collapse functionality and pagination for large datasets
*   **Export Capabilities:** Excel export formats work correctly with summary data only (no chart visualization)
*   **Print Functionality:** Professional print layout generates correctly formatted financial summaries
*   **Performance Optimization:** Loading indicators and pagination implemented for large datasets (50+ projects, 500+ data points)
*   **Error Handling:** Appropriate error messages for missing data, validation failures, and system errors
*   **Data Integration:** Real-time financial data from Billing, Contractor Invoices, and Expenses modules
*   **Mobile Responsiveness:** Interface adapts correctly to different screen sizes while maintaining functionality
*   **Data Persistence:** Selected filters and preferences maintained during user session
*   **Security Compliance:** Financial data access properly restricted based on user roles and permissions
#347
**Functional Requirements Document (FRD) - Profit and Loss Module** > **14\. Dependencies**
~165 tok
## **14\. Dependencies**

**Module/System**

**Dependency Type**

**Impact if Unavailable**

Billing/Client Invoices Module

Critical Data Dependency

Cannot calculate income; profit calculations are incomplete

Contractor Invoices Module

Critical Data Dependency

Cannot calculate contractor expenses, profit calculations inaccurate

Expenses Module

Critical Data Dependency

Cannot calculate operational expenses, missing COGS and OPEX data

Project Management Module

Data Dependency

Cannot provide project-level breakdowns, PM role restrictions fail

Authentication System

Security Dependency

Role-based access control fails, data security compromised
#348
**Functional Requirements Document (FRD) - Profit and Loss Module** > **15\. References**
~15 tok
## **15\. References**

*   Profit and Loss tab Figma

Taxes
#349
Note: Need to confirm with the client
~10 tok
# Note: Need to confirm with the client
#350
**Functional Requirements Document (FRD) - Taxes Sub module**
~16 tok
# **Functional Requirements Document (FRD) - Taxes Sub module**
#351
**Functional Requirements Document (FRD) - Taxes Sub module** > **1\. Module Overview**
~110 tok
## **1\. Module Overview**

**Module Name:** Taxes Module (Sub-module within Finance Management)  
**Purpose:** Generate country-specific tax reporting documents based on agency income and contractor payment data for compliance and filing purposes  
**Business Goal:** Provide automated tax compliance reporting, streamline tax document preparation, and ensure accurate financial data for tax filing requirements across supported countries
#352
**Functional Requirements Document (FRD) - Taxes Sub module** > **2\. User Roles & Permissions**
~138 tok
## **2\. User Roles & Permissions**

**Role**

**Description**

**Key Permissions**

Agency Owner

Business owner with full financial oversight

Full access to all tax reports, can view/download reports, configure country settings, access sales tax reports

Admin

System administrator with financial access

Full access to all tax reports, can view/download reports, configure country settings, access sales tax reports

Project Manager (PM)

Project-specific management role

**No Access** - Tax reports are restricted to Owner and Admin roles only
#353
**Functional Requirements Document (FRD) - Taxes Sub module** > **3\. User Flow**
~5 tok
## **3\. User Flow**
#354
**Functional Requirements Document (FRD) - Taxes Sub module** > **3\. User Flow** > **Primary Flow - Tax Report Generation:**
~148 tok
### **Primary Flow - Tax Report Generation:**

1.  **Module Access:** User (Owner/Admin) navigates to Finance Management → Taxes
2.  **Country Selection:** System auto-detects country (currently US, expanding to Canada), user can manually change selection
3.  **Year Selection:** System defaults to the current year; user can select different tax years from the dropdown
4.  **Report Generation:** The System automatically generates a year-to-date tax report using contractor payment data
5.  **Download Action:** User clicks "Download Report" to generate a CSV file with 1099-NEC support data
#355
**Functional Requirements Document (FRD) - Taxes Sub module** > **3\. User Flow** > **Secondary Flow - Sales Tax Report Access:**
~78 tok
### **Secondary Flow - Sales Tax Report Access:**

1.  **Sales Tax Navigation:** User clicks "View Sales Tax Reports" button
2.  **Reports Module Redirect:** System navigates to Reports module, Sales Tax Report section
3.  **Detailed Analysis:** User accesses comprehensive sales tax calculations and breakdowns
#356
**Functional Requirements Document (FRD) - Taxes Sub module** > **4\. Field Details & Validations**
~10 tok
## **4\. Field Details & Validations**
#357
**Functional Requirements Document (FRD) - Taxes Sub module** > **4\. Field Details & Validations** > **4.1 Tax Report Configuration Fields**
~118 tok
### **4.1 Tax Report Configuration Fields**

**Field Name**

**Type**

**Required**

**Validation Rules**

**Description**

Country Selection

Dropdown

Yes

Values: United States, Canada (future expansion)

Country for tax reporting compliance

Tax Year

Dropdown

Yes

Current year default, historical years available

Year for which tax report is generated

Report Type

Static

Yes

Automatically determined by country selection

Type of tax document (1099-NEC for US)
#358
**Functional Requirements Document (FRD) - Taxes Sub module** > **4\. Field Details & Validations** > **4.2 Contractor Tax Data Fields (Auto-populated from Contractor Profiles)**
~132 tok
### **4.2 Contractor Tax Data Fields (Auto-populated from Contractor Profiles)**

**Field**

**Description**

Contractor Name

Full name,  
autopopulated from the system

Contractor Email

Optional, for reference  
autopopulated from the system

Contractor Address

If collected  
autopopulated from the system

Contractor Tax ID (TIN/SSN)

autopopulated from the system

Total Paid (USD)

For the tax year, autopopulated from the system

First & Last Payment Date

Useful for an activity timeline  
Autopopulated from the system
#359
**Functional Requirements Document (FRD) - Taxes Sub module** > **4\. Field Details & Validations** > **
~44 tok
### **  
5\. Success Message Handling**

**Validation Scenario**

**Success Message**

Tax report downloaded successfully

"Your tax report has been downloaded successfully."
#360
**Functional Requirements Document (FRD) - Taxes Sub module** > **6\. Error Message Handling**
~134 tok
## **6\. Error Message Handling**

**Field**

**Validation Scenario**

**Error Message**

Report Generation

Report generation system failure

"Unable to generate tax report. Please try again later."

Data Validation

Missing critical contractor information

"Some contractor profiles are missing required tax information. Reports may be incomplete."

Year Selection

Invalid year selected

"Please select a valid tax year."

File Download

Download failure

"Unable to download report file. Please check your connection and try again."
#361
**Functional Requirements Document (FRD) - Taxes Sub module** > **7\. Functional Logic**
~7 tok
## **7\. Functional Logic**
#362
**Functional Requirements Document (FRD) - Taxes Sub module** > **7\. Functional Logic** > **Data Aggregation Logic**
~161 tok
### **Data Aggregation Logic**

*   **Contractor Payment Calculation:** System aggregates all payments made to each contractor during the selected tax year from the Contractor Invoices module.
*   **Income Calculation:** Total agency income calculated from all client payments received during the selected tax year.
*   **Year-to-Date Reporting:** For the current year, the report includes data from January 1st through the download date.
*   **Historical Reporting:** For previous years, the report includes complete calendar year data
*   **Missing Data Handling:** Fields with missing contractor information display "--" in generated reports
#363
**Functional Requirements Document (FRD) - Taxes Sub module** > **7\. Functional Logic** > **Country-Specific Compliance**
~107 tok
### **Country-Specific Compliance**

*   **United States:** Generates 1099-NEC support report format with required contractor information
*   **Canada (Future):** Will support Canadian tax compliance formats when implemented
*   **Auto-Detection:** The System automatically detects the agency country based on profile settings
*   **Manual Override:** Users can manually select a different country for specific reporting needs
#364
**Functional Requirements Document (FRD) - Taxes Sub module** > **7\. Functional Logic** > **Report Generation Process**
~111 tok
### **Report Generation Process**

*   **Real-Time Data:** Reports generated using the most current data available at the time of download
*   **Multiple Downloads:** Users can download the same report multiple times without restrictions
*   **Data Persistence:** Generated reports remain accessible and downloadable indefinitely
*   **Format Specification:** 1099-NEC support reports generated in CSV format for easy import into tax software
#365
**Functional Requirements Document (FRD) - Taxes Sub module** > **7\. Functional Logic** > **Access Control and Security**
~93 tok
### **Access Control and Security**

*   **Role Restriction:** Only Agency Owner and Admin roles can access tax module
*   **PM Exclusion:** Project Managers have no access to any tax reporting functionality
*   **Data Retention:** All tax data and reports stored permanently in system
*   **No Audit Trail:** System does not track download history or user access patterns
#366
**Functional Requirements Document (FRD) - Taxes Sub module** > **8\. Edge Cases**
~320 tok
## **8\. Edge Cases**

**Scenario**

**Expected Behavior**

Contractor profile missing required tax information

Report generation continues, missing fields display "--", user receives warning message

No contractor payments made in selected year

Report shows "No data available" message, empty report can still be downloaded

Selected year has no client income data

Agency income fields show $0.00, contractor data still displayed if available

Report generation fails due to system error

User receives error message "Unable to generate tax report. Please try again later"

User selects future year for reporting

System prevents selection, shows validation error for invalid year

Large number of contractors causing performance issues

System maintains functionality, may show loading indicator for extended processing time

Contractor deleted after payments made

Contractor data preserved in tax reports using historical payment records

Multiple currencies in payment data

All amounts converted to USD for reporting purposes

Partial year reporting for first year of operation

Report includes only actual operating period data with appropriate date ranges

User attempts to access without proper permissions

System shows access denied message, redirects to dashboard
#367
**Functional Requirements Document (FRD) - Taxes Sub module** > **9\. Report Format Specifications**
~10 tok
## **9\. Report Format Specifications**
#368
**Functional Requirements Document (FRD) - Taxes Sub module** > **9\. Report Format Specifications** > **9.1 1099-NEC Support Report (CSV Format)**
~184 tok
### **9.1 1099-NEC Support Report (CSV Format)**

**Column Name**

**Data Type**

**Description**

**Source**

Contractor\_Name

Text

Full legal name

Contractor Profile

Contractor\_Email

Text

Email address or "--"

Contractor Profile

Contractor\_Address

Text

Complete mailing address or "--"

Contractor Profile

Tax\_ID

Text

TIN/SSN or "--"

Contractor Profile

Total\_Paid\_USD

Number

Total payments in selected year

Payment History

First\_Payment\_Date

Date

First payment date (MM/DD/YYYY)

Payment History

Last\_Payment\_Date

Date

Last payment date (MM/DD/YYYY)

Payment History

Reporting\_Year

Number

Tax year (YYYY)

User Selection

Report\_Generated\_Date

Date

Download date (MM/DD/YYYY)

System Generated
#369
**Functional Requirements Document (FRD) - Taxes Sub module** > **10\. Test Cases**
~6 tok
## **10\. Test Cases**
#370
**Functional Requirements Document (FRD) - Taxes Sub module** > **11\. Acceptance Criteria**
~259 tok
## **11\. Acceptance Criteria**

*   **Access Control:** Only Agency Owner and Admin users can access the Taxes module; PM users receive an access denied message
*   **Country Support:** System supports United States tax reporting with CSV format 1099-NEC support reports
*   **Year Selection:** Current year selected by default, historical years available in dropdown
*   **Data Aggregation:** Reports accurately aggregate all contractor payments and agency income for the selected year
*   **Missing Data Handling:** Reports generate successfully even with incomplete contractor information, showing "--" for missing fields
*   **Download Functionality:** Users can download CSV reports multiple times without restrictions
*   **Sales Tax Integration:** "View Sales Tax Reports" button successfully navigates to Reports module
*   **Error Handling:** Appropriate error messages for report generation failures, access violations, and data issues
*   **Report Format:** CSV reports include all required fields for tax compliance purposes
#371
**Functional Requirements Document (FRD) - Taxes Sub module** > **12\. Dependencies**
~133 tok
## **12\. Dependencies**

**Module/System**

**Impact if Unavailable**

Contractor Invoices Module

Cannot calculate contractor payments, reports incomplete or unavailable

Client Invoices/Billing Module

Cannot calculate agency income, financial summaries incomplete

Contractor Profiles

Cannot populate contractor information, tax compliance data missing

Reports Module

Sales Tax Reports link non-functional, reduces user workflow efficiency

Authentication System

Access control fails, unauthorized users may access tax data
#372
**Functional Requirements Document (FRD) - Taxes Sub module** > **13\. References**
~25 tok
## **13\. References**

*   Figma design

  

Deprecated Versions

Contractor Invoices\_Deprecated
#373
**Functional Requirements Document (FRD) - Contractor Invoices**
~17 tok
# **Functional Requirements Document (FRD) - Contractor Invoices**
#374
**1\. Module Overview**
~236 tok
# **1\. Module Overview**

*   **Module Name:** Contractor Invoices
*   **Purpose:** The Contractor Invoices module enables agency owners and admins to manage, review, and process payments for invoices submitted by contractors for work completed on project events. It provides a centralized view of all contractor invoices across multiple status states, supports both online payments via Stripe ACH and manual payment recording, and integrates with QuickBooks for expense tracking.
*   **Business Goal:** Streamline the contractor payment workflow by providing real-time visibility into invoice statuses, enabling secure online payments through Stripe ACH bank transfers, supporting flexible manual payment recording for offline methods, and maintaining accurate financial records through QuickBooks integration. This module ensures contractors are paid accurately and on time while giving agencies complete control over their outgoing payments.
#375
**1\. Module Overview** > **2\. User Roles & Permissions**
~46 tok
## **2\. User Roles & Permissions**

Refer- Click Here

**Note:** Agency Admins cannot initiate online ACH payments or retry failed payments. Only Agency Owners have these capabilities.
#376
**1\. Module Overview** > **3\. User Flow**
~5 tok
## **3\. User Flow**
#377
**1\. Module Overview** > **3\. User Flow** > **3.1 Navigation Path**
~73 tok
### **3.1 Navigation Path**

Primary Navigation: **Finances → Contractor Invoices**

Alternative Entry Points:

*   From Project Detail → View contractor invoices for that project
*   From Event Detail → View contractor invoices for that event
*   From Dashboard notifications (if implemented)
#378
**1\. Module Overview** > **3\. User Flow** > **3.2 Primary User Flow - Viewing Invoices**
~273 tok
### **3.2 Primary User Flow - Viewing Invoices**

1.  **User navigates to Contractor Invoices**
    *   System loads the Contractor Invoices page
    *   System checks for prerequisites (brands, projects, events, contractor assignments)
    *   If prerequisites missing, display appropriate empty state with CTA
    *   If prerequisites met but no invoices, display "No contractor invoices yet" message
    *   If invoices exist, display Unpaid tab by default with invoice list
2.  **User views invoice list**
    *   System displays invoices in tabular format with columns specific to the active tab
    *   Each row shows contractor avatar, name, issued date, status, project, amount, and available actions
    *   User can sort by clicking column headers
    *   User can filter using the Filters panel (funnel icon)
3.  **User switches between status tabs**
    *   System updates the list to show only invoices matching the selected status
    *   Columns adjust based on tab requirements
    *   Filters persist across tab switches
    *   Sorting preferences maintained within session
#379
**1\. Module Overview** > **3\. User Flow** > **3.3 User Flow - Online Payment (Agency Owner Only)**
~394 tok
### **3.3 User Flow - Online Payment (Agency Owner Only)**

1.  **User clicks "Pay" button on Unpaid invoice**
    *   System opens "Pay Contractor" modal
    *   Modal displays contractor info, project, issue date, and amount (editable)
    *   System checks if agency has configured funding bank account
2.  **If agency bank account NOT configured:**
    *   Modal shows "No payment method set up" message
    *   Display "Add Payment Method" button
    *   "Pay Contractor" button is disabled
    *   User clicks "Add Payment Method" → redirected to Agency Settings → Finances
3.  **If agency bank account IS configured:**
    *   Modal shows bank account info (e.g., "Emma Taylor Company - Bank account ending in 6021")
    *   "Pay Contractor" button is enabled
4.  **System checks if contractor has payout bank account configured**
    *   If NOT configured: Display warning message "Contractor has not set up their bank account for payouts"
    *   Payment cannot proceed until contractor adds bank details
5.  **User confirms payment**
    *   User can adjust amount if needed (editable field)
    *   User clicks "Pay Contractor"
    *   System initiates Stripe ACH payout
    *   Invoice status changes: **Unpaid → Processing**
    *   Invoice moves to Processing tab
    *   Success message displayed
6.  **Payment processing completes**
    *   Stripe webhook received
    *   If successful: Status changes **Processing → Paid**, moves to Paid tab, QB sync triggered
    *   If failed: Status changes **Processing → Failed**, moves to Failed tab with failure reason
#380
**1\. Module Overview** > **3\. User Flow** > **3.4 User Flow - Manual Payment (Mark as Paid)**
~203 tok
### **3.4 User Flow - Manual Payment (Mark as Paid)**

1.  **User clicks "Mark as Paid" button on Unpaid invoice**
    *   System opens "Mark as Paid" modal
    *   Modal displays confirmation message: "You are about to mark this invoice as paid. Do you want to continue?"
2.  **User fills in payment details**
    *   Amount field (pre-filled with invoice amount, editable)
    *   Payment Method dropdown (required): Cash, Check, Zelle, PayPal, Venmo, Google Pay, Apple Pay, Other
    *   Note field (optional): Text area for internal notes
3.  **User confirms action**
    *   User clicks "Mark as Paid"
    *   System validates required fields
    *   Invoice status changes: **Unpaid → Paid**
    *   Invoice moves to Paid tab immediately
    *   QuickBooks sync triggered
    *   Success message displayed
#381
**1\. Module Overview** > **3\. User Flow** > **3.5 User Flow - Retry Failed Payment (Agency Owner Only)**
~161 tok
### **3.5 User Flow - Retry Failed Payment (Agency Owner Only)**

1.  **User views Failed tab**
    *   System displays failed invoices with failure reasons from Stripe
    *   Each row shows failure date and specific reason (e.g., "Card Declined", "Insufficient Funds")
2.  **User clicks Retry Payment icon**
    *   System initiates new Stripe ACH payout attempt
    *   Invoice status changes: **Failed → Processing**
    *   Invoice moves to Processing tab
    *   System awaits new webhook response
3.  **Retry result**
    *   If successful: **Processing → Paid**
    *   If failed again: **Processing → Failed** with new failure reason
#382
**1\. Module Overview** > **3\. User Flow** > **3.6 User Flow - View Invoice Details**
~143 tok
### **3.6 User Flow - View Invoice Details**

1.  **User clicks "View Invoice" button**
    *   System opens PDF viewer in modal/overlay
    *   Modal displays invoice PDF with contractor name, project, and date in header
    *   Print and Download buttons available in top right
    *   Zoom controls available (+, -, percentage dropdown)
    *   Back arrow to close modal
2.  **User downloads invoice**
    *   User clicks "Download" button
    *   PDF file downloads to user's device
    *   Filename format: "\[Contractor Name\] - \[Project Name\] (\[Issue Date\]).pdf"
#383
**1\. Module Overview** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#384
**1\. Module Overview** > **4\. Functional Logic** > **4.1 Empty State Logic (Hierarchical Empty State Priority)**
~318 tok
### **4.1 Empty State Logic (Hierarchical Empty State Priority)**

The Contractor Invoices module depends on a complete hierarchy of data. Empty states are displayed based on priority order, showing only the highest-priority missing prerequisite.

**Priority Order:**

**Priority**

**Condition**

**Message**

**CTA Button**

**Action**

1

No Brands exist

"Create a brand to manage contractor invoices."

Create Brand

Navigate to Brand creation

2

No Projects exist

"Create a project to start tracking contractor work and invoices."

Create Project

Navigate to Project creation

3

No Events exist

"Create an event to allow contractors to upload invoices."

Create Event

Navigate to Event creation

4

No Contractors Assigned

"No contractors are assigned to any events yet."

Assign Contractor

Navigate to Event → Contractor assignment

5

No Invoices Uploaded

"No contractor invoices yet."

None

Subtext: "Contractors will appear here once they submit invoices for event work."

**Display Rules:**

1.  Check conditions in priority order
2.  Display only the first unmet condition
3.  Empty states appear only after data fully loads (no loading flicker)
4.  Filters remain accessible even during empty states
5.  Pagination does not create false empty states
#385
**1\. Module Overview** > **4\. Functional Logic** > **4.1.1 Tab-Level Empty States**
~69 tok
### **4.1.1 Tab-Level Empty States**

When invoices exist but specific tabs have no entries:

**Tab**

**Message**

Unpaid

"No unpaid contractor invoices."

Processing

"No invoices are currently processing."

Paid

"No paid invoices yet."

Failed

"No failed invoices found."
#386
**1\. Module Overview** > **4\. Functional Logic** > **4.1.2 Filter-Induced Empty State**
~55 tok
### **4.1.2 Filter-Induced Empty State**

When active filters return zero results:

*   Message: "No invoices match your selected filters."
*   CTA: "Clear Filters" button
*   Action: Resets all filters to default state
#387
**1\. Module Overview** > **4\. Functional Logic** > **4.2 Status Definitions & Lifecycle**
~440 tok
### **4.2 Status Definitions & Lifecycle**

**Invoice Statuses:**

**Status**

**Definition**

**Unpaid**

Invoice uploaded by contractor; no payment attempt initiated (no ACH payout, no manual mark as paid)

**Processing**

Stripe ACH payout initiated; awaiting final confirmation from Stripe

**Paid**

ACH payout successfully completed (confirmed by Stripe webhook) OR Agency manually marked as paid with offline method

**Failed**

ACH payout failed due to bank/Stripe error

**Status Transitions:**

UNPAID ─────┬──────────────────► PROCESSING ─────┬──────► PAID

│ (Pay button - ▲ │ (Stripe webhook

│ Stripe ACH) │ │ success)

│ │ │

│ │ └──────► FAILED

│ │ (Stripe webhook

│ │ failure)

│ │ │

│ └──────────────────────────────┘

│ (Retry Payment)

│

└──────────────────────────────────────────────────► PAID

(Mark as Paid - manual payment)

**Transition Rules:**

1.  **Unpaid → Processing**
    *   Trigger: Agency Owner clicks "Pay" and confirms (Stripe ACH initiated)
    *   System action: Create Stripe payout request, update status, move to Processing tab
2.  **Unpaid → Paid**
    *   Trigger: Agency Owner/Admin clicks "Mark as Paid" and confirms
    *   System action: Update status with payment method and note, move to Paid tab, trigger QB sync
3.  **Processing → Paid**
    *   Trigger: Stripe webhook confirms successful ACH payout
    *   System action: Update status, move to Paid tab, trigger QB sync
4.  **Processing → Failed**
    *   Trigger: Stripe webhook returns failure
    *   System action: Update status with failure reason, move to Failed tab
5.  **Failed → Processing**
    *   Trigger: Agency Owner clicks "Retry Payment"
    *   System action: Create new Stripe payout request, update status, move to Processing tab
#388
**1\. Module Overview** > **4\. Functional Logic** > **4.3 Invoice-Event-Project Relationship**
~142 tok
### **4.3 Invoice-Event-Project Relationship**

**Data Hierarchy:**

Brand

└── Project

└── Event

└── Contractor Assignment (with agreed fee)

└── Contractor Invoice(s)

**Relationship Rules:**

1.  Every Contractor Invoice MUST be linked to exactly one Event
2.  Each Event belongs to exactly one Project
3.  Each Project belongs to exactly one Brand
4.  A contractor can have multiple invoices for the same event (partial billing)
5.  A contractor can be assigned to multiple events within the same project
6.  Multiple contractors can be assigned to the same event
#389
**1\. Module Overview** > **4\. Functional Logic** > **4.4 Contractor Fee Tracking & Overage Warning**
~324 tok
### **4.4 Contractor Fee Tracking & Overage Warning**

**Fee Tracking Logic:**

Each contractor has an agreed fee per event (set during contractor assignment). The system tracks the cumulative total of all invoices submitted by that contractor for that specific event.

**Calculation:**

Total Invoiced = SUM(all invoice amounts for contractor + event combination)

Assigned Fee = Contractor's agreed fee for that event

Overage = Total Invoiced - Assigned Fee (when positive)

**Overage Warning Rules:**

1.  System does NOT block invoices that exceed the assigned fee
2.  When Total Invoiced > Assigned Fee:
    *   Display warning icon (⚠️) next to the amount in list view
    *   Show tooltip on hover: "Total invoiced (X) exceeds assigned contractor fee (X) exceeds assigned contractor fee ( X) exceeds assigned contractor fee (Y)"
    *   Display warning banner in "Pay Contractor" modal
    *   Notify both agency owner and contractor (optional notification)
3.  Warning appears in:
    *   Amount column in list view (warning icon)
    *   "Pay Contractor" modal (warning banner with details)
4.  Valid reasons for overage (not an error):
    *   Scope increased after initial agreement
    *   Event duration extended
    *   Additional services requested
    *   Negotiated change orders
#390
**1\. Module Overview** > **4\. Functional Logic** > **4.5 Tab-Specific Column Configuration**
~361 tok
### **4.5 Tab-Specific Column Configuration**

**Unpaid Tab:**

**Column**

**Sortable**

**Description**

Contractor

Yes

Avatar + full name

Issued

Yes

Date invoice was submitted

Status

Yes

"Unpaid" badge

Project

Yes

Project name (clickable)

Amount

Yes

Invoice amount in USD

Actions

No

Pay, Mark as Paid, View Invoice, More (⋮)

**Processing Tab:**

**Column**

**Sortable**

**Description**

Contractor

Yes

Avatar + full name

Issued

Yes

Date invoice was submitted

Paid

Yes

Date payment was initiated

Payment Method

Yes

"Bank Transfer" (ACH)

Status

Yes

"Processing" badge

Project

Yes

Project name (clickable)

Actions

No

View Invoice, More (⋮)

**Paid Tab:**

**Column**

**Sortable**

**Description**

Contractor

Yes

Avatar + full name

Issued

Yes

Date invoice was submitted

Paid

Yes

Date payment completed

Payment Method

Yes

Bank Transfer, Cash, Check, etc.

Status

Yes

"Paid" badge

QuickBooks

No

Sync status icon (see 4.8)

Project

Yes

Project name (clickable)

Actions

No

View Invoice, More (⋮)

**Failed Tab:**

**Column**

**Sortable**

**Description**

Contractor

Yes

Avatar + full name

Issued

Yes

Date invoice was submitted

Failed Date

Yes

Date + failure reason (e.g., "January 20, 2025 - Card Declined")

Payment Method

Yes

"Bank Transfer" (ACH)

Status

Yes

"Failed" badge

Project

Yes

Project name (clickable)

Actions

No

View Invoice, Retry Payment icon, More (⋮)
#391
**1\. Module Overview** > **4\. Functional Logic** > **4.6 Filtering Logic**
~271 tok
### **4.6 Filtering Logic**

**Filter Panel Components:**

1.  **Date Issued** (Date Picker)
    *   Select date or date range
    *   Filters invoices by submission date
2.  **Brand** (Single-Select Dropdown)
    *   Options: "All Brands" + list of agency brands
    *   Selecting a brand filters the Project list to show only projects under that brand
3.  **Contractor** (Multi-Select with Search)
    *   Searchable list of all contractors
    *   Select one or multiple contractors
    *   Real-time search filtering
4.  **Project** (Multi-Select with Search)
    *   Searchable list of projects
    *   Scoped to selected Brand (if brand filter active)
    *   Select one or multiple projects

**Filter Behavior Rules:**

1.  Filters apply across ALL four status tabs
2.  Filters persist when switching between tabs until manually cleared
3.  Reset button (↻) clears all filters
4.  Brand filter scopes Project dropdown options
5.  Multiple filter conditions use AND logic
6.  Filter-induced empty state shows: "No invoices match your selected filters" with "Clear Filters" CTA
#392
**1\. Module Overview** > **4\. Functional Logic** > **4.7 Sorting Logic**
~159 tok
### **4.7 Sorting Logic**

**Default Sort:** Issued Date (descending - newest first)

**Sortable Columns:**

*   Contractor (alphabetical)
*   Issued Date (chronological)
*   Paid Date (chronological) - Processing/Paid/Failed tabs
*   Failed Date (chronological) - Failed tab only
*   Payment Method (alphabetical)
*   Status (alphabetical)
*   Project (alphabetical)
*   Amount (numerical)

**Sort Behavior:**

1.  Click column header to sort ascending
2.  Click again to sort descending
3.  Sort indicator arrow shows direction (↓ or ↑)
4.  Sorting preferences persist within session
5.  Sorting maintained when switching between tabs
#393
**1\. Module Overview** > **4\. Functional Logic** > **4.8 Pagination**
~92 tok
### **4.8 Pagination**

**Configuration:**

*   Rows per page options: 10, 25, 50, 100
*   Default: 10 rows per page
*   Page indicator format: "1-4 of 4"
*   Navigation: Previous (‹) and Next (›) arrows

**Behavior:**

*   Pagination resets to page 1 when filters change
*   Pagination maintained when sorting changes
*   Each tab maintains its own pagination state
#394
**1\. Module Overview** > **4\. Functional Logic** > **4.9 QuickBooks Integration**
~232 tok
### **4.9 QuickBooks Integration**

**Sync Trigger:** When invoice status changes to "Paid"

**Sync Behavior:**

*   Automatic sync initiated immediately upon status change to Paid
*   Creates expense entry in QuickBooks
*   Both online (ACH) and manual payments sync

**Sync Status Icons (Paid Tab):**

**Icon State**

**Meaning**

**Visual**

Green Checkmark

Successfully synced to QuickBooks

✓ (green)

Grey/Loading

Sync in progress or pending

○ (grey)

Red Warning

Sync failed - requires attention

⚠ (red)

**Failed Sync Handling:**

1.  Display red warning icon in QB column
2.  Show error details on hover
3.  Three-dot menu includes "Sync with QuickBooks" option for manual retry
4.  Admin can manually trigger resync

**Mapping:**

*   Contractor → Vendor in QuickBooks
*   Project → Class/Job (if configured)
*   Invoice Amount → Expense Amount
*   Payment Date → Transaction Date
*   Payment Method → Payment Type
#395
**1\. Module Overview** > **4\. Functional Logic** > **4.10 Three-Dot Menu Actions**
~92 tok
### **4.10 Three-Dot Menu Actions**

**Unpaid Tab:**

*   View Details (opens invoice detail view)
*   Download PDF
*   Sync with QuickBooks (disabled/hidden)

**Processing Tab:**

*   View Details
*   Download PDF

**Paid Tab:**

*   View Details
*   Download PDF
*   Sync with QuickBooks (manual retry if needed)

**Failed Tab:**

*   View Details
*   Download PDF
#396
**1\. Module Overview** > **4\. Functional Logic** > **4.11 Search Functionality**
~122 tok
### **4.11 Search Functionality**

**Global Search Bar:**

*   Located in page header
*   Placeholder: "Search..."
*   Minimum 2 characters to initiate search
*   Real-time filtering as user types

**Searchable Fields:**

*   Contractor name
*   Project name
*   Invoice amount
*   Any other relevant text fields

**Search Behavior:**

*   Searches within current tab only
*   Respects active filters
*   Results update dynamically
*   Clear search to show all invoices (within filters)
#397
**1\. Module Overview** > **5\. Field Details & Validations**
~10 tok
## **5\. Field Details & Validations**
#398
**1\. Module Overview** > **5\. Field Details & Validations** > **5.1 Pay Contractor Modal**
~207 tok
### **5.1 Pay Contractor Modal**

**Field Name**

**Field Type**

**Display Format**

**Validation Rules**

Contractor Info

Display Only

Avatar + Name + Project + Issue Date

Read-only

View Invoice Link

Button

Text link

Opens PDF viewer

Amount

Currency Input

"$X,XXX.XX"

Required, numeric, positive value, pre-filled with invoice amount but editable

Payment Method Display

Display Only

Bank icon + Company Name + "Bank account ending in XXXX"

Shows only if agency bank configured

No Payment Method Warning

Alert Box

"No payment method set up" message

Shows only if agency bank NOT configured

**Modal Actions:**

*   Cancel: Closes modal without action
*   Pay Contractor: Initiates ACH payment (disabled if no payment method)
*   Add Payment Method: Redirects to Agency Settings (shown when no payment method)
#399
**1\. Module Overview** > **5\. Field Details & Validations** > **5.2 Mark as Paid Modal**
~143 tok
### **5.2 Mark as Paid Modal**

**Field Name**

**Field Type**

**Display Format**

**Validation Rules**

Amount

Currency Input

"$X,XXX.XX"

Required, numeric, positive value, pre-filled with invoice amount but editable

Payment Method

Dropdown

Single selection

Required, options: Cash, Check, Zelle, PayPal, Venmo, Google Pay, Apple Pay, Other

Note

Text Area

Multi-line text

Optional, max 500 characters, internal only (not visible to contractor)

**Modal Actions:**

*   Cancel: Closes modal without action
*   Mark as Paid: Updates status to Paid immediately
#400
**1\. Module Overview** > **5\. Field Details & Validations** > **5.3 PDF Viewer Modal**
~139 tok
### **5.3 PDF Viewer Modal**

**Field Name**

**Field Type**

**Display Format**

**Validation Rules**

Header Title

Display Only

"\[Contractor\] - \[Project\] (\[Date\]).pdf"

Read-only

Print Button

Button

Icon + "Print"

Opens system print dialog

Download Button

Button

Icon + "Download"

Downloads PDF file

Zoom Controls

Control Group

"-" button, percentage dropdown, "+" button

Range: 25% - 400%, default 65%

Page Indicator

Display Only

"Page X/Y"

Shows current page of multi-page PDFs

Back Arrow

Button

"←" icon

Closes modal/overlay
#401
**1\. Module Overview** >
~1 tok
##
#402
**1\. Module Overview** > **6\. Error Messages & Notifications**
~10 tok
## **6\. Error Messages & Notifications**
#403
**1\. Module Overview** > **6\. Error Messages & Notifications** > **6.1 Payment Flow Errors**
~237 tok
### **6.1 Payment Flow Errors**

**Scenario**

**Error Message**

**Type**

**Display Location**

Agency bank not configured

"No payment method set up. To pay your contractor, you'll need to add a payment method first."

Warning

Pay Contractor modal

Contractor bank not configured

"Contractor has not set up their bank account for payouts. Please notify the contractor to add their bank details."

Warning

Pay Contractor modal

Amount field empty

"Please enter an amount"

Error

Below Amount field

Amount is zero or negative

"Amount must be greater than $0"

Error

Below Amount field

Amount exceeds invoice

"Payment amount exceeds the invoice amount. Are you sure?"

Warning

Pay Contractor modal (confirmation)

Payment initiation failed

"Unable to initiate payment. Please try again."

Error

Toast notification

Stripe connection error

"Payment service temporarily unavailable. Please try again later."

Error

Toast notification
#404
**1\. Module Overview** > **6\. Error Messages & Notifications** > **6.2 Mark as Paid Errors**
~112 tok
### **6.2 Mark as Paid Errors**

**Scenario**

**Error Message**

**Type**

**Display Location**

Payment method not selected

"Please select a payment method"

Error

Below Payment Method field

Amount field empty

"Please enter an amount"

Error

Below Amount field

Amount is zero or negative

"Amount must be greater than $0"

Error

Below Amount field

Note exceeds character limit

"Note cannot exceed 500 characters"

Error

Below Note field
#405
**1\. Module Overview** > **6\. Error Messages & Notifications** > **6.3 Stripe Failure Reasons (Failed Tab)**
~120 tok
### **6.3 Stripe Failure Reasons (Failed Tab)**

**Stripe Error**

**Display Message**

account\_closed

"Bank Account Closed"

insufficient\_funds

"Insufficient Funds"

invalid\_account\_number

"Invalid Account Number"

bank\_account\_restricted

"Bank Account Restricted"

debit\_not\_authorized

"Debit Not Authorized"

card\_declined

"Card Declined"

invalid\_card\_details

"Invalid Card Details"

payment\_blocked

"Payment Blocked"

generic\_decline

"Payment Declined"
#406
**1\. Module Overview** > **6\. Error Messages & Notifications** > **6.4 Success Notifications**
~127 tok
### **6.4 Success Notifications**

**Action**

**Success Message**

**Type**

Payment initiated

"Payment initiated successfully. Status updated to Processing."

Toast (success)

Payment completed

"Payment completed successfully."

Toast (success)

Mark as paid

"Invoice marked as paid successfully."

Toast (success)

Retry payment initiated

"Payment retry initiated. Status updated to Processing."

Toast (success)

QuickBooks sync success

"Invoice synced to QuickBooks successfully."

Toast (success)
#407
**1\. Module Overview** > **6\. Error Messages & Notifications** > **6.5 Warning Notifications**
~101 tok
### **6.5 Warning Notifications**

**Scenario**

**Warning Message**

**Display Location**

Invoice overage

"Warning: Total invoiced amount (X)exceedsassignedcontractorfee(X) exceeds assigned contractor fee (

X)exceedsassignedcontractorfee(Y) for this event."

Pay Contractor modal + List view tooltip

QuickBooks sync failed

"Failed to sync with QuickBooks. Click to retry."

QB column icon tooltip
#408
**1\. Module Overview** > **7\. Edge Cases & Special Scenarios**
~532 tok
## **7\. Edge Cases & Special Scenarios**

**Scenario**

**Expected Behavior**

**Contractor uploads invoice while agency viewing list**

New invoice appears on next page refresh or real-time update (if implemented)

**Multiple invoices for same contractor-event**

All invoices display separately in list; system tracks cumulative total for overage warning

**Payment initiated but webhook delayed**

Invoice remains in Processing tab; status updates when webhook received

**Stripe webhook received out of order**

System processes based on timestamp; latest status wins

**Agency pays more than invoice amount**

System allows (editable amount field); logs actual payment amount

**Agency pays less than invoice amount**

System allows (editable amount field); partial payment recorded

**Contractor deletes bank account after invoice submission**

Payment attempt fails; displays "Contractor bank account not available" error

**Concurrent payment attempts (race condition)**

First successful request wins; subsequent attempts blocked

**Invoice PDF file corrupted or missing**

Display error message: "Unable to load invoice. Please contact support."

**QuickBooks disconnected**

Sync fails; warning icon displayed; manual retry available when reconnected

**Network connection lost during payment**

Display error; payment status remains unchanged; user can retry

**Browser closed during payment processing**

Payment continues server-side; status updates via webhook

**Filters return partial matches**

Display only invoices matching ALL filter criteria (AND logic)

**User switches tabs rapidly**

Cancel pending requests; load data for active tab only

**Large dataset (1000+ invoices)**

Implement server-side pagination; load only visible page

**Contractor assigned to event but later unassigned**

Existing invoices remain; no new invoices can be created

**Project or Event deleted**

Invoices remain for historical record; display "Deleted Project/Event" indicator

**Same contractor, same event, same amount, same date**

System allows (valid scenario for multiple submissions); each has unique invoice\_id
#409
**1\. Module Overview** > **8\. Acceptance Criteria**
~425 tok
## **8\. Acceptance Criteria**

1.  Users can navigate to Contractor Invoices via Finances menu and view invoices organized in four status tabs (Unpaid, Processing, Paid, Failed)
2.  System displays appropriate empty state based on hierarchical priority when prerequisites are missing (no brands → no projects → no events → no contractors assigned → no invoices)
3.  Agency Owner can initiate online payment via Stripe ACH for unpaid invoices when both agency and contractor bank accounts are configured
4.  System transitions invoice status from Unpaid to Processing when ACH payment is initiated
5.  System automatically updates status from Processing to Paid or Failed based on Stripe webhook response
6.  Agency Owner and Admin can mark invoices as paid manually with payment method selection and optional note
7.  Agency Owner can retry failed payments, which transitions status from Failed back to Processing
8.  Filters persist across tab switches and can be combined (Date Issued, Brand, Contractor, Project)
9.  Sorting is available on all tabs for relevant columns and preferences persist within session
10.  System displays warning when total invoiced amount exceeds contractor's assigned fee for the event
11.  Invoice PDF viewer opens in modal with print and download functionality
12.  QuickBooks sync triggers automatically when invoice status changes to Paid
13.  Three-dot menu provides contextual actions based on invoice status (View Details, Download PDF, Sync with QuickBooks)
14.  All form validations display appropriate error messages before submission is allowed
15.  Status transitions occur automatically based on defined business rules with no manual intervention required
#410
**1\. Module Overview** > **9\. Dependencies**
~290 tok
## **9\. Dependencies**

**Module/System**

**Dependency Type**

**Impact if Unavailable**

Stripe Payment Gateway

Integration

Cannot process online ACH payments; manual payment still functional

Contractor Portal

Service Dependency

Contractors cannot upload invoices; existing invoices remain accessible

Event Management

Data Dependency

Cannot link invoices to events; core functionality broken

Project Management

Data Dependency

Cannot associate invoices with projects; filtering by project fails

Brand Management

Data Dependency

Cannot filter by brand; brand hierarchy broken

QuickBooks Online

Integration

Expense sync fails; financial tracking incomplete

User Authentication

Security Dependency

Cannot verify user permissions; module inaccessible

Contractor Management

Data Dependency

Cannot display contractor information; assignment data unavailable

Agency Settings (Finances)

Configuration Dependency

Cannot configure agency bank account for payouts

File Storage Service

Service Dependency

Cannot store or retrieve invoice PDFs

Notification Service

Service Dependency

Email/in-app notifications for overage warnings fail
#411
**1\. Module Overview** > **10\. References**
~10 tok
## **10\. References**

*   **Design:**
#412
**1\. Module Overview** > **Deprecated —--------------------**
~10 tok
## **Deprecated —--------------------**
#413
**1\. Module Overview** > **4\. Status-Specific Field Details & Validations**
~14 tok
## **4\. Status-Specific Field Details & Validations**
#414
**1\. Module Overview** > **4\. Status-Specific Field Details & Validations** > **4.1 Unpaid Status Tab Fields**
~222 tok
### **4.1 Unpaid Status Tab Fields**

**Field Name**

**Type**

**Validation Rules**

Contractor

Text with Profile

The contractor who submitted the invoice  
  
Links to contractor profile, displays name with profile image

Issued Date

Date

Date the invoice was issued by the contractor. Must be a valid date format, representing the submission date of the invoice.

Status

Static Text

Always displays "Unpaid"

Project

Text

Links to the associated project

Pay CTA

Button

Initiate payment to the contractor  
  
Opens payment popup, requires payment method setup

Mark as Paid CTA

Button

Manually mark the payment as completed  
  
Opens manual payment confirmation pop-up- with fields of amount, payment method,a nd note to be added

View Invoice CTA

Button

Opens invoice details view

Actions

Kebab Menu

Sync to QuickBooks, Copy Invoice Link, Download PDF, Print Invoice
#415
**1\. Module Overview** > **4\. Status-Specific Field Details & Validations** > **4.2 Processing Status Tab Fields**
~187 tok
### **4.2 Processing Status Tab Fields**

**Field Name**

**Type**

**Validation Rules**

Contractor

Text with Profile

The contractor who submitted the invoice  
  
Links to contractor profile, displays name with profile image

Issued Date

Date

Date the invoice was issued by the contractor  
  
Valid date format, original invoice date

Paid Date

Date

Valid date format, date payment was initiated

Payment Method

Text

Method used for payment processing  
  
Values: Bank Transfer, Credit Card, ACH

Status

Static Text

Always displays "Processing"

Project

Text

Links to the associated project

View Invoice CTA

Button

Opens invoice details view

Actions

Kebab Menu

Sync to QuickBooks, Copy Invoice Link, Download PDF, Print Invoice
#416
**1\. Module Overview** > **4\. Status-Specific Field Details & Validations** > **4.3 Paid Status Tab Fields**
~273 tok
### **4.3 Paid Status Tab Fields**

**Field Name**

**Type**

**Required**

**Validation Rules**

Contractor

Text with Profile

Yes

The contractor who submitted the invoice  
  
Links to contractor profile, displays name with profile image

Issued Date

Date

Yes

Date the invoice was issued by the contractor  
  
Valid date format, original invoice date

Paid Date

Date

Yes

Date payment was successfully completed  
  
Valid date format, date payment

Payment Method

Text

Yes

Method used for payment completion  
  
Values: Bank Transfer, Credit Card, ACH, Cash

Status

Static Text

Yes

Always displays "Paid"

Comment

Text

Conditional

Appears when payment is manually marked as paid

Project

Text

Yes

Links to the associated project

View Invoice CTA

Button

Yes

Opens invoice details view with download button

QuickBooks Sync

Icon

Yes

Auto or manual synchronization with QuickBooks  
  
Green tick (auto-synced) or clickable icon (manual sync needed)

Actions

Kebab Menu

Yes

Sync to QuickBooks (if auto sync fails), Copy Invoice Link, Download PDF, Print Invoice
#417
**1\. Module Overview** > **4\. Status-Specific Field Details & Validations** > **4.4 Failed Status Tab Fields**
~220 tok
### **4.4 Failed Status Tab Fields**

**Field Name**

**Type**

**Validation Rules**

Contractor

Text with Profile

The contractor who submitted the invoice & payment failed

  
  
Links to contractor profile, displays name with profile image

Issued Date

Date

Date the invoice was issued by the contractor  
  
Valid date format, original invoice date

Failed Date

DateTime with Reason

Auto-populated by Stripe with a detailed failure reason

Payment Method

Text

Method attempted for payment  
  
Values: Bank Transfer, Credit Card, ACH

Status

Static Text

Always displays "Failed"

Project

Text

Links to the associated project

View Invoice CTA

Button

Opens invoice details view

Retry Payment CTA

Button

Retry payment processing  
  
Opens payment popup for retry attempt

Actions

Kebab Menu

Sync to QuickBooks, Copy Invoice Link, Download PDF, Print Invoice
#418
**1\. Module Overview** > **5\. Popup Specifications**
~8 tok
## **5\. Popup Specifications**
#419
**1\. Module Overview** > **5\. Popup Specifications** > **5.1 Pay Contractor Popup**
~177 tok
### **5.1 Pay Contractor Popup**

**Field Name**

**Type**

**Required**

**Validation Rules**

Contractor Info

Display

Yes

Shows contractor name, profile image, project, and issued date

Amount

Currency

Yes

Pre-filled from invoice, editable, must be positive

Payment Method Selection

Dropdown/Cards

Yes

Shows available payment methods or sets up payment methods

View Invoice Link

Button

No

Opens invoice in new view

Add Payment Method Button

Button

Conditional

Set up the payment gateway  
  
Appears when no payment method is configured

Cancel Button

Button

Yes

Cancel the payment process  
Closes pop-up without action

Pay Contractor Button

Button

Yes

Initiates payment processing
#420
**1\. Module Overview** > **5\. Popup Specifications** > **5.2 Mark as Paid Popup**
~142 tok
### **5.2 Mark as Paid Popup**

**Field Name**

**Type**

**Required**

**Validation Rules**

Confirmation Message

Text

Yes

"You are about to mark this invoice as paid. Do you want to continue?"

Amount

Currency

Yes

Pre-filled from invoice, editable, must be positive

Payment Method

Dropdown

Yes

Method used for manual payment  
  
Values: Cash, Bank Transfer, Credit Card, ACH

Note

Text Area

No

Optional additional information

Cancel Button

Button

Yes

Closes pop-up without action

Mark as Paid Button

Button

Yes

Confirms manual payment marking
#421
**1\. Module Overview** > **5\. Popup Specifications** >
~1 tok
###
#422
**1\. Module Overview** > **6\. Filter Specifications**
~8 tok
## **6\. Filter Specifications**
#423
**1\. Module Overview** > **6\. Filter Specifications** > **6.1 Contractor Invoices Filter Panel**
~105 tok
### **6.1 Contractor Invoices Filter Panel**

**Field Name**

**Type**

**Description**

Date Issued

Date

Filter by invoice issue date

Brand Filter

Multi-select Dropdown

Filter by project or contractor brand

Contractor Search and multi-select

Text with multi-select value

Search and select specific contractors

Project Search and

Multi select

Text with multi select value

Search and select specific projects
#424
**1\. Module Overview** > **7\. Success Message Handling**
~150 tok
## **7\. Success Message Handling**

**Validation Scenario**

**Success Message**

Payment successfully initiated

"Payment initiated successfully"

Payment marked as paid manually

"Invoice marked as paid successfully"

QuickBooks sync completed

"Invoice synced with QuickBooks successfully."

Payment method added

"Payment method added successfully."

Invoice PDF downloaded

"Invoice downloaded successfully."

Invoice link copied

"Invoice link copied to clipboard."

Print job initiated

"Invoice sent to printer successfully."

Payment retry initiated

"Payment retry initiated successfully."
#425
**1\. Module Overview** > **8\. Error Message Handling**
~233 tok
## **8\. Error Message Handling**

**Field**

**Validation Scenario**

**Error Message**

Payment Processing

Payment gateway connection failed

"Payment processing failed. Please check your payment method and try again."

Payment Processing

Insufficient funds or payment declined

"Payment declined. Please verify payment method details and try again."

Payment Method Setup

Setup failed

"Unable to set up payment method. Please contact support."

General

Network connection failed

"Unable to load contractor invoices. Please check your connection and try again."

General

Server timeout

"Request timed out. Please refresh the page and try again."

Filter Validations

Invalid date range

"End date must be after start date."

Filter Validations

No matching results

"No contractor invoices match the selected filter criteria."

PDF Generation

PDF creation failed

"Unable to generate invoice PDF. Please try again later."
#426
**1\. Module Overview** > **10\. Edge Cases**
~354 tok
## **10\. Edge Cases**

**Scenario**

**Expected Behavior**

Partial payment processing through Pay CTA

System processes partial amount as entered, remaining balance stays in Unpaid status for future payment

Payment remains in Processing status for an extended period

Status remains in Processing indefinitely until Stripe provides success or failure response, no automatic timeout

Manual Mark as Paid with backdated information

System accepts any date entered without validation restrictions, records manual entry in audit trail

QuickBooks sync failure for paid invoice

Manual sync option remains available indefinitely, sync status shows red cross until successful completion

View Invoice clicked from any status

Opens invoice details in new page with download button available for PDF generation

Contractor name search with partial text

Real-time search displays matching contractor names only, no company name or email matching

Project-specific user access preventing concurrent actions

System design ensures project-specific users cannot create conflicts, access restricted by project assignment

Payment processing with no contractor notifications

System completes all payment processes without sending any automated notifications to contractors

Payment method setup required for new users

System blocks access to financial functionality until payment method configured, enforced on first access
#427
**1\. Module Overview** > **11\. Test Cases**
~6 tok
## **11\. Test Cases**
#428
**1\. Module Overview** > **13\. Dependencies**
~149 tok
## **13\. Dependencies**

**Module/System**

**Dependency Type**

**Impact if Unavailable**

Stripe Payment Gateway

Critical Integration

Cannot process payments, no payment status updates, payment processing fails

QuickBooks Integration

Accounting Integration

Sync functionality unavailable, manual accounting reconciliation required

Project Management Module

Data Dependency

Cannot link invoices to projects, project-based filtering fails

Contractor Management Module

Data Dependency

Cannot display contractor information, contractor filtering unavailable

24 Dec Contractor Invoices
#429
**Functional Requirements Document (FRD) - Contractor Invoices Module**
~48 tok
# **Functional Requirements Document (FRD) - Contractor Invoices Module**

**Document Version:** 1.0  
**Created Date:** December 23, 2025  
**Module Location:** Finances → Contractor Invoices
#430
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **1\. Module Overview**
~257 tok
## **1\. Module Overview**

**Module Name:** Contractor Invoices

**Purpose:** The Contractor Invoices module enables agency owners and admins to view, manage, and process payments for invoices submitted by contractors for work completed on specific project events. Contractors upload invoices through the Contractor Portal, and agencies can pay via Stripe, ACH bank transfer or record manual offline payments.

**Business Goals:**

*   Streamline contractor payment workflows by centralizing all invoice management in one location.
*   Provide real-time visibility into invoice statuses across Unpaid, Processing, Paid, and Failed states.
*   Enable flexible payment options through online ACH transfers and manual payment recording.
*   Track discrepancies between agreed contractor fees and invoiced amounts to prevent overpayments.
*   Synchronize contractor payments with QuickBooks as expenses for accurate financial reporting.
*   Reduce payment processing time and improve contractor satisfaction through timely payments.
#431
**Functional Requirements Document (FRD) - Contractor Invoices Module** >
~1 tok
##
#432
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **2\. User Roles & Permissions**
~202 tok
## **2\. User Roles & Permissions**

**Role**

**View Invoices**

**Pay (Stripe ACH)**

**Mark as Paid**

**Retry Payment**

**View Invoice PDF**

**Download Invoice**

**Sync QuickBooks**

Agency Owner

✅

✅

✅

✅

✅

✅

✅

Agency Admin

✅

❌

✅

❌

✅

✅

✅

**Role Descriptions:**

*   **Agency Owner:** Has full access to all contractor invoice functionalities, including initiating online ACH payments via Stripe, retrying failed payments, marking invoices as paid manually, viewing and downloading invoice PDFs, and triggering QuickBooks sync.  
    
*   **Agency Admin:** Can view all contractor invoices, mark invoices as paid manually using offline payment methods, view and download invoice PDFs, and trigger QuickBooks sync. Agency Admins cannot initiate online ACH payouts or retry failed payments.
#433
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **3\. User Flow**
~776 tok
## **3\. User Flow**

**3.1** The user navigates to the Finances section from the left sidebar menu and clicks on Contractor Invoices.

**3.2** The system loads the Contractor Invoices module and displays the Unpaid tab by default, with all unpaid and overdue invoices listed.

**3.3** If no invoices have been submitted by the contractors, the system displays an empty state with the message "No contractor invoices yet." and secondary text "The invoices will appear here once the contractors submit invoices for event work."

**3.4** The user can switch between Unpaid, Processing, Paid, and Failed tabs by clicking on the respective tab headers.

**3.5** The system displays the invoice list for the selected tab with columns appropriate to that tab's context.

**3.6** The user clicks the expand arrow on any invoice row to view the Expected Contractor Payment details including the Event Price, total amount invoiced, and any discrepancy.

**3.7** The system expands the row inline and displays the Expected Contractor Payment amount, Amount Invoiced by Contractor, and Discrepancy (if applicable).

**3.8** The user clicks the filter icon to open the Filters panel.

**3.9** The system displays the Filters panel with Date Issued, Brand, Contractor, and Project filter options.

**3.10** The user selects filter values and the system immediately filters the invoice list based on the selected criteria.

**3.11** The user clicks the "Pay" button on an unpaid invoice row (Agency Owner only).

**3.12** The system opens the "Pay Contractor" modal displaying contractor details, project name, issue date, Expected Contractor Payment, Amount Invoiced by Contractor, Discrepancy (if applicable), and an editable Amount field pre-filled with the invoice amount.

**3.13** If the agency has not connected their Stripe account or added a payment method, the system displays "No payment method set up" with the message "To pay your contractor, you'll need to add a payment method first." and an "Add Payment Method" button.

**3.14** If the contractor has not set up their bank account, the system displays a message "You can't process the payment as the contractor does not have their bank account set up to receive the payment. Please ask the contractor to add their bank account."

**3.15** If both agency and contractor payment methods are configured, the system displays the agency's linked bank account details with account name and last 4 digits.

**3.16** The user reviews the payment details, optionally modifies the amount, and clicks "Pay Contractor" to initiate the ACH transfer.

**3.17** The system initiates the Stripe ACH payout and moves the invoice from Unpaid to Processing status.

**3.18** The user clicks the "Mark as Paid" button on an unpaid invoice row.

**3.19** The system opens the "Mark as Paid" modal with confirmation text "You are about to mark this invoice as paid. Do you want to continue?", contractor details, Expected Contractor Payment, Amount Invoiced by Contractor, Discrepancy (if applicable), editable Amount field, Payment Method dropdown, and optional Note field.
#434
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **3\. User Flow**
~546 tok
**3.20** The user selects a payment method from the dropdown (Cash, Check, Zelle, PayPal, Venmo, Google Pay, or Apple Pay), optionally enters a note, and clicks "Mark as Paid".

**3.21** The system moves the invoice directly from Unpaid to Paid status and records the manual payment details.

**3.22** The user clicks the "View Invoice" button on any invoice row.

**3.23** The system opens a PDF viewer popup displaying the uploaded invoice document with Print, Download, and zoom controls.

**3.24** The user clicks the 3-dot overflow menu on any invoice row.

**3.25** The system displays menu options: View Invoice, Sync with QuickBooks (if not synced or sync failed), and Download Invoice.

**3.26** The user clicks "Retry Payment" icon on a failed invoice row (Agency Owner only).

**3.27** The system initiates a new ACH payout attempt and moves the invoice from Failed back to Processing status.

**3.28** The system receives a Stripe webhook confirming successful payout and moves the invoice from Processing to Paid status.

**3.29** The system receives a Stripe webhook indicating payout failure and moves the invoice from Processing to Failed status, storing the failure reason.

**3.30** The user clicks on a Project name link in the invoice list.

**3.31** The system navigates the user to the Project details page.

**3.32** The user enters a search term in the search bar.

**3.33** The system filters the invoice list to show invoices matching the search term against Contractor Name, Project Name, or Amount.

**3.34** The user clicks a column header to sort the invoice list.

**3.35** The system sorts the invoice list by the selected column in ascending or descending order.

**3.36** The user clicks the QuickBooks sync icon on a Paid invoice.

**3.37** The system displays a tooltip showing the sync status ("Synced: \[Date\] at \[Time\]", "Not synced yet. Press QuickBooks icon to sync this transaction.", or "Sync failed. Press to retry.").

**3.38** If sync is pending or failed, the user clicks the icon and the system initiates a sync to QuickBooks.

**3.39** The system creates or updates the corresponding expense entry in QuickBooks upon successful sync.
#435
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#436
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.1 Navigation & Entry Points**
~158 tok
### **4.1 Navigation & Entry Points**

*   The Contractor Invoices module is accessible from the left sidebar under Finances → Contractor Invoices.
*   The module can also be accessed contextually from Project details or Event details pages, where contractor invoice links may be present.
*   When the user navigates to the module, the system loads the Unpaid tab by default.
*   The system displays a Brand dropdown filter in the header set to "All Brands" by default.
*   The system displays a search bar in the header for quick invoice lookup.
*   The system displays a filter icon button that opens the advanced Filters panel.
#437
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.2 Empty State Logic**
~137 tok
### **4.2 Empty State Logic**

*   The system evaluates empty states in a hierarchical priority order to display the most relevant message.
*   **No Invoices:** If no invoices have been submitted by the contractors, the system displays the message "No contractor invoices yet" with secondary text "The Invoices will appear here once the contractors submit invoices."
*   Empty states are displayed only after data loading is complete to prevent UI flicker.
*   Filters remain accessible during empty states to allow users to adjust filter criteria.
#438
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.3 Tab-Level Empty States**
~107 tok
### **4.3 Tab-Level Empty States**

*   If invoices exist in the system but the Unpaid tab has no entries, the system displays "No unpaid contractor invoices."
*   If the Processing tab has no entries, the system displays "No invoices are currently processing."
*   If the Paid tab has no entries, the system displays "No paid invoices yet."
*   If the Failed tab has no entries, the system displays "No failed invoices found."
#439
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.4 Filter-Induced Empty State**
~76 tok
### **4.4 Filter-Induced Empty State**

*   If the user applies filters that return zero results, the system displays the message "No invoices match your selected filters." with a "Clear Filters" CTA.
*   Clicking "Clear Filters" resets all filter values to their defaults and refreshes the invoice list.
#440
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.5 Invoice Status Definitions**
~194 tok
### **4.5 Invoice Status Definitions**

*   **Unpaid:** The invoice has been uploaded by the contractor, but no payment attempt has been initiated (no ACH payout, no manual "Mark as Paid").
*   **Overdue:** Displays the invoices where the payment due date has passed without successful payment.
*   **Processing:** A Stripe ACH payout has been initiated to the contractor's bank account, and final confirmation is pending from Stripe (typically 3-5 business days).
*   **Paid:** The ACH payout was successfully completed based on Stripe webhook confirmation, OR the agency used "Mark as Paid" to record a manual offline payment.
*   **Failed:** The ACH payout failed due to a bank or Stripe error, such as insufficient funds, a blocked transaction, or invalid account details.
#441
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.6 Status Transitions**
~161 tok
### **4.6 Status Transitions**

*   **Unpaid → Processing:** Occurs when the agency owner clicks "Pay" and confirms the online ACH payment via Stripe.
*   **Unpaid → Paid:** Occurs when an agency user clicks "Mark as Paid" and confirms a manual offline payment method.
*   **Processing → Paid:** Occurs when Stripe webhook confirms successful ACH payout completion.
*   **Processing → Failed:** Occurs when Stripe webhook returns a failure response.
*   **Failed → Processing:** Occurs when the agency owner uses "Retry Payment" to initiate a new payout attempt for the same invoice.
*   No other status transitions are permitted by the system.
#442
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.7 List View & Tab Structure**
~9 tok
### **4.7 List View & Tab Structure**
#443
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.7 List View & Tab Structure** > **4.7.1 Unpaid Tab Columns**
~86 tok
#### **4.7.1 Unpaid Tab Columns**

*   Contractor (with avatar and name)
*   Issued (date the invoice was submitted)
*   Status (always displays "Unpaid" badge)
*   Project (project name with event name and event color dot below)
*   Amount (invoice amount in currency format)
*   Actions (Pay, Mark as Paid, View Invoice buttons, 3-dot menu)
#444
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.7 List View & Tab Structure** > **4.7.2 Processing Tab Columns**
~100 tok
#### **4.7.2 Processing Tab Columns**

*   Contractor (with avatar and name)
*   Issued (date the invoice was submitted)
*   Paid (date the payment was initiated)
*   Payment Method (displays "Bank Transfer" for ACH or manual method name)
*   Status (always displays "Processing" badge)
*   Project (project name with event name and event color dot below)
*   Actions (View Invoice button, 3-dot menu)
#445
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.7 List View & Tab Structure** > **4.7.3 Paid Tab Columns**
~109 tok
#### **4.7.3 Paid Tab Columns**

*   Contractor (with avatar and name)
*   Issued (date the invoice was submitted)
*   Paid (date the payment was completed)
*   Payment Method (displays "Bank Transfer" for ACH or manual method name)
*   Status (always displays "Paid" badge)
*   Project (project name with event name and event color dot below)
*   QuickBooks Sync Icon (displays sync status)
*   Actions (View Invoice button, 3-dot menu)
#446
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.7 List View & Tab Structure** > **4.7.4 Failed Tab Columns**
~104 tok
#### **4.7.4 Failed Tab Columns**

*   Contractor (with avatar and name)
*   Issued (date the invoice was submitted)
*   Failed Date (date and failure reason below)
*   Payment Method (displays "Bank Transfer" or last attempted method)
*   Status (always displays "Failed" badge in red)
*   Project (project name with event name and event color dot below)
*   Actions (View Invoice, Retry Payment icon, 3-dot menu)
#447
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.8 Expandable Row Logic**
~185 tok
### **4.8 Expandable Row Logic**

*   Each invoice row in the Unpaid tab has an expand/collapse arrow on the left side.
*   When the user clicks the expand arrow, the row expands inline to display additional payment context.
*   The expanded section displays: Expected Contractor Payment (the agreed contractor fee for the event), Amount Invoiced by Contractor (cumulative total of all invoices submitted by this contractor for this event), and Discrepancy (if applicable) showing the difference when the invoiced amount exceeds the expected payment.
*   The discrepancy value is displayed only when the Amount Invoiced exceeds the Expected Contractor Payment.
*   Clicking the expand arrow again collapses the row back to its default state.
#448
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.9 Contractor Fee Tracking & Overage Warning**
~198 tok
### **4.9 Contractor Fee Tracking & Overage Warning**

*   Each contractor has an agreed fee per event that is set when the agency assigns the contractor to the event.
*   The system tracks the cumulative total of all invoices submitted by a contractor for a specific event.
*   The system does NOT block invoices that exceed the assigned contractor fee.
*   When the total invoiced amount exceeds the assigned contractor fee, the system displays the discrepancy amount in the expanded row view.
*   The discrepancy warning is also displayed in the Pay Contractor modal and Mark as Paid modal to alert the agency before processing payment.
*   The agency can proceed with payment even when a discrepancy exists, as there may be valid reasons such as scope changes or extended event duration.
#449
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.10 Pay Contractor Modal (Online Payment)**
~435 tok
### **4.10 Pay Contractor Modal (Online Payment)**

*   The Pay Contractor modal opens when an Agency Owner clicks the "Pay" button on an unpaid invoice.
*   The modal header displays "Pay Contractor" with a close (X) button.
*   The Contractor section displays the contractor's avatar, name, linked project name, and issue date.
*   A "View Invoice" link is displayed to allow the user to view the PDF without closing the modal.
*   The modal displays Expected Contractor Payment, Amount Invoiced by Contractor, and Discrepancy (if applicable) as read-only informational fields.
*   The Amount field is pre-filled with the invoice amount but is editable to allow partial payments.
*   If the contractor has not set up their bank account, the modal displays "You can't process the payment as the contractor does not have their bank account set up to receive the payment. Please ask the contractor to add their bank account." and the Pay Contractor button is disabled.
*   If the agency has not set up their payment method, the modal displays "No payment method set up" with the message "To pay your contractor, you'll need to add a payment method first." and an "Add Payment Method" button that redirects to Stripe Financial Connections.
*   If both payment methods are configured, the modal displays the agency's connected bank account with company name and last 4 digits of the account number, along with an edit icon to change the payment method.
*   The Cancel button closes the modal without any changes.
*   The Pay Contractor button is enabled only when both agency and contractor payment methods are configured and the amount field has a valid value.
*   Clicking Pay Contractor initiates the Stripe ACH payout and closes the modal.
#450
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.11 Mark as Paid Modal (Manual Payment)**
~350 tok
### **4.11 Mark as Paid Modal (Manual Payment)**

*   The Mark as Paid modal opens when an agency user clicks the "Mark as Paid" button on an unpaid invoice.
*   The modal header displays "Mark as Paid" with a close (X) button.
*   The modal displays confirmation text: "You are about to mark this invoice as paid. Do you want to continue?"
*   The Contractor section displays the contractor's avatar, name, linked project name, and issue date.
*   A "View Invoice" link is displayed to allow the user to view the PDF without closing the modal.
*   The modal displays Expected Contractor Payment, Amount Invoiced by Contractor, and Discrepancy (if applicable) as read-only informational fields.
*   The Amount field is pre-filled with the invoice amount but is editable.
*   The Payment Method dropdown is required and contains options: Cash, Check, Zelle, PayPal, Venmo, Google Pay, Apple Pay.
*   The Note field is optional and allows the agency to record internal notes about the payment (maximum 1000 characters).
*   The Note field content is visible only to agency owner and team members, not to the contractor.
*   The Cancel button closes the modal without any changes.
*   The Mark as Paid button is enabled when a payment method is selected and the amount field has a valid value.
*   Clicking Mark as Paid records the manual payment, moves the invoice to Paid status, and closes the modal.
#451
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.12 View Invoice Functionality**
~132 tok
### **4.12 View Invoice Functionality**

*   Clicking the "View Invoice" button opens a full-screen PDF viewer popup.
*   The popup header displays the invoice filename in the format "\[Contractor Name\] - \[Project Name\] (\[Issue Date\]).pdf".
*   The popup header includes Print, Download, zoom out (-), zoom percentage dropdown, and zoom in (+) controls.
*   A back arrow in the top-left allows the user to close the popup and return to the invoice list.
*   The PDF viewer displays the contractor-uploaded invoice document.
#452
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.13 Failed Payment & Retry Logic**
~162 tok
### **4.13 Failed Payment & Retry Logic**

*   When an ACH payout fails, the system stores the failure reason received from Stripe.
*   The Failed tab displays the failure date and failure reason below each failed invoice (e.g., "Card Declined", "Invalid Card Details", "Insufficient Funds", "Payment Blocked").
*   The Retry Payment action is available only to Agency Owners.
*   Clicking the Retry Payment icon initiates a new Stripe ACH payout attempt for the same invoice.
*   Upon retry, the invoice status changes from Failed to Processing.
*   The subsequent Stripe webhook will determine whether the invoice moves to Paid or back to Failed.
#453
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.14 Filters Panel Logic**
~298 tok
### **4.14 Filters Panel Logic**

*   The Filters panel is accessed by clicking the filter icon in the header.
*   A refresh icon at the top of the panel resets all filters to default values.
*   **Date Issued Filter:** A date picker allowing the user to select a specific date or date range.
*   **Brand Filter:** A single-select dropdown defaulting to "All Brands" that filters invoices by the brand associated with the project.
*   **Contractor Filter:** A multi-select list with search functionality allowing the user to select one or more contractors.
*   **Project Filter:** A multi-select list with search functionality allowing the user to select one or more projects.
*   When a Brand is selected, the Project filter list is scoped to show only projects belonging to that brand.
*   When a Brand is selected, the Contractor filter list is scoped to show only contractors assigned to events within that brand.
*   Filters apply across all four status tabs (Unpaid, Processing, Paid, Failed).
*   Filter selections persist when switching between status tabs until manually cleared.
*   Applying filters immediately refreshes the invoice list without requiring a separate "Apply" action.
#454
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.15 Search Functionality**
~88 tok
### **4.15 Search Functionality**

*   The search bar in the header allows quick lookup of invoices.
*   Search matches against Contractor Name, Project Name, and Amount.
*   Search results are displayed in real-time as the user types.
*   Search works in conjunction with applied filters.
*   Clearing the search field restores the full filtered list.
#455
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.16 Sorting Logic**
~137 tok
### **4.16 Sorting Logic**

*   All column headers with a down arrow (↓) are sortable.
*   Clicking a sortable column header sorts the list by that column in ascending order.
*   Clicking the same column header again toggles to descending order.
*   Sortable columns include: Contractor, Issued, Paid (where applicable), Payment Method (where applicable), Status, Project, Amount.
*   Default sort order is by Issued date in descending order (most recent first).
*   Sorting preferences persist while navigating between tabs within the same session.
#456
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.17 Pagination Logic**
~86 tok
### **4.17 Pagination Logic**

*   The invoice list supports pagination with a "Rows per page" dropdown (default: 10).
*   Available options for rows per page are: 10, 25, 50.
*   The pagination footer displays the current range (e.g., "1-4 of 4") and navigation arrows.
*   Pagination state resets when switching tabs or applying new filters.
#457
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.18 Project & Event Linkage**
~120 tok
### **4.18 Project & Event Linkage**

*   Every Contractor Invoice is mandatorily linked to a specific Event.
*   Every Event is mandatorily linked to a Project.
*   Every Project is mandatorily linked to a Brand.
*   The Project column displays the project name with the event name and event color dot displayed below.
*   Clicking on the Project name navigates the user to the Project details page.
*   Multiple invoices can exist for the same contractor and event combination.
#458
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.19 3-Dot Overflow Menu Actions**
~85 tok
### **4.19 3-Dot Overflow Menu Actions**

*   **View Invoice:** Opens the PDF viewer popup to display the uploaded invoice document.
*   **Sync with QuickBooks:** Displayed only if the invoice is not synced or sync has failed; triggers a manual sync to QuickBooks.
*   **Download Invoice:** Downloads the invoice PDF to the user's device.
#459
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.20 QuickBooks Integration**
~207 tok
### **4.20 QuickBooks Integration**

*   Contractor payments (both online ACH and manual) sync to QuickBooks as expenses.
*   When an invoice status becomes Paid, the system creates or updates the corresponding expense entry in QuickBooks.
*   The QuickBooks sync icon displays one of three states: Synced successfully, Sync failed, Sync pending.
*   Hovering over the sync icon displays a tooltip with status details (e.g., "Synced: Aug 20, 2025 at 7:00pm" or "Not synced yet. Press QuickBooks icon to sync this transaction.").
*   If sync fails, the user can click the icon to manually retry the sync.
*   Data mapping: Contractor maps to Vendor in QuickBooks, Project maps to Class/Job, and payment amount maps to expense amount.
*   If the agency has not connected their QuickBooks account, the sync icon is not displayed.
#460
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.21 Stripe Connect Integration**
~204 tok
### **4.21 Stripe Connect Integration**

*   Pixally maintains a master Stripe account with both agencies and contractors as connected accounts.
*   When an agency invites a contractor to Pixally for the first time, the system creates a Stripe Connect account for the contractor under Pixally's master account.
*   Contractors complete the Stripe onboarding process only once, even if invited by multiple agencies.
*   Each agency that wants to pay a contractor must set up a customer profile and payment method within the contractor's Stripe account.
*   If a contractor is already associated with another agency on Pixally, they do not need to complete onboarding again.
*   For ACH payouts to succeed, both the agency's funding bank account and the contractor's payout bank account must be configured in Stripe.
#461
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.22 Notifications & Emails**
~206 tok
### **4.22 Notifications & Emails**

*   **Payment Success (to Contractor):** When a contractor payment is successfully processed (either via ACH or marked as paid manually), the system sends an email notification and an in-app notification to the contractor confirming the payment.
*   **Payment Failed (to Agency Owner):** When an ACH payout fails, the system sends an email notification to the agency owner with the failure reason.
*   **New Invoice Submitted (to Agency):** When a contractor submits a new invoice, the system sends an in-app notification to agency users.
*   **Invoice Overage Warning:** The warning is displayed only in the UI (Pay Contractor modal and Mark as Paid modal) when the agency attempts to pay an invoice that exceeds the expected contractor fee; no email notification is sent for overage.
#462
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Functional Logic** > **4.23 Audit Trail**
~106 tok
### **4.23 Audit Trail**

*   The system maintains an audit trail for all payment-related actions.
*   Logged actions include: Invoice submitted, Payment initiated, Payment completed, Payment failed, Payment retried, Invoice marked as paid, QuickBooks sync attempted, QuickBooks sync completed, QuickBooks sync failed.
*   Each audit entry captures the action timestamp, user who performed the action, and relevant details.
#463
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **5\. Field Details & Validations**
~529 tok
## **5\. Field Details & Validations**

**Field Name**

**Field Type**

**Validation Rules**

Contractor Name

Text (Display)

Read-only; pulled from contractor profile

Contractor Avatar

Image (Display)

Read-only; pulled from contractor profile

Issued Date

Date (Display)

Read-only; set when contractor submits invoice; Format: MMM D, YYYY

Paid Date

Date (Display)

Read-only; set when payment completes; Format: MMM D, YYYY

Failed Date

Date (Display)

Read-only; set when payment fails; Format: Month D, YYYY

Status

Badge (Display)

Read-only; system-managed based on payment lifecycle

Project Name

Text (Link)

Read-only; clickable to navigate to project details

Event Name

Text (Display)

Read-only; displayed with event color dot below project name

Invoice Amount

Currency (Display)

Read-only; set by contractor; Format: $X,XXX.XX

Expected Contractor Payment

Currency (Display)

Read-only; pulled from contractor assignment on event

Amount Invoiced by Contractor

Currency (Display)

Read-only; cumulative sum of all invoices for contractor-event

Discrepancy

Currency (Display)

Read-only; calculated as (Amount Invoiced - Expected Payment) when positive

Payment Amount

Currency (Input)

Required; Numeric only; Must be greater than $0.00; Pre-filled with invoice amount; Format: $X,XXX.XX

Payment Method (Manual)

Dropdown (Select)

Required for Mark as Paid; Options: Cash, Check, Zelle, PayPal, Venmo, Google Pay, Apple Pay

Note

Text Area (Input)

Optional; Maximum 1000 characters; Internal use only

Failure Reason

Text (Display)

Read-only; populated from Stripe webhook response

QuickBooks Sync Status

Icon (Display)

Read-only; States: Synced, Failed, Pending

Search Query

Text (Input)

Optional; Matches against Contractor Name, Project Name, Amount

Date Issued Filter

Date Picker

Optional; Accepts single date or date range

Brand Filter

Dropdown (Single-select)

Optional; Default: All Brands

Contractor Filter

Multi-select List

Optional; Searchable; Multiple selections allowed

Project Filter

Multi-select List

Optional; Searchable; Scoped to selected brand
#464
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **6\. Success Message Handling**
~332 tok
## **6\. Success Message Handling**

**Operation**

**Success Message**

**Trigger Condition**

**Post-Success Action**

Pay Contractor (ACH)

"Payment initiated successfully. The contractor will receive funds within 3-5 business days."

User clicks "Pay Contractor" and ACH payout is initiated

Modal closes; Invoice moves to Processing tab; List refreshes

Mark as Paid

"Invoice marked as paid successfully."

User clicks "Mark as Paid" with valid payment method selected

Modal closes; Invoice moves to Paid tab; List refreshes

Retry Payment

"Payment retry initiated. Processing will complete within 3-5 business days."

User clicks Retry Payment icon on failed invoice

Invoice moves to Processing tab; List refreshes

QuickBooks Sync

"Successfully synced with QuickBooks."

Manual or automatic sync completes successfully

Sync icon updates to "Synced" state; Tooltip shows sync timestamp

Download Invoice

"Invoice downloaded successfully."

User clicks Download Invoice from 3-dot menu

PDF file downloads to user's device

Filters Applied

(No toast message - list updates silently)

User selects filter values

Invoice list refreshes to show filtered results

Filters Cleared

"Filters cleared."

User clicks "Clear Filters" or refresh icon

All filters reset to defaults; List shows all invoices for current tab
#465
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **7\. Error Message Handling**
~793 tok
## **7\. Error Message Handling**

**Error Scenario**

**Error Message**

**Trigger Condition**

**Required Action**

Agency Payment Method Not Set Up

"No payment method set up. To pay your contractor, you'll need to add a payment method first."

Agency clicks Pay but has not connected Stripe or added payment method

Click "Add Payment Method" to configure Stripe Financial Connections

Contractor Bank Account Not Set Up

"You can't process the payment as the contractor does not have their bank account set up to receive the payment. Please ask the contractor to add their bank account."

Agency clicks Pay but contractor has not completed Stripe onboarding

Contact contractor to complete bank account setup in Contractor Portal

Payment Amount Invalid

"Please enter a valid payment amount greater than $0.00."

User enters zero, negative, or non-numeric value in Amount field

Enter a valid positive numeric amount

Payment Amount Exceeds Limit

"Payment amount exceeds the maximum allowed limit."

User enters amount exceeding Stripe ACH limit

Enter an amount within the allowed limit

Payment Method Required

"Please select a payment method to continue."

User clicks Mark as Paid without selecting payment method

Select a payment method from the dropdown

ACH Payout Failed - Insufficient Funds

"Payment failed: Insufficient funds in the source account."

Stripe webhook returns insufficient funds error

Verify agency bank account balance and retry payment

ACH Payout Failed - Invalid Account

"Payment failed: Invalid bank account details."

Stripe webhook returns invalid account error

Contractor must update bank account details

ACH Payout Failed - Account Blocked

"Payment failed: The recipient's bank account is blocked."

Stripe webhook returns blocked account error

Contractor must resolve issue with their bank

ACH Payout Failed - Card Declined

"Payment failed: Card declined by the bank."

Stripe webhook returns card declined error

Verify payment details and retry

QuickBooks Sync Failed

"Failed to sync with QuickBooks. Click to retry."

QuickBooks API returns error during sync

Click sync icon to retry; If persistent, verify QuickBooks connection

QuickBooks Not Connected

"Connect your QuickBooks account to sync contractor payments."

User attempts sync but QuickBooks is not connected

Navigate to Settings → Integrations to connect QuickBooks

Search No Results

"No invoices found matching your search."

Search query returns no matching invoices

Modify search term or clear search

Filter No Results

"No invoices match your selected filters."

Applied filters return zero results

Adjust filter criteria or click "Clear Filters"

Note Exceeds Character Limit

"Note cannot exceed 1000 characters."

User enters more than 1000 characters in Note field

Reduce note content to 1000 characters or less

Network Error

"Unable to complete the request. Please check your connection and try again."

Network connectivity issue during any operation

Check internet connection and retry the action

Session Expired

"Your session has expired. Please log in again."

User session times out during operation

Log in again to continue
#466
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **8\. Edge Cases**
~747 tok
## **8\. Edge Cases**

**Edge Case**

**System Behavior**

Contractor submits multiple invoices for the same event

The system accepts all invoices and displays them as separate line items; Amount Invoiced by Contractor shows cumulative total

Total invoiced amount exceeds agreed contractor fee

The system displays a discrepancy warning but does not block payment; Agency can proceed with payment

Agency attempts to pay more than invoice amount

The system allows overpayment as the Amount field is editable; This is useful for tips or bonus payments

Agency pays partial amount

The system processes the partial payment; Invoice status changes based on payment flow; Original invoice amount remains unchanged for reference

Stripe webhook delayed beyond 5 business days

Invoice remains in Processing status until webhook is received; No timeout mechanism auto-fails the payment

Stripe webhook received out of order

The system processes webhooks based on event timestamp, not receipt order

User switches tabs while payment is processing

The invoice correctly appears in Processing tab; Original tab updates upon return

User applies filters then switches tabs

Filter selections persist across tab switches within the same session

Brand with no projects is selected in filter

Project filter shows empty list; Contractor filter shows empty list

Contractor is removed from event after submitting invoice

Existing invoices remain visible and can still be paid; New invoices cannot be submitted

Project is deactivated after invoice submission

Existing invoices remain visible and can still be processed; Project name displays with deactivated indicator

Multiple users attempt to pay same invoice simultaneously

First successful payment request is processed; Subsequent attempts fail with "Invoice already processing" error

QuickBooks sync fails due to disconnection

Sync icon shows failed state; User can reconnect QuickBooks and retry sync

Agency disconnects Stripe account with invoices in Processing

Processing invoices continue through Stripe; New payments cannot be initiated until reconnection

Contractor has multiple bank accounts

The system uses the default payout bank account set in contractor's Stripe Connect account

PDF invoice file is corrupted or cannot be rendered

System displays error "Unable to load invoice. Please contact support." with option to download file directly

User opens Pay modal for invoice that was just paid by another user

Modal displays current status and refreshes; Shows message "This invoice has already been paid."

Internet disconnects during payment confirmation

System displays network error; User should check Processing tab to verify if payment was initiated

Note field contains special characters

System accepts all UTF-8 characters including emojis; Properly escapes for storage

Amount field receives paste with currency symbol

System strips non-numeric characters except decimal point; Validates resulting number
#467
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **9\. Acceptance Criteria**
~8 tok
## **9\. Acceptance Criteria**
#468
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **9\. Acceptance Criteria** > **9.1 Navigation & Access**
~88 tok
### **9.1 Navigation & Access**

*   Users can access Contractor Invoices from Finances menu in left sidebar.
*   Unpaid tab is displayed by default when module loads.
*   All four status tabs (Unpaid, Processing, Paid, Failed) are visible and clickable.
*   Brand dropdown filter defaults to "All Brands" and shows all brands the user has access to.
#469
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **9\. Acceptance Criteria** > **9.2 Empty States**
~79 tok
### **9.2 Empty States**

*   System displays hierarchical empty states in correct order.
*   Each empty state shows appropriate message.
*   Tab-level empty states display when no invoices exist for specific status.
*   Filter-induced empty state displays with Clear Filters option when filters return no results.
#470
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **9\. Acceptance Criteria** > **9.3 Invoice List Display**
~99 tok
### **9.3 Invoice List Display**

*   Invoice rows display correct columns for each tab type.
*   Expandable rows show Expected Contractor Payment, Amount Invoiced, and Discrepancy.
*   Project column shows project name with event name and color dot below.
*   Status badges display correct color and text for each status.
*   Pagination controls work correctly with configurable rows per page.
#471
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **9\. Acceptance Criteria** > **9.4 Pay Contractor Flow**
~123 tok
### **9.4 Pay Contractor Flow**

*   Pay button is visible only to Agency Owners.
*   Pay Contractor modal displays all required information fields.
*   Modal shows appropriate message when agency payment method is not configured.
*   Modal shows appropriate message when contractor bank account is not configured.
*   Amount field is pre-filled and editable.
*   Pay Contractor button initiates Stripe ACH payout.
*   Invoice moves to Processing status after successful payment initiation.
#472
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **9\. Acceptance Criteria** > **9.5 Mark as Paid Flow**
~98 tok
### **9.5 Mark as Paid Flow**

*   Mark as Paid button is visible to both Agency Owners and Agency Admins.
*   Modal displays confirmation message and all required fields.
*   Payment Method dropdown shows all seven options (Cash, Check, Zelle, PayPal, Venmo, Google Pay, Apple Pay).
*   Note field accepts up to 1000 characters.
*   Invoice moves directly to Paid status after confirmation.
#473
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **9\. Acceptance Criteria** > **9.6 Failed Payment & Retry**
~63 tok
### **9.6 Failed Payment & Retry**

*   Failed invoices display failure date and reason.
*   Retry Payment icon is visible only to Agency Owners.
*   Retry initiates new ACH payout attempt.
*   Invoice moves to Processing status after retry initiation.
#474
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **9\. Acceptance Criteria** > **9.7 Filters & Search**
~90 tok
### **9.7 Filters & Search**

*   All filter types function correctly (Date, Brand, Contractor, Project).
*   Project filter scopes to selected Brand.
*   Contractor filter scopes to selected Brand.
*   Filters persist across tab switches.
*   Search matches against Contractor Name, Project Name, and Amount.
*   Clear Filters resets all filters to defaults.
#475
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **9\. Acceptance Criteria** > **9.8 Sorting**
~41 tok
### **9.8 Sorting**

*   All designated columns are sortable.
*   Sort order toggles between ascending and descending.
*   Sort preferences persist within session.
#476
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **9\. Acceptance Criteria** > **9.9 QuickBooks Integration**
~62 tok
### **9.9 QuickBooks Integration**

*   Sync icon displays correct state (Synced, Failed, Pending).
*   Tooltip shows sync status details on hover.
*   Manual sync triggers successfully when clicked.
*   Paid invoices sync to QuickBooks as expenses.
#477
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **9\. Acceptance Criteria** > **9.10 Notifications**
~60 tok
### **9.10 Notifications**

*   Contractor receives email and in-app notification on successful payment.
*   Agency owner receives email notification on failed payment.
*   Agency receives in-app notification when new invoice is submitted.
#478
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **9\. Acceptance Criteria** > **9.11 View & Download Invoice**
~48 tok
### **9.11 View & Download Invoice**

*   View Invoice opens PDF viewer popup.
*   PDF viewer has Print, Download, and zoom controls.
*   Download Invoice downloads PDF file to user's device.
#479
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **10\. Manual Test Cases**
~63 tok
## **10\. Manual Test Cases**

Test cases are documented in a separate Excel file for import into test management tools.

**Refer:** [Click Here](https://docs.google.com/spreadsheets/d/1xdQUrwWc_ywwfQi5k53hBhoiB1SBpeg9l3AqDnfXemM/edit?usp=drive_link)
#480
**Functional Requirements Document (FRD) - Contractor Invoices Module** >
~1 tok
##
#481
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **11\. Dependencies**
~411 tok
## **11\. Dependencies**

**Dependency Type**

**Dependency Name**

**Description**

**Impact if Unavailable**

Internal Module

Brands

Brand creation and management

Cannot create invoices; Empty state Priority 1 displayed

Internal Module

Projects

Project creation and linking

Cannot create invoices; Empty state Priority 2 displayed

Internal Module

Events

Event creation within projects

Cannot create invoices; Empty state Priority 3 displayed

Internal Module

Contractor Management

Contractor profiles and event assignment

Cannot submit invoices; Empty state Priority 4 displayed

Internal Module

Contractor Portal

Interface for contractors to submit invoices

Invoices cannot be created by contractors

External Service

Stripe Connect

Payment processing for ACH payouts

Online payments cannot be processed; Mark as Paid still available

External Service

Stripe Financial Connections

Bank account linking for agencies

Agencies cannot add payment methods for ACH

External Service

Stripe Webhooks

Payment status updates

Payment status stuck in Processing; Manual verification required

External Service

QuickBooks API

Expense synchronization

Expense entries not created; Manual accounting required

Configuration

Agency Stripe Account

Agency's connected Stripe account

Cannot initiate ACH payments

Configuration

Contractor Stripe Account

Contractor's Stripe Connect account

Cannot receive ACH payments

Configuration

Agency Payment Method

Linked bank account for fund source

Cannot initiate ACH payments

Configuration

Contractor Bank Account

Linked bank account for payout

Cannot receive ACH payments
#482
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **12\. References**
~41 tok
## **12\. References**

Please refer- [Click Here](https://www.figma.com/design/ej0kxwP45mDKmZCZfAJ5O8/Pixally?node-id=29141-24236&t=7RQKgcJBUkbtY4aT-0)

☑️ Expenses
#483
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **1\. Module Overview**
~266 tok
## **1\. Module Overview**

**Module Name:** Expenses Management Module (Sub-module within Finance Management)  
**Purpose:** Record, manage, and track all outgoing monetary expenses of the company with comprehensive categorization, brand association, and automated QuickBooks integration  
**Business Goal:** Provide centralized expense management with detailed categorization (COGS/OPEX), contractor payment tracking, and brand-specific filtering.

**2\. User Roles & Permissions**

**Role**

**Description**

**Key Permissions**

Agency Owner

Business owner with full financial oversight

Full access: add, edit, delete, view all expenses, manage QuickBooks sync, access all brands and projects

Admin

System administrator with operational control

Full access: add, edit, delete, view all expenses, manage QuickBooks sync, access all brands and projects

Project Manager (PM)

Project-specific management role

Limited access: add expenses only for assigned projects, view own project expenses, cannot delete or edit others' expenses, restricted brand access
#484
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **3\. User Flow**
~5 tok
## **3\. User Flow**
#485
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **3\. User Flow** > **Primary Flow - Expense Management:**
~215 tok
### **Primary Flow - Expense Management:**

1.  **Module Access:** User navigates to Finance Management → Expenses
2.  **Expense Listing:** System displays expense table with Date, Amount, Category, Notes, QuickBooks Sync Status, Actions
3.  **Filter Application:** User applies filters (contractor toggle, brand filter, date range, price range, category search), user can also use the toggle of “Only show amount paid to contractor" to filter out only the amount paid to contractors from all other expenses
4.  **Expense Actions:** The User can add new expenses, edit existing ones, or delete expenses based on permissions
5.  **QuickBooks Integration:** The System automatically attempts sync with QuickBooks, and provides a manual retry for failed syncs
6.  **Data Management:** User manages expense records with proper categorization and project assignment
#486
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **3\. User Flow** > **Secondary Flow - Add New Expense:**
~151 tok
### **Secondary Flow - Add New Expense:**

1.  **Add Expense:** User clicks "Add Expense" button
2.  **Type Selection:** User selects COGS or OPEX expense type
3.  **Category Selection:** User selects from a predefined category list based on expense type
4.  **Form Completion:** User fills required fields (brand, project, date, amount) and optional notes
5.  **Contractor Selection:** If the category is "Contractors," the user selects a specific contractor
6.  **Submission:** System validates data and creates an expense record
7.  **Auto-Sync:** System attempts automatic QuickBooks synchronization
#487
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **3\. User Flow** > **Tertiary Flow - QuickBooks Sync Management:**
~100 tok
### **Tertiary Flow - QuickBooks Sync Management:**

1.  **Auto-Sync Attempt:** The System automatically tries to sync new/modified expenses
2.  **Sync Status Update:** System updates the QuickBooks sync icon based on success/failure
3.  **Manual Retry:** User clicks the QuickBooks icon for failed syncs to retry manually
4.  **Status Tracking:** System maintains sync status for all expense records
#488
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Field Details & Validations**
~10 tok
## **4\. Field Details & Validations**
#489
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Field Details & Validations** > **4.1 Expense Form Fields**
~118 tok
### **4.1 Expense Form Fields**

**Field Name**

**Required**

**Validation Rules**

Date

Yes

The date of payment

Amount

Yes

The total amount paid for the expenses  
  
  
Must be numeric and > 0, formatted to 2 decimal places

Category

Yes

The category in which the payment was made

Notes

Yes

Maximum 250 characters

QuickBooks icon

Yes

Will be active if the sync happens, else the user can manually sync by clicking on the icon

Actions

Yes

Delete and edit
#490
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Field Details & Validations** > **4.2 COGS (Cost of Goods Sold) Categories**
~111 tok
### **4.2 COGS (Cost of Goods Sold) Categories**

**Category Group**

**Specific Categories**

**Select Category**

Drop-down values will auto-populate with COGS Values

**Select Brand**

Drop-down values, Brand values will auto-populate

**Select Project (Optional )**

Dropdown values and Project values will be autopopulated

**Date**

Date picker

**Amount**

Text field to add amount (Only numeric value)

**Notes(Optional)**

Text Fileds
#491
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Field Details & Validations** > **4.3 OPEX (Operating Expenses) Categories**
~108 tok
### **4.3 OPEX (Operating Expenses) Categories**

**Category Group**

**Specific Categories**

**Select Brand**

Drop-down values, Brand values will auto-populate

**Select Category**

Drop-down values will auto-populate with OPEX values

**Select Contrcator**

Drop-down values with the respective contractors from the brand

**Date**

Date picker

**Amount**

Text field to add amount (Only numeric value)

**Notes**

Text Fileds
#492
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Field Details & Validations** > **4.4 Filter Panel Fields**
~151 tok
### **4.4 Filter Panel Fields**

**Field Name**

**Type**

**Validation Rules**

Contractor Toggle

Toggle Switch

Filter to show only contractor payment expenses  
  
On/Off state

Brand Filter

Dropdown

Filter expenses by brand association  
  
Must select from available brands, "All Brands" default

Date Filter

Date Range

Filter expenses by date range  
  
Start date ≤ end date, valid date format

Price Range

Number Range

Filter expenses by amount range (Min $0 - Max $200+)

Category Search

Text Input

Search within expense categories of both category  
  
Real-time search functionality
#493
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **4\. Field Details & Validations** >
~1 tok
###
#494
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **5\. Success Message Handling**
~76 tok
## **5\. Success Message Handling**

**Validation Scenario**

**Success Message**

Expense created successfully

"Expense has been added successfully."

Expense updated successfully

"Expense details have been updated successfully."

Expense deleted successfully

"Expense has been deleted successfully."
#495
**Functional Requirements Document (FRD) - Contractor Invoices Module** >
~1 tok
##
#496
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **6\. Error Message Handling**
~182 tok
## **6\. Error Message Handling**

**Field**

**Validation Scenario**

**Error Message**

Expense Type

Not selected

"Please select expense type (COGS or OPEX)"

Category

Not selected

"Please select a category."

Brand

Not selected

"Please select a brand."

Project

Not selected (when required for PM)

"Please select a project from your assigned projects."

Contractor

Not selected when required

"Please select a contractor for this expense."

Date

Invalid or empty date

"Please select a valid date."

Amount

Invalid or ≤ 0

"Please enter a valid expense amount greater than $0."

Amount

Non-numeric input

"Please enter a valid numeric amount."

Notes

Exceeds 250 characters

"Notes cannot exceed 250 characters."
#497
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **7\. Functional Logic**
~7 tok
## **7\. Functional Logic**
#498
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **7\. Functional Logic** > **Expense Type and Category Logic**
~126 tok
### **Expense Type and Category Logic**

*   **COGS Selection:** When the user selects the COGS expense type, the system displays only the COGS-related categories
*   **OPEX Selection:** When the user selects the OPEX expense type, the system displays only OPEX-related categories
*   **Contractor Category Logic:** When the "Contractors" category is selected, the contractor dropdown becomes required
*   **Category Validation:** System ensures selected category matches chosen expense type (COGS/OPEX)
#499
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **7\. Functional Logic** > **Project Assignment Logic**
~94 tok
### **Project Assignment Logic**

*   **PM User Restrictions:** Project Manager users can only select from assigned projects in the dropdown
*   **Optional Project Assignment:** Agency Owner and Admin can leave the project field empty for company-wide expenses
*   **Project-Specific Validation:** System validates that PM users cannot assign expenses to unassigned projects
#500
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **7\. Functional Logic** > **Brand Association Logic**
~86 tok
### **Brand Association Logic**

*   **Company-Wide Brand Selection:** All expenses can be associated with any brand or "All Brands"
*   **No Brand Restrictions:** No validation rules restrict which expense types can be assigned to specific brands
*   **Default Brand Setting:** System defaults to "All Brands" unless user selects specific brand
#501
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **7\. Functional Logic** > **QuickBooks Integration Logic**
~343 tok
### **QuickBooks Integration Logic**

*   **Automatic Sync Attempt:** Every new or modified expense automatically attempts QuickBooks synchronization
*   **Background Retry Logic:** Failed syncs retry automatically in the background at configured intervals
*   **Manual Sync Capability:** Users can manually trigger sync for failed expenses via the QuickBooks icon
*   **Sync Data Transfer:** All expense fields (amount, category, date, notes, project) sync to QuickBooks
*   **Sync Status Tracking:** The System maintains a persistent sync status for each expense record

**Price Range Filter Logic**

*   **System-Derived Min/Max:** The system automatically calculates the minimum value from the lowest expense amount in the dataset and the maximum value from the highest expense amount. These bounds update dynamically whenever the expense dataset changes.
*   **User Interaction:** The user can drag the range slider between the system-defined Min and Max bounds to filter the expense list. The slider reflects only the range within the actual data.
*   **Display:** The Min ()andMax() and Max ( )andMax() labels are shown above the slider as informational read-only values reflecting the current dataset range.
*   **Removal of Event Types Filter:** The Event Types dropdown has been removed from the filter panel. It is no longer part of the Expenses filter options.
#502
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **8\. Edge Cases**
~143 tok
## **8\. Edge Cases**

**Scenario**

**Expected Behavior**

QuickBooks service unavailable

Expense saved locally, background retry continues, manual sync available when service restored

Contractor toggle applied with no contractor expenses

Show "No contractor expenses found" message with option to clear filter

Category selection with no matching contractor

If contractor required but none available, show "No contractors available" message

Expense deletion with QuickBooks sync

Attempt to delete from QuickBooks, maintain local deletion regardless of sync success
#503
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **9\. Test Cases**
~5 tok
## **9\. Test Cases**
#504
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **10\. Acceptance Criteria**
~415 tok
## **10\. Acceptance Criteria**

*   **Role-Based Access Control:** PM users are restricted to assigned project expenses, Owner/Admins have full access to all expenses
*   **Expense Type Classification:** COGS and OPEX categories display correctly based on expense type selection
*   **Category Management:** All predefined categories from the COGS and OPEX lists are available and properly organized
*   **Contractor Integration:** Contractor dropdown appears only for the Contractors category, required when selected
*   **Project Assignment:** PM users can only assign expenses to assigned projects; others can leave the project optional
*   **Brand Association:** All expenses can be associated with any brand or "All Brands" without restrictions
*   **QuickBooks Integration:** Automatic sync attempts for all new/modified expenses, manual retry available for failures
*   **Filter Functionality:** Contractor toggle, brand filter, date range, price range, and category search work correctly
*   **Form Validation:** All required field validations work properly with appropriate error messaging
*   **CRUD Operations:** Create, read, update, and delete operations work according to user role permissions
*   **Data Persistence:** All expense data is stored correctly with proper formatting and validation
*   **Sync Status Tracking:** QuickBooks sync status displayed accurately with visual indicators
*   **Performance:** Pagination and filtering work efficiently for large expense datasets
*   **Filter Functionality:** Contractor toggle, brand filter, date range, price range slider (with system-generated min/max), and category search work correctly.
#505
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **11\. Dependencies**
~152 tok
## **11\. Dependencies**

**Module/System**

**Impact if Unavailable**

Brands Management

Cannot associate expenses with brands; brand filtering is unavailable

Contractor Management

Cannot select contractors for contractor category expenses

Project Management

Cannot assign expenses to projects, PM role restrictions fail

QuickBooks Integration

Sync functionality unavailable, manual accounting reconciliation required

Authentication System

Role-based access control fails; permission restrictions cannot be enforced

Client/Project Data

Project assignment and validation cannot function properly
#506
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **12\. QuickBooks Integration Specifications**
~12 tok
## **12\. QuickBooks Integration Specifications**
#507
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **12\. QuickBooks Integration Specifications** > **12.1 Sync Status Indicators**
~75 tok
### **12.1 Sync Status Indicators**

**Status**

**Visual Indicator**

**Description**

Synced

Green checkmark icon on the QuickBooks logo

Successfully synchronized with QuickBooks

Failed

Red cross icon with disabled QuickBooks logo

Sync failed, manual retry available by clicking on it to sync
#508
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **12\. QuickBooks Integration Specifications** >
~1 tok
###
#509
**Functional Requirements Document (FRD) - Contractor Invoices Module** > **13\. References**
~35 tok
## **13\. References**

*   [Figma](https://www.figma.com/design/ej0kxwP45mDKmZCZfAJ5O8/Pixally?node-id=28823-122672&t=ShhIDg0jGuZ3l3Li-0)