apache / apache/fineract-backoffice-ui

Two refund commands the platform accepts have no screen: refund by cash and charge refund

Open
#506 0 comments 0 reactions 0 assignees View on GitHub
angular enhancement good first issue help wanted loans typescript
Dominant language
TypeScript
Stars
15
Forks
60
Avg merge
10h 15m
Merged PRs (30d)
108

Description

## What is missing

The app offers three refund-shaped transactions — Merchant Issued Refund, Payout Refund and Goodwill Credit. The platform accepts two more that have no UI at all.

Confirmed against a running `apache/fineract` using the #268 discriminator, where an unrecognised command answers `error.msg.query.parameter.value.unsupported` on the `command` parameter:

| Probe | Result |
|---|---|
| `POST /loans/{id}/transactions?command=totallyNotACommand` | `error.msg.query.parameter.value.unsupported` — **unrecognised** (control) |
| `POST /loans/{id}/transactions?command=writeoff` | `validation.msg.loan.transaction.transactionDate.cannot.be.blank` — **recognised** (control) |
| `POST /loans/{id}/transactions?command=refundByCash` | `validation.msg.loan.transaction.transactionDate.cannot.be.blank` — **recognised** |
| `POST /loans/{id}/transactions?command=chargeRefund` | `validation.msg.loan.charge.refund.transaction.loanChargeId.cannot.be.blank` — **recognised** |

Permissions `REFUNDBYCASH_LOAN` and `CHARGEREFUND_LOAN` are both present in `GET /permissions`.

## What the UI offers today

The Actions menu on a real progressive Active loan — 17 entries, neither refund among them:

![The Actions menu on a progressive Active loan](https://raw.githubusercontent.com/Aman-Mittal/fineract-backoffice-ui/assets/issue-screenshots/loan-actions-progressive.png)

## The two halves are not the same size

**Refund by cash** needs only a date and an amount, which is exactly what the existing generic transaction form already sends. `loan-transaction-form.component.ts` is driven by the route's `:type` parameter and posts `postLoansLoanIdTransactions(loanId, transaction, type)` with `transactionDate`, `dateFormat`, `locale`, `transactionAmount` and `paymentTypeId`. Adding it is a menu entry, a title key, `AMOUNT_VISIBLE_TYPES` membership and an i18n string — no new form.

**Charge refund** additionally requires `loanChargeId`, so it needs a picker listing the loan's charges. That is a genuinely new field on the shared form, and worth doing separately rather than bolting onto the simpler change.

## A stale comment to fix while in here

`loan-transaction-form.component.ts:406` says:

> the transaction *template* endpoint accepts fewer commands than the transaction endpoint itself — reAmortize, chargeRefund and undowriteoff are rejected there with "unsupported value" even though the POST works.

But `NO_TEMPLATE_TYPES` is `{ approve, undoDisbursal, reAmortize, undowriteoff }` — `chargeRefund` is **not** in the set the comment describes. Today that is harmless, because nothing can reach the form with that type. The moment charge refund is offered, the form will issue a template request the comment already predicts will fail. Either the comment is wrong or the set is missing an entry, and whoever implements charge refund needs to settle which.

## Why it is worth doing

Refund by cash is how an over-payment is handed back across the counter — the ordinary counterpart to taking a repayment, and the one refund route that needs no card or wallet rail behind it. Charge refund reverses a fee that should not have been levied, which today can only be approximated with a goodwill credit; that records a gift rather than a correction, and the two are not the same thing in the ledger.

## Environment

`main` at `7c51d90b`. Probes against `apache/fineract` running locally via `deploy/docker-compose-e2e.yml`; screenshot from a loan seeded with the repository's own `e2e/utils/seed-api.ts` helpers.

Contributor guide

Open the contributing guide

Research direction

Start with the Actions menu and loan-transaction-form.component.ts, following the route :type parameter, AMOUNT_VISIBLE_TYPES, and the POST transaction call. Trace how refundByCash could use the existing fields, then inspect the chargeRefund requirements and the NO_TEMPLATE_TYPES comment before deciding the implementation boundary. Done means the supported refund actions are exposed with appropriate form fields and their transaction requests behave as described.

Written by the indexing model from the issue text.

Assessment

Tech stack
angular, typescript
Domain
frontend
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.