Skip to main content

Overview

Creating a dividend pool establishes the framework for distributing a specific amount of retained earnings to eligible members over a defined time period. Pools start in draft status and must be distributed separately to make actual payments.
What happens: Creating a pool sets up the metadata (period, amount, label) but does NOT distribute any funds or create journal entries. Pools start as drafts with journalEntryId = null and must be distributed separately.

Before You Begin

Prerequisites:
  • You have dividends:write permission
  • You have decided on the dividend period (start and end dates)
  • You have determined the total dividend amount to distribute
  • You have sufficient retained earnings balance
  • You understand your organization’s distribution method (equal or by_contribution)
  • You understand time-weighting settings (if enabled)
Distribution method is organization-level: The distribution method (equal vs. by_contribution) and time-weighting settings are configured at the organization level in dividend settings, NOT per pool. All pools use the same distribution rules.

Step-by-Step Instructions

Step 1: Navigate to Dividends

1

Open Dividends section

Click Dividends in the left sidebar
2

Click Add Pool or New Pool

Opens the dividend pool creation dialog

Step 2: Enter Pool Details

FieldDescriptionRequiredValidation
Period LabelDescriptive name for the period (e.g., “Q1 2026”)YesNon-empty string
Period StartFirst day of dividend eligibility periodYesISO date (YYYY-MM-DD), must be ≤ Period End
Period EndLast day of dividend eligibility periodYesISO date (YYYY-MM-DD), must be ≥ Period Start
AmountTotal amount to distribute from retained earningsYesMust be ≥ 0.01, respects currency scale
Field naming: The backend field is periodLabel, not “name” or “pool name”. This is a descriptive label for the dividend period.

Step 3: Define Dividend Period

The dividend period determines member eligibility and (if time-weighting is enabled) how allocations are calculated. Period Start:
  • First day members become eligible for this dividend
  • Typically the first day of the fiscal quarter/year
  • Format: YYYY-MM-DD (e.g., “2026-01-01”)
Period End:
  • Last day of dividend eligibility
  • Must be on or before the last closed accounting period end (validated at distribution time)
  • Format: YYYY-MM-DD (e.g., “2026-03-31”)
Examples: Quarterly dividend:
Period Label: "Q1 2026 Dividend"
Period Start: 2026-01-01
Period End: 2026-03-31
Amount: 5000000
Annual dividend:
Period Label: "2026 Annual Dividend"
Period Start: 2026-01-01
Period End: 2026-12-31
Amount: 20000000
Mid-year dividend:
Period Label: "H1 2026 Dividend"
Period Start: 2026-01-01
Period End: 2026-06-30
Amount: 10000000

Step 4: Choose Period Label

Use clear, specific labels that indicate the time period: Good labels:
  • “Q1 2026 Dividend”
  • “2026 Annual Dividend”
  • “January-March 2026”
  • “2026 Year-End Distribution”
  • “H2 2025 Member Dividend”
Poor labels:
  • “Dividend 1”
  • “Distribution”
  • “Money”
  • “Pool”
Naming guidelines:
  • Include the time period (year, quarter, month range)
  • Include the word “Dividend” for clarity
  • Keep concise but descriptive (under 50 characters)
  • Use consistent naming convention across all pools

Step 5: Set Dividend Amount

Enter the total amount to distribute from retained earnings. Validation:
  • Amount must be ≥ 0.01
  • Amount must respect your currency scale (e.g., 2 decimals for RWF amounts like 1000.50)
  • Amount will be normalized to valid precision automatically
Determining amount:
  1. Check retained earnings balance:
    • View retained earnings balance in the dividend creation form
    • Or navigate to General Ledger → View RETAINED_EARNINGS account balance
    • Dividend amount cannot exceed available retained earnings
  2. Consider organization policy:
    • Some organizations distribute a fixed percentage of profit (e.g., 50% of annual profit)
    • Others distribute a fixed amount per period (e.g., 2,000,000 RWF quarterly)
    • Refer to your bylaws or financial policies
  3. Calculate per-member amount (informational only):
    • Equal distribution: Amount ÷ Number of active members
    • By contribution: Amount allocated proportionally by savings contributions
    • This is automatic - you only enter total amount
