Feature: Financial Calculations
Relevant source files
The following files were used as context for generating this wiki page:- src/main/java/com/paymaster/backend/domain/service/CalculationService.java
- src/main/java/com/paymaster/backend/presentation/controller/HomeController.java
- src/main/resources/templates/contracts/form.html
- src/main/resources/static/js/app.js
- src/main/java/com/paymaster/backend/domain/service/DashboardService.java
- src/main/java/com/paymaster/backend/domain/repository/InstallmentRepository.java
Introduction
The Financial Calculations feature is a core component of the PayMaster system, providing the essential logic for all monetary computations related to contracts and installments. Its primary purpose is to ensure accurate and consistent calculations for simple interest, total contract amounts, installment values, and late payment penalties. This feature is exposed through a backend service (CalculationService), consumed by an API endpoint for real-time previews in the user interface, and used in backend reporting to generate financial statistics. The system relies heavily on BigDecimal for precision in financial calculations to avoid floating-point errors.
Sources: src/main/java/com/paymaster/backend/domain/service/CalculationService.java, src/main/java/com/paymaster/backend/presentation/controller/HomeController.java, src/main/resources/static/js/app.js
Core Calculation Service
The CalculationService class is the centralized hub for all financial calculation logic. It offers a set of stateless methods to perform common financial operations required throughout the application.
Sources: src/main/java/com/paymaster/backend/domain/service/CalculationService.java
Class Diagram
The diagram below shows the public methods available in the CalculationService.
Key Methods
The service provides methods for various calculations, using BigDecimal internally for precision and returning long values representing amounts in Rials.
| Method | Description | Parameters |
|---|---|---|
calculateSimpleInterest | Calculates simple interest based on the formula: Principal * (Rate / 100) * (Months / 12). | principal (long), annualRate (double), months (int) |
calculateTotalAmount | Computes the total contract amount by adding the simple interest to the principal. | principal (long), annualRate (double), months (int) |
calculateInstallmentAmount | Determines the amount for each installment by dividing the total amount by the number of installments. | totalAmount (long), installmentCount (int) |
calculatePenalty | Calculates the late payment penalty using the formula: Remaining Amount * (Daily Rate / 100) * Delay Days. | remainingAmount (long), dailyPenaltyRate (double), delayDays (long) |
calculateDelayDays | Calculates the number of days between a due date and a payment date. | dueDate (LocalDate), paymentDate (LocalDate) |
calculateProgressPercentage | Calculates the completion percentage of a payment. | paid (long), total (long) |
formatCurrency | Formats a long amount into a Rial currency string (e.g., "1,500,000 ریال"). | amount (long) |
Sources: src/main/java/com/paymaster/backend/domain/service/CalculationService.java:21-181
Real-time Calculation API
To provide a dynamic user experience, the application exposes an API endpoint that performs financial calculations on the fly. This is used in the "New Contract" form to give users a real-time preview of installment details as they input data.
API Endpoint Details
The client-side JavaScript makes a GET request to an endpoint to fetch calculation results. Based on the frontend code, the endpoint is /api/calculate-installments. The backend implementation is provided by the calculateInstallment method in HomeController, which is mapped to /api/calculate.
| Property | Value |
|---|---|
| Path | /api/calculate-installments (as per JS) or /api/calculate (as per Controller) |
| HTTP Method | GET |
| Description | Calculates interest, total amount, and installment amount for a new contract. |
Request Parameters:
| Parameter | Type | Description |
|---|---|---|
principal | Long | The principal amount of the loan. |
rate | Double | The annual interest rate (percentage). |
months | Integer | The number of installments (duration in months). |
Response Body (CalculationResult):
| Field | Type | Description |
|---|---|---|
principal | long | The original principal amount. |
interest | long | The calculated total simple interest. |
total | long | The total amount (principal + interest). |
installmentAmount or installment | long | The calculated amount for each installment. |
Sources: src/main/java/com/paymaster/backend/presentation/controller/HomeController.java:413-426, src/main/resources/templates/contracts/form.html:233, src/main/resources/static/js/app.js:312-314
Sequence Diagram
This diagram illustrates the flow of a real-time calculation request, from user input in the browser to the server and back.
Frontend Integration
The financial calculations are seamlessly integrated into the "New Contract" page (contracts/form.html) via the ContractCalculator module in app.js.
Client-Side Calculation Flow
The ContractCalculator object listens for input or change events on the form fields for principal, interest rate, and installment count. When an event occurs, it debounces the call to its calculate method to avoid excessive API requests. The method then calls the API, receives the calculated data, and updates the "Calculation Preview" section and a Chart.js doughnut chart to visualize the principal vs. interest ratio.
This diagram shows the client-side logic flow.
The UI provides immediate feedback, enhancing usability and transparency for the user creating the contract.
Sources: src/main/resources/templates/contracts/form.html:150-176
Financial Aggregations and Reporting
Financial calculations are also crucial for reporting and dashboard statistics. The DashboardService aggregates financial data from across the system to provide a high-level overview.
Data Aggregation Flow
The DashboardService relies on other services, primarily ContractService and InstallmentService, to gather statistics. These services, in turn, use InstallmentRepository to execute database queries that sum up financial figures.
This diagram shows how DashboardService uses InstallmentRepository queries to compute financial statistics.
Sources: src/main/java/com/paymaster/backend/domain/service/DashboardService.java:32-46, src/main/java/com/paymaster/backend/domain/repository/InstallmentRepository.java:108-119
Key Aggregation Queries
The InstallmentRepository contains several JPQL queries for financial aggregation:
sumPaidAmount(): Calculates the total amount received across all paid installments.sumOverdueAmount(): Calculates the total outstanding amount from all overdue installments.sumPenaltyAmount(): Sums all collected penalty fees.
These queries ensure that financial reporting is performed efficiently at the database level.
Sources: src/main/java/com/paymaster/backend/domain/repository/InstallmentRepository.java:108-125
Conclusion
The Financial Calculations feature is a foundational element of the PayMaster application. It provides a robust and centralized system for handling all monetary computations, from real-time previews during contract creation to high-level financial reporting on the dashboard. By combining a precise backend CalculationService, a responsive API, and a dynamic frontend implementation, the feature ensures accuracy, transparency, and an intuitive user experience.