Skip to contents

Extends ChildAccount to model low-level accounts such as bills, loans, and targeted savings. Adds time-based logic, due tracking, and automatic closure/reactivation to ensure intelligent fund allocation.

Details

This class introduces behavior tailored to two main categories:

1. Periodic Accounts (e.g., Bills, Rent, Fixed Savings):

  • Require recurring payments before a due_date.

  • If fully funded before the due date, the account is marked "inactive" and any surplus is returned to the parent.

  • Upon reaching the next due date, the account reactivates and begins tracking the next cycle's funding needs.

2. Open-Ended Accounts (e.g., Long-Term Debts, Target Savings):

  • Do not rely on due_date or cycles.

  • Once the fixed_amount target is met, the account is permanently closed and surplus funds are redirected.

  • This prevents over-allocation to already satisfied targets.

These behaviors:

  • Guard against poor user allocation strategies by reallocating excess funds from fully funded accounts.

  • Adapt automatically to variable incomes, ensuring flexible prioritization (e.g., for freelancers).

  • Allow non-expert users to benefit from dynamic, self-adjusting savings and debt repayment logic over time.

Methods

initialize(...)

Constructor. Sets allocation, type, due date, fixed target, etc.

deposit(...)

Handles reactivation on due date and closes account when target met. Returns surplus to parent account for redistribution.

withdraw(...)

Withdraws funds and adjusts period tracking accordingly.

get_/set_ methods

Get/set values for due date, amount, account type, freq, periods.

Super classes

finman::MainAccount -> finman::ChildAccount -> GrandchildAccount

Public fields

status

Character. "active", "inactive", or "closed".

due_date

POSIXct or NULL. When funding is due (for bills, etc.).

amount_due

Numeric. Amount left to fully fund the account.

fixed_amount

Numeric. Fixed target for each funding cycle.

account_type

Character. e.g., "Bill", "Debt", "FixedSaving".

freq

Numeric or NULL. Cycle length in days (for recurring accounts).

num_periods

Numeric. Number of unpaid cycles.

Track_dues_and_balance

Data frame. History of balance and dues.

Methods

Inherited methods


Method new()

Initializes a new GrandchildAccount instance with attributes and tracking suitable for both periodic (e.g., bills, rent, fixed savings) and open-ended (e.g., long-term debts, target savings) accounts. Inherits from ChildAccount and sets up account-specific parameters like due dates, target amounts, and funding cycles.

Usage

GrandchildAccount$new(
  name,
  allocation = 0,
  priority = 0,
  fixed_amount = 0,
  due_date = NULL,
  account_type = "Expense",
  freq = NULL,
  status = "active"
)

Arguments

name

Character. Name or label of the account (e.g., "Rent", "Car Loan").

allocation

Numeric. Proportion of parent funds to allocate to this account. Used during distribution logic. Defaults to 0.

priority

Numeric. Priority weight for redistribution of residual funds, especially in cases of overflow or unmet allocations. Defaults to 0.

fixed_amount

Numeric. Target amount required to fully fund the account per period or in total. Used for both bills and savings goals.

due_date

POSIXct or NULL. Optional due date indicating when the next funding cycle is expected (for recurring accounts).

account_type

Character. Type of the account: e.g., "Bill", "Debt", "FixedSaving", or "Expense". Influences reactivation and closure behavior. Defaults to "Expense".

freq

Numeric or NULL. Frequency in days for periodic accounts to recur. Required for automated reactivation logic.

status

Character. "active", "inactive", or "closed".

Details

The constructor also initializes a data frame Track_dues_and_balance to monitor the account's funding status over time. Each row logs the current due amount and balance upon deposit or withdrawal.

For accounts of type "Bill", "FixedSaving", or "Debt" (with a due_date), the constructor sets up fields that support automated activation, deactivation, and fund tracking per cycle.

Examples

# Initialize a rent account due every 30 days with a fixed monthly cost
library(R6)
library(uuid)
library(tidyverse)
rent <- GrandchildAccount$new(
  name = "Rent",
  allocation = 0.3,
  priority = 2,
  fixed_amount = 75000,
  due_date = Sys.Date() + 30,
  account_type = "Bill",
  freq = 30
)

