migration2026-07-19

Exporting Data off Niagawan: Full CSV Migration Guide to a Cloud General Ledger

A field-level Niagawan migration guide covering CSV exports, document mapping, opening balances, idempotency, and trial-balance verification.

GetPay Engineering Team
Updated: 2026-09-10

TL;DR (Key Takeaways)

  • Export each Niagawan module separately and keep the untouched CSV, report, and attachment files before cleaning or transforming anything.
  • Build a control sheet by module, financial year, row count, unique reference, and total; a folder full of CSV files is not yet a complete accounting archive.
  • Choose either transaction-level ledger migration or an opening-balance cutover. Never post both the historical transaction and its opening balance into the new general ledger.
  • Import master data before documents, documents before payments, and keep stable source references in an idempotency key so every batch can be replayed safely.
  • Do not cut over until the new trial balance ties by financial year, open receivables and payables tie to their schedules, and sampled source values match field by field.

What is the safest way to export data off Niagawan?

Export data off Niagawan in three layers: an untouched source archive, a transformation workspace, and a signed-off target ledger. Never clean the only copy of a CSV.

The practical sequence is:

  1. Freeze new entries in Niagawan at an agreed date and time.
  2. List every module the business used, including documents that do not affect the ledger.
  3. Export every available CSV or accounting report and save the original files read-only.
  4. Save document PDFs and attachments separately, with a manifest linking each file to its source reference.
  5. Record counts, date ranges, unique references, and control totals before transforming data.
  6. Transform copies into the target schema.
  7. Dry-run every import, review exceptions, and only then write to the cloud ledger.
  8. Reconcile values and balances before staff begin entering new transactions in the target.

Niagawan's published guidance identifies export capability for sales invoices, customers, products, inventory, purchase invoices, suppliers, purchase payments, invoice payments, profit and loss, trial balance, balance sheet, general ledger, and cash book statements. That list is a starting point, not proof that your account is fully backed up. Your own tenant may contain delivery orders, payment vouchers, quotations, credit documents, attachments, or custom operational history that must be inventoried separately.

What should the migration control workbook contain?

A migration control workbook is the evidence trail between “we downloaded files” and “the new books are complete.” Use one row per source module and financial year.

Control fieldWhat to record
Source moduleSales invoices, receipts, customers, products, cash book, general ledger, delivery orders, payment vouchers, or another used module
Source periodCalendar year and the business's actual financial year
Raw fileOriginal filename, export date, and checksum if available
Row controlExported rows, distinct source references, earliest date, latest date
Value controlGross amount, payment amount, debit total, credit total, or another module-appropriate total
Target objectcustomers, invoices, invoice_payments, bank_transactions, journal_entries, or document archive
Import resultInserted, matched, skipped, rejected, and duplicate counts
ReviewerPerson who checked the exception file and sample values

Keep three directories: raw/ for immutable exports, working/ for normalized files, and evidence/ for control totals, exception reports, screenshots, and sign-off. If a transformation fails, regenerate it from raw/; do not repair the raw file in place.

This discipline mattered in GetPay's own July 2026 migration. The first-party project moved 578 invoices and 568 receipts, then later closed operational gaps by migrating 333 delivery orders and 514 payment vouchers. Those counts are not a benchmark for another company. They illustrate why a sales-and-receipts export alone can still miss important audit and service history.

Which Niagawan fields map into a cloud general ledger?

Map source meaning, not just column position. CSV layouts can change, and a visually similar column can contain a different concept.

For each customer, preserve a stable source identity, name, company name, contact details, tax identifiers if legitimately present, and the unmodified raw value when normalization is uncertain. Do not “fix” an ambiguous telephone number or merge two similar names automatically. Put uncertain values into a review queue.

For each sales invoice, normalize at least:

  • source reference to invoice_number;
  • transaction date to issue_date;
  • contractual payment date to due_date;
  • customer link to customer_id;
  • line description, quantity, unit price, discount, tax treatment, and line total;
  • document subtotal, tax amount, and total;
  • source status and outstanding amount;
  • original notes and provenance; and
  • a stable idempotency_key, such as niagawan:{source_ref}.

