# @payafter/currency

Shared currency utilities for PayAfter applications supporting RWF (Rwandan Franc) and XOF (West African CFA Franc).

## Features

- ✅ **Precise monetary calculations** using Dinero.js
- ✅ **RWF rounding constraint** - All installments (except last) are multiples of 100
- ✅ **Multi-currency support** - RWF and XOF
- ✅ **Type-safe** - Full TypeScript support
- ✅ **Well-tested** - >90% code coverage

## Installation

```bash
npm install @payafter/currency dinero.js
```

**Note**: `dinero.js` is a peer dependency and must be installed separately.

## Usage

### Calculate Installments

```typescript
import { calculateInstallments } from '@payafter/currency';

// RWF - with rounding to multiples of 100
const installments = calculateInstallments(100000, 3, 'RWF');
// [33300, 33300, 33400]

// XOF - no rounding constraint
const installments = calculateInstallments(100000, 3, 'XOF');
// [33333, 33333, 33334]
```

### Format Money

```typescript
import { formatMoney } from '@payafter/currency';

// Format RWF
const formatted = formatMoney(100000, 'RWF');
// "RWF 100,000"

// Format XOF with French locale
const formatted = formatMoney(100000, 'XOF', 'fr-FR');
// "100 000 XOF"
```

### Calculate Monthly Repayment

```typescript
import { calculateMonthlyRepayment } from '@payafter/currency';

const result = calculateMonthlyRepayment(
  100000,  // amountFunded
  20000,   // expectedProfit
  6,       // paymentLength (months)
  'RWF'    // currency
);

console.log(result);
// {
//   monthlyReturn: 20000,
//   monthlyPrincipal: 16700,
//   monthlyProfit: 3300
// }
```

### Round to Minimum Unit

```typescript
import { roundToMinimumUnit } from '@payafter/currency';

// RWF - rounds to nearest 100
roundToMinimumUnit(33333, 'RWF'); // 33300
roundToMinimumUnit(33350, 'RWF'); // 33400

// XOF - no rounding
roundToMinimumUnit(33333, 'XOF'); // 33333
```

## API Reference

### Types

```typescript
type Currency = 'RWF' | 'XOF';
type Locale = 'rw' | 'ci';

interface CurrencyConfig {
  currency: Currency;
  minimumUnit: number;
  locale: string;
}
```

### Constants

```typescript
CURRENCY_CONFIGS: Record<Currency, CurrencyConfig>
LOCALE_TO_CURRENCY: Record<string, Currency>
```

### Functions

#### `calculateInstallments(totalPrice: number, count: number, currency: Currency): number[]`

Calculates installment amounts with precise distribution.

- **RWF**: Each installment (except last) is rounded to multiples of 100
- **XOF**: No rounding constraint
- Last installment absorbs any remainder to ensure sum = totalPrice

#### `formatMoney(amount: number | Dinero.Dinero, currency: Currency, locale?: string): string`

Formats money for display.

#### `roundToMinimumUnit(amount: number, currency: Currency): number`

Rounds amount to the currency's minimum unit.

#### `calculateMonthlyRepayment(amountFunded: number, expectedProfit: number, paymentLength: number, currency: Currency)`

Calculates monthly repayment details for investors.

#### `createMoney(amount: number, currency: Currency): Dinero.Dinero`

Creates a Dinero money object.

## Development

```bash
# Install dependencies
npm install

# Build
npm run build

# Run tests
npm test

# Watch mode
npm run dev
```

## Testing

The package has comprehensive test coverage (>90%) including:

- Installment calculations for both currencies
- Rounding constraints for RWF
- Money formatting
- Edge cases (zero count, single installment, etc.)

Run tests:

```bash
npm test
```

## License

UNLICENSED - Private package for PayAfter

## Support

For issues or questions, contact the PayAfter development team.