# Initialize a target savings account without a due date
car_saving <- GrandchildAccount$new(
  name = "Car Fund",
  allocation = 0.2,
  fixed_amount = 500000,
  account_type = "FixedSaving"
)


Method get_due_date()

Retrieves the current due date of the account. This is typically used for periodic accounts such as bills or fixed savings that require funding on a recurring schedule.

Usage

GrandchildAccount$get_due_date()

Returns

A POSIXct object representing the due date, or NULL if no due date is set.

Examples

rent <- GrandchildAccount$new(
  name = "Rent",
  fixed_amount = 75000,
  due_date = Sys.Date() + 30
)
rent$get_due_date()


Method set_due_date()

Sets a new due date for the account. This is useful for accounts with periodic funding requirements, such as rent, bills, or fixed savings.

Usage

GrandchildAccount$set_due_date(due_date)

Arguments

due_date

POSIXct. The new due date to assign to the account.

Returns

None. Updates the account's due_date field and prints a confirmation message.

Examples

bill <- GrandchildAccount$new(name = "Electricity", fixed_amount = 5000)
bill$set_due_date(Sys.Date() + 15)


Method get_fixed_amount()

Retrieves the fixed amount assigned to the account. This is typically used in accounts like bills, fixed savings, or loan payments where a specific amount is expected periodically.

Usage

GrandchildAccount$get_fixed_amount()

Returns

Numeric. The fixed amount required by the account.

Examples

rent <- GrandchildAccount$new(name = "Rent", fixed_amount = 75000)
rent$get_fixed_amount()
#> [1] 75000


Method set_fixed_amount()

Sets a new fixed amount for the account. This value represents the expected periodic contribution or payment (e.g., monthly rent, loan installment). It also recalculates the current amount due based on the number of unpaid periods and the account balance.

Usage

GrandchildAccount$set_fixed_amount(fixed_amount)

Arguments

fixed_amount

Numeric. The new fixed amount to be assigned to the account.

Returns

None. Updates internal fields and prints a confirmation message.

Examples

rent <- GrandchildAccount$new(name = "Rent", fixed_amount = 50000)
rent$set_fixed_amount(75000)
#> Fixed amount for Rent set to 75000


Method get_account_type()

Sets a new fixed amount for the account. This value represents the expected periodic contribution or payment (e.g., monthly rent, loan installment). It also recalculates the current amount due based on the number of unpaid periods and the account balance.

Usage

GrandchildAccount$get_account_type()

Arguments

fixed_amount

Numeric. The new fixed amount to be assigned to the account.

Returns

None. Updates internal fields and prints a confirmation message.

Examples

rent <- GrandchildAccount$new(name = "Rent", fixed_amount = 50000)
rent$set_fixed_amount(75000)
#> Fixed amount for Rent set to 75000


Method set_account_type()

Sets the type of the account, which influences how it behaves with respect to funding, reactivation, and closure policies. This field is central to determining whether the account is recurring, fixed, or target-based.

Usage

GrandchildAccount$set_account_type(account_type)

Arguments

account_type

Character. One of the supported types such as "Bill", "Debt", "FixedSaving", "NonFixedSaving", or "Expense". Determines how due dates, funding limits, and surplus reallocation are handled.

Details

- "Bill" or "FixedSaving": These accounts are period-based and are reactivated upon due dates. - "Debt" or target savings: Once fully funded, they are closed and not reopened. - "Expense" or "NonFixedSaving": Do not enforce due dates or strict funding targets.

Returns

None. Sets the account_type field and prints a confirmation.

Examples

rent <- GrandchildAccount$new(name = "Rent", fixed_amount = 75000)
rent$set_account_type("Bill")
#> Account type for Rent set to Bill


Method deposit()

Handles incoming deposits for grandchild accounts, including complex behavior for fixed-amount accounts such as Bills, FixedSavings, and Debts. It intelligently manages due dates, period increments, surplus reallocation, and account status updates.

Usage

GrandchildAccount$deposit(
  amount,
  transaction_number = NULL,
  by = "User",
  channel = NULL,
  date = Sys.time()
)

Arguments

amount

Numeric. The amount of money being deposited into the account.

transaction_number

Character or NULL. Optional unique identifier for the transaction. If NULL, a new one is generated.

