EnAccess / EnAccess/micropowermanager

[Feature Request]: Monthly postpaid electricity billing

Open
#1,595 1 comment 1 reaction 0 assignees View on GitHub
Dominant language
PHP
Stars
27
Forks
19
Avg merge
1d 18h
Merged PRs (30d)
27

Description

### Preflight Checklist

- [x] I have read the [Contributing Guidelines](https://github.com/EnAccess/micropowermanager/blob/main/CONTRIBUTING.md) for this project.
- [x] I agree to follow the [Code of Conduct](https://github.com/EnAccess/micropowermanager/blob/main/CODE_OF_CONDUCT.md) that this project adheres to.
- [x] I have searched the [issue tracker](https://github.com/EnAccess/micropowermanager/issues) for a matching feature request, without success.

### Problem Description

MPM currently focuses on prepaid electricity sales and does not provide a complete monthly postpaid billing workflow for metered customers.

Mini-grid operators need to record monthly cumulative meter readings, calculate progressive tariff charges, issue auditable customer bills, notify customers, and collect the exact bill amount through a supported payment provider.

Without this workflow, operators must calculate usage, prepare invoices, track due dates, and reconcile payments outside MPM.

Issue #1457 is related to PDF invoices after a successful payment, but it does not cover usage-based monthly bill generation before payment.

### Proposed Solution

Add per-meter postpaid electricity billing with the following initial behavior:

- Operators can mark individual meters as prepaid or postpaid.
- Billing periods cover the previous calendar month.
- On or after the first day of the new month, an operator enters audited cumulative readings, previews eligible bills, and explicitly starts the billing run.
- For each eligible meter, usage is the difference between the first and last manual readings available within the billing period.
- Meters with fewer than two readings, invalid decreasing readings, or zero usage are skipped with a visible reason.
- Each postpaid tariff supports configurable progressive kWh tiers.
- A tenant-wide service charge and VAT rate are applied to the bill. Initial NFE examples use a UGX 5,320 service charge and 18% VAT.
- The tariff assigned when the bill is generated prices the entire billing period.
- Generated invoices snapshot their readings, tier thresholds, rates, taxes, and totals so historical bills remain auditable.
- Bills are due seven calendar days after issue.
- Customers receive an issue SMS with a secure, invoice-specific payment link, followed by reminders three days before the due date, on the due date, and weekly while overdue.
- V1 tracks arrears and sends reminders but does not automatically disconnect meters.
- Customers can pay only an existing bill and must pay 100% of its outstanding amount. Partial payments, credits, and overpayments are not supported in V1.
- Pesapal is the first supported provider. The payable amount and currency are derived server-side, and verified callbacks settle the bill without generating a prepaid token.
- Staff can view bills by customer, meter, period, and status and download a one-page PDF containing customer details, readings, progressive energy charges, service charge, VAT, total due, and payment information.
- Unpaid bills can be voided and regenerated while preserving the original audit record. Paid bills remain immutable.

### Acceptance Criteria

- A customer can have both prepaid and postpaid meters.
- An operator can enter dated cumulative readings and see who entered each reading.
- A preview shows bill totals and explains every skipped meter before generation.
- Re-running or concurrently starting the same billing period does not create duplicate active bills.
- Progressive tier calculations are correct at and across each configured threshold.
- The generated PDF reproduces the configured readings, tier calculations, service charge, VAT, total, due date, and secure payment link.
- A bill issued on the first is due on the eighth.
- Reminder delivery is idempotent and follows the initial release schedule.
- Pesapal rejects tampered, partial, mismatched-currency, and duplicate settlements.
- A successful Pesapal IPN marks the matching bill paid exactly once and does not generate an energy token.
- Tenant data and invoice sequences remain isolated.
- Unpaid bills can be voided and replaced; paid bills cannot be edited or voided.

### Alternatives Considered

- Reusing prepaid transactions and debt-clearing behavior was rejected because postpaid bills require invoice-specific accounting, immutable pricing snapshots, due dates, and exact settlement.
- Automatic generation at midnight on the first was considered, but manual-only readings make an operator-reviewed billing run safer for the first release.
- Customer-wide and tariff-wide enrollment were considered, but per-meter enrollment supports customers with mixed arrangements.
- Partial payments and automatic disconnection were considered but deferred to keep the first release operationally safe and auditable.
- Applying the nearest cycle-boundary readings was considered; the initial workflow instead bills the first and last available readings within the period and clearly exposes the measured interval.

### Additional Information

Five anonymized example NFE invoices were reviewed to define the required one-page layout and billing breakdown.

Codex helped structure this feature proposal from the contributor requirements, repository inspection, and sample invoices. The contributor reviewed and approved the resulting scope and remains responsible for the proposal and any implementation.

Contributor guide

Open the contributing guide

Research direction

The proposal names no implementation files, tests, or entry points; begin by reading CONTRIBUTING.md and inspecting the existing prepaid, payment-provider, notification, invoice/PDF, and meter-reading flows. Use issue #1457 and the five anonymized NFE invoices as context. Done requires the listed billing, audit, reminder, settlement, isolation, and invoice criteria to pass.

Written by the indexing model from the issue text.

Assessment

Tech stack
php
Domain
backend, database, payments
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.