Skip to main content

Imports: Unit Level Charge & Payment History

How to bring in your prior history per unit

This tool lets you backfill historical dues, fees, assessments, payments, and credits against individual units. It's designed for onboarding or reconstructing account history without affecting your General Ledger.

Where to Find It

Admin β†’ Financials β†’ Import Tools β†’ Unit Ledger History

Before You Begin

  1. Import your properties/units first. Addresses in your CSV are matched against existing properties in your system by street address. Any rows with unmatched addresses will be flagged as warnings.

  2. Preview before committing. The tool always runs in preview mode first - you'll see every row classified as ready, warning, or error before anything is written to the database.

  3. Balances are recalculated automatically for each affected unit after the import completes.

CSV Format

Your CSV needs these columns (header names are case-insensitive and accept several common aliases):

Column

Required

Description

unit_address

Yes

Street address that matches a property in your system (e.g. 5757 Old Lucerne Park Rd)

date

Yes

Transaction date in MM/DD/YYYY or YYYY-MM-DD format

type

Yes

One of: annual_dues, dues, monthly_dues, quarterly_dues, late_fee, fine, special_assessment, prior_balance, payment, credit, other

description

Yes

Free-text description (e.g. "2024 Annual Dues")

amount

Yes

Always a positive number - the sign is inferred from the type. Payments and credits become negative automatically.

status

No

paid or pending. Defaults to paid.

Header aliases: address, property, street_address, transaction_date, due_date, charge_type, transaction_type, memo, notes, total, and charge_status are all accepted.

The Two Approaches - Pick One Per Unit

This is the most important thing to get right. There are two valid ways to represent historical charges that have been paid, and mixing them will double-count the money and create phantom credit balances.


πŸ‘‰ Approach A: Import Charges as "Paid" (Recommended for Fully Settled History)

Each row is a self-contained historical record. Set status to paid on every charge row. Do not add separate payment rows.

Example:

unit_address,date,type,description,amount,status

123 Main St,01/15/2024,annual_dues,2024 Annual Dues,400.00,paid

123 Main St,03/31/2024,late_fee,Q1 Late Fee,25.00,paid

What happens behind the scenes: Each charge is created with status paid. No OfflinePayment records are created. The unit's charge history shows each settled charge. The balance is $0.

When to use this approach:

  • You're backfilling years of history that's already fully settled

  • Each charge was paid in full with its own transaction

  • You don't need to track which specific payments covered which specific charges


πŸ‘‰ Approach B: Import Charges as "Pending" + Separate Payment Rows

Leave charges with status set to pending (or blank β€” but note the default is paid, so you must explicitly set pending). Then add separate rows with type payment to represent the money that came in.

Example:

unit_address,date,type,description,amount,status

123 Main St,01/15/2024,annual_dues,2024 Annual Dues,400.00,pending

123 Main St,03/31/2024,late_fee,Q1 Late Fee,25.00,pending

123 Main St,04/10/2024,payment,Check #1234,425.00,

What happens behind the scenes: Two charges are created as pending. One OfflinePayment of $425 is created and auto-allocated to the oldest outstanding charges first. Both charges become paid (or partially_paid if the payment doesn't cover them fully). Any remainder becomes a credit on the unit.

When to use this approach:

  • One payment covers multiple charges

  • The payment amount differs from the charge total (partial payment, overpayment)

  • You want to preserve the original payment-to-charge relationships

  • You need to record overpayments as credits on the unit


‼️ Critical Rule: Do Not Mix Approaches

Do not import a charge as paid AND include a separate payment row that also covers that charge. This double-counts the money:

  • The charge shows $400 with status paid (settled)

  • The payment row creates a $400 OfflinePayment on the account

  • Result: unit shows a phantom $400 credit balance

If this happens: You'll see a credit on the account that doesn't reflect real money. The fix is to either delete the duplicate payment rows OR change the charges back to pending and let the system re-allocate.


Multiple Payments on the Same Unit

Approach B handles multiple payment rows cleanly. Payments are processed in date order, and each one auto-allocates against the oldest outstanding charges first:

unit_address,date,type,description,amount,status

123 Main St, 01/15/2024, annual_dues,2024 Annual Dues, 400.00, pending

123 Main St, 06/30/2024, special_assessment, Roof Assessment, 200.00, pending

123 Main St, 02/01/2024, payment, Check #1100, 400.00

123 Main St, 07/05/2024, payment, Check #1250, 250.00

Result: The $400 payment pays off the annual dues. The $250 payment covers the $200 assessment and leaves a $50 credit on the account.


Special Transaction Types

  • prior_balance β€” Use this for opening balances at the start of a fiscal year. Treated as a charge (positive).

  • credit β€” Same effect as a payment row: reduces balance, auto-allocates to outstanding charges, any remainder becomes a credit on the unit.

  • late_fee, fine, special_assessment, other β€” All treated as regular charges.


How the Preview Works

When you upload your CSV, the system:

  1. Parses every row and normalizes headers

  2. Matches each unit_address against your existing properties using fuzzy street-address matching

  3. Classifies each row:

    • Ready β€” all required fields valid, address matched β€” will be imported

    • Warning β€” address couldn't be matched β€” row will be skipped

    • Error β€” missing/invalid data (bad date, invalid type, zero amount) β€” row will be skipped

  4. Flags duplicates β€” rows with the same address, date, type, and amount are flagged but still imported (you may have legitimate duplicates, like two late fees on the same day)

  5. Shows a summary with counts: ready, warnings, errors, total charges, total credits, unique units affected

You then confirm to execute the actual import.


What Happens During Import

  1. Phase 1: Charges are created first (all non-payment/credit rows). Each becomes a UnitCharge with the status you specified.

  2. Phase 2: Payments/Credits are created as OfflinePayment records and auto-allocated against outstanding charges on the same unit (oldest first).

  3. Phase 3: Balance Recalculation β€” every affected unit's account summary is recomputed.


Multi-Year History

You can include multiple years of transactions in a single CSV. The system sorts and processes everything correctly. There's no year limit.


Verifying the Results

After import, navigate to Community Management β†’ Units β†’ [any affected unit] and check:

  • Charge History β€” should show each charge with the correct status

  • Payment History β€” should show any payments imported under Approach B (labeled "Imported")

  • Account Summary β€” balance should match your expectation

If a balance looks wrong:

  • Most common cause: mixed Approach A and Approach B for the same unit

  • Vlge Support team can "Recalculate All Balances" to force a full re-computation across all units if needed


Troubleshooting

Problem

Likely Cause

Fix

Unit shows phantom credit balance

Mixed Approach A (paid charges) with payment rows for the same period

If this happens, you should contact support so we can reverse that import. For audit purposes, payments typically cannot be deleted at the organization level.

Address not matched

CSV address doesn't match property address closely enough

Edit the CSV to use the exact street format, or add the property first

Dates off by one day

Date format ambiguity or timezone issue

Use YYYY-MM-DD format for unambiguous parsing

Charges imported but no payment history

Used Approach A (payments embedded as "paid" status)

This is correct behavior - Payment History only shows separate payment rows

Balance didn't update

Rare - import completed before balance job finished

Contact support to Recalculate All Balances

Download a Template

On the import page, click Download Template to get a sample CSV with the correct column headers and example rows.

Did this answer your question?