by

Character. The party initiating the transaction (default is "User").

channel

Character or NULL. The method or channel used for the transaction (e.g., "Mobile Money").

date

POSIXct. The timestamp for the transaction (defaults to current system time).

Details

This method supports two core behaviors depending on the type of account:

## 1. Period-based Accounts (`Bill`, `FixedSaving`) - If the due date has passed, the system automatically increments the number of unpaid periods and extends the due date. - If the deposited amount fully covers the required amount across all unpaid periods, the account is marked as `"inactive"` (temporarily closed). - Any surplus is redirected to the parent account for reallocation, ensuring no money is trapped in overfunded accounts. - The transaction is logged in `Track_dues_and_balance` to track financial health over time.

## 2. Non-period Accounts (`LongTermDebt`, `TargetSaving`) - When the required amount is met, the account is permanently closed, and will not reactivate. This design ensures funds are focused on accounts that still need attention.

This mechanism encourages automatic reallocation of excess funds to critical needs without requiring users to micromanage their allocations — useful especially for users with fluctuating income.

Returns

None. Internally updates the account status, balance, due amounts, and transaction history.

Examples

# main account
main<- MainAccount$new("main")

# child account
child <- ChildAccount$new(
  name = "Emergency Fund",
  allocation = 0.3,
  priority = 2
)

# Grand child account
bill <- GrandchildAccount$new(
  name = "Rent",
  fixed_amount = 75000,
  account_type = "Bill",
  due_date = Sys.Date(),
  freq = 30
)
# attach grand child to parent
main$add_child_account(child)
child$add_child_account(bill)
bill$deposit(75000,channel="ABSA")

# Example with surplus being returned to parent:
bill$deposit(80000,channel="ABSA")

# Example with underpayment:
bill$deposit(20000,channel="ABSA")  # Remains active, shows updated due


Method withdraw()

Handles withdrawal requests from a grandchild account. The method ensures sufficient balance is available, updates the internal transaction tracking, and compensates for partial withdrawals in fixed-amount accounts by adjusting the effective number of periods.

Usage

GrandchildAccount$withdraw(
  amount,
  transaction_number = NULL,
  by = "User",
  channel = NULL,
  date = Sys.time()
)

Arguments

amount

Numeric. The amount to withdraw from the account.

transaction_number

Character or NULL. Optional transaction reference ID.

by

Character. The party initiating the withdrawal (default is "User").

channel

Character or NULL. Source or medium of the transaction (e.g., "Mobile Money").

date

POSIXct. The date and time of withdrawal (default is current system time).

Details

The method performs the following steps:

- Checks whether the account balance is sufficient for the requested withdrawal. - If sufficient, it processes the withdrawal via the parent class method. - It then logs the updated balance and remaining amount due into the `Track_dues_and_balance` history.

For accounts with a `fixed_amount` (e.g., Bills, FixedSavings, Debts):

- Partial withdrawals are treated as funding reversals and reduce the number of fulfilled periods. - This ensures that the system maintains accurate state about what's left to fulfill for the account, without modifying the `fixed_amount` itself.

This mechanism is crucial in dynamic environments where users may occasionally retrieve money from priority accounts — e.g., for emergencies — and helps the system readjust allocation logic accordingly.

Returns

None. The internal state of the account (balance, period count, logs) is updated.

Examples

# Withdraw a partial amount from a fully funded rent account
rent <- GrandchildAccount$new("Rent", fixed_amount = 75000,
account_type = "Bill")
rent$deposit(75000,channel="ABSA")
# Now equivalent to 0.53 of the rent period remaining.
rent$withdraw(35000,channel="ABSA")


Method get_account_freq()

Retrieves the recurrence frequency of the account, typically used for accounts with periodic obligations such as bills, fixed savings, or loans.

Usage

GrandchildAccount$get_account_freq()

Details

This frequency determines how often the account expects funding. For instance, a rent account with a monthly cycle would have a frequency of 30 (days), while a weekly expense might have 7.

This field is primarily used in due date updates and period tracking, especially for auto-reactivating accounts like Bills or Fixed Savings after their due dates lapse.

Returns

The frequency of recurrence, as stored in the account (e.g., number of days, or a character label like "monthly").

