> ## Documentation Index
> Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt
> Use this file to discover all available pages before exploring further.

# FA Module: D365 Business Central Migration Guide

> This guide outlines the strategy, tools, and processes for migrating financial data from Microsoft Dynamics 365 Business Central to the Encore OS FA (Finance &…

**Target Audience:** Implementation Team, Data Migration Specialists, CFO/Controller

***

## 1. Overview

This guide outlines the strategy, tools, and processes for migrating financial data from **Microsoft Dynamics 365 Business Central** to the **Encore OS FA (Finance & Accounting) module**.

### 1.1 Migration Scope

**Data to Migrate:**

* Chart of Accounts (Account Master)
* Fiscal Year and Period Definitions
* General Ledger (Historical Balances)
* Vendor Master and Open Payables
* Customer Master and Open Receivables
* Open Purchase Orders (if applicable)
* Budget Data (if applicable)

**Data NOT Migrated:**

* Closed transactions older than 7 years (per retention policy)
* Draft/cancelled transactions
* System audit logs (start fresh in Encore OS)

### 1.2 Migration Phases

| Phase                             | Timeline   | Description                                                  |
| --------------------------------- | ---------- | ------------------------------------------------------------ |
| **Phase 1: Planning**             | Week 1-2   | Data assessment, mapping, resource allocation                |
| **Phase 2: Setup**                | Week 3-4   | Configure Encore OS FA, create CoA, define funds/departments |
| **Phase 3: Data Extraction**      | Week 5     | Export data from D365 BC via SQL/Excel                       |
| **Phase 4: Transformation**       | Week 6-7   | Map D365 fields to Encore OS schema, cleanse data            |
| **Phase 5: Load & Validate**      | Week 8-9   | Import data to Encore OS, validate balances                  |
| **Phase 6: Parallel Run**         | Week 10-11 | Run both systems in parallel, reconcile daily                |
| **Phase 7: Cutover**              | Week 12    | Go-live on Encore OS, freeze D365 BC                         |
| **Phase 8: Post-Cutover Support** | Week 13-16 | Monitor, troubleshoot, user training                         |

**Total Timeline:** \~4 months (including parallel run and stabilization)

***

## 2. Chart of Accounts Mapping

### 2.1 D365 BC Structure

D365 Business Central uses a flat account structure:

```
Account Number: 1010
Account Name: Cash - Operating Account
Account Type: Bank Account
Direct Posting: Yes
```

### 2.2 Encore OS FA Structure

Encore OS uses fund accounting with multi-dimensional tracking:

```
Account Number: 1010
Account Name: Cash - Operating Account
Account Type: Asset
Account Subtype: Bank Account - Checking
Fund: Unrestricted General Fund
Requires Department: No
Requires Program: No
```

### 2.3 Mapping Strategy

**Step 1: Export D365 CoA**

```sql theme={null}
-- SQL query for D365 BC (adjust table names)
SELECT 
  "No_" AS account_number,
  "Name" AS account_name,
  "Account Type" AS account_type,
  "Income/Balance" AS income_balance,
  "Direct Posting" AS direct_posting,
  "Blocked" AS is_blocked
FROM "G/L Account"
WHERE "Direct Posting" = 1 -- Only posting accounts
ORDER BY "No_";
```

**Step 2: Map Account Types**

| D365 BC Account Type  | Encore OS Account Type            | Notes                                           |
| --------------------- | --------------------------------- | ----------------------------------------------- |
| Bank Account          | Asset (Bank Account - Checking)   | Map to cash account subtype                     |
| Accounts Receivable   | Asset (Accounts Receivable)       |                                                 |
| Fixed Assets          | Asset (Fixed Assets)              |                                                 |
| Accounts Payable      | Liability (Accounts Payable)      |                                                 |
| Long-term Liabilities | Liability (Long-term Liabilities) |                                                 |
| Equity                | Equity (Net Assets)               | Nonprofits use "Net Assets" instead of "Equity" |
| Revenue               | Revenue                           | Map to appropriate revenue subtype              |
| Cost of Goods Sold    | Expense (Direct Program Costs)    |                                                 |
| Operating Expenses    | Expense (Operating Expenses)      |                                                 |

**Step 3: Assign Funds**

Default all accounts to "Unrestricted General Fund" unless:

* Account number starts with "3xxx" (Restricted Grant Accounts) → Assign to specific grant fund
* Account name contains "Endowment" → Assign to "Permanently Restricted Fund"

**Step 4: Determine Departmental Requirements**

* Expense accounts → `requires_department = true`
* Revenue accounts → `requires_program = true` (for program attribution)

***

## 3. General Ledger Migration

### 3.1 Balance Migration (Opening Balances)

**Recommended Approach:** Migrate opening balances as of fiscal year start, NOT transaction-by-transaction.

**Step 1: Extract Trial Balance from D365 BC**

```sql theme={null}
SELECT 
  g."No_" AS account_number,
  g."Name" AS account_name,
  SUM(CASE WHEN e."Debit Amount" > 0 THEN e."Debit Amount" ELSE 0 END) AS total_debits,
  SUM(CASE WHEN e."Credit Amount" > 0 THEN e."Credit Amount" ELSE 0 END) AS total_credits
FROM "G/L Entry" e
JOIN "G/L Account" g ON e."G/L Account No_" = g."No_"
WHERE e."Posting Date" <= '2024-12-31'  -- As of last day of prior fiscal year
GROUP BY g."No_", g."Name"
HAVING SUM(e."Debit Amount" - e."Credit Amount") <> 0;
```

**Step 2: Create Opening Balance Journal Entry in Encore OS**

```typescript theme={null}
// Create journal entry with all opening balances
const openingBalanceEntry = {
  organization_id: orgId,
  fiscal_period_id: firstPeriodId,
  entry_date: '2025-01-01',
  entry_type: 'opening_balance',
  description: 'Opening balances migrated from D365 BC',
  reference_number: 'D365-MIGRATE-OB-2025',
  lines: trialBalanceData.map((row, index) => ({
    line_number: index + 1,
    account_id: accountMap[row.account_number], // Mapped Encore OS account ID
    debit_amount: row.total_debits > row.total_credits ? row.total_debits - row.total_credits : null,
    credit_amount: row.total_credits > row.total_debits ? row.total_credits - row.total_debits : null,
    description: `Opening balance - ${row.account_name}`
  }))
};
```

**Step 3: Post Entry and Validate**

* Entry must balance (total debits = total credits)
* Run trial balance in Encore OS and compare to D365 BC trial balance
* Reconcile to penny-level accuracy

***

### 3.2 Transaction-Level Migration (Optional)

**When to Use:**

* Regulatory requirement to maintain transaction history (e.g., grant audit trail)
* Need to drill down to original journal entries for forensic accounting

**Process:**

1. Export ALL D365 BC journal entries for fiscal year
2. Map entry types (General, Payment, Invoice, etc.) to Encore OS entry types
3. Create journal entries in Encore OS with `migrated_from_d365 = true` flag
4. Post all entries to recreate historical balances

**Warning:** This is MUCH slower and more complex. Only use if legally required.

***

## 4. Vendor & Customer Migration

### 4.1 Vendor Master Migration

**Step 1: Export Vendors from D365 BC**

```sql theme={null}
SELECT 
  "No_" AS vendor_number,
  "Name" AS vendor_name,
  "Address" AS address_line1,
  "Address 2" AS address_line2,
  "City",
  "State" AS state_province,
  "ZIP Code" AS postal_code,
  "Country/Region Code" AS country,
  "Phone No_" AS phone,
  "E-Mail" AS email,
  "Federal ID No_" AS tax_id,
  "Payment Terms Code" AS payment_terms,
  "Blocked" AS is_blocked
FROM "Vendor"
WHERE "Blocked" = 0;
```

**Step 2: Transform and Load to Encore OS**

```typescript theme={null}
const vendors = d365VendorData.map(v => ({
  organization_id: orgId,
  vendor_number: v.vendor_number,
  vendor_name: v.vendor_name,
  vendor_type: 'general', // Default, customize as needed
  address_line1: v.address_line1,
  address_line2: v.address_line2,
  city: v.City,
  state_province: v.state_province,
  postal_code: v.postal_code,
  country: v.country || 'US',
  phone: v.phone,
  email: v.email,
  tax_id_encrypted: await encryptTaxId(v.tax_id), // CRITICAL: Encrypt!
  payment_terms_days: mapPaymentTerms(v.payment_terms),
  is_active: !v.is_blocked,
  is_1099_eligible: v.tax_id ? true : false
}));

// Bulk insert
const { data, error } = await supabase.from('fa_vendors').insert(vendors);
```

***

### 4.2 Customer Master Migration

**Step 1: Export Customers from D365 BC**

```sql theme={null}
SELECT 
  "No_" AS customer_number,
  "Name" AS customer_name,
  "Address",
  "City",
  "State",
  "ZIP Code",
  "Country/Region Code",
  "Phone No_",
  "E-Mail",
  "Federal ID No_",
  "Payment Terms Code",
  "Blocked"
FROM "Customer"
WHERE "Blocked" = 0;
```

**Step 2: Load to Encore OS**

* Similar process to vendors
* Encrypt `tax_id_encrypted` field
* Map payment terms to days (e.g., "NET30" → 30)

***

## 5. Open Payables & Receivables

### 5.1 Open Vendor Bills

**Step 1: Export Open Payables from D365 BC**

```sql theme={null}
SELECT 
  "Vendor No_" AS vendor_number,
  "Document No_" AS bill_number,
  "Document Date" AS bill_date,
  "Due Date" AS due_date,
  "Amount" AS amount,
  "Remaining Amount" AS remaining_amount,
  "Description"
FROM "Vendor Ledger Entry"
WHERE "Remaining Amount" <> 0  -- Open invoices only
  AND "Document Type" IN ('Invoice', 'Credit Memo');
```

**Step 2: Create Vendor Bills in Encore OS**

```typescript theme={null}
const bills = d365PayablesData.map(b => ({
  organization_id: orgId,
  vendor_id: vendorMap[b.vendor_number], // Mapped Encore OS vendor ID
  bill_number: b.bill_number,
  bill_date: b.bill_date,
  due_date: b.due_date,
  amount: b.amount,
  amount_paid: b.amount - b.remaining_amount,
  amount_remaining: b.remaining_amount,
  status: b.remaining_amount === b.amount ? 'approved' : 'partial',
  approval_status: 'approved', // Pre-approved in D365
  description: b.Description
}));
```

***

### 5.2 Open Customer Invoices

**Step 1: Export Open Receivables from D365 BC**

```sql theme={null}
SELECT 
  "Customer No_" AS customer_number,
  "Document No_" AS invoice_number,
  "Document Date" AS invoice_date,
  "Due Date" AS due_date,
  "Amount" AS amount,
  "Remaining Amount" AS remaining_amount,
  "Description"
FROM "Cust. Ledger Entry"
WHERE "Remaining Amount" <> 0
  AND "Document Type" = 'Invoice';
```

**Step 2: Create Invoices in Encore OS**

* Similar process to vendor bills
* Update invoice status (`sent`, `partial`, `overdue`)

***

## 6. Budget Migration

### 6.1 D365 BC Budget Export

```sql theme={null}
SELECT 
  b."Budget Name",
  b."G/L Account No_",
  b."Date" AS period_start,
  SUM(b."Amount") AS budget_amount
FROM "G/L Budget Entry" b
WHERE b."Budget Name" = 'FY2025 Budget'
GROUP BY b."Budget Name", b."G/L Account No_", b."Date"
ORDER BY b."Date", b."G/L Account No_";
```

### 6.2 Encore OS Budget Load

```typescript theme={null}
// Create budget header
const { data: budget } = await supabase.from('fa_budgets').insert({
  organization_id: orgId,
  fiscal_year: 2025,
  budget_name: 'FY2025 Operating Budget (Migrated)',
  status: 'approved'
}).select().single();

// Create budget lines
const budgetLines = d365BudgetData.map(b => ({
  budget_id: budget.id,
  account_id: accountMap[b["G/L Account No_"]],
  period_month: new Date(b.period_start).getMonth() + 1,
  budget_amount: b.budget_amount,
  department_id: null, // Assign if D365 has dimension data
  program_id: null
}));

await supabase.from('fa_budget_lines').insert(budgetLines);
```

***

## 7. Data Validation & Reconciliation

### 7.1 Validation Checklist

**Pre-Migration Validation:**

* [ ] D365 BC trial balance balanced (debits = credits)
* [ ] All account numbers mapped to Encore OS accounts
* [ ] Vendor/customer counts match (D365 export vs Encore OS import)
* [ ] Open payables total matches D365 BC Accounts Payable balance
* [ ] Open receivables total matches D365 BC Accounts Receivable balance

**Post-Migration Validation:**

* [ ] Encore OS trial balance matches D365 BC trial balance (by account)
* [ ] Total assets = Total liabilities + Total equity
* [ ] Cash account balance matches bank reconciliation
* [ ] Vendor aging report totals match
* [ ] Customer aging report totals match
* [ ] Budget totals match (revenue and expense)

***

### 7.2 Reconciliation Report

**Generate Comparison Report:**

```sql theme={null}
-- Compare D365 BC vs Encore OS balances
SELECT 
  d.account_number,
  d.account_name,
  d.d365_balance,
  n.northsight_balance,
  (n.northsight_balance - d.d365_balance) AS variance
FROM d365_trial_balance d
FULL OUTER JOIN northsight_trial_balance n 
  ON d.account_number = n.account_number
WHERE ABS(n.northsight_balance - d.d365_balance) > 0.01  -- Variance > 1 cent
ORDER BY ABS(variance) DESC;
```

**Investigate Variances:**

* Variance > \$0.01 requires investigation
* Common causes: rounding errors, unmapped accounts, missing transactions
* Document all variances in migration log

***

## 8. Parallel Run Strategy

### 8.1 Parallel Run Duration

**Timeline:** 2-4 weeks (minimum 1 full month-end close)

**Process:**

1. **Week 1-2:** Post all transactions in BOTH D365 BC and Encore OS
2. **Week 3-4:** Reconcile daily balances between systems
3. **Month-End Close:** Perform month-end in both systems, compare financial statements
4. **Go/No-Go Decision:** If variance \< \$100 total and all reconciliations complete, proceed to cutover

***

### 8.2 Daily Reconciliation Procedure

**End of Day (5:00 PM):**

1. Print trial balance from D365 BC
2. Print trial balance from Encore OS FA
3. Compare account-by-account
4. Investigate any variance > \$1
5. Document findings in `parallel_run_log.xlsx`

**Weekly Review:**

* Finance team meeting every Friday at 2 PM
* Review week's variances
* Identify process improvements
* Update user training materials

***

## 9. Cutover Plan

### 9.1 Cutover Timeline

**Friday, 5:00 PM (Last day of parallel run):**

* [ ] Final reconciliation complete
* [ ] All variances documented and resolved
* [ ] CFO approval obtained
* [ ] Users notified of cutover window

**Friday, 5:00 PM - Monday, 8:00 AM (Cutover Window):**

* [ ] Freeze D365 BC (read-only mode)
* [ ] Post final journal entries in Encore OS
* [ ] Run final trial balance and financial statements
* [ ] Update DNS/URLs to point to Encore OS
* [ ] Send go-live notification to all users

**Monday, 8:00 AM (Go-Live):**

* [ ] Users begin using Encore OS FA exclusively
* [ ] On-site support available for first 3 days
* [ ] Helpdesk tickets monitored hourly

***

### 9.2 Rollback Plan

**Criteria for Rollback:**

* Critical system failure preventing GL posting
* Data corruption discovered in Encore OS
* Unrecoverable variance in financial statements

**Rollback Procedure:**

1. Re-enable D365 BC posting
2. Notify all users to revert to D365 BC
3. Schedule emergency meeting with implementation team
4. Analyze root cause
5. Reschedule cutover after issues resolved

***

## 10. Post-Cutover Support

### 10.1 Support Schedule

**Week 1 (Critical Support):**

* On-site support: 8 AM - 6 PM daily
* Helpdesk: 24/7 monitoring
* Daily check-ins with CFO and Controller

**Week 2-4 (Standard Support):**

* On-site support: 8 AM - 5 PM Mon-Fri
* Helpdesk: Standard hours (8 AM - 8 PM)
* Weekly check-ins with finance team

**Month 2+:**

* Helpdesk: Standard hours
* Monthly user training refreshers
* Quarterly system health review

***

### 10.2 Training Plan

**Pre-Cutover Training:**

* [ ] 2-hour overview session for all finance staff
* [ ] Hands-on training: Journal entries and month-end close
* [ ] Hands-on training: Vendor bill processing and payments
* [ ] Hands-on training: Customer invoicing and receipts
* [ ] Hands-on training: Financial reporting

**Post-Cutover Training:**

* [ ] Just-in-time training during first week
* [ ] Advanced topics (budgeting, consolidation) in month 2
* [ ] Admin training (chart of accounts maintenance) in month 2

***

## 11. Migration Tools & Scripts

### 11.1 SQL Export Scripts

**Location:** `migrations/d365-export/`

* `export_coa.sql` - Chart of Accounts export
* `export_trial_balance.sql` - Trial balance as of cutover date
* `export_vendors.sql` - Vendor master
* `export_customers.sql` - Customer master
* `export_open_payables.sql` - Open vendor bills
* `export_open_receivables.sql` - Open customer invoices
* `export_budgets.sql` - Budget data

***

### 11.2 Transformation Scripts

**Location:** `migrations/transform/`

* `transform_coa.ts` - Map D365 accounts to Encore OS schema
* `transform_vendors.ts` - Cleanse and encrypt vendor data
* `transform_customers.ts` - Cleanse and encrypt customer data
* `validate_balances.ts` - Compare D365 vs Encore OS balances

**Usage:**

```bash theme={null}
# Run transformation
npm run migrate:transform -- --source d365-export/coa.csv --output encoreos-load/accounts.json

# Validate
npm run migrate:validate -- --d365-trial-balance d365-export/trial_balance.csv
```

***

### 11.3 Data Load Scripts

**Location:** `migrations/load/`

* `load_accounts.ts` - Bulk insert chart of accounts
* `load_vendors.ts` - Bulk insert vendors
* `load_customers.ts` - Bulk insert customers
* `load_opening_balances.ts` - Create opening balance journal entry
* `load_open_payables.ts` - Create open vendor bills
* `load_open_receivables.ts` - Create open customer invoices

***

## 12. Known Issues & Workarounds

### 12.1 D365 BC Multi-Currency

**Issue:** Encore OS FA v1.0 does not support multi-currency.

**Workaround:**

* Convert all foreign currency balances to USD at cutover date exchange rate
* Document exchange rates used in migration log
* Plan for multi-currency support in Encore OS FA v1.1 (Q2 2026)

***

### 12.2 D365 BC Dimensions

**Issue:** D365 BC has 8 dimensions (Department, Program, Grant, etc.), Encore OS FA has 3 (Fund, Department, Program).

**Workaround:**

* Map D365 "Department" dimension to Encore OS `department_id`
* Map D365 "Program" dimension to Encore OS `program_id`
* Map D365 "Grant" dimension to Encore OS `fund_id` (create fund per grant)
* Additional dimensions (Project, Location, etc.) stored in `custom_fields` JSONB column

***

### 12.3 D365 BC Fixed Assets

**Issue:** Encore OS FA v1.0 does not include fixed asset module (depreciation, asset tracking).

**Workaround:**

* Migrate fixed asset GL account balances only (not detail records)
* Continue using D365 BC fixed asset module for depreciation
* Post monthly depreciation entries from D365 BC to Encore OS via journal entry
* Plan for fixed asset module in Encore OS FA v1.2 (Q3 2026)

***

## 13. Success Criteria

**Migration is successful when:**

* [ ] All account balances reconciled to penny-level accuracy
* [ ] All open payables and receivables migrated and reconciled
* [ ] First month-end close completed successfully in Encore OS
* [ ] Financial statements match prior month D365 BC statements
* [ ] All users trained and comfortable with Encore OS FA
* [ ] No critical or high-severity issues outstanding
* [ ] CFO sign-off obtained

***

## 14. Contacts & Resources

**Migration Project Manager:**

* Name: \[TBD]
* Email: \[TBD]
* Phone: \[TBD]

**D365 BC Expert:**

* Name: \[TBD]
* Credentials: D365 BC Functional Consultant

**Encore OS Implementation Lead:**

* Name: \[TBD]
* Credentials: Encore OS Certified Developer

**Escalation Path:**

* Level 1: Implementation team
* Level 2: Encore OS Product Manager
* Level 3: Encore OS CTO

***

**Document Status:** OUTLINE - To be completed before migration begins\
**Next Review:** Before Phase 1 kickoff meeting