For each receipt, keep receipt_number, payment_date, amount, the related invoice reference, payment method where available, and its own idempotency key. Link the receipt to the imported invoice; do not match by customer name and amount alone.

Niagawan may describe an invoice as Paid, Unpaid, or Partial. The target may model state differently. GetPay, for example, has no manually stored PARTIAL invoice status in this migration path. It records the actual rows in invoice_payments; a fully covered invoice becomes PAID, while the unpaid remainder is represented by the payment sum and the invoice's ISSUED or OVERDUE state. Preserve the source status in notes or migration metadata so the conversion remains auditable.

Should historical documents post into the new general ledger?

Choose one accounting basis before importing:

MethodWhat enters the target GLWhen it fits
Full historical rebuildOne balanced journal effect for every historical transactionThe target will become the complete transaction-level ledger for all migrated years
Opening-balance cutoverOne controlled opening journal at cutover, plus new transactions after cutoverHistorical documents are retained for lookup, while prior-period balances are brought forward
Existing-ledger overlayNo new GL effect for document history already represented in the targetThe target already holds audited or reconciled journals and needs only missing documents

Never combine the first two for the same amount. If an unpaid historical invoice is posted as Dr Accounts Receivable / Cr Sales Revenue and the same receivable is included again in the opening balance, assets and income are overstated.

GetPay's own Niagawan migration used the third pattern for migrated invoices. The documents were retained with idempotency_key values matching niagawan:%, remained document-only, and were protected from automatic sale, payment, credit-note, write-off, and backfill posting. This was an explicit accounting boundary, not an importer limitation.

A normal new sale in a posted ledger may create:

Dr Accounts Receivable
  Cr Sales Revenue
  Cr Tax Payable, where applicable

Its customer payment may create:

Dr Bank
  Cr Accounts Receivable

Those lines explain the target accounting, but they must not be generated again for a document whose effect is already present in an opening balance or an existing journal.

How do you prepare opening balances without double-counting?

Pick a cutover timestamp, close all source entries through that point, and produce the final trial balance plus supporting schedules. Opening balances must come from that final, reviewed position—not from summing convenient CSV columns.

A balanced opening journal commonly contains:

Dr Bank and cash balances
Dr Accounts Receivable from the open-invoice schedule
Dr Inventory, fixed assets, deposits, and other debit balances
  Cr Accounts Payable from the open-bill schedule
  Cr Loans, tax liabilities, and other credit balances
  Cr Capital or retained earnings as supported by the closing books

The debit total must equal the credit total exactly. Do not create an unexplained “migration suspense” amount merely to force balance. If a difference remains, stop and trace it to the source trial balance, the account map, a sign convention, a missing module, or a duplicated transaction.

Import open invoices and open bills as subledger documents so customer and supplier schedules remain usable. Mark them document-only if their control-account values are already in the opening journal. The opening Accounts Receivable must equal the sum of outstanding customer invoices at the same timestamp; Accounts Payable must equal the open supplier schedule.

Use a dependency-first order:

  1. Create the target chart-of-accounts map and approve every unmapped account.
  2. Import customers, suppliers, products, tax settings, bank accounts, and other master data.
  3. Import sales invoices, purchase invoices, quotations, delivery orders, and payment vouchers.
  4. Import invoice receipts and supplier payments only after their parent documents exist.
  5. Import bank transactions and pair transfers without treating both bank legs as income or expense.
  6. Post the approved opening journal or historical journals, according to the chosen basis.
  7. Link attachments after target document IDs are stable.
  8. Run all control and value-level reconciliations.

Each batch should fail closed. A receipt with no matching invoice, a document with two possible customers, or a ledger row with no approved account map belongs in an exception file. LIMIT 1, first-name matching, and silent fallbacks turn visible migration problems into hidden accounting errors.

The GetPay migration parsers followed the same separation of duties: they parsed and validated files, produced dry-run evidence, and emitted reviewable batches without holding database credentials. A single authorized operator performed the live write after sample review.

How should idempotency work?

Every imported record needs a source-derived identity that survives retries. For a document, the pattern can be:

niagawan:{document_reference}

For distinct document families, include the family:

niagawan:invoice:{reference}
niagawan:receipt:{reference}
niagawan:do:{reference}

Enforce uniqueness within the company or tenant, not globally across unrelated businesses. On replay, the importer should return the existing record or perform a deliberate no-op. It must not silently create a second invoice because a network response was lost.

Also test parent consistency. Reusing a receipt idempotency key against a different invoice should fail, not “succeed” by returning an unrelated prior row. After the first successful import, run the same batch again and prove that inserted counts remain zero and all source references resolve to the same target IDs.

How do you verify a Niagawan migration?

Verification has four layers.

1. Census

For every module and period, compare source rows, distinct references, date range, and target rows. Investigate gaps and duplicates individually. Counts are necessary but insufficient.

2. Value sampling

Select records across early, middle, and late periods, plus paid, unpaid, partial, cancelled, high-line-count, tax, and unusual-name cases. Compare source and target field by field: reference, dates, party, item text, quantity, price, tax, total, payment allocation, status, and notes.

3. Accounting reconciliation

For every financial year:

  • target trial-balance debits must equal target credits;
  • each mapped account must tie to the approved source balance or documented cutover treatment;
  • Accounts Receivable must tie to the open-customer schedule;
  • Accounts Payable must tie to the open-supplier schedule;
  • bank balances must tie to bank statements, not merely to a software report; and
  • retained earnings must roll forward consistently from closing profit or loss.

4. Negative controls

Prove there are no imported rows in the wrong tenant, no duplicate source references, no orphan receipts, no missing parent documents, and no journal entries attached to records designated document-only. Replay the import to prove idempotency. Verify attachments by filename, byte size, and checksum where possible.

A successful trial-balance tie-out does not excuse corrupted names, dates, or descriptions. A successful count does not prove the values survived. Both accounting totals and sampled real values must pass.

When is it safe to stop using Niagawan?

Cut over only after the freeze snapshot, raw archive, target imports, trial-balance tie-out, subledger tie-outs, bank reconciliation, exception sign-off, and staff workflow test are complete.

Keep Niagawan read-only during a defined assurance period if access remains available. Store an offline copy of the raw exports and attachments independently of both vendors. Agree retention periods and statutory evidence requirements with your accountant or tax adviser under the rules applicable to your entity; do not rely on a SaaS subscription as the only archive.

Finally, document the authority boundary: the old system is historical evidence up to the cutover, and the cloud general ledger is the only place for new entries after it. Without that rule, staff can reopen dual books even after a technically perfect migration.

Frequently Asked Questions

Can I export all Niagawan accounting data in one CSV?

Plan for module-by-module exports, not one universal file. Niagawan's own guidance lists export buttons across sales invoices, customers, products, inventory, purchase invoices, suppliers, payments, profit and loss, trial balance, balance sheet, general ledger, and cash book reporting. Inventory every module you actually used because operational documents and attachments may need separate handling.

Does GetPay have a one-click Niagawan importer?

The migration described here did not use a named, one-click Niagawan whole-ledger importer. GetPay has a generic customer CSV intake path, while the full migration used controlled parsers, dry runs, operator review, idempotent database batches, and value-level verification. Treat this article as a migration playbook, not a claim that every file can be uploaded through one screen.

Should imported Niagawan invoices create journal entries?

Only if your migration design intentionally rebuilds the historical ledger transaction by transaction. If the new general ledger already contains audited history or you post opening balances at cutover, import old invoices as document-only records and do not auto-post them. In GetPay, Niagawan-provenance documents use idempotency keys beginning with niagawan: and are deliberately excluded from automatic posting and backfill.

How do I prove the migration is complete?

Reconcile source and target counts, unique references, and totals by module and financial year; then tie the target trial balance, receivables, payables, bank balances, and retained earnings. Finally, compare sampled records field by field and replay each import batch to prove that idempotency prevents duplicates.

Sources & Ground Truth

Direct LHDN MyInvois Submission Engine

Ready to automate your Malaysian e-invoicing & bookkeeping?

GetPay handles 100% compliant e-invoices, multi-bank reconciliation, and statutory payroll out of the box.

Get Started Free

Related Articles