Examples

acc <- GrandchildAccount$new(
  "Rent",
  fixed_amount = 1000,
  freq = 30
)
acc$get_account_freq()
# [1] 30


Method set_account_freq()

Sets the recurrence frequency of the account, which defines how often the account expects to be funded.

Usage

GrandchildAccount$set_account_freq(account_freq)

Arguments

account_freq

Numeric or character value representing the recurrence frequency. For example, use `30` for a monthly bill or `"weekly"` if implementing a custom handler.

Details

This frequency value is crucial for managing due dates and determining when a new period starts (e.g., when a rent account should reactivate after a month).It is used in conjunction with the due date to trigger reactivation and allocation adjustments for fixed-type accounts such as Bills, Fixed Savings, and Loans. Changing the frequency may affect how missed or overdue periods are computed going forward.

Examples

acc <- GrandchildAccount$new("Water Bill", fixed_amount = 500)
acc$set_account_freq(30)
# Frequency for Water Bill set to 30


Method get_account_periods()

Retrieves the number of unpaid or active periods associated with the account.

Usage

GrandchildAccount$get_account_periods()

Details

This is particularly relevant for fixed-type accounts like Bills, Fixed Savings, or Debts with a defined frequency. The number of periods (`num_periods`) represents how many cycles have passed without full funding. It increases when due dates pass without adequate deposits and decreases when partial withdrawals are made from already-funded periods.

For example, if a rent account expects funding every 30 days and misses two cycles, `num_periods` will be 3 (including the current one), and the system will attempt to fund all missed cycles.

Returns

Numeric value indicating how many periods are currently pending or tracked for the account.

Examples

acc <- GrandchildAccount$new(
  "Internet Bill",
  fixed_amount = 2500,
  freq = 30
 )
acc$get_account_periods()
# [1] 1


Method set_account_periods()

Manually sets the number of unpaid or active periods for the account.

Usage

GrandchildAccount$set_account_periods(periods)

Arguments

periods

Numeric value representing the number of periods to assign.

Details

This method allows manual control of how many cycles (e.g., months or days) are currently due or tracked for the account. It can be used in administrative corrections or simulations of time passage in budgeting models.

Use with caution: setting `num_periods` directly may desynchronize with the actual due date logic unless adjustments are consistently maintained.

Examples

acc <- GrandchildAccount$new("Loan Payment", fixed_amount = 10000,
freq = 30)
acc$set_account_periods(3)
# Output: Loan Payment has 3 period(s)


Method clone()

The objects of this class are cloneable with this method.

Usage

GrandchildAccount$clone(deep = FALSE)

Arguments

deep

Whether to make a deep clone.

Examples


## ------------------------------------------------
## Method `GrandchildAccount$new`
## ------------------------------------------------

# Initialize a rent account due every 30 days with a fixed monthly cost
library(R6)
library(uuid)
library(tidyverse)
rent <- GrandchildAccount$new(
  name = "Rent",
  allocation = 0.3,
  priority = 2,
  fixed_amount = 75000,
  due_date = Sys.Date() + 30,
  account_type = "Bill",
  freq = 30
)

# Initialize a target savings account without a due date
car_saving <- GrandchildAccount$new(
  name = "Car Fund",
  allocation = 0.2,
  fixed_amount = 500000,
  account_type = "FixedSaving"
)

## ------------------------------------------------
## Method `GrandchildAccount$get_due_date`
## ------------------------------------------------

rent <- GrandchildAccount$new(
  name = "Rent",
  fixed_amount = 75000,
  due_date = Sys.Date() + 30
)
rent$get_due_date()
#> [1] "2025-08-31"

## ------------------------------------------------
## Method `GrandchildAccount$set_due_date`
## ------------------------------------------------

bill <- GrandchildAccount$new(name = "Electricity", fixed_amount = 5000)
bill$set_due_date(Sys.Date() + 15)
#> Due date for Electricity set to 20316 

## ------------------------------------------------
## Method `GrandchildAccount$get_fixed_amount`
## ------------------------------------------------

rent <- GrandchildAccount$new(name = "Rent", fixed_amount = 75000)
rent$get_fixed_amount()
#> [1] 75000
#> [1] 75000