Examples: 50% of quarterly profit:
Quarterly net profit: 8,000,000 RWF
Dividend amount: 4,000,000 RWF (50%)
Retained: 4,000,000 RWF
Fixed quarterly distribution:
Policy: Distribute 2,000,000 RWF every quarter regardless of profit
Amount: 2,000,000 RWF
Annual distribution:
Annual profit: 30,000,000 RWF
Target: Distribute 60% to members, retain 40% for reserves
Amount: 18,000,000 RWF
Retained earnings requirement: You must have sufficient retained earnings balance to cover the dividend amount. If retained earnings is insufficient, you cannot create the pool.

Step 6: Review Validation Constraints

Before submitting, verify: Period validation:
  • Period Start ≤ Period End
  • No overlapping periods with existing dividend pools
  • Period label is non-empty
Amount validation:
  • Amount ≥ 0.01
  • Amount respects currency scale
  • Sufficient retained earnings available
Overlapping periods: If another pool exists with an overlapping date range, creation will fail with error:
A dividend pool already exists for overlapping period: Q1 2026 Dividend
Example of overlap:
Existing pool: 2026-01-01 to 2026-03-31
New pool: 2026-02-01 to 2026-04-30
Result: ❌ Overlaps (Feb-Mar overlap)
Non-overlapping periods:
Existing pool: 2026-01-01 to 2026-03-31
New pool: 2026-04-01 to 2026-06-30
Result: ✅ No overlap

Step 7: Submit

1

Review all fields

Verify period dates are correct
Check amount is accurate
Confirm period label is descriptive
2

Click Save or Create Pool

Pool is created in draft status
3

Confirm creation

Pool appears in dividend pools list with status “Draft”
4

Distribute dividends (next step)

After creation, use “Distribute” action to calculate allocations and make payments

What Happens During Creation

When you create a dividend pool, Agatabo automatically:
  1. Validates period
    • Checks periodStart ≤ periodEnd
    • Checks for overlapping periods with existing pools
    • Validates amount is positive and respects currency scale
  2. Creates DividendPoolMeta record
    • Stores pool metadata (id, organizationId, periodLabel, periodStart, periodEnd, amount)
    • Sets journalEntryId = null (draft status)
    • Records creation timestamp
  3. Adds to pools list
    • Appears in dividend pools listing with status “Draft”
    • Queryable via /dividends/pools endpoint
    • Available for distribution
  4. Does NOT create journal entries
    • No accounting entries created yet
    • Retained earnings balance unchanged
    • No member allocations calculated yet
Important: Creating a pool does NOT distribute funds or create journal entries. The pool starts as a draft (journalEntryId = null). You must separately distribute the pool to calculate member allocations and create the accounting entries that debit retained earnings and credit member savings accounts.
Learn how to distribute pools →

Distribution Method (Organization-Level)

The distribution method determines how the total amount is allocated among eligible members. This is configured at the organization level in dividend settings, NOT per pool.

Distribution Methods

Equal Distribution (equal):
  • Total amount divided equally among all eligible members
  • Each active member receives the same amount
  • If time-weighting is enabled, amount is weighted by participation days
By Contribution (by_contribution):
  • Amount allocated proportionally based on net savings contributions during the period
  • Members with higher contributions receive larger dividends
  • If time-weighting is enabled, contributions are weighted by time
Organization-level setting: You cannot choose distribution method when creating a pool. All pools use the distribution method configured in your organization’s dividend settings. To change the distribution method, update organization dividend settings (requires admin access).

Time-Weighting (Organization-Level)

Time-weighting adjusts allocations based on how long members were active during the period. Without time-weighting:
  • Equal: All active members get equal shares
  • By contribution: Allocations based on total contributions (regardless of when made)
With time-weighting:
  • Equal: Shares weighted by participation days (days active during period)
  • By contribution: Contributions weighted by time (recent contributions count more)
Example (equal, time-weighted):
Period: Jan 1 - Mar 31 (90 days)
Total: 9,000,000 RWF
Members:
  - Alice: Active all 90 days → 90/180 × 9M = 4,500,000 RWF
  - Bob: Active 45 days (joined Feb 15) → 45/180 × 9M = 2,250,000 RWF
  - Carol: Active 45 days (left Feb 15) → 45/180 × 9M = 2,250,000 RWF