## ------------------------------------------------
## Method `GrandchildAccount$set_fixed_amount`
## ------------------------------------------------

rent <- GrandchildAccount$new(name = "Rent", fixed_amount = 50000)
rent$set_fixed_amount(75000)
#> Fixed amount for Rent set to 75000 
#> Fixed amount for Rent set to 75000

## ------------------------------------------------
## Method `GrandchildAccount$get_account_type`
## ------------------------------------------------

rent <- GrandchildAccount$new(name = "Rent", fixed_amount = 50000)
rent$set_fixed_amount(75000)
#> Fixed amount for Rent set to 75000 
#> Fixed amount for Rent set to 75000


## ------------------------------------------------
## Method `GrandchildAccount$set_account_type`
## ------------------------------------------------

rent <- GrandchildAccount$new(name = "Rent", fixed_amount = 75000)
rent$set_account_type("Bill")
#> Account type for Rent set to Bill 
#> Account type for Rent set to Bill

## ------------------------------------------------
## Method `GrandchildAccount$deposit`
## ------------------------------------------------

# main account
main<- MainAccount$new("main")

# child account
child <- ChildAccount$new(
  name = "Emergency Fund",
  allocation = 0.3,
  priority = 2
)

# Grand child account
bill <- GrandchildAccount$new(
  name = "Rent",
  fixed_amount = 75000,
  account_type = "Bill",
  due_date = Sys.Date(),
  freq = 30
)
# attach grand child to parent
main$add_child_account(child)
child$add_child_account(bill)
bill$deposit(75000,channel="ABSA")
#> Due date extended. Number of periods unpaid: 2 
#> Rent reactivated. Outstanding balance due: 150000 
#> Deposited: 75000 via ABSA - Transaction ID: sys1 

# Example with surplus being returned to parent:
bill$deposit(80000,channel="ABSA")
#> Deposited: 75000 via ABSA - Transaction ID: sys2 
#> Rent has become inactive .
#> Extra amount of 5000 moved to Emergency Fund 
#> Rent fully funded for 2 period(s)

# Example with underpayment:
bill$deposit(20000,channel="ABSA")  # Remains active, shows updated due
#> Deposit not allowed. Account is not active.
#> Rent has become inactive .
#> Extra amount of 20000 moved to Emergency Fund 
#> Rent fully funded for 2 period(s)

## ------------------------------------------------
## Method `GrandchildAccount$withdraw`
## ------------------------------------------------

# Withdraw a partial amount from a fully funded rent account
rent <- GrandchildAccount$new("Rent", fixed_amount = 75000,
account_type = "Bill")
rent$deposit(75000,channel="ABSA")
#> Deposited: 75000 via ABSA - Transaction ID: sys1 
#> Rent has become inactive .
#> Rent fully funded for 1 period(s)
# Now equivalent to 0.53 of the rent period remaining.
rent$withdraw(35000,channel="ABSA")
#> Withdrew: 35000 via ABSA - Transaction ID: sys2 


## ------------------------------------------------
## Method `GrandchildAccount$get_account_freq`
## ------------------------------------------------

acc <- GrandchildAccount$new(
  "Rent",
  fixed_amount = 1000,
  freq = 30
)
acc$get_account_freq()
#> [1] 30
# [1] 30

## ------------------------------------------------
## Method `GrandchildAccount$set_account_freq`
## ------------------------------------------------

acc <- GrandchildAccount$new("Water Bill", fixed_amount = 500)
acc$set_account_freq(30)
#> Frequency for Water Bill set to 30 
# Frequency for Water Bill set to 30

## ------------------------------------------------
## Method `GrandchildAccount$get_account_periods`
## ------------------------------------------------

acc <- GrandchildAccount$new(
  "Internet Bill",
  fixed_amount = 2500,
  freq = 30
 )
acc$get_account_periods()
#> [1] 1
# [1] 1

## ------------------------------------------------
## Method `GrandchildAccount$set_account_periods`
## ------------------------------------------------

acc <- GrandchildAccount$new("Loan Payment", fixed_amount = 10000,
freq = 30)
acc$set_account_periods(3)
#> Loan Payment has 3 period(s)
# Output: Loan Payment has 3 period(s)