Total participation days: 180
Organization-level setting: Time-weighting is configured at the organization level, not per pool. All pools use the same time-weighting setting.

Common Scenarios

Creating Quarterly Dividend

Standard quarterly dividend distribution:
1

Determine quarter dates

Q1: Jan 1 - Mar 31
Q2: Apr 1 - Jun 30
Q3: Jul 1 - Sep 30
Q4: Oct 1 - Dec 31
2

Calculate amount

Based on quarterly profit and dividend policy
Example: 50% of quarterly net profit
3

Create pool

Period Label: “Q1 2026 Dividend”
Period Start: 2026-01-01
Period End: 2026-03-31
Amount: 4,000,000 (based on 8M profit × 50%)
4

Wait for accounting period closure

Ensure Q1 accounting period is closed before distributing
5

Distribute pool

Use “Distribute” action to calculate allocations and make payments

Creating Annual Dividend

End-of-year profit distribution:
1

Close fiscal year

Ensure all accounting periods for the year are closed
2

Calculate annual profit

Review Income Statement for the year
Determine net profit after all expenses
3

Determine distribution amount

Based on bylaws or board decision
Example: 60% to members, 40% to reserves
4

Create pool

Period Label: “2026 Annual Dividend”
Period Start: 2026-01-01
Period End: 2026-12-31
Amount: 18,000,000 (60% of 30M annual profit)
5

Distribute at AGM

Typically distributed during annual general meeting in January

Creating Special One-Time Dividend

Exceptional distribution from accumulated profits:
1

Identify surplus

Example: Large retained earnings balance from prior years
Board approves one-time distribution
2

Define period

Can use fiscal year or specific period
Example: Entire 2026 for eligibility determination
3

Create pool

Period Label: “2026 Special Distribution”
Period Start: 2026-01-01
Period End: 2026-12-31
Amount: 10,000,000 (board-approved amount)
4

Distribute

After approval and accounting period closure

Creating Multiple Pools (Quarterly Strategy)

Setting up all four quarterly dividends at once:
1

Create Q1 pool

Label: “Q1 2026 Dividend”
Period: 2026-01-01 to 2026-03-31
Amount: 2,000,000
2

Create Q2 pool

Label: “Q2 2026 Dividend”
Period: 2026-04-01 to 2026-06-30
Amount: 2,000,000
3

Create Q3 pool

Label: “Q3 2026 Dividend”
Period: 2026-07-01 to 2026-09-30
Amount: 2,000,000
4

Create Q4 pool

Label: “Q4 2026 Dividend”
Period: 2026-10-01 to 2026-12-31
Amount: 2,000,000
5

Distribute each quarter

Distribute each pool after its respective accounting period closes
Strategy advantage: Creating all pools upfront provides visibility into planned distributions and helps with financial planning. Each pool remains in draft status until distributed.

Validation and Constraints

Period Validation

Rules enforced at creation:
  • ✅ periodStart must be ≤ periodEnd
  • ✅ Period must not overlap with any existing pool
  • ✅ periodLabel must be non-empty string
Rules enforced at distribution (not creation):
  • periodEnd must be on or before last closed accounting period end
  • At least one accounting period must be closed
  • Distribution date must be after last closed period end
Overlap detection: Two periods overlap if:
pool1.periodStart <= pool2.periodEnd AND pool1.periodEnd >= pool2.periodStart
Example overlaps:
Pool 1: 2026-01-01 to 2026-03-31
Pool 2: 2026-02-01 to 2026-04-30
Result: ❌ Overlaps (Feb-Mar)

Pool 1: 2026-01-01 to 2026-03-31
Pool 2: 2026-03-31 to 2026-06-30
Result: ❌ Overlaps (Mar 31 is in both)

Pool 1: 2026-01-01 to 2026-03-31
Pool 2: 2026-04-01 to 2026-06-30
Result: ✅ No overlap

Amount Validation

Rules:
  • ✅ Amount must be ≥ 0.01
  • ✅ Amount must respect currency scale (e.g., max 2 decimals for RWF)
  • ✅ Amount is automatically normalized to valid precision
  • ⚠️ Sufficient retained earnings recommended (not enforced at creation, but required for distribution)
Invalid amounts:
Amount: 0 → ❌ Must be > 0
Amount: -1000 → ❌ Must be positive
Amount: 1000.567 (RWF with 2 decimal scale) → ❌ Too many decimals
Valid amounts:
Amount: 0.01 → ✅ Minimum
Amount: 1000000 → ✅ Standard
Amount: 1000000.50 → ✅ Valid precision

Period Label Validation

Rules:
  • ✅ Must be non-empty string
  • ✅ No uniqueness constraint (can reuse labels, but not recommended)
  • ✅ No length limit (but keep reasonable)

Best Practices

Dividend pool best practices:Period Definition:
  • Use consistent period boundaries (e.g., always calendar quarters)
  • Align with accounting period structure for easier closure
  • Don’t create pools far in advance - wait until profit is confirmed
  • Use fiscal year boundaries for annual dividends
Labeling:
  • Include time period in label (quarter, year, month range)
  • Use consistent naming convention across all pools
  • Add “Dividend” to labels for clarity in reports
  • Examples: “Q1 2026 Dividend”, “2026 Annual Dividend”
Amount Determination:
  • Base on documented dividend policy (% of profit)
  • Get board/member approval for amounts
  • Verify retained earnings balance before creating pool
  • Consider reserve allocations before dividend distribution
  • Document rationale in meeting minutes
Timing:
  • Create pools after accounting periods are closed
  • Wait for profit/loss determination before setting amounts
  • Don’t create pools too far in advance (profit projections may change)
  • Create quarterly pools within 1-2 weeks after quarter end
Financial Planning:
  • Maintain minimum retained earnings cushion after distribution
  • Allocate to reserves before creating dividend pools
  • Consider upcoming expenses and cash flow needs
  • Document dividend policy in bylaws
Governance:
  • Get member approval for dividend policy (rate, frequency)
  • Board approves specific dividend amounts
  • Document decisions in meeting minutes
  • Report dividend pools and distributions at member meetings
Distribution Method:
  • Understand organization-level distribution method before creating pools
  • Communicate method to members (equal vs. by_contribution)
  • Explain time-weighting if enabled
  • Update organization settings if method needs to change

Troubleshooting

”A dividend pool already exists for overlapping period”

Cause: Another pool has dates that overlap with the period you’re trying to create Solutions:
  1. View existing pools to identify the overlapping pool
  2. Adjust period dates to avoid overlap
  3. Delete or edit the existing pool if it was created in error
  4. Use adjacent, non-overlapping periods (e.g., Q1: Jan-Mar, Q2: Apr-Jun)
How to find overlapping pool:
1

Navigate to Dividends

View list of all existing pools
2

Check period dates

Look for pools with dates overlapping your intended period
3

Adjust or delete

Either adjust your new pool dates or delete the conflicting pool

”periodStart cannot be after periodEnd”

Cause: Period Start date is after Period End date Solution:
  • Swap the dates (period start should be the earlier date)
  • Verify you’re using YYYY-MM-DD format correctly
  • Check for typos in year/month/day
Example:
❌ Incorrect:
Period Start: 2026-03-31
Period End: 2026-01-01

✅ Correct:
Period Start: 2026-01-01
Period End: 2026-03-31

“Amount must be greater than 0”

Cause: Amount is zero or negative, or has invalid precision Solutions:
  1. Enter amount ≥ 0.01
  2. Check for typos or negative signs
  3. Ensure amount respects currency scale (e.g., max 2 decimals)

Cannot find pool after creation

Possible causes:
  1. Filter applied
    • Solution: Check status filter (ensure “All” or “Draft” is selected)
  2. Different organization
    • Solution: Verify correct organization is selected
  3. Creation failed silently
    • Solution: Check for error messages, verify permissions
  4. Page not refreshed
    • Solution: Refresh the page to reload pool list

Insufficient retained earnings

Cause: Creating a pool doesn’t immediately check retained earnings balance, but distribution will fail if insufficient Solution:
  • Check retained earnings balance before creating pool
  • View balance via Dividends → Retained Earnings Balance
  • Or navigate to General Ledger → RETAINED_EARNINGS account
  • Adjust pool amount to not exceed available retained earnings
How to check:
1

Navigate to Dividends or General Ledger

Either section shows retained earnings balance
2

View RETAINED_EARNINGS account balance

Check current balance
3

Compare with dividend amount

Ensure pool amount ≤ retained earnings balance
4

Adjust if needed

Reduce dividend amount or allocate more profit to retained earnings first

Cannot distribute pool immediately after creation

Cause: Distribution requires period end to be in a closed accounting period Explanation:
  • Creating a pool is separate from distributing it
  • Distribution validates that pool.periodEnd ≤ last closed accounting period end
  • This ensures all transactions for the period are finalized before distribution
Solution:
1

Create the pool

Pool can be created anytime (draft status)
2

Close accounting period

Ensure the accounting period containing pool.periodEnd is closed
3

Distribute pool

After period closure, use “Distribute” action
Example:
Pool period: 2026-01-01 to 2026-03-31
Requirement: Q1 2026 accounting period must be closed
Timeline:
  - Jan-Mar: Business operations
  - Apr 1: Create draft pool (allowed)
  - Apr 5: Close Q1 accounting period
  - Apr 6: Distribute pool (now allowed)
Learn about accounting periods →

Permissions Required

ActionPermissionScope
View poolsdividends:readANY
Create pooldividends:writeANY
Edit pooldividends:writeANY (only drafts can be edited)
Delete pooldividends:writeANY (only drafts can be deleted)
Typical roles: Administrators and Accountants have dividends:write. Regular members typically have dividends:read (view only) or no access.

Technical Details

API Endpoint

POST /dividends/pools

Headers:
  x-organization-id: <organization_id>

Body:
{
  "periodStart": "2026-01-01",
  "periodEnd": "2026-03-31",
  "periodLabel": "Q1 2026 Dividend",
  "amount": 5000000
}

Response:
{
  "message": "Dividend pool created",
  "pool": {
    "id": "<pool_id>",
    "organizationId": "<organization_id>",
    "periodLabel": "Q1 2026 Dividend",
    "periodStart": "2026-01-01T00:00:00.000Z",
    "periodEnd": "2026-03-31T00:00:00.000Z",
    "amount": 5000000,
    "journalEntryId": null,
    "status": "draft",
    "createdAt": "2026-04-01T10:30:00Z",
    "updatedAt": "2026-04-01T10:30:00Z",
    "eligibleMembersCount": 42
  }
}

Database Structure

DividendPoolMeta:
{
  id: string (UUID)
  organizationId: string
  periodLabel: string
  periodStart: DateTime
  periodEnd: DateTime
  amount: Decimal
  journalEntryId: string | null  // null = draft, populated = distributed
  createdAt: DateTime
  updatedAt: DateTime
}

Status Determination

Pool status is determined by journalEntryId:
status = journalEntryId === null ? 'draft' : 'distributed'
  • Draft: journalEntryId = null - Pool created but not distributed, no journal entries, no member allocations
  • Distributed: journalEntryId = <uuid> - Pool distributed, journal entry created, member savings credited

Validation Logic

At creation:
// Period validation
if (periodStart > periodEnd) {
  throw BadRequestException('periodStart cannot be after periodEnd')
}

// Overlap check
const overlapping = await findPool({
  periodStart: { lte: periodEnd },
  periodEnd: { gte: periodStart }
})
if (overlapping) {
  throw BadRequestException('A dividend pool already exists for overlapping period')
}

// Amount validation
if (amount <= 0) {
  throw BadRequestException('Amount must be greater than 0')
}
validateAmountScale(amount, currencyScale)
At distribution (separate operation):
// Accounting period constraint
const lastClosedEnd = await getLastClosedPeriodEnd(organizationId)
if (!lastClosedEnd) {
  throw BadRequestException('No accounting period has been closed yet')
}
if (periodEnd > lastClosedEnd) {
  throw BadRequestException('Period end must be on or before last closed period')
}

// Distribution date constraint
if (distributionDate <= lastClosedEnd) {
  throw BadRequestException('Distribution date must be after last closed period end')
}

Dividends Overview

Understand dividend pools and how they work

Distributing Dividends

Calculate allocations and make payments

Dividend Reporting

View pool details and member allocations

Managing Dividend Pools

Edit or delete draft pools

Retained Earnings

Understand retained earnings and profit allocation

Accounting Periods

Learn about period closure requirements