Source code documentation
Contracts
1. Introduction
The contracts describe the terms (ACTUS contract terms) of the contract agreed upon between counterparties as one part, and the payment details (payment gateways) of each of the counterparties involved in the contractual agreement.
The contracts endpoints allows adding new and managing existing contracts. The contract is described in terms of one or multiple ACTUS contract templates. For each attribute of a template is according to the ACTUS data dictionary
2. Tables and relations
Establishing relationships
-
In relational databases like PostgreSQL, relationships between tables are crucial for organizing and querying data effectively. These relationships are typically established using foreign key constraints, which define links between tables based on the values of specific columns. Common types of relationships include one-to-one, one-to-many, and many-to-many relationships, each serving different data modeling needs.
Tables
-
Schema
-
Table business_events
Index Name Data type * 🔑 ⬋
eventid
uuid
*
event_time
timestamp
* 🔎
event_type
varchar(10)
event_body
json
* 🔎
status
varchar(10)
* 🔎
execution_type
varchar(20)
contractid
varchar(255)
*
userid
uuid
* 🔎 ⬈
contractuuid
uuid
value
numeric
remaining_value
numeric
credit_payment_channel_id
uuid
debit_payment_channel_id
uuid
units
varchar(10)
-
Foreign keys
Type Name On fk_business_events_contracts_contractuuid
contractuuid
-
Constraints
Name Definition business_events_event_type_check
((event_type)::text ~* ’^(AD/IED/FP/PR/PD/PRF/PY/PP/IP/IPCI/CE/RRF/RR/DV/PRD/MR/TD/SC/IPCB/MD/XD/STD/PI/IPFX/IPFL/ME/TP/OPS)$'::text)
business_events_status_check
((status)::text ~* ’^(scheduled
pending
processed)$'::text)
-
-
Table contracts
Index Name Data type * 🔑 ⬋
contractuuid
uuid
⬈
productid
bigint
*
createdby
uuid
executedby
uuid
*
system_time
timestamp
selection
json
-
Foreign keys
Type Name On contracts_product_fk
productid
-
-
Table contracts_history
Index Name Data type * 🔑 ⬋
contractuuid
uuid
* 🔑 ⬋
status_date
timestamp
productid
bigint
selection
json
*
system_time
timestamp
-
Table payment_channels
Index Name Data type * 🔑 ⬋
payment_channelid
uuid
contractid
uuid
details
json
*
identifier
varchar(100)
label
varchar(100)
*
type
varchar(50)
* 🔎
owner_type
varchar(10)
*
units
varchar(10)
*
system
varchar(50)
account_characteristic
varchar(50)
* 🔎
ownerid
uuid
* 🔎
userid
uuid
-
Constraints
Name Definition payment_channels_owner_type_check
((owner_type)::text ~* ’^(root/profile)$'::text)
-
-
Table payment_details
Index Name Data type * 🔑
id
bigint GENERATED BY DEFAULT AS IDENTITY
⬈
contract_uuid
uuid
⬈
record_creator_paymentchannel_id
uuid
⬈
counterparty_paymentchannel_id
uuid
⬈
contract_paymentchannel_id
uuid
-
Foreign keys
Type Name On paymentdetails_contractuuid_fk
contract_uuid
paymentdetails_contract_payment_fk
contract_paymentchannel_id
paymentdetails_counterparty_fk
counterparty_paymentchannel_id
paymentdetails_record_creator_fk
record_creator_paymentchannel_id
-
-
Table products
Idx Name Data Type * 🔑 ⬋
productid
bigint GENERATED BY DEFAULT AS IDENTITY
*
status
varchar(10)
*
template
json
* 🔎
userid
uuid
-
Constraints
Name Definition products_status_check
((status)::text ~* ’^(active/inactive)$'::text)
-
-
Table profile_forms
Idx Name Data Type * 🔑 ⬋
profile_formid
bigint GENERATED BY DEFAULT AS IDENTITY
*
profile_form_details
json
*
userid
uuid
-
Table profiles
Index Name Data type * 🔑 ⬋
profileid
uuid
profile_details
json
*
status
varchar(10)
*
userid
uuid
* ⬈
profile_formid
bigint
-
Foreign keys
Type Name On fk_profiles_profile_forms_profile_formid
profile_formid
-
Constraints
Name Definition profiles_status_check
((status)::text ~* ’^(active/inactive)$'::text)
-
-
Table terms
Index Name Data type * 🔑
id
integer GENERATED BY DEFAULT AS IDENTITY
accrued_interest
numeric
amortization_date
timestamp
array_cycle_anchor_date_of_interest_payment
varchar(255)
array_cycle_anchor_date_of_principal_redemption
varchar(255)
array_cycle_anchor_date_of_rate_reset
varchar(255)
array_cycle_of_interest_payment
varchar(255)
array_cycle_of_principal_redemption
varchar(255)
array_cycle_of_rate_reset
varchar(255)
array_fixed_variable
varchar(255)
array_increase_decrease
varchar(255)
array_next_principal_redemption_payment
varchar(255)
array_rate
varchar(255)
business_day_convention
varchar(5)
calendar
varchar(2)
capitalization_end_date
timestamp
contract_deal_date
timestamp
contractid
varchar(255)
*
contract_role
varchar(6)
contract_performance
varchar(10)
*
contract_type
varchar(15)
*
currency
varchar(10)
currency2
varchar(10)
cycle_anchor_date_of_dividend_payment
timestamp
cycle_anchor_date_of_fee
timestamp
cycle_anchor_date_of_interest_calculation_base
timestamp
cycle_anchor_date_of_interest_payment
timestamp
cycle_anchor_date_of_optionality
timestamp
cycle_anchor_date_of_principal_redemption
timestamp
cycle_anchor_date_of_rate_reset
timestamp
cycle_anchor_date_of_scaling_index
timestamp
cycle_of_dividend_payment
varchar(10)
cycle_of_fee
varchar(10)
cycle_of_interest_calculation_base
varchar(10)
cycle_of_interest_payment
varchar(10)
cycle_of_optionality
varchar(10)
cycle_of_principal_redemption
varchar(10)
cycle_of_rate_reset
varchar(10)
cycle_of_scaling_index
varchar(10)
cycle_point_of_interest_payment
varchar(1)
cycle_point_of_rate_reset
varchar(1)
*
day_count_convention
varchar(10)
delivery_settlement
varchar(1)
end_of_month_convention
varchar(5)
fee_accrued
numeric
fee_basis
varchar(1)
fee_rate
numeric
fixing_period
varchar(255)
initial_exchange_date
timestamp
interest_calculation_base
varchar(10)
interest_calculation_base_amount
numeric
life_cap
numeric
life_floor
numeric
market_object_code
varchar(255)
market_object_code_of_dividend_rate
varchar(255)
market_object_code_of_rate_reset
varchar(255)
market_object_code_of_scaling_index
varchar(255)
market_value_observed
numeric
maturity_date
timestamp
maximum_penalty_free_disbursement
varchar(255)
next_principal_redemption_payment
numeric
next_reset_rate
numeric
nominal_interest_rate
numeric
nominal_interest_rate2
numeric
notional_principal
numeric
notional_principal2
numeric
object_code_of_prepayment_model
varchar(255)
penalty_rate
numeric
penalty_type
varchar(1)
period_cap
numeric
period_floor
numeric
premium_discount_atied
numeric
price_at_purchase_date
numeric
price_at_termination_date
numeric
purchase_date
timestamp
quantity
numeric
rate_spread
numeric
rounding_convention
varchar(255)
scaling_effect
varchar(5)
scaling_index_at_contract_deal_date
numeric
settlement_period
varchar(255)
status_date
timestamp
x_day_notice
varchar(255)
termination_date
timestamp
delinquency_period
varchar(255)
grace_period
varchar(255)
market_object_code_of_dividends
varchar(255)
rate_multiplier
numeric
* ⬈
contract_uuid
uuid
⬈
counterparty_id
uuid
* 🔎
creator_id
uuid
-
Foreign keys
Type Name On terms_contractuuid_fk
contract_uuid
terms_counterparty_id_fk
counterparty_id
-
Constraints
Name Definition terms_business_day_convention_check
((business_day_convention)::text ~* ’^(NOS/SCF/SCMF/CSF/CSMF/SCP/SCMP/CSP/SCMP)$'::text)
terms_calendar_check
((calendar)::text ~* ’^(NC/MF)$'::text)
terms_fee_basis_check
((fee_basis)::text ~* ’^(A/N)$'::text)
terms_delivery_settlement_check
((delivery_settlement)::text ~* ’^(D/S)$'::text)
terms_cycle_of_dividend_payment_check
cycle_of_dividend_payment)::text ~ `(([-]?)P(?:([-]?)Y)?(?:([-]?)M)?(?:([-]?)W)?(?:([-]?[0-9]+)D)?L(?:([0-1]?)'::text)
terms_cycle_of_interest_calculation_base_check
cycle_of_interest_calculation_base)::text ~ `(([-]?)P(?:([-]?)Y)?(?:([-]?)M)?(?:([-]?)W)?(?:([-]?[0-9]+)D)?L(?:([0-1]?)'::text)
terms_cycle_of_interest_payment_check
cycle_of_interest_payment)::text ~ `(([-]?)P(?:([-]?)Y)?(?:([-]?)M)?(?:([-]?)W)?(?:([-]?[0-9]+)D)?L(?:([0-1]?)'::text)
terms_cycle_of_principal_redemption_check
cycle_of_principal_redemption)::text ~ `(([-]?)P(?:([-]?)Y)?(?:([-]?)M)?(?:([-]?)W)?(?:([-]?[0-9]+)D)?L(?:([0-1]?)'::text)
terms_cycle_of_rate_reset_check
cycle_of_rate_reset)::text ~ `(([-]?)P(?:([-]?)Y)?(?:([-]?)M)?(?:([-]?)W)?(?:([-]?[0-9]+)D)?L(?:([0-1]?)'::text)
terms_cycle_of_scaling_index_check
cycle_of_scaling_index)::text ~ `(([-]?)P(?:([-]?)Y)?(?:([-]?)M)?(?:([-]?)W)?(?:([-]?[0-9]+)D)?L(?:([0-1]?)'::text)
terms_cycle_point_of_interest_payment_check
((cycle_point_of_interest_payment)::text ~* ’^(B/E)$'::text)
terms_contract_performance_check
((contract_performance)::text ~* ’^(PF/DL/DQ/DF/MA/TE/PreDeal)$'::text)
terms_penalty_type_check
((penalty_type)::text ~* ’^(N/A/R/I)$'::text)
-
-
Table terms_history
Index Name Data type * 🔑
terms_history_id
bigint GENERATED BY DEFAULT AS IDENTITY
accrued_interest
numeric
amortization_date
timestamp
array_cycle_anchor_date_of_interest_payment
varchar(255)
array_cycle_anchor_date_of_principal_redemption
varchar(255)
array_cycle_anchor_date_of_rate_reset
varchar(255)
array_cycle_of_interest_payment
varchar(255)
array_cycle_of_principal_redemption
varchar(255)
array_cycle_of_rate_reset
varchar(255)
array_fixed_variable
varchar(255)
array_increase_decrease
varchar(255)
array_next_principal_redemption_payment
varchar(255)
array_rate
varchar(255)
business_day_convention
varchar(5)
calendar
varchar(2)
capitalization_end_date
timestamp
contract_deal_date
timestamp
contractid
varchar(255)
*
contract_role
varchar(6)
contract_performance
varchar(10)
*
contract_type
varchar(15)
*
currency
varchar(10)
currency2
varchar(10)
cycle_anchor_date_of_dividend_payment
timestamp
cycle_anchor_date_of_fee
timestamp
cycle_anchor_date_of_interest_calculation_base
timestamp
cycle_anchor_date_of_interest_payment
timestamp
cycle_anchor_date_of_optionality
timestamp
cycle_anchor_date_of_principal_redemption
timestamp
cycle_anchor_date_of_rate_reset
timestamp
cycle_anchor_date_of_scaling_index
timestamp
cycle_of_dividend_payment
varchar(10)
cycle_of_fee
varchar(10)
cycle_of_interest_calculation_base
varchar(10)
cycle_of_interest_payment
varchar(10)
cycle_of_optionality
varchar(10)
cycle_of_principal_redemption
varchar(10)
cycle_of_rate_reset
varchar(10)
cycle_of_scaling_index
varchar(10)
cycle_point_of_interest_payment
varchar(1)
cycle_point_of_rate_reset
varchar(1)
*
day_count_convention
varchar(10)
delivery_settlement
varchar(1)
end_of_month_convention
varchar(5)
fee_accrued
numeric
fee_basis
varchar(1)
fee_rate
numeric
fixing_period
varchar(255)
initial_exchange_date
timestamp
interest_calculation_base
varchar(10)
interest_calculation_base_amount
numeric
life_cap
numeric
life_floor
numeric
market_object_code
varchar(255)
market_object_code_of_dividend_rate
varchar(255)
market_object_code_of_rate_reset
varchar(255)
market_object_code_of_scaling_index
varchar(255)
market_value_observed
numeric
maturity_date
timestamp
maximum_penalty_free_disbursement
varchar(255)
next_principal_redemption_payment
numeric
next_reset_rate
numeric
nominal_interest_rate
numeric
nominal_interest_rate2
numeric
notional_principal
numeric
notional_principal2
numeric
object_code_of_prepayment_model
varchar(255)
penalty_rate
numeric
penalty_type
varchar(1)
period_cap
numeric
period_floor
numeric
premium_discount_atied
numeric
price_at_purchase_date
numeric
price_at_termination_date
numeric
purchase_date
timestamp
quantity
numeric
rate_spread
numeric
rounding_convention
varchar(255)
scaling_effect
varchar(5)
scaling_index_at_contract_deal_date
numeric
settlement_period
varchar(255)
x_day_notice
varchar(255)
termination_date
timestamp
delinquency_period
varchar(255)
grace_period
varchar(255)
market_object_code_of_dividends
varchar(255)
rate_multiplier
numeric
*
creator_id
uuid
⬈
contractuuid
uuid
⬈
status_date
timestamp
-
Foreign keys
Type Name On fk-contracts_history-terms_history
contractuuid, status_date
-
Constraints
-
Name Definition terms_history_business_day_convention_check
((business_day_convention)::text ~* ’^(NOS/SCF/SCMF/CSF/CSMF/SCP/SCMP/CSP/SCMP)$'::text)
terms_history_calendar_check
((calendar)::text ~* ’^(NC/MF)$'::text)
terms_history_fee_basis_check
((fee_basis)::text ~* ’^(A/N)$'::text)
terms_history_delivery_settlement_check
((delivery_settlement)::text ~* ’^(D/S)$'::text)
terms_history_cycle_of_dividend_payment_check
cycle_of_dividend_payment)::text ~ `(([-]?)P(?:([-]?)Y)?(?:([-]?)M)?(?:([-]?)W)?(?:([-]?[0-9]+)D)?L(?:([0-1]?)'::text)
terms_history_cycle_of_interest_calculation_base_check
cycle_of_interest_calculation_base)::text ~ `(([-]?)P(?:([-]?)Y)?(?:([-]?)M)?(?:([-]?)W)?(?:([-]?[0-9]+)D)?L(?:([0-1]?)'::text)
terms_history_cycle_of_interest_payment_check
cycle_of_interest_payment)::text ~ `(([-]?)P(?:([-]?)Y)?(?:([-]?)M)?(?:([-]?)W)?(?:([-]?[0-9]+)D)?L(?:([0-1]?)'::text)
terms_history_cycle_of_principal_redemption_check
cycle_of_principal_redemption)::text ~ `(([-]?)P(?:([-]?)Y)?(?:([-]?)M)?(?:([-]?)W)?(?:([-]?[0-9]+)D)?L(?:([0-1]?)'::text)
terms_history_cycle_of_rate_reset_check
cycle_of_rate_reset)::text ~ `(([-]?)P(?:([-]?)Y)?(?:([-]?)M)?(?:([-]?)W)?(?:([-]?[0-9]+)D)?L(?:([0-1]?)'::text)
terms_history_cycle_of_scaling_index_check
cycle_of_scaling_index)::text ~ `(([-]?)P(?:([-]?)Y)?(?:([-]?)M)?(?:([-]?)W)?(?:([-]?[0-9]+)D)?L(?:([0-1]?)'::text)
terms_history_cycle_point_of_interest_payment_check
((cycle_point_of_interest_payment)::text ~* ’^(B/E)$'::text)
terms_history_contract_performance_check
((contract_performance)::text ~* ’^(PF/DL/DQ/DF/MA/TE/PreDeal)$'::text)
terms_history_penalty_type_check
((penalty_type)::text ~* ’^(N/A/R/I)$'::text)
terms_history_scaling_effect_check
((scaling\_effect)::text ~* '^(OOO/IOO/ONO/INO)$'::text)
-
|
(🔑) - Primary key (*) - Mandatory (⬈) - Foreign key (🔎) - Constraint |
3. Dependencies and libraries
3.1. Dependencies
Description
The following dependencies are used in the project to provide various functionalities and features:
-
spring-kafka
-
Purpose: Spring for Apache Kafka for building Kafka-based messaging systems.
-
Usage: Producing and consuming messages from Kafka topics.
-
-
spring-cloud-starter-openfeign
-
Purpose: The spring-cloud-starter-openfeign dependency is used in Spring Boot applications to simplify the process of creating REST clients. It integrates the Feign client library into your application, providing a declarative way to define RESTful service clients.
-
Usage: Use spring-cloud-starter-openfeign to define interfaces for RESTful services and easily make HTTP requests to those services. Feign handles the creation of the HTTP request and mapping of the response to Java objects, reducing the boilerplate code typically required for REST client implementations.
-
-
spring-cloud-starter-loadbalancer
-
Purpose: The spring-cloud-starter-loadbalancer dependency is used in Spring Boot applications to provide client-side load balancing. It integrates with Spring Cloud’s load balancing features, allowing applications to distribute traffic across multiple instances of a service.
-
Usage: Use spring-cloud-starter-loadbalancer to enable client-side load balancing in your application. It provides a simple API for making requests to services registered with a service registry (e.g., Eureka), automatically handling the load balancing logic. This helps improve the availability and scalability of your application by distributing traffic evenly across service instances.
-
-
modelmapper (version 0.7.5)
-
Purpose: The
modelmapperdependency simplifies the process of mapping objects between different data models by automatically determining how properties should be mapped from one object to another. -
Usage: Use
modelmapperto streamline the mapping process between DTOs (Data Transfer Objects), entities, and other data models, reducing the need for manual mapping code and improving code maintainability.
-
3.2. Libraries
Description
The following libraries are used in the project to provide various functionalities and features:
-
actus-core (version 1.0.1)
-
Purpose: The
actus-corelibrary provides core functionality and utilities for working with financial contracts and cash flow projections based on the ACTUS standard. -
Usage: Use to perform calculations, projections, and analysis of financial contracts and cash flows according to the ACTUS (Algorithmic Contract Types Unified Standards) standard.
-
-
ariadne-contracts (version 0.0.2)
-
Purpose: The
ariadne-contractslibrary offers functionality and utilities for working with contract data and management within financial applications. -
Usage: Use
ariadne-contractsto handle contract data, perform contract management tasks, and integrate contract-related functionalities into financial applications.
-
4. Exception handling
Description
The RestExceptionHandler class is responsible for handling various exceptions that may occur during the execution of RESTful API endpoints. It provides centralized exception handling to ensure consistent error responses across the application.
Example usage
@ControllerAdvice
public class RestExceptionHandler {
@ExceptionHandler({ContractsException.class, IllegalArgumentException.class}) (1)
public ResponseEntity<ResponseDto> exceptionToDoHandler(Exception ex) {
final ResponseDto error = new ResponseDto();
error.setStatus(HttpStatus.BAD_REQUEST.value());
error.setMessage(ex.getMessage());
return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(value = { AccessDeniedException.class }) (2)
public ResponseEntity<ResponseDto> exceptionHandler(Exception ex) {
final ResponseDto error = new ResponseDto();
error.setStatus(HttpStatus.UNAUTHORIZED.value());
error.setMessage("Access Denied...");
return new ResponseEntity<>(error, HttpStatus.UNAUTHORIZED);
}
@ExceptionHandler(value = { Exception.class, }) (3)
public ResponseEntity<ResponseDto> exceptionHandlerr(Exception ex) {
final ResponseDto error = new ResponseDto();
error.setStatus(HttpStatus.BAD_REQUEST.value());
error.setMessage("The request could not be understood by the server due to malformed syntax.");
return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
}
}
| 1 | ContractsException and IllegalArgumentException handler
|
| 2 | AccessDeniedException handler
|
| 3 | Generic exception handler
|
Customization
-
Additional exception handlers can be added to address specific use cases or domain-specific exceptions.
-
Error messages and status codes can be customized based on application requirements and error scenarios.
6. ContractsServiceController
6.1. Create contract
6.1.1. Sequential flow
Contract creation process
The below business process / method ‘createContract’ enables creation of a Loan account / Checking account. Here below are process steps -
-
To fetch the product form (Product Template) with ProductID as specified in the contract object.
-
Product template this is fetched is validated with request payload (Contract terms)
-
Counterparty and PaymentDetails are validated.
The validation that are performed at this stage are
-
If counterpartyIDs (Profile IDs) and Counterparty payment channel exists
-
If creator ID (user ID) and creator payment channel ID exist
-
If contract terms are compliant with ACTUS data dictionary
-
If applicability rules of ACTUS are valid for the contract terms provided
After the necessary contract creation process steps and validations are completed, a new contracts with ContractStatus = “PreDeal” is created.
6.1.2. Endpoint
Description
This endpoint allows users with the appropriate permissions to create contracts based on the provided data.
URL
/contracts
Method
POST
Request body
The request body should contain a JSON array of objects, each representing data for creating a contract. The structure of each object should adhere to the CreateContractsDto format.
Example request body
[
{
"productID": 1,
"terms": [
{
"contractPerformance": "PreDeal",
"businessDayConvention": "SCF",
"contractType": "ANN",
"statusDate": "2023-07-31T06:30:00",
"contractRole": "RPA",
"creatorID": "a43c22ed-27df-4324-a453-3e7707c9b82d",
"counterpartyID": "e548956c-1f3b-493e-952e-00cdcca6b599",
"contractID": "a6b799db-c448-4aad-9382-3ae47383f5b2",
"cycleAnchorDateOfInterestPayment": "2023-09-01T06:30:00",
"cycleOfInterestPayment": "P1ML1",
"nominalInterestRate": 0.02,
"dayCountConvention": "30E360",
"currency": "CHF",
"contractDealDate": "2023-07-31T06:30:00",
"initialExchangeDate": "2023-08-01T06:30:00",
"maturityDate": "2024-08-01T06:30:00",
"notionalPrincipal": 50000,
"cycleAnchorDateOfPrincipalRedemption": "2023-09-01T06:30:00",
"cycleOfPrincipalRedemption": "P1ML1",
"nextPrincipalRedemptionPayment": 2312.7827499791606
}
],
"paymentDetails": {
"recordCreatorPaymentChannelID": "e03c2694-71f8-48e0-a68d-8328630fd0c5",
"counterpartyPaymentChannelID": "6963c361-1c1f-40b6-b8b4-47f604be36ef"
},
"selection": {
"productCategory": "Loans",
"department": "DeptB",
"profitCenter": "A",
"tenure": "12M"
}
}
]
Responses
-
201 CREATED: Success. Returns a JSON response containing details of the created contracts.
Example response body
{
"status": 201,
"message": "Success",
"data": [
{
"productID": 1,
"terms": [
{
"contractPerformance": "PreDeal",
"businessDayConvention": "SCF",
"contractType": "ANN",
"statusDate": "2023-07-31T06:30:00",
"contractRole": "RPA",
"creatorID": "a43c22ed-27df-4324-a453-3e7707c9b82d",
"counterpartyID": "e548956c-1f3b-493e-952e-00cdcca6b599",
"contractID": "a6b799db-c448-4aad-9382-3ae47383f5b2",
"cycleAnchorDateOfInterestPayment": "2023-09-01T06:30:00",
"cycleOfInterestPayment": "P1ML1",
"nominalInterestRate": 0.02,
"dayCountConvention": "30E360",
"currency": "CHF",
"contractDealDate": "2023-07-31T06:30:00",
"initialExchangeDate": "2023-08-01T06:30:00",
"maturityDate": "2024-08-01T06:30:00",
"notionalPrincipal": 50000,
"cycleAnchorDateOfPrincipalRedemption": "2023-09-01T06:30:00",
"cycleOfPrincipalRedemption": "P1ML1",
"nextPrincipalRedemptionPayment": 2312.7827499791606
}
],
"paymentDetails": {
"recordCreatorPaymentChannelID": "e03c2694-71f8-48e0-a68d-8328630fd0c5",
"counterpartyPaymentChannelID": "6963c361-1c1f-40b6-b8b4-47f604be36ef"
},
"selection": {
"productCategory": "Loans",
"department": "DeptB",
"profitCenter": "A",
"tenure": "12M"
}
}
]
}
-
400 bad request: If the request body is not in the correct format or if there are validation errors.
-
401 unauthorized: If the user is not authenticated or lacks the necessary permissions to create contracts.
-
5xx server error: If there is a server-side error while processing the request.
Example
{
"status": 400,
"message": "Contract creation failed",
"data": [
{
"contractUUID": null,
"contractID": null,
"errors": [
{
"Product data": "Specified result type [java.lang.String] did not match Query selection type [com.solitx.contracts.entity.Terms] - multiple selections: use Tuple or array"
}
]
}
]
}
6.1.3. Methods
Description
The method createContract is responsible for creating contracts based on the provided list of contract data. It iterates through each contract data object, validates it using a validator (createContractValidator), and then creates the contract if there are no validation errors. It returns a list of ContractsResponseDto objects containing the result of each contract creation attempt.
Parameters
-
contractDataList(List<CreateContractsDto>): A list of objects representing contract data to be used for creating contracts.
Returns
-
List<ContractsResponseDto>: A list of ContractsResponseDto objects containing the result of each contract creation attempt.
Example usage
public List<ContractsResponseDto> createContract(List<CreateContractsDto> contractDataList) {
List<ContractsResponseDto> contractResponseDtoList = new ArrayList<>();
ContractsResponseDto contractResponseDto;
for (CreateContractsDto createContractDto : contractDataList) { (1)
// Validate the contract data using the createContractValidator. (2)
contractResponseDto = createContractValidator.validateContractData(createContractDto);
if (contractResponseDto.getErrors().isEmpty()) {
// If there are no validation errors, create the contract.
contractResponseDto = contractsWorker.createContract(createContractDto); (3)
}
contractResponseDtoList.add(contractResponseDto); (4)
}
return contractResponseDtoList; (5)
}
| 1 | Iterates through each CreateContractsDto object in the provided contractDataList. |
| 2 | Validates the contract data using the createContractValidator. |
| 3 | If there are no validation errors (errors list in the ContractsResponseDto is empty), the contract is created using the contractsWorker. |
| 4 | Adds the resulting ContractsResponseDto object to the contractResponseDtoList. |
| 5 | Returns the list of ContractsResponseDto objects containing the result of each contract creation attempt. |
Exceptions
-
None explicitly thrown by this method. However, exceptions may occur within the validator or worker methods, which are handled internally.
6.1.4. Model classes
Description
The CreateContractsDto class represents the data transfer object (DTO) used for creating contracts in the system. It encapsulates the necessary information required to initialize and configure a contract, including product ID, contract terms, payment details, and selection criteria.
-
productId-
Type: Long
-
Description:Identifier of the product associated with the contract.
-
Constraints: Required field.
-
Example: 1
-
-
terms-
Type: List<Map<String, Object>>
-
Description: Collection of contract terms represented as key-value pairs.
-
Constraints: Required field.
-
Example
{ "terms": [ { "contractPerformance": "PreDeal", "businessDayConvention": "SCF", "contractType": "ANN", "statusDate": "2023-07-31T06:30:00", "contractRole": "RPA", "creatorID": "a43c22ed-27df-4324-a453-3e7707c9b82d", "counterpartyID": "e548956c-1f3b-493e-952e-00cdcca6b599", "contractID": "a6b799db-c448-4aad-9382-3ae47383f5b2", "cycleAnchorDateOfInterestPayment": "2023-09-01T06:30:00", "cycleOfInterestPayment": "P1ML1", "nominalInterestRate": 0.02, "dayCountConvention": "30E360", "currency": "CHF", "contractDealDate": "2023-07-31T06:30:00", "initialExchangeDate": "2023-08-01T06:30:00", "maturityDate": "2024-08-01T06:30:00", "notionalPrincipal": 50000, "cycleAnchorDateOfPrincipalRedemption": "2023-09-01T06:30:00", "cycleOfPrincipalRedemption": "P1ML1", "nextPrincipalRedemptionPayment": 2312.7827499791606 } ] } -
-
paymentDetails-
Type: Map<String, Object>
-
Description: Details of the payment associated with the contract.
-
Constraints: Required field.
-
Example
{ "paymentDetails": { "recordCreatorPaymentChannelID": "e03c2694-71f8-48e0-a68d-8328630fd0c5", "counterpartyPaymentChannelID": "6963c361-1c1f-40b6-b8b4-47f604be36ef" } } -
-
selection-
Type: Map<String, Object>
-
Description: Additional selection criteria or parameters for the contract (optional).
-
Example
-
{
"selection": {
"productCategory": "Loans",
"department": "DeptB",
"profitCenter": "A",
"tenure": "12M"
}
}
Constructors
-
Default Constructor: Initializes an empty
CreateContractsDtoobject. -
All-args Constructor: Initializes a
CreateContractsDtoobject with all attributes. -
Getter and Setter Methods: Accessors and mutators for the attributes of the class.
Example usage
// Create a new instance of CreateContractsDto
CreateContractsDto contractDto = new CreateContractsDto();
contractDto.setProductId((long) 1);
contractDto.setTerms(termsList);
contractDto.setPaymentDetails(paymentDetailsMap);
contractDto.setSelection(selectionMap);
Serialization and deserialization
-
The
CreateContractsDtoclass can be serialized to and deserialized from JSON format using libraries like Jackson, Gson, or JSON-B.
6.1.5. Validation
Description
The validateContractData method is responsible for validating contract data before the creation of contracts. It ensures that the provided contract data meets the necessary criteria and constraints, performing various checks on the product associated with the contract, the contract itself, and its terms. If any validation errors are encountered, they are collected and returned in a structured format.
Parameters
-
createContractDto(CreateContractsDto): An object representing the contract data to be validated.
Returns
-
ContractsResponseDto: An object containing the result of the validation process, including any encountered errors.
Example usage
public ContractsResponseDto validateContractData(CreateContractsDto createContractDto) {
// Initialize data structures to store validation errors.
HashMap<String, Object> createContractErrors = new HashMap<>();
List<Map<String, Object>> errorList = new ArrayList<>();
String contractID;
try {
// Validate the product associated with the contract.
Products products = contractsValidator.validateProduct(createContractDto.getProductId()); (1)
// Validate the contract and product template size.
contractsValidator.validateContractAndProductTemplateSize(products, createContractDto.getTerms()); (2)
// Extract contract terms and ID.
Map<String, Object> contractTerms = createContractDto.getTerms().get(0);
contractID = String.valueOf(contractTerms.get(Constants.CONTRACTID));
// Perform selection validation and add any errors to the error list.
Map<String, Object> selectionValidationErrors = this.contractSelectionValidation(products,
createContractDto); (3)
if (!selectionValidationErrors.isEmpty()) {
errorList.add(selectionValidationErrors);
}
// Perform terms validation and add any errors to the error list.
List<Map<String, Object>> termsValidationErrors = validateContractTerms(products, createContractDto); (4)
errorList.addAll(termsValidationErrors);
} catch (Exception e) { (5)
// If an exception occurs during validation, add an error entry to the error
// list.
createContractErrors.put("Product data", e.getMessage());
errorList.add(createContractErrors);
return new ContractsResponseDto(null, null, errorList);
}
return new ContractsResponseDto(null, contractID, errorList);
}
| 1 | Product validation
|
| 2 | Contract and product template size validation
|
| 3 | Contract selection validation
|
| 4 | Terms validation
|
| 5 | Error handling
|
6.1.6. Testing
Description
This section provides an overview of the testing strategy and objectives for the create contract method.
Example usage
@SuppressWarnings("unchecked")
@Test
void evaluateContractTest() throws ParseException { (1)
CreateContractsDto createContractsDto = createContractsDtoList.get(0);
createContractValidator.validateContractData(createContractsDto);
final List<Map<String, Object>> productTermsList = (List<Map<String, Object>>) product.getTemplate()
.get(Constants.TERMS);
List<Map<String, Object>> contractTermsList = createContractsDto.getTerms();
Map<String, Object> selectionMap = createContractsDto.getSelection();
contractsHelper.evaluateContractTerms(contractTermsList, productTermsList, selectionMap);
contracts = contractsWorker.computeContract(product, createContractsDto);
Terms masterTerms = contracts.getContractTerms().get(0);
PaymentDetails paymentDetails = contracts.getPaymentDetails();
Assertions.assertEquals(contracts.getProductID().toString(), product.getProductID().toString());
Assertions.assertEquals(50000, masterTerms.getNotionalPrincipal().doubleValue(), 0.0);
Assertions.assertEquals(2312.7827499791606, masterTerms.getNextPrincipalRedemptionPayment().doubleValue(), 0.01);
Assertions.assertEquals(LocalDateTime.parse("2023-08-01T00:00:00"), masterTerms.getInitialExchangeDate());
Assertions.assertEquals(LocalDateTime.parse("2023-07-31T00:00:00"), masterTerms.getStatusDate());
Assertions.assertEquals(profile.getProfileID(), masterTerms.getCounterpartyID());
Assertions.assertEquals(paymentDetails.getCounterpartyPaymentChannelID(), counterPartyPaymentChannel.getPaymentChannelID());
Assertions.assertEquals(paymentDetails.getRecordCreatorPaymentChannelID(), recordCreatorPaymentChannel.getPaymentChannelID());
}
@Test
void createContractTest() { (2)
List<ContractsResponseDto> createContractList = contractServiceImpl.createContract(createContractsDtoList);
System.out.println("createContractList :"+createContractList);
String contractUUID = createContractList.get(0).getContractUUID();
Assertions.assertEquals(contracts.getContractUUID(), UUID.fromString(contractUUID));
}
| 1 | evaluateContractTest
|
| 2 | createContractTest
|
Test environment
-
Framework : JUnit 5 (https://junit.org/junit5/docs/current/user-guide/)
-
Mocking framework : Mockito (if applicable) (https://site.mockito.org/)
-
How to run test cases : (https://www.baeldung.com/spring-boot-testing)
Coverage
-
Test coverage includes both positive and negative scenarios to ensure comprehensive validation of contract creation and evaluation processes.
-
Additional test cases may be added to cover edge cases, boundary conditions, and error handling scenarios.
6.2. Get computed schedule
6.2.1. Sequential flow
Getting the computed contract schedule
-
User requests the computed schedule for a contract.
-
Controller validates the contract UUID.
-
If contract not found, return error.
-
If contract status is not "PreDeal", return error.
-
Retrieve contract from repository.
-
Use FactoryWorker to generate schedule based on contract and risk factor model.
-
Return the computed schedule or error message to the user.
6.2.2. Endpoint
Description
The endpoint computes and returns the schedule of a contract based on the provided contractUUID.
URL
/contracts/compute
Method
GET
Request parameters
Parameters |
Type |
Required |
Description |
contractUUID |
UUID |
Yes |
The UUID of the existing contract for which the schedule needs to be computed. |
Responses
-
200 OK
-
Returns a list of business events comprising the schedule.
-
Response body
{ "status": 200, "message": "Success", "data": [ { "eventID": "23a83225-007e-47f2-8dcd-21534a0b92f4", "eventTime": "2023-01-01T00:00:00", "eventType": "IED", "eventBody": { "transaction": { "nominalValue": 50000.0, "nominalAccrued": 0.0 } }, "status": "pending", "executionType": "transaction", "value": -50000.0, "remainingValue": -50000.0, "creditPaymentChannelID": "fb0fdb85-87ee-4af2-b39a-f3a23227203c", "debitPaymentChannelID": "2ae5b30b-3fba-4f4b-a45f-c1d0c03b4144", "userID": "902375cc-4f72-428f-8db0-95a7baa69b51", "contractUUID": "2d904008-f6d4-4740-8a9f-8723ff03fd45", "contractID": "75361862-baec-4bf1-9e05-b87539196d5b", "units": "INR" }, { "eventID": "423ec885-8af4-4a19-8f1f-7d707fd5eefe", "eventTime": "2023-01-01T00:00:00", "eventType": "FP", "eventBody": { "transaction": { "nominalValue": 0.0, "nominalAccrued": 0.0 } }, "status": "pending", "executionType": "transaction", "value": 5000.0, "remainingValue": 5000.0, "creditPaymentChannelID": "2ae5b30b-3fba-4f4b-a45f-c1d0c03b4144", "debitPaymentChannelID": "fb0fdb85-87ee-4af2-b39a-f3a23227203c", "userID": "902375cc-4f72-428f-8db0-95a7baa69b51", "contractUUID": "2d904008-f6d4-4740-8a9f-8723ff03fd45", "contractID": "Loan processing fee", "units": "INR" }, { "eventID": "adbca86d-95a9-4327-bddc-71c69af1a1dc", "eventTime": "2023-01-01T00:00:00", "eventType": "FP", "eventBody": { "transaction": { "nominalValue": 0.0, "nominalAccrued": 0.0 } }, "status": "pending", "executionType": "transaction", "value": 2500.0, "remainingValue": 2500.0, "creditPaymentChannelID": "2ae5b30b-3fba-4f4b-a45f-c1d0c03b4144", "debitPaymentChannelID": "fb0fdb85-87ee-4af2-b39a-f3a23227203c", "userID": "902375cc-4f72-428f-8db0-95a7baa69b51", "contractUUID": "2d904008-f6d4-4740-8a9f-8723ff03fd45", "contractID": "Insurance Fee", "units": "INR" }, { "eventID": "433a60c6-2429-40d1-9783-2484c90ac987", "eventTime": "2023-02-01T00:00:00", "eventType": "IP", "eventBody": { "transaction": { "nominalValue": 45833.0, "nominalAccrued": 0.0 } }, "status": "pending", "executionType": "transaction", "value": 833.0, "remainingValue": 833.0, "creditPaymentChannelID": "2ae5b30b-3fba-4f4b-a45f-c1d0c03b4144", "debitPaymentChannelID": "fb0fdb85-87ee-4af2-b39a-f3a23227203c", "userID": "902375cc-4f72-428f-8db0-95a7baa69b51", "contractUUID": "2d904008-f6d4-4740-8a9f-8723ff03fd45", "contractID": "75361862-baec-4bf1-9e05-b87539196d5b", "units": "INR" }, { "eventID": "1b062381-3b44-404a-afb7-d6296ca95b9e", "eventTime": "2023-02-01T00:00:00", "eventType": "PR", "eventBody": { "transaction": { "nominalValue": 45833.0, "nominalAccrued": 833.0 } }, "status": "pending", "executionType": "transaction", "value": 4167.0, "remainingValue": 4167.0, "creditPaymentChannelID": "2ae5b30b-3fba-4f4b-a45f-c1d0c03b4144", "debitPaymentChannelID": "fb0fdb85-87ee-4af2-b39a-f3a23227203c", "userID": "902375cc-4f72-428f-8db0-95a7baa69b51", "contractUUID": "2d904008-f6d4-4740-8a9f-8723ff03fd45", "contractID": "75361862-baec-4bf1-9e05-b87539196d5b", "units": "INR" }, { "eventID": "e0ac4b65-4584-4437-a8e3-2c4c5e3e5d67", "eventTime": "2023-03-01T00:00:00", "eventType": "IP", "eventBody": { "transaction": { "nominalValue": 41597.0, "nominalAccrued": 0.0 } }, "status": "pending", "executionType": "transaction", "value": 764.0, "remainingValue": 764.0, "creditPaymentChannelID": "2ae5b30b-3fba-4f4b-a45f-c1d0c03b4144", "debitPaymentChannelID": "fb0fdb85-87ee-4af2-b39a-f3a23227203c", "userID": "902375cc-4f72-428f-8db0-95a7baa69b51", "contractUUID": "2d904008-f6d4-4740-8a9f-8723ff03fd45", "contractID": "75361862-baec-4bf1-9e05-b87539196d5b", "units": "INR" }, { "eventID": "f71cbff0-1708-48d6-9ed2-d15c6534f69d", "eventTime": "2023-03-01T00:00:00", "eventType": "PR", "eventBody": { "transaction": { "nominalValue": 41597.0, "nominalAccrued": 764.0 } }, "status": "pending", "executionType": "transaction", "value": 4236.0, "remainingValue": 4236.0, "creditPaymentChannelID": "2ae5b30b-3fba-4f4b-a45f-c1d0c03b4144", "debitPaymentChannelID": "fb0fdb85-87ee-4af2-b39a-f3a23227203c", "userID": "902375cc-4f72-428f-8db0-95a7baa69b51", "contractUUID": "2d904008-f6d4-4740-8a9f-8723ff03fd45", "contractID": "75361862-baec-4bf1-9e05-b87539196d5b", "units": "INR" }, { "eventID": "0afd9e04-8a31-4826-886d-bdb2489dd28c", "eventTime": "2023-04-01T00:00:00", "eventType": "IP", "eventBody": { "transaction": { "nominalValue": 37291.0, "nominalAccrued": 0.0 } }, "status": "pending", "executionType": "transaction", "value": 693.0, "remainingValue": 693.0, "creditPaymentChannelID": "2ae5b30b-3fba-4f4b-a45f-c1d0c03b4144", "debitPaymentChannelID": "fb0fdb85-87ee-4af2-b39a-f3a23227203c", "userID": "902375cc-4f72-428f-8db0-95a7baa69b51", "contractUUID": "2d904008-f6d4-4740-8a9f-8723ff03fd45", "contractID": "75361862-baec-4bf1-9e05-b87539196d5b", "units": "INR" } ] }
-
-
400 bad request
-
If the provided
contractUUIDis invalid or not found, the endpoint will return an HTTP status code 404 Not Found.
-
-
403 forbidden
-
If the user does not have the necessary permissions to execute contracts.
-
-
404 not found
-
If the contract with the provided UUID does not exist.
-
-
500 internal server error
-
If there is an unexpected error executing the contract.
-
Example error response
-
400 bad request
-
If the provided
contractUUIDis invalid or does not exist. -
Response body
{ "status": 400, "message": "Invalid contractUUID " + 36c7d13e-55dc-4b89-a1b8-98f1f8716698, "data": "null" } -
6.2.3. Methods
Description
This method is responsible for creating a dynamic event associated with a contract.
-
Method :
computeContract-
Purpose
-
This method computes the schedule of business events for a given contract identified by its UUID.
-
-
Parameters
-
contractUUID (UUID) :The UUID of the contract for which the schedule is to be computed.
-
-
Return type
-
List<BusinessEvents> :A list of business events representing the schedule for the contract.public List<BusinessEvents> computeContract(UUID contractUUID) throws ContractsException { List<BusinessEvents> contractSchedule; Contracts contract = contractsServiceRepo.findById(contractUUID) .orElseThrow(() -> new IllegalArgumentException(CONTRACT_ERROR)); (1) try { // Compute the contract schedule. contractSchedule = getContractSchedule(contract); (2) } catch (Exception e) { throw new ContractsException(e.getMessage()); (3) } return contractSchedule; }
-
-
Behavior
1 Retrieves contract information from the contracts service repository. 2 Calls the getContractSchedulemethod to compute the contract schedule.3 Throws a ContractsExceptionif any error occurs during computation. -
-
Method :
getContractSchedule-
Purpose
-
This method generates the schedule of business events for a given contract.
-
-
Parameters
-
contract (Contracts) :The contract object for which the schedule is to be generated.
-
-
Return type
-
List<BusinessEvents> :A list of business events representing the schedule for the contract.public List<BusinessEvents> getContractSchedule(Contracts contract) throws ParseException { // Get the risk factor model provider for the contract. RiskFactorModelProvider riskFactorModelProvider = getRiskFactorModelProvider(contract); (1) // Generate the schedule of business events using the actusFactoryWorker. return actusFactoryWorker.generateSchedule(contract, riskFactorModelProvider); (2) }
-
-
Behavior
1 Retrieves the risk factor model provider for the contract. 2 Calls the generateSchedulemethod to generate the contract schedule. -
-
Method :
generateSchedule-
Purpose
-
This method generates the schedule of business events for a given contract using the provided risk factor model.
-
-
Parameters
-
contract (Contracts) :The contract object for which the schedule is to be generated. -
riskFactorModelProvider (RiskFactorModelProvider) :The risk factor model provider used for generating the schedule.
-
-
Return type
-
List<BusinessEvents> :A list of business events representing the schedule for the contract.public List<BusinessEvents> generateSchedule(Contracts contract, RiskFactorModelProvider riskFactorModelProvider) { List<ContractEvent> contractEvents; log.info("Contract generate schedule started by UserId : {}, ContractUUID : {}", usersHelper.getUserID(), contract.getContractUUID()); final Terms masterTerm = contract.getContractTerms().get(0); LocalDateTime statusDate = masterTerm.getStatusDate(); LocalDateTime maturityDate = masterTerm.getMaturityDate(); final List<String> specialContractTypes = Arrays.asList("AINV", "ARES", "AEQT"); List<BusinessEvents> businessEventsList = new ArrayList<>(); if (specialContractTypes.contains(masterTerm.getContractType())) { // Need to implement return businessEventsList; } else { for (final Terms contractTerms : contract.getContractTerms()) { Map<String, Object> termsMap = ContractsMapper.termsToMap(contractTerms); // Mapping terms object to ContractModel object ContractModelProvider model = getContractModel(termsMap); // Get contract events based on the model, status date, and risk factor model // provider. contractEvents = getContractEvents(model, maturityDate, statusDate, riskFactorModelProvider); (1) // Mapping contractEvent to BusinessEvents List<BusinessEvents> businessEvents = getBusinessEvents(contract, contractTerms, contractEvents); (2) businessEventsList.addAll(businessEvents); } Collections.sort(businessEventsList, new SortByEventTime()); (3) log.info("Contract generate schedule finihed by UserId : {}, ContractUUID : {}", usersHelper.getUserID(), contract.getContractUUID()); return businessEventsList; (4) } }
-
-
Behavior
1 Processes the contract terms and generates contract events based on the provided model, maturity date, and status date. 2 Maps contract events to business events and adds them to the list of business events. 3 Sorts the list of business events by event time. 4 Returns business events list. -
6.2.4. Validation
Description
The method validateContract(String contractUUID) is responsible for validating a contract identified by its UUID.
-
Parameters
-
contractUUID :The UUID of the contract to validate.
-
-
Returns
-
This method does not return any value (
void).
-
-
Functionality
-
Validates the contract UUID to ensure it is valid.
-
Validates the status of the contract to ensure it is in the "PreDeal" state.
-
-
Exceptions
-
Throws
IllegalArgumentExceptionif the contract UUID is invalid or if the contract status is not "PreDeal".
-
-
Example usage
/**
* Retrieves a contract based on its UUID.
*
* @param contractUUID The UUID of the contract to retrieve.
* @return The Contracts object representing the retrieved contract.
* @throws IllegalArgumentException If the contract UUID is invalid.
*/
public Contracts validateContractUUID(String contractUUID) {
// Provides contract information based on contractUUID
final Optional<Contracts> optionalContract = contractsRepo.findById(UUID.fromString(contractUUID)); (1)
Assert.isTrue(optionalContract.isPresent(), "Invalid contractUUID " + contractUUID);
return optionalContract.get(); (2)
}
/**
* Validates the status of a contract.
*
* @param contract The Contracts object representing the contract data to
* validate.
* @throws IllegalArgumentException If the contract status is not "PreDeal".
*/
public void validateContractStatus(Contracts contract) {
final Terms term = contract.getContractTerms().get(0);
Assert.isTrue(term.getContractPerformance().equals("PreDeal"), "Contract already executed"); (3)
}
| 1 | Validating contract UUID
|
| 2 | Retrieving contract
|
| 3 | Validating contract status
|
|
|
6.2.5. Testing
Description
This section provides an overview of the testing strategy and objectives for the get computed contract schedule method.
Example usage
@Test
void computeContractTest() throws ContractsException { (1)
List<BusinessEvents> eventsList = contractServiceImpl
.computeContract(contracts.getContractUUID());
Assertions.assertEquals(25, eventsList.size());
}
@TestFactory
Stream<DynamicTest> computeContractScheduleTest() throws IOException, ContractsException { (2)
List<DynamicTest> dynamicTests = new ArrayList<>();
List<BusinessEventsDto> expectedEventsList = MappingUtils
.mapToEventsList("./src/test/resources/events/events-contract-ann.json");
List<BusinessEvents> computedEventsList = contractServiceImpl
.computeContract(contracts.getContractUUID());
Assertions.assertEquals(expectedEventsList.size(), computedEventsList.size(), "Number of events should match.");
for (int i = 0; i < expectedEventsList.size(); i++) {
BusinessEventsDto expectedEvent = expectedEventsList.get(i);
BusinessEvents computedEvent = computedEventsList.get(i);
dynamicTests.add(contractUtils.createDynamicTest(expectedEvent, computedEvent));
}
return dynamicTests.stream();
}
| 1 | computeContractTest()
|
| 2 | computeContractScheduleTest()
|
6.3. Execute contracts
6.3.1. Sequential flow
Contract execution process
-
This method executes a contract identified by the given contract UUID.
-
It validates the contract, sets its performance to "PF" (Performant).
-
Saves the contract schedule.
-
Creates a Metaco account for the contract, only if the contract’s selection contains a "Ledger ID" key.
-
Updates contract payment channels, and sends a Kafka event signaling the contract execution.
-
If successful, it returns a list of business events associated with the execution.
6.3.2. Endpoint
Description
This endpoint executes a contract and returns its schedule based on the provided contractUUID.
URL
/contracts/execute
Method
POST
Request parameters
Parameters |
Type |
Required |
Description |
contractUUID |
UUID |
Yes |
The UUID of an existing contract to be executed. |
Responses
-
200 OK
-
Returns the schedule of the executed contract.
-
Response body
{ "status": 200, "message": "Success", "data": [ { "eventID": "23a83225-007e-47f2-8dcd-21534a0b92f4", "eventTime": "2023-01-01T00:00:00", "eventType": "IED", "eventBody": { "transaction": { "nominalValue": 50000.0, "nominalAccrued": 0.0 } }, "status": "pending", "executionType": "transaction", "value": -50000.0, "remainingValue": -50000.0, "creditPaymentChannelID": "fb0fdb85-87ee-4af2-b39a-f3a23227203c", "debitPaymentChannelID": "2ae5b30b-3fba-4f4b-a45f-c1d0c03b4144", "userID": "902375cc-4f72-428f-8db0-95a7baa69b51", "contractUUID": "2d904008-f6d4-4740-8a9f-8723ff03fd45", "contractID": "75361862-baec-4bf1-9e05-b87539196d5b", "units": "INR" }, { "eventID": "423ec885-8af4-4a19-8f1f-7d707fd5eefe", "eventTime": "2023-01-01T00:00:00", "eventType": "FP", "eventBody": { "transaction": { "nominalValue": 0.0, "nominalAccrued": 0.0 } }, "status": "pending", "executionType": "transaction", "value": 5000.0, "remainingValue": 5000.0, "creditPaymentChannelID": "2ae5b30b-3fba-4f4b-a45f-c1d0c03b4144", "debitPaymentChannelID": "fb0fdb85-87ee-4af2-b39a-f3a23227203c", "userID": "902375cc-4f72-428f-8db0-95a7baa69b51", "contractUUID": "2d904008-f6d4-4740-8a9f-8723ff03fd45", "contractID": "Loan processing fee", "units": "INR" }, { "eventID": "adbca86d-95a9-4327-bddc-71c69af1a1dc", "eventTime": "2023-01-01T00:00:00", "eventType": "FP", "eventBody": { "transaction": { "nominalValue": 0.0, "nominalAccrued": 0.0 } }, "status": "pending", "executionType": "transaction", "value": 2500.0, "remainingValue": 2500.0, "creditPaymentChannelID": "2ae5b30b-3fba-4f4b-a45f-c1d0c03b4144", "debitPaymentChannelID": "fb0fdb85-87ee-4af2-b39a-f3a23227203c", "userID": "902375cc-4f72-428f-8db0-95a7baa69b51", "contractUUID": "2d904008-f6d4-4740-8a9f-8723ff03fd45", "contractID": "Insurance Fee", "units": "INR" }, { "eventID": "433a60c6-2429-40d1-9783-2484c90ac987", "eventTime": "2023-02-01T00:00:00", "eventType": "IP", "eventBody": { "transaction": { "nominalValue": 45833.0, "nominalAccrued": 0.0 } }, "status": "pending", "executionType": "transaction", "value": 833.0, "remainingValue": 833.0, "creditPaymentChannelID": "2ae5b30b-3fba-4f4b-a45f-c1d0c03b4144", "debitPaymentChannelID": "fb0fdb85-87ee-4af2-b39a-f3a23227203c", "userID": "902375cc-4f72-428f-8db0-95a7baa69b51", "contractUUID": "2d904008-f6d4-4740-8a9f-8723ff03fd45", "contractID": "75361862-baec-4bf1-9e05-b87539196d5b", "units": "INR" }, { "eventID": "1b062381-3b44-404a-afb7-d6296ca95b9e", "eventTime": "2023-02-01T00:00:00", "eventType": "PR", "eventBody": { "transaction": { "nominalValue": 45833.0, "nominalAccrued": 833.0 } }, "status": "pending", "executionType": "transaction", "value": 4167.0, "remainingValue": 4167.0, "creditPaymentChannelID": "2ae5b30b-3fba-4f4b-a45f-c1d0c03b4144", "debitPaymentChannelID": "fb0fdb85-87ee-4af2-b39a-f3a23227203c", "userID": "902375cc-4f72-428f-8db0-95a7baa69b51", "contractUUID": "2d904008-f6d4-4740-8a9f-8723ff03fd45", "contractID": "75361862-baec-4bf1-9e05-b87539196d5b", "units": "INR" }, { "eventID": "e0ac4b65-4584-4437-a8e3-2c4c5e3e5d67", "eventTime": "2023-03-01T00:00:00", "eventType": "IP", "eventBody": { "transaction": { "nominalValue": 41597.0, "nominalAccrued": 0.0 } }, "status": "pending", "executionType": "transaction", "value": 764.0, "remainingValue": 764.0, "creditPaymentChannelID": "2ae5b30b-3fba-4f4b-a45f-c1d0c03b4144", "debitPaymentChannelID": "fb0fdb85-87ee-4af2-b39a-f3a23227203c", "userID": "902375cc-4f72-428f-8db0-95a7baa69b51", "contractUUID": "2d904008-f6d4-4740-8a9f-8723ff03fd45", "contractID": "75361862-baec-4bf1-9e05-b87539196d5b", "units": "INR" }, { "eventID": "f71cbff0-1708-48d6-9ed2-d15c6534f69d", "eventTime": "2023-03-01T00:00:00", "eventType": "PR", "eventBody": { "transaction": { "nominalValue": 41597.0, "nominalAccrued": 764.0 } }, "status": "pending", "executionType": "transaction", "value": 4236.0, "remainingValue": 4236.0, "creditPaymentChannelID": "2ae5b30b-3fba-4f4b-a45f-c1d0c03b4144", "debitPaymentChannelID": "fb0fdb85-87ee-4af2-b39a-f3a23227203c", "userID": "902375cc-4f72-428f-8db0-95a7baa69b51", "contractUUID": "2d904008-f6d4-4740-8a9f-8723ff03fd45", "contractID": "75361862-baec-4bf1-9e05-b87539196d5b", "units": "INR" }, { "eventID": "0afd9e04-8a31-4826-886d-bdb2489dd28c", "eventTime": "2023-04-01T00:00:00", "eventType": "IP", "eventBody": { "transaction": { "nominalValue": 37291.0, "nominalAccrued": 0.0 } }, "status": "pending", "executionType": "transaction", "value": 693.0, "remainingValue": 693.0, "creditPaymentChannelID": "2ae5b30b-3fba-4f4b-a45f-c1d0c03b4144", "debitPaymentChannelID": "fb0fdb85-87ee-4af2-b39a-f3a23227203c", "userID": "902375cc-4f72-428f-8db0-95a7baa69b51", "contractUUID": "2d904008-f6d4-4740-8a9f-8723ff03fd45", "contractID": "75361862-baec-4bf1-9e05-b87539196d5b", "units": "INR" } ] }
-
-
400 bad request
-
If the required parameter
contractUUIDis missing or invalid.
-
-
403 forbidden
-
If the user does not have the necessary permissions to execute contracts.
-
-
404 not found
-
If the contract with the provided UUID does not exist.
-
-
500 internal server error
-
If there is an unexpected error executing the contract.
-
Example error response
-
400 bad request
-
If the provided
contractUUIDis invalid or does not exist. -
Response body
{ "status": 400, "message": "Invalid contractUUID provided.", "data": "null" } -
6.3.3. Methods
Description
The method executeContract executes a contract identified by the given UUID. It performs various actions related to contract execution, including setting contract performance status, saving contract schedule, updating contract payment channels, saving contract execution details, and sending a Kafka event for contract execution.
Method signature
public List<BusinessEvents> executeContract(String contractUUID) throws ContractsException
Parameters
-
contractUUID (String):The UUID of the contract to execute.
Returns
-
List<BusinessEvents> :A list ofBusinessEventsrepresenting the business events generated by executing the contract.
Exceptions
-
ContractsException :Thrown if there’s an error executing the contract.
Usage example
contractsValidator.validateContract(contractUUID); (1)
public List<BusinessEvents> executeContract(String contractUUID) throws ContractsException {
log.info("Contract execution started by UserId : {}, ContractUUID : {}", usersHelper.getUserID(), contractUUID);
List<BusinessEvents> businessEvents;
Contracts contract = contractsServiceRepo.findById(UUID.fromString(contractUUID))
.orElseThrow(() -> new IllegalArgumentException(CONTRACT_ERROR)); (2)
Terms contractTerms = contract.getContractTerms().get(0);
// Set the contract status to "PF".
contractTerms.setContractPerformance("PF"); (3)
try {
// Save the contract schedule.
businessEvents = saveContractSchedule(contract); (4)
// Create a Metaco account for the contract.
contractsHelper.createMetacoAccount(contract); (5)
// Update contract payment channels(Linking contract to paymentChannel).
updateContractPaymentChannel(contract); (6)
contract.setExecutedBy(usersHelper.getUserID());
contract.setTimeStamp(UtilityHelper.dateTime());
contractsServiceRepo.save(contract); (7)
// Send a request to Kafka for contract execution.
sendKafkaContractExecutedEvent(contract); (8)
log.info("Contract execution finished by UserId : {}, ContractUUID : {}", usersHelper.getUserID(),
contractUUID);
} catch (Exception e) {
throw new ContractsException(e.getMessage()); (9)
}
return businessEvents;
}
| 1 | The method validates the contract identified by contractUUID using the contractsValidator.validateContract method. |
| 2 | Retrieves the contract details from the repository based on the provided UUID. |
| 3 | Sets the contract performance status to "PF". |
| 4 | Saves the contract schedule. |
| 5 | If the contract selection contains a LedgerID key, then it creates a Metaco account for the contract. |
| 6 | Updates contract payment channels. |
| 7 | Saves contract execution details including the executor’s user ID and timestamp. |
| 8 | Sends a Kafka event indicating contract execution. |
| 9 | If any exception occurs during the execution, it is caught, and a ContractsException is thrown with the corresponding error message. |
|
6.3.4. Validation
Description
The method validateContract(String contractUUID) is responsible for validating a contract identified by its UUID.
-
Parameters
-
contractUUID :The UUID of the contract to validate.
-
-
Returns
-
This method does not return any value (
void).
-
-
Functionality
-
Validates the contract UUID to ensure it is valid.
-
Validates the status of the contract to ensure it is in the "PreDeal" state.
-
-
Exceptions
-
Throws
IllegalArgumentExceptionif the contract UUID is invalid or if the contract status is not "PreDeal".
-
-
Example usage
/**
* Retrieves a contract based on its UUID.
*
* @param contractUUID The UUID of the contract to retrieve.
* @return The Contracts object representing the retrieved contract.
* @throws IllegalArgumentException If the contract UUID is invalid.
*/
public Contracts validateContractUUID(String contractUUID) {
// Provides contract information based on contractUUID
final Optional<Contracts> optionalContract = contractsRepo.findById(UUID.fromString(contractUUID)); (1)
Assert.isTrue(optionalContract.isPresent(), "Invalid contractUUID " + contractUUID);
return optionalContract.get(); (2)
}
/**
* Validates the status of a contract.
*
* @param contract The Contracts object representing the contract data to
* validate.
* @throws IllegalArgumentException If the contract status is not "PreDeal".
*/
public void validateContractStatus(Contracts contract) {
final Terms term = contract.getContractTerms().get(0);
Assert.isTrue(term.getContractPerformance().equals("PreDeal"), "Contract already executed"); (3)
}
| 1 | Validating contract UUID
|
| 2 | Retrieving contract
|
| 3 | Validating contract status
|
|
|
6.3.5. Testing
Description
This section provides an overview of the testing strategy and objectives for the execute contract method.
Example usage
@Test
void executeContractTest() throws ContractsException { (1)
List<BusinessEvents> executeContract = contractServiceImpl.executeContract(contracts.getContractUUID());
System.err.println("gfjfg "+executeContract);
Contracts contracts1 = contractsRepo.findById(contracts.getContractUUID()).get();
String contractStatus = contracts1.getContractTerms().get(0).getContractPerformance();
Assertions.assertEquals("PF", contractStatus);
}
@TestFactory
Stream<DynamicTest> executeContractAfterTest() throws IOException, ContractsException { (2)
List<DynamicTest> dynamicTests = new ArrayList<>();
List<BusinessEventsDto> expectedEventsList = MappingUtils
.mapToEventsList("./src/test/resources/events/events-contract-ann.json");
List<BusinessEvents> computedEventsList = contractServiceImpl
.executeContract(contracts.getContractUUID());
Assertions.assertEquals(expectedEventsList.size(), computedEventsList.size(), "Number of events should match.");
for (int i = 0; i < expectedEventsList.size(); i++) {
int eventIndex = i;
BusinessEventsDto expectedEvent = expectedEventsList.get(eventIndex);
BusinessEvents computedEvent = computedEventsList.get(eventIndex);
dynamicTests.add(contractUtils.createDynamicTest(expectedEvent, computedEvent));
}
return dynamicTests.stream();
}
| 1 | executeContractTest()
|
| 2 | executeContractAfterTest()
|
6.4. Get contracts
6.4.1. Sequential flow
Contract retrieval process
-
Retrieve contracts entities : The
getContractsmethod starts by fetching a list of Contracts entities from the data source based on the provided filtering criteria and pagination parameters. -
Iterate through contracts list
-
For each contract in the retrieved list
-
-
Retrieve contract terms : The terms associated with each contract are retrieved to provide additional details.
-
Optional: Update notional principle
-
If the contract’s performance is not "PreDeal" and the contract type is "COM" (commodity contract), the notional principal of the contract is updated.
-
-
Map terms to DTO
-
The terms associated with each contract are mapped to a list of TermsDto objects using a mapping function.
-
-
Create ContractsDto object
-
A ContractsDto object is created and populated with relevant contract information:
-
contractUUID
-
productID
-
terms (mapped to a list of TermsDto)
-
selection
-
paymentDetails
-
createdBy
-
executedBy
-
timeStamp
-
-
-
Add ContractsDto to list : The created ContractsDto object is added to the list of ContractsDto objects representing the retrieved contracts.
-
Return contracts list : The list of ContractsDto objects representing the retrieved contracts is returned.
6.4.2. Endpoint
Description
Retrieves a list of contract information based on specified filter parameters and pagination.
URL
/contracts
Method
GET
Request filter parameters
Parameters |
Type |
Required |
Description |
JSON object |
No |
Provided based on the requirements. |
|
pageNumber |
Integer |
No |
Default value is 0. |
pageSize |
Integer |
No |
Default value is 100. |
Responses
-
200 OK
-
Returns the contracts information.
-
Response body
{ "status": 200, "message": "Success", "data": [ { "contractUUID": "28ee9eb5-e4b9-491c-98ce-a451abbedae9", "productID": 4, "paymentDetails": { "recordCreatorPaymentChannelID": "2ae5b30b-3fba-4f4b-a45f-c1d0c03b4144", "counterpartyPaymentChannelID": "fb0fdb85-87ee-4af2-b39a-f3a23227203c", "contractPaymentChannelID": null }, "terms": [ { "contractPerformance": "PreDeal", "businessDayConvention": "SCF", "contractType": "ANN", "statusDate": "2023-01-01T00:00:00", "contractRole": "RPA", "creatorID": "902375cc-4f72-428f-8db0-95a7baa69b51", "counterpartyID": "d2c87ded-489e-4510-8fe1-95f12c048a5d", "contractID": "9ec8997e-70b5-4fa1-82fe-56cbc0fc8149", "cycleAnchorDateOfInterestPayment": "2023-02-02T00:00:00", "cycleOfInterestPayment": "P1ML1", "nominalInterestRate": 0.01, "dayCountConvention": "30E360", "currency": "CHF", "contractDealDate": "2023-01-01T00:00:00", "initialExchangeDate": "2023-01-02T00:00:00", "maturityDate": "2024-01-02T00:00:00", "notionalPrincipal": 20000.0, "cycleAnchorDateOfPrincipalRedemption": "2023-02-02T00:00:00", "cycleOfPrincipalRedemption": "P1ML1", "nextPrincipalRedemptionPayment": 1260.9478399993018 } ], "selection": { "tenure": "12M", "department": "DeptB", "profitCenter": "A", "remainingValue": 5000, "productCategory": "Microfinance Loan" }, "createdBy": "902375cc-4f72-428f-8db0-95a7baa69b51", "executedBy": null, "timeStamp": "2024-02-26T17:15:10" } ] }
-
-
403 forbidden
-
If the user does not have the necessary permissions to execute contracts.
-
-
500 internal server error
-
If there is an unexpected error executing the contract.
-
6.4.3. Methods
Description
This method is responsible for retrieving a list of contract data based on specified filtering criteria and pagination.
-
Method :
getContracts-
Purpose
-
Retrieve a list of contract data based on specified filtering criteria and pagination.
-
-
Parameters
-
contractsFilterDto :An object containing filtering criteria for contracts. -
pageable :An object representing pagination settings.
-
-
Return type
-
List<ContractsDto> :A list of contract data transfer objects (ContractsDto).public List<ContractsDto> getContracts(ContractsFilterDto contractsFilterDto, Pageable pageable) { List<ContractsDto> contractsModelList = new ArrayList<>(); // Retrieve a list of Contracts entities based on the filtering criteria and // pagination. List<Contracts> contractsList = getContractsList(contractsFilterDto, pageable);(1) for (final Contracts contract : contractsList) { (2) final Terms term = contract.getContractTerms().get(0); // Notional principle update for commodity contracts if (!term.getContractPerformance().equalsIgnoreCase("PreDeal") && term.getContractType().equalsIgnoreCase("COM")) { Contracts updatedContract = contractsHelper.updateNotionalPrincipal(contract); (3) contractsServiceRepo.save(updatedContract); } // Map terms to a list of TermsDto objects List<TermsDto> termsDtoList = ContractsMapper.mapToTermsDto(contract.getContractTerms()); (4) Map<String, Object> termsMap = new HashMap<>(); termsMap.put("Terms", termsDtoList); // Create a ContractsDto object for the contract ContractsDto contractsModel = new ContractsDto(); (5) contractsModel.setContractUUID(contract.getContractUUID()); contractsModel.setProductUUID(contract.getProductUUID()); contractsModel.setTerms(termsMap); contractsModel.setSelection(contract.getSelection()); contractsModel.setPaymentDetails(contract.getPaymentDetails()); contractsModel.setCreatedBy(contract.getCreatedBy()); contractsModel.setExecutedBy(contract.getExecutedBy()); contractsModel.setProfileId(contract.getProfileId()); contractsModel.setTimeStamp(contract.getTimeStamp()); contractsModelList.add(contractsModel); } return contractsModelList; (6) }
-
-
Behavior
1 Retrieves a list of contract entities based on the provided filtering criteria and pagination. 2 Iterates through each contract entity. 3 Updates the notional principle for commodity contracts if certain conditions are met. 4 Maps contract terms to a list of term data transfer objects (TermsDto). 5 Constructs a ContractsDto object for each contract entity with mapped data. 6 Returns a list of constructed ContractsDto objects. -
-
Method :
getContractsList-
Purpose
-
Retrieve a list of contract entities based on specified filtering criteria and pagination.
-
-
Parameters
-
contractsFilterDto :An object containing filtering criteria for contracts. -
pageable :An object representing pagination settings.
-
-
Return type
-
List<Contracts> :A list of contract entities.public List<Contracts> getContractsList(ContractsFilterDto contractsFilterDto, Pageable pageable) { // Build a JPA query using the buildContractsQuery method. TypedQuery<Tuple> contractsQuery = buildContractsQuery(contractsFilterDto, pageable); (1) // Execute the query and retrieve a list of contract UUIDs. List<UUID> contractUUIDs = contractsQuery.getResultList().stream().map(tuple -> tuple.get(0, UUID.class)) .toList(); (2) return contractsServiceRepo.findByContractUUIDIn(contractUUIDs); (3) }
-
-
Behavior
1 Builds a JPA query using the provided filtering criteria and pagination. 2 Executes the query to retrieve a list of contract UUIDs. 3 Retrieves contract entities based on the retrieved UUIDs and returns the list of entities. -
-
Method :
buildContractsQuery-
Purpose
-
Build a JPA query for retrieving contract entities based on specified filtering criteria and pagination.
-
-
Parameters
-
contractsFilterDto :An object containing filtering criteria for contracts. -
pageable :An object representing pagination settings.
-
-
Return type
-
TypedQuery<Tuple> :A typed query for retrieving contract entities.
private TypedQuery<Tuple> buildContractsQuery(ContractsFilterDto contractsFilterDto, Pageable pageable) { (1) CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaQuery<Tuple> query = cb.createTupleQuery(); Root<Contracts> rootContracts = query.from(Contracts.class); Join<Contracts, Terms> joinTerms = rootContracts.join("contractTerms", JoinType.INNER); // Select specific columns (contractUUID and timeStamp) query.multiselect(rootContracts.get("contractUUID"), rootContracts.get("timeStamp")); Predicate predicate = cb.conjunction(); predicate = cb.and(predicate, cb.equal(joinTerms.get("creatorID"), usersHelper.getUserID())); // Apply additional filter conditions based on ContractsFilterDto if (!UtilityHelper.isNullorEmpty(contractsFilterDto.getContractUUID())) { (2) predicate = cb.and(predicate, cb.equal(rootContracts.get("contractUUID"), contractsFilterDto.getContractUUID())); } if (!UtilityHelper.isNullorEmpty(contractsFilterDto.getProductID())) { predicate = cb.and(predicate, cb.equal(rootContracts.get("productID"), contractsFilterDto.getProductID())); } if (!UtilityHelper.isNullorEmpty(contractsFilterDto.getTimestamp())) { predicate = cb.and(predicate, cb.like(rootContracts.get("timeStamp"), "%" + contractsFilterDto.getTimestamp() + "%")); } query.where(predicate); // Apply ordering query.orderBy(cb.desc(rootContracts.get("timeStamp"))); (3) query.distinct(true); // Create the TypedQuery TypedQuery<Tuple> typedQuery = entityManager.createQuery(query); // Apply pagination if provided if (pageable != null) { (4) typedQuery.setFirstResult(pageable.getPageNumber() * pageable.getPageSize()); typedQuery.setMaxResults(pageable.getPageSize()); } return typedQuery; (5) } -
-
Behavior
-
| 1 | Constructs a JPA query for retrieving contract entities. |
| 2 | Applies filtering conditions based on the provided criteria. |
| 3 | Orders the results by timestamp in descending order. |
| 4 | Applies pagination settings if provided. |
| 5 | Returns the constructed typed query. |
6.4.4. Model classes
Description
The ContractsFilterDto represents a data transfer object (DTO) used for filtering contracts based on specific criteria.
-
contractUUID-
Description: Represents the unique identifier of a contract.
-
Usage: Used to filter contracts by a specific UUID.
-
Type: UUID
-
Example: ad3a03d5-d109-440a-8d70-619c780d471a
-
-
timestamp-
Type: LocalDateTime
-
Description: Represents the timestamp associated with contracts.
-
Usage: Used to filter contracts by a specific timestamp.
-
Example: 2024-02-19 16:02:51
-
-
productId-
Type: Long
-
Description: Represents the identifier of the product associated with contracts.
-
Usage: Used to filter contracts by a specific product ID.
-
Example: 1
-
ContractsFilterDto
@Setter
@Getter
@NoArgsConstructor
@ToString
public class ContractsFilterDto {
private UUID contractUUID;
private LocalDateTime timestamp;
private Long productID;
}
6.5. Update contracts
6.5.1. Sequential flow
Contract updation process
Validation process
-
The validation process ensures the accuracy and integrity of contract update requests.
-
Here, the Validator meticulously examines contract data for consistency and adherence to predefined rules.
-
If the contract UUID is valid, the updation process proceeds.
Updation process
-
The contract status and terms are verified against product specifications.
-
Error handling mechanisms swiftly address issues such as invalid UUIDs or contract term discrepancies, guaranteeing a robust validation process.
-
Subsequently, the business process meticulously executes contract updates, involving validation against product specifications and computation of contract terms.
-
This ensures accuracy and integrity throughout the operation.
6.5.2. Endpoint
Description
This endpoint allows users with the appropriate permissions to update contracts based on the provided data.
URL
/contracts
Method
PUT
Request body
The request body should contain a JSON array of objects, each representing data for updating a contract. The structure of each object should adhere to the UpdateContractDto format.
Example request body
[
{
"contractUUID": "28ee9eb5-e4b9-491c-98ce-a451abbedae9",
"productID": 4,
"terms": [
{
"initialExchangeDate": "2023-01-02T00:00:00",
"notionalPrincipal": "20000"
}
],
"selection": {
"remainingValue": 5000,
"tenure": "18M"
}
}
]
Responses
-
200 : Success. Returns a JSON response containing details of the updated contracts.
Example response body
{
"status": 200,
"message": "Contracts updated successfully",
"data": [
{
"contractUUID": "28ee9eb5-e4b9-491c-98ce-a451abbedae9",
"contractID": "9ec8997e-70b5-4fa1-82fe-56cbc0fc8149",
"errors": []
}
]
}
-
400 bad request: If the request body is not in the correct format or if there are validation errors.
-
401 unauthorized: If the user is not authenticated or lacks the necessary permissions to create contracts.
-
5xx server error: If there is a server-side error while processing the request.
Example
{
"status": 400,
"message": "Invalid ContractUUID 28ee9eb5-e4b9-491c-98ce-a451abbedae9",
"data": "28ee9eb5-e4b9-491c-98ce-a451abbedae9"
}
6.5.3. Methods
Description
The method updateContract updates contracts based on the provided contract data list.
Method signature
public List<ContractsResponseDto> updateContract(List<UpdateContractDto> contractDataList)
Parameters
-
contractDataList :List ofUpdateContractDtoobjects containing contract update information.
Returns
-
List<ContractsResponseDto> :List ofContractsResponseDtoobjects representing the response for each contract update.
Example usage
public List<ContractsResponseDto> updateContract(List<UpdateContractDto> contractDataList) {
List<ContractsResponseDto> contractResponseDtoList = new ArrayList<>();
ContractsResponseDto contractResponseDto;
for (UpdateContractDto updateContractData : contractDataList) { (1)
// Validate the contract data using the updateContractValidator.
contractResponseDto = updateContractValidator.validateContractData(updateContractData); (2)
// If there are no validation errors, proceed with the contract update.
if (contractResponseDto.getErrors().isEmpty()) {
contractResponseDto = contractsWorker.updateContract(updateContractData); (3)
}
contractResponseDtoList.add(contractResponseDto);
}
return contractResponseDtoList; (4)
}
| 1 | This method iterates through the provided list of contract data. |
| 2 | It validates each contract data using the updateContractValidator. |
| 3 | If there are no validation errors, it proceeds with the contract update using the contractsWorker. |
| 4 | The method returns a list of ContractsResponseDto objects containing the response for each contract update. |
Exceptions
-
None explicitly thrown by this method. However, exceptions may occur within the validator or worker methods, which are handled internally.
6.5.4. Model classes
Description
The UpdateContractDto class represents the data transfer object used for updating contract information. It encapsulates details such as the contract UUID, product ID, and terms to be updated.
-
contractUUID-
Type: UUID
-
Description: Represents the universally unique identifier (UUID) of the contract to be updated.
-
Example: 3539ebf7-e93f-4e38-90d5-8c4729ed493c
-
-
productID-
Type: Long
-
Description: Represents the identifier of the product associated with the contract.
-
Example: 1
-
-
terms-
Type: List<Map<String, Object>>
-
Description: Collection of contract terms represented as key-value pairs.
-
Example:
{ "terms": [ { "contractPerformance": "PreDeal", "businessDayConvention": "SCF", "contractType": "ANN", "statusDate": "2023-07-31T06:30:00", "contractRole": "RPA", "creatorID": "a43c22ed-27df-4324-a453-3e7707c9b82d", "counterpartyID": "e548956c-1f3b-493e-952e-00cdcca6b599", "contractID": "a6b799db-c448-4aad-9382-3ae47383f5b2", "cycleAnchorDateOfInterestPayment": "2023-09-01T06:30:00", "cycleOfInterestPayment": "P1ML1", "nominalInterestRate": 0.02, "dayCountConvention": "30E360", "currency": "CHF", "contractDealDate": "2023-07-31T06:30:00", "initialExchangeDate": "2023-08-01T06:30:00", "maturityDate": "2024-08-01T06:30:00", "notionalPrincipal": 50000, "cycleAnchorDateOfPrincipalRedemption": "2023-09-01T06:30:00", "cycleOfPrincipalRedemption": "P1ML1", "nextPrincipalRedemptionPayment": 2312.7827499791606 } ] } -
6.5.5. Validation
Description
The validateContractData method is responsible for validating the contract data before proceeding with the contract update process. It ensures that the contract UUID is valid and then delegates further validation to the validateContractTerms method.
-
Parameters
-
updateContractData :An instance of theUpdateContractDtoclass containing the contract data to be validated.
-
-
Returns
-
ContractsResponseDto :A data transfer object containing the result of the validation process. -
Example usage
public ContractsResponseDto validateContractData(UpdateContractDto updateContractData) {
String contractID = null;
HashMap<String, Object> contractErrors = new HashMap<>();
List<Map<String, Object>> errorList = new ArrayList<>();
try {
// Validate the contract UUID by calling the contractsValidator.
contractsValidator.validateContract(updateContractData.getContractUUID()); (1)
// If there are no errors related to the contract UUID, proceed with further
// validation.
return validateContractTerms(updateContractData); (2)
} catch (Exception e) { (3)
contractErrors.put("Contract data", e.getMessage());
errorList.add(contractErrors);
return new ContractsResponseDto(null, contractID, errorList);
}
}
| 1 | Contract UUID validation
|
| 2 | Contract terms validation
|
| 3 | Error handling
|
6.5.6. Testing
Description
This section comprises two test methods: updateContractBeforeTest and updateContractAfterTest. These methods validate the behavior of the contract update process before and after execution, respectively.
Example usage
@Test
void updateContractBeforeTest() { (1)
Terms masterTerms = contracts.getContractTerms().get(0);
PaymentDetails paymentDetails = contracts.getPaymentDetails();
System.err.println("paymentDetails"+paymentDetails);
BigDecimal NotionalPrincipal = new BigDecimal("50000.0");
BigDecimal NextPrincipalRedemptionPayment = new BigDecimal("2312.7827499791606");
Assertions.assertEquals(contracts.getProductID(), 1L);
Assertions.assertEquals(NotionalPrincipal, masterTerms.getNotionalPrincipal(), "0.0");
Assertions.assertEquals(NextPrincipalRedemptionPayment, masterTerms.getNextPrincipalRedemptionPayment(), "0.01");
Assertions.assertEquals(LocalDateTime.parse("2023-08-01T00:00:00"), masterTerms.getInitialExchangeDate());
Assertions.assertEquals(LocalDateTime.parse("2023-07-31T00:00:00"), masterTerms.getStatusDate());
Assertions.assertEquals(profile.getProfileID(), masterTerms.getCounterpartyID());
Assertions.assertEquals(paymentDetails.getCounterpartyPaymentChannelID(),
counterPartyPaymentChannel.getPaymentChannelID());
Assertions.assertEquals(paymentDetails.getRecordCreatorPaymentChannelID(),
recordCreatorPaymentChannel.getPaymentChannelID());
}
@Test
void updateContractAfterTest() { (2)
when(usersHelper.getUserID()).thenReturn(UUID.fromString("a43c22ed-27df-4324-a453-3e7707c9b82d"));
when(productRepo.findById(product.getProductID())).thenReturn(Optional.of(product));
BigDecimal NotionalPrincipal = new BigDecimal("47771.0");
BigDecimal NextPrincipalRedemptionPayment = new BigDecimal("2312.7827499791606");
Map<String, Object> termsMap = new HashMap<>();
List<Map<String, Object>> termsList = new ArrayList<>();
List<UpdateContractDto> updateContractDtoList = new ArrayList<>();
termsMap.put("initialExchangeDate", "2023-01-01T00:00:00");
termsMap.put("notionalPrincipal", "47771.0");
termsMap.put("remainingValue", "2000");
termsMap.put("remainingValue", "2000");
UpdateContractDto updateContractDto = new UpdateContractDto();
contracts.setContractUUID(contractUUID);
updateContractDto.setContractUUID(contracts.getContractUUID());
updateContractDto.setProductID(contracts.getProductID());
termsList.add(termsMap);
updateContractDto.setTerms(termsList);
updateContractDtoList.add(updateContractDto);
List<ContractsResponseDto> updateContractsResponse = contractServiceImpl.updateContract(updateContractDtoList);
Contracts contracts2 = contractsRepo.findById(UUID.fromString(updateContractsResponse.get(0).getContractUUID()))
.get();
Terms masterTerms = contracts2.getContractTerms().get(0);
PaymentDetails paymentDetails = contracts2.getPaymentDetails();
Assertions.assertEquals(contracts2.getProductID(), 1L);
Assertions.assertEquals(NotionalPrincipal, masterTerms.getNotionalPrincipal(), "0.0");
Assertions.assertEquals(NextPrincipalRedemptionPayment, masterTerms.getNextPrincipalRedemptionPayment(), "0.01");
Assertions.assertEquals(LocalDateTime.parse("2023-01-01T00:00"), masterTerms.getInitialExchangeDate());
Assertions.assertEquals(LocalDateTime.parse("2022-12-31T00:00"), masterTerms.getStatusDate());
Assertions.assertEquals(profile.getProfileID(), masterTerms.getCounterpartyID());
Assertions.assertEquals(paymentDetails.getCounterpartyPaymentChannelID(),
counterPartyPaymentChannel.getPaymentChannelID());
Assertions.assertEquals(paymentDetails.getRecordCreatorPaymentChannelID(),
recordCreatorPaymentChannel.getPaymentChannelID());
}
| 1 | updateContractBeforeTest
|
| 2 | updateContractAfterTest
|
6.6. Update executed contract
6.6.1. Sequential flow
Executed contract updation process
-
The User triggers the "updateExecutedContract" operation by providing updation data and the contract UUID.
-
The Controller receives the request and activates.
-
The Controller forwards the request to the ContractService.
-
The ContractService activates to process the update.
-
The ContractService delegates validation of the executed contract data to the UpdateContractValidator.
-
If the validation of executed contract data is successful
-
The UpdateContractValidator verifies the contract UUID using ContractsValidator.
-
ContractsValidator retrieves the contract from ContractsRepository by its UUID.
-
UpdateContractValidator checks if the contract update terms are valid against master contract terms using ContractService.
-
If the validation of contract update terms is successful:
-
ContractsWorker updates the executed contract.
-
Updated contract is saved in ContractsRepository.
-
The ContractService responds with a success message to the Controller.
-
The Controller sends a ResponseEntity<ResponseDto> containing the success message to the User.
-
-
If the validation of contract update terms fails:
-
The ContractService responds with an error message indicating invalid contract data to the Controller.
-
The Controller sends a ResponseEntity<ResponseDto> containing the error message to the User.
-
-
-
If the validation of executed contract data fails
-
The UpdateContractValidator responds with an error message indicating invalid contract UUID to the ContractService.
-
The ContractService responds with a ResponseEntity<ResponseDto> containing the error message to the Controller.
-
The Controller sends a ResponseEntity<ResponseDto> containing the error message to the User.
-
6.6.2. Endpoint
Description
This endpoint allows you to update an executed contract based on the provided contract data.
URL
/contracts/updateContract/{contractUUID}
Method
POST
Request parameters
Parameters |
Type |
Required |
Description |
contractUUID |
UUID |
Yes |
The UUID of the contract to be updated. |
Request body
The request body should contain a JSON array of objects, each representing data for updating a contract. The structure of each object should adhere to the TermsDto format.
Example request body
{
"notionalPrincipal": 60000
}
Response
-
200 : Success. Returns a JSON response containing details of the updated contracts.
Example response body
{
"status": 200,
"message": "Contract Rescheduled",
"data": "36c7d13e-55dc-4b89-a1b8-98f1f8716698"
}
-
400 bad request
Example
{
"status": 400,
"message": "Invalid contractUUID",
"data": "36c7d13e-55dc-4b89-a1b8-98f1f8716698"
}
-
400 bad request: If the request body is not in the correct format or if there are validation errors.
-
401 unauthorized: If the user is not authenticated or lacks the necessary permissions to create contracts.
-
5xx server error: If there is a server-side error while processing the request.
|
6.6.3. Methods
Description
The updateExecutedContract method updates an executed contract based on the provided contract UUID and data.
Method signature
public void updateExecutedContract(String contractUUID, TermsDto updationData)
throws ContractsException, IllegalAccessException, ParseException
Parameters
-
contractUUID (UUID):The UUID of the contract to be updated. -
updationData (TermsDto):The data used for updating the contract
Returns
-
contractUUID (UUID):The contractUUID of which the contract has been updated.
Exceptions
-
ContractsException :Thrown if there is an issue with the contract. -
IllegalAccessException :Thrown if there is illegal access during contract update. -
ParseException :Thrown if there is an error while parsing data.
Usage example
public void updateExecutedContract(UUID contractUUID, TermsDto updationData)
throws ContractsException, IllegalAccessException, ParseException {
// Validate the executed contract data before updating.
updateContractValidator.validateExecutedContractData(contractUUID, updationData); (1)
// Perform the actual contract update.
contractsWorker.updateExecutedContract(contractUUID, updationData); (2)
}
public void updateExecutedContract(UUID contractUUID, TermsDto updationData)
throws IllegalAccessException, ParseException {
log.info("Contract update started by UserId : {}, ContractUUID : {}, Request : {}", usersHelper.getUserID(),
contractUUID, updationData);
// Retrieve the executed contract by its UUID.
Contracts contract = contractsServiceRepo.findById(contractUUID)
.orElseThrow(() -> new IllegalArgumentException(CONTRACT_ERROR)); (3)
// Save a history snapshot of the contract before updating.
saveContractHistory(contract); (4)
// Update the contract data based on the provided data.
updateContractData(contract, updationData); (5)
// Reschedule events associated with the updated contract.
rescheduleEvents(contract); (6)
contractsServiceRepo.save(contract); (7)
log.info("Contract update finished by UserId : {}, ContractUUID : {}", usersHelper.getUserID(), contractUUID);
}
| 1 | Validates the executed contract data before updating. |
| 2 | Performs the actual contract update. |
| 3 | Retrieves the executed contract by its UUID. |
| 4 | Saves a history snapshot of the contract before updating. |
| 5 | Updates the contract data based on the provided data. |
| 6 | Reschedules events associated with the updated contract. |
| 7 | Saves the updated contract. |
6.6.4. Model classes
Description
The TermsDto class serves as a data transfer object (DTO) that encapsulates various terms and details associated with a contract. It is designed to facilitate the transfer of contract-related information between different components of the application.
-
contractPerformance
-
Type: String
-
Description: Indicates the performance status of the contract.
-
Example: "PreDeal"
-
-
calendar
-
Type: String
-
Description: Specifies the calendar system used for scheduling events related to the contract.
-
Example: "Monday to Friday"
-
-
businessDayConvention
-
Type: String
-
Description: Defines the method for adjusting dates that fall on non-business days.
-
Example: "SCF"
-
-
endOfMonthConvention
-
Type: String
-
Description: Specifies how end-of-month dates are handled in calculations.
-
Example: "EOM"
-
-
contractType
-
Type: String
-
Description: Identifies the type or category of the contract.
-
Example: "PAM"
-
-
statusDate
-
Type: LocalDateTime
-
Description: Represents the date at which the status of the contract was last updated.
-
Example: "2022-12-31 00:00:00"
-
-
contractRole
-
Type: String
-
Description: Specifies the role of the contract in a transaction or relationship.
-
Example: "RPA"
-
-
creatorID
-
Type: String
-
Description: Identifier of the user or system that created the contract.
-
Example: "902375cc-4f72-428f-8db0-95a7baa69b51"
-
-
counterpartyID
-
Type: String
-
Description: Identifier of the counterparty involved in the contract.
-
Example: "d2c87ded-489e-4510-8fe1-95f12c048a5d"
-
-
contractID
-
Type: String
-
Description: Unique identifier for the contract.
-
Example: "9ec8997e-70b5-4fa1-82fe-56cbc0fc8149"
-
click to see more….
-
marketObjectCodeOfDividends
-
Type: String
-
Description: Code or identifier for the market object related to dividends.
-
Example: "DIV"
-
-
cycleAnchorDateOfFee
-
Type: LocalDateTime
-
Description: Date used as a reference point for fee calculation cycles.
-
Example: "2023-01-01T00:00:00"
-
-
cycleOfFee
-
Type: String
-
Description: Specifies the frequency or pattern of fee payments.
-
Example: "1M"
-
-
feeBasis
-
Type: String
-
Description: Basis or method used for calculating fees.
-
Example: "A"
-
-
feeRate
-
Type: BigDecimal
-
Description: Rate at which fees are applied, usually expressed as a percentage.
-
Example: 2500.00
-
-
feeAccrued
-
Type: BigDecimal
-
Description: Total amount of fees accrued up to the present time.
-
Example: 1000.0
-
-
cycleAnchorDateOfInterestPayment
-
Type: LocalDateTime
-
Description: Date serving as a reference point for interest payment cycles.
-
Example: "2023-01-21T06:30:00"
-
-
arrayCycleAnchorDateOfInterestPayment
-
Type: String
-
Description: An array containing multiple cycle anchor dates of interest payments.
-
Example: ["2023-01-21T06:30:00", "2023-06-01T06:30:00", "2023-07-26T06:30:00"]
-
-
cycleOfInterestPayment
-
Type: String
-
Description: Frequency or pattern of interest payments.
-
Example: "P1ML1"
-
-
arrayCycleOfInterestPayment
-
Type: String
-
Description: An array containing multiple cycles of interest payments.
-
Example: ["1M", "6M"]
-
-
nominalInterestRate
-
Type: BigDecimal
-
Description: Nominal interest rate applied to the principal.
-
Example: 0.01
-
-
nominalInterestRate2
-
Type: BigDecimal
-
Description: Additional nominal interest rate, if applicable.
-
Example: 0.03
-
-
dayCountConvention
-
Type: String
-
Description: Method used for calculating the number of days between two dates.
-
Example: "30E360"
-
-
accruedInterest
-
Type: BigDecimal
-
Description: Total amount of interest accrued up to the present time.
-
Example: 500.0
-
-
capitalizationEndDate
-
Type: LocalDateTime
-
Description: Date when interest capitalization ends.
-
Example: "2024-12-31T23:59:59"
-
-
cycleAnchorDateOfInterestCalculationBase
-
Type: LocalDateTime
-
Description: Date used as a reference point for interest calculation.
-
Example: "2024-03-01T00:00:00"
-
-
cycleOfInterestCalculationBase
-
Type: String
-
Description: Frequency or pattern of interest calculation.
-
Example: "P1ML1"
-
-
interestCalculationBase
-
Type: String
-
Description: Specifies the base amount or balance used for interest calculation.
-
Example: "NT"
-
-
interestCalculationBaseAmount
-
Type: BigDecimal
-
Description: Amount used as the base for interest calculation.
-
Example: 10000.0
-
-
cyclePointOfInterestPayment
-
Type: String
-
Description: Specifies the point within each interest period when interest payments are made.
-
Example: "E"
-
-
currency
-
Type: String
-
Description: The currency in which monetary values are expressed.
-
Example: "USD"
-
-
currency2
-
Type: String
-
Description: Another currency, if applicable.
-
Example: "EUR"
-
-
amortizationDate
-
Type: LocalDateTime
-
Description: Date when the principal is scheduled to be repaid.
-
Example: "2024-12-31T23:59:59"
-
-
contractDealDate
-
Type: LocalDateTime
-
Description: Date when the contract was executed or agreed upon.
-
Example: "2024-03-01T00:00:00"
-
-
initialExchangeDate
-
Type: LocalDateTime
-
Description: Date of the initial exchange or transaction related to the contract.
-
Example: "2024-03-01T00:00:00"
-
-
maturityDate
-
Type: LocalDateTime
-
Description: Date when the contract reaches maturity or expires.
-
Example: "2024-12-31T23:59:59"
-
-
notionalPrincipal
-
Type: BigDecimal
-
Description: The principal amount on which interest is calculated.
-
Example: 100000.0
-
-
notionalPrincipal2
-
Type: BigDecimal
-
Description: Another principal amount, if applicable.
-
Example: 50000.0
-
-
quantity
-
Type: String
-
Description: Quantity or amount associated with the contract.
-
Example: "3"
-
-
cycleAnchorDateOfPrincipalRedemption
-
Type: LocalDateTime
-
Description: Date used as a reference point for principal redemption cycles.
-
Example: "2024-03-01T00:00:00"
-
-
arrayCycleAnchorDateOfPrincipalRedemption
-
Type: String
-
Description: An array containing multiple cycle anchor dates of principal redemption.
-
Example: ["2024-01-01", "2024-04-01", "2024-07-01"]
-
-
cycleOfPrincipalRedemption
-
Type: String
-
Description: Frequency or pattern of principal redemption.
-
Example: "P1ML1"
-
-
arrayCycleOfPrincipalRedemption
-
Type: String
-
Description: An array containing multiple cycles of principal redemption.
-
Example: ["1M", "6M"]
-
-
nextPrincipalRedemptionPayment
-
Type: BigDecimal
-
Description: Next scheduled payment for principal redemption.
-
Example: 1000.0
-
-
arrayNextPrincipalRedemptionPayment
-
Type: String
-
Description: An array containing multiple next principal redemption payments.
-
Example: ["1000.0", "500.50", "750.25"]
-
-
arrayIncreaseDecrease
-
Type: String
-
Description: An array containing information about increases or decreases in certain aspects of the contract.
-
Example: "INC"
-
-
purchaseDate
-
Type: LocalDateTime
-
Description: Date when the contract was purchased or acquired.
-
Example: "2024-03-01T00:00:00"
-
-
priceAtPurchaseDate
-
Type: BigDecimal
-
Description: Price of the contract at the time of purchase.
-
Example: 100.0
-
-
terminationDate
-
Type: LocalDateTime
-
Description: Date when the contract is terminated or ends.
-
Example: "2024-12-31T23:59:59"
-
-
priceAtTerminationDate
-
Type: BigDecimal
-
Description: Price of the contract at the time of termination.
-
Example: 90.0
-
-
marketObjectCodeOfScalingIndex
-
Type: String
-
Description: Code or identifier for the market object related to scaling index.
-
Example: "SCAL-001"
-
-
scalingIndexAtContractDealDate
-
Type: BigDecimal
-
Description: Scaling index value at the contract deal date.
-
Example: 120.0
-
-
cycleAnchorDateOfScalingIndex
-
Type: LocalDateTime
-
Description: Date used as a reference point for scaling index cycles.
-
Example: "2024-03-01T00:00:00"
-
-
cycleOfScalingIndex
-
Type: String
-
Description: Frequency or pattern of scaling index adjustments.
-
Example: "3M"
-
-
scalingEffect
-
Type: String
-
Description: Effect or impact of scaling on the contract.
-
Example: "0N0"
-
-
cycleAnchorDateOfRateReset
-
Type: LocalDateTime
-
Description: Date used as a reference point for rate reset cycles.
-
Example: "2024-03-01T00:00:00"
-
-
arrayCycleAnchorDateOfRateReset
-
Type: String
-
Description: An array containing multiple cycle anchor dates of rate reset.
-
Example: ["2024-01-01", "2024-04-01", "2024-07-01"]
-
-
cycleOfRateReset
-
Type: String
-
Description: Frequency or pattern of rate resets.
-
Example: "Monthly", "Quarterly", "Annually"
-
-
arrayCycleOfRateReset
-
Type: String
-
Description: An array containing multiple cycles of rate resets.
-
Example: ["1M","1Y"]
-
-
rateSpread
-
Type: BigDecimal
-
Description: Additional interest rate spread applied to a benchmark rate.
-
Example: 0.02
-
-
arrayRate
-
Type: String
-
Description: An array containing multiple interest rates.
-
Example: ["0.05", "0.06", "0.04"]
-
-
arrayFixedVariable
-
Type: String
-
Description: An array indicating whether interest rates are fixed or variable.
-
Example: "F"
-
-
marketObjectCodeOfRateReset
-
Type: String
-
Description: Code or identifier for the market object related to rate reset.
-
Example: "e4d7d42c-f11a-4ff3-886f-5bf36db3bac9"
-
-
cyclePointOfRateReset
-
Type: String
-
Description: Specifies the point within each interest period when rate resets occur.
-
Example: "B"
-
-
fixingPeriod
-
Type: String
-
Description: Period during which interest rates are fixed.
-
Example: "3M"
-
-
nextResetRate
-
Type: BigDecimal
-
Description: Next scheduled rate after a reset.
-
Example: 0.07
-
-
rateMultiplier
-
Type: BigDecimal
-
Description: Multiplier applied to a reference rate to determine the interest rate.
-
Example: 1.5
-
-
settlementPeriod
-
Type: LocalDateTime
-
Description: Period during which settlement occurs.
-
Example: "2024-03-01T00:00:00"
-
-
deliverySettlement
-
Type: String
-
Description: Method or process used for delivery settlement.
-
Example: "S"
-
-
marketValueObserved
-
Type: BigDecimal
-
Description: Observed market value of the contract.
-
Example: 10000.0
-
-
premiumDiscountAtIED
-
Type: BigDecimal
-
Description: Premium or discount applied at the initial exchange date (IED).
-
Example: 500.0
-
-
cycleAnchorDateOfOptionality
-
Type: LocalDateTime
-
Description: Date used as a reference point for optionality cycles.
-
Example: "2024-03-01T00:00:00"
-
-
cycleOfOptionality
-
Type: String
-
Description: Frequency or pattern of optionality.
-
Example: "P1ML1"
-
-
lifeCap
-
Type: BigDecimal
-
Description: Maximum cap on interest rates over the life of the contract.
-
Example: 0.08
-
-
lifeFloor
-
Type: BigDecimal
-
Description: Minimum floor on interest rates over the life of the contract.
-
Example: 0.03
-
-
penaltyType
-
Type: String
-
Description: Type or category of penalty associated with the contract.
-
Example: "N"
-
-
penaltyRate
-
Type: BigDecimal
-
Description: Rate at which penalties are applied, usually expressed as a percentage.
-
Example: 0.05
-
-
objectCodeOfPrepaymentModel
-
Type: String
-
Description: Code or identifier for the prepayment model object.
-
Example: "PREPAY-MODEL"
-
-
periodCap
-
Type: BigDecimal
-
Description: Maximum cap on interest rates for a specific period.
-
Example: 0.08
-
-
periodFloor
-
Type: BigDecimal
-
Description: Minimum floor on interest rates for a specific period.
-
Example: 0.03
-
-
marketObjectCode
-
Type: String
-
Description: Code or identifier for the market object associated with the contract.
-
Example: "YC.USA.TREASURY"
-
-
cycleAnchorDateOfDividendPayment
-
Type: LocalDateTime
-
Description: Date used as a reference point for dividend payment cycles.
-
Example: "2024-03-01T00:00:00"
-
-
cycleOfDividendPayment
-
Type: String
-
Description: Frequency or pattern of dividend payments.
-
Example: "1Q"
-
-
tenure
-
Type: String
-
Description: Duration or term of the contract.
-
Example: "5Y"
-
-
roundingConvention
-
Type: String
-
Description: Method used for rounding numerical values in calculations.
-
Example: "Half Up"
-
-
xDayNotice
-
Type: String
-
Description: Notice period required for certain actions or events.
-
Example: "30D"
-
-
maximumPenaltyFreeDisbursement
-
Type: String
-
Description: Maximum amount that can be disbursed without incurring penalties.
-
Example: "10000"
-
-
delinquencyPeriod
-
Type: String
-
Description: Period during which a payment is considered delinquent.
-
Example: "30D"
-
-
gracePeriod
-
Type: String
-
Description: Period of time after a payment is due before penalties are applied.
-
Example: "7D"
-
|
6.6.5. Validation
Description
The validateExecutedContractData method is responsible for validating the data associated with an executed contract. This ensures the integrity and accuracy of the contract information before any further processing is performed.
Parameters
-
Contract UUID (Type: UUID) :The UUID of the executed contract to be validated. -
updationContractTerms (Type: TermsDto) :Contains the updated contract terms to be validated.
Returns
-
Returns the master contract terms associated with the provided UUID.
Example usage
public void validateExecutedContractData(UUID contractUUID, TermsDto updationContractTerms)
throws ContractsException {
// Validate the contract UUID and retrieve the contract.
Contracts contract = contractsValidator.validateContractUUID(contractUUID); (1)
Terms masterContractTerms = contract.getContractTerms().get(0);
// Validate the updated contract terms against the master contract terms.
validateContractUpdateTerms(masterContractTerms, updationContractTerms); (2)
}
| 1 | Contract UUID validation
|
| 2 | Updated contract terms validation
|
Error handling
-
If the contract UUID is invalid or does not exist, a ContractsException is thrown with an appropriate error message.
-
If the updated contract terms do not align with the master contract terms, validation fails and a ContractsException is thrown.
6.6.6. Testing
Description
This section provides an overview of the testing strategy and objectives for the update executed contract method.
Example usage
@TestFactory
Stream<DynamicTest> updatePFContractBeforeTest() throws IOException { (1)
List<DynamicTest> dynamicTests = new ArrayList<>();
List<BusinessEventsDto> expectedEventsList = MappingUtils
.mapToEventsList("./src/test/resources/events/events-contract-ann.json");
List<BusinessEvents> computedEventsList = eventsRepo.findByContractUUID(contracts);
Assertions.assertEquals(expectedEventsList.size(), computedEventsList.size(), "Number of events should match.");
for (int i = 0; i < expectedEventsList.size(); i++) {
BusinessEventsDto expectedEvent = expectedEventsList.get(i);
BusinessEvents computedEvent = computedEventsList.get(i);
dynamicTests.add(contractUtils.createDynamicTest(expectedEvent, computedEvent));
}
return dynamicTests.stream();
}
@TestFactory
Stream<DynamicTest> updatePFContractAfterTest()
throws IOException, ParseException, IllegalAccessException, ContractsException, InterruptedException { (2)
List<DynamicTest> dynamicTests = new ArrayList<>();
List<BusinessEventsDto> expectedEventsList = MappingUtils
.mapToEventsList("./src/test/resources/events/updated-events-contract-ann.json");
updatePFContractTest();
List<BusinessEvents> computedEventsList = eventsRepo.findByContractUUID(contracts);
Assertions.assertEquals(expectedEventsList.size(), computedEventsList.size(), "Number of events should match.");
for (int i = 0; i < expectedEventsList.size(); i++) {
BusinessEventsDto expectedEvent = expectedEventsList.get(i);
BusinessEvents computedEvent = computedEventsList.get(i);
dynamicTests.add(contractUtils.createDynamicTest(expectedEvent, computedEvent));
}
return dynamicTests.stream();
}
| 1 | updatePFContractBeforeTest
|
| 2 | updatePFContractAfterTest
|
6.7. Create dynamic event
6.7.1. Sequential flow
Steps to create dynamic event
-
Receive request
-
The system receives a request from the user to create a dynamic event.
-
-
Validate data
-
The system validates the provided contract UUID and event date.
-
If the contract UUID is invalid or doesn’t exist, an error is returned.
-
If the event date is after the maturity date or future events are already processed, an error is returned.
-
-
-
Create dynamic event
-
If the data is valid, the system creates a dynamic event based on the provided data.
-
-
Save event
-
The system saves the created dynamic event.
-
-
Respond to user
-
A response containing information about the created dynamic event is sent back to the user.
-
6.7.2. Endpoint
Description
This endpoint is used to create a dynamic event associated with a contract.
URL
/contracts/newEvent/{contractUUID}
Method
POST
Request parameters
Parameters |
Type |
Required |
Description |
contractUUID |
UUID |
Yes |
The unique identifier of the contract. |
Request body
The request body should contain a JSON array of objects, each representing data for creating a dynamic event. The structure of each object should adhere to the DynamicEventDto format.
Example request body
{
"time": "2024-02-23T06:30",
"type": "TP",
"value": 5000
}
Response
-
200 : Success. Returns a JSON response containing UUID of the created dynamic event.
Example response body
{
"status": 200,
"message": "Event created successfully",
"data": "36c7d13e-55dc-4b89-a1b8-98f1f8716698"
}
-
400 bad request
Example
{
"status": 400,
"message": "Invalid contractUUID 36c7d13e-55dc-4b89-a1b8-98f1f8716698",
"data": null
}
-
400 bad request: If the request body is not in the correct format or if there are validation errors.
-
401 unauthorized: If the user is not authenticated or lacks the necessary permissions to create contracts.
-
5xx server error: If there is a server-side error while processing the request.
|
6.7.3. Methods
Description
This method is responsible for creating a dynamic event associated with a contract.
-
Method :
validateDynamicEventData-
Purpose
-
This method validates the dynamic event data and checks for any future events already processed.
-
-
Parameters
-
dynamicEventData (Type: DynamicEventDto) :JSON data representing the dynamic event. -
contractUUID (Type: String) :The unique identifier of the contract.
-
-
Return type
-
Contracts - The validated contract associated with the dynamic event.
public Contracts validateDynamicEventData(DynamicEventDto dynamicEventData, UUID contractUUID) { Contracts contract = validateContractUUID(contractUUID); (1) validateEventDateWithMaturityDate(dynamicEventData, contract); (2) final Integer futureProcessed = eventsRepo.countByContractUUIDAndStatusAndEventTimeGreaterThan(contract, "processed", dynamicEventData.getTime()); // Check if there are any future events already processed. If so, throw an // exception. Assert.isTrue(futureProcessed == 0, "Future events already processed"); (3) return contract; (4) }
-
-
Behavior
1 Calls validateContractUUIDmethod to validate the contract UUID.2 Validates the event date with the maturity date of the contract. 3 Checks if there are any future events already processed. 4 Returns the validated contract. -
-
Method :
createDynamicEvent-
Purpose
-
This method creates a dynamic event based on the provided data and contract.
-
-
Parameters
-
dynamicEventData (Type: DynamicEventDto) :JSON data representing the dynamic event. -
contract (Type: Contracts) :The contract associated with the dynamic event.
-
-
Return type
-
DynamicEventResponseDto : Response containing information about the created dynamic event.
public DynamicEventResponseDto createDynamicEvent(DynamicEventDto dynamicEventData, Contracts contract) { log.info("Dynamic event creation started by UserId : {}, ContractUUID : {}, Request : {} ", usersHelper.getUserID(), contract.getContractUUID(), dynamicEventData); // Create a dynamic event based on the provided data and contract. BusinessEvents dynamicEvent = eventsHelper.createDynamicEvent(dynamicEventData, contract); (1) // Update the status of the dynamic event. eventsHelper.updateEventStatus(dynamicEvent); (2) // Save the dynamic event . businessEventsService.save(dynamicEvent); (3) log.info("Dynamic event created by UserId : {}, ContractUUID : {}, EventId: {} ", usersHelper.getUserID(), contract.getContractUUID(), dynamicEvent.getEventID()); return new DynamicEventResponseDto("Event created", dynamicEvent.getEventID(), dynamicEvent.getEventBody()); (4) }
-
-
Behavior
1 Creates a dynamic event using the provided data and contract by calling createDynamicEventmethod from the EventsHelper component.2 Updates the status of the dynamic event using the EventsHelper component. 3 Saves the dynamic event using the BusinessEventsService component. 4 Returns a DynamicEventResponseDto containing information about the created dynamic event. -
6.7.4. Model classes
Description
The DynamicEventDto class represents the data transfer object (DTO) for a dynamic event.
It encapsulates the attributes necessary to create a dynamic event.
-
time
-
Type: LocalDateTime
-
Description: Represents the time of the dynamic event.
-
Constraints: Cannot be null.
-
Example: "2024-02-23T06:30"
-
-
type
-
Type: String
-
Description: Represents the type of the dynamic event.
-
Constraints: Cannot be null.
-
Example: "TP"
-
-
value
-
Type: BigDecimal
-
Description: Represents the value associated with the dynamic event.
-
Constraints: Cannot be null.
-
Example: 5000
-
-
contractID
-
Type: String
-
Description: Represents the unique identifier of the contract associated with the dynamic event.
-
Constraints: None specified.
-
Example: "1234567890"
-
Usage example
BusinessEvents businessEvents = new BusinessEvents();
businessEvents.setEventTime(UtilityHelper.toLocalDateTime(dynamicEventData.getTime()).toString());
businessEvents.setEventType(dynamicEventData.getType());
businessEvents.setEventBody(determineEventBodyForDynamicEvent(contract, term, dynamicEventData));
businessEvents.setStatus("scheduled");
businessEvents.setExecutionType(determineExecutionTypeForDynamicEvent(dynamicEventData.getType()));
businessEvents.setUserID(term.getCreatorID());
businessEvents.setCreatedBy(contract.getCreatedBy());
businessEvents.setContractUUID(contract);
businessEvents.setContractID(contractId);
-
The
DynamicEventDtoclass is used to create a new business events object which is used to create a dynamic event.
6.7.5. Validation
Description
The method validateContract(UUID contractUUID) validates dynamic event data against a given contract.
-
Parameters
-
dynamicEventData :A DTO representing dynamic event data. -
contractUUID :The UUID of the contract to be validated.
-
-
Returns
-
Returns the validated
Contractsobject representing the contract associated with the provided UUID.
-
-
Functionality
-
It ensures that the event date is valid with respect to the contract’s maturity date.
-
It ensures that no future events have already been processed.
-
-
Exceptions
-
If future events are found to be already processed, an IllegalStateException is thrown with the message "Future events already processed".
-
-
Example usage
public Contracts validateDynamicEventData(DynamicEventDto dynamicEventData, UUID contractUUID) {
Contracts contract = validateContractUUID(contractUUID); (1)
validateEventDateWithMaturityDate(dynamicEventData, contract); (2)
final Integer futureProcessed = eventsRepo.countByContractUUIDAndStatusAndEventTimeGreaterThan(contract,
"processed", dynamicEventData.getTime());
// Check if there are any future events already processed. If so, throw an
// exception.
Assert.isTrue(futureProcessed == 0, "Future events already processed"); (3)
return contract;
}
| 1 | Contract UUID validation
|
| 2 | Event date validation
|
| 3 | Future processed events check
|
6.7.6. Testing
Description
This section provides an overview of the testing strategy and objectives for the create dynamic event method.
Example usage
@Test
void createDynamicEventTest() throws ContractsException { (1)
Response<UUID> dynamicEventResponseDto = contractServiceImpl.createDynamicEvent(dynamicEventDto,
contractUUID);
BusinessEvents dynamicEvent = eventsHelper.createDynamicEvent(dynamicEventDto, contract);
BigDecimal eventValue = dynamicEvent.getValue() ;
UUID creditPaymentChannel = dynamicEvent.getCreditPaymentChannelID();
UUID debitPaymentChannel = dynamicEvent.getDebitPaymentChannelID();
PaymentDetails paymentDetails = contract.getPaymentDetails();
assertEquals("Event created successfully", dynamicEventResponseDto.getMessage());
assertEquals(value.doubleValue(), eventValue.doubleValue(), 0.0);
assertEquals(paymentDetails.getCounterpartyPaymentChannelID(), creditPaymentChannel);
assertEquals(paymentDetails.getRecordCreatorPaymentChannelID(), debitPaymentChannel);
}
| 1 | createDynamicEventTest()
|
Transactions
1. Introduction
The transactions service allows registering or processing events and updating the contract accordingly.
2. Tables and relations
Establishing relationships
-
In relational databases like PostgreSQL, relationships between tables are crucial for organizing and querying data effectively. These relationships are typically established using foreign key constraints, which define links between tables based on the values of specific columns. Common types of relationships include one-to-one, one-to-many, and many-to-many relationships, each serving different data modeling needs.
Tables
-
Schema
-
Table business_events
Index Name Data type * 🔑 ⬋
eventid
uuid
*
event_time
timestamp
* 🔎
event_type
varchar(10)
event_body
json
* 🔎
status
varchar(10)
* 🔎
execution_type
varchar(20)
contractid
varchar(255)
*
userid
uuid
* 🔎 ⬈
contractuuid
uuid
value
numeric
remaining_value
numeric
credit_payment_channel_id
uuid
debit_payment_channel_id
uuid
units
varchar(10)
-
Foreign keys
Type Name On fk_business_events_contracts_contractuuid
contractuuid
-
Constraints
Name Definition business_events_event_type_check
((event_type)::text ~* ’^(AD
business_events_status_check
((status)::text ~* ’^(scheduled
-
-
Table contracts
Index Name Data type * 🔑 ⬋
contractuuid
uuid
⬈
productid
bigint
*
createdby
uuid
executedby
uuid
*
system_time
timestamp
selection
json
-
Foreign keys
Type Name On contracts_product_fk
productid
-
-
Table contracts_history
Index Name Data type * 🔑 ⬋
contractuuid
uuid
* 🔑 ⬋
status_date
timestamp
productid
bigint
selection
json
*
system_time
timestamp
-
Table payment_channels
Index Name Data type * 🔑 ⬋
payment_channelid
uuid
contractid
uuid
details
json
*
identifier
varchar(100)
label
varchar(100)
*
type
varchar(50)
* 🔎
owner_type
varchar(10)
*
units
varchar(10)
*
system
varchar(50)
account_characteristic
varchar(50)
* 🔎
ownerid
uuid
* 🔎
userid
uuid
-
Constraints
Name Definition payment_channels_owner_type_check
((owner_type)::text ~* ’^(root
-
-
Table payment_details
Index Name Data type * 🔑
id
bigint GENERATED BY DEFAULT AS IDENTITY
⬈
contract_uuid
uuid
⬈
record_creator_paymentchannel_id
uuid
⬈
counterparty_paymentchannel_id
uuid
⬈
contract_paymentchannel_id
uuid
-
Foreign keys
Type Name On paymentdetails_contractuuid_fk
contract_uuid
paymentdetails_contract_payment_fk
contract_paymentchannel_id
paymentdetails_counterparty_fk
counterparty_paymentchannel_id
paymentdetails_record_creator_fk
record_creator_paymentchannel_id
-
-
Table products
Index Name Data type * 🔑 ⬋
productid
bigint GENERATED BY DEFAULT AS IDENTITY
*
status
varchar(10)
*
template
json
* 🔎
userid
uuid
-
Constraints
Name Definition products_status_check
((status)::text ~* ’^(active
-
-
Table profile_forms
Index Name Data type * 🔑 ⬋
profile_formid
bigint GENERATED BY DEFAULT AS IDENTITY
*
profile_form_details
json
*
userid
uuid
-
Table profiles
Index Name Data type * 🔑 ⬋
profileid
uuid
profile_details
json
*
status
varchar(10)
*
userid
uuid
* ⬈
profile_formid
bigint
-
Foreign keys
Type Name On fk_profiles_profile_forms_profile_formid
profile_formid
-
Constraints
Name Definition profiles_status_check
((status)::text ~* ’^(active
-
-
Table terms
Index Name Data type * 🔑
id
bigint GENERATED BY DEFAULT AS IDENTITY
accrued_interest
numeric
amortization_date
timestamp
array_cycle_anchor_date_of_interest_payment
varchar(255)
array_cycle_anchor_date_of_principal_redemption
varchar(255)
array_cycle_anchor_date_of_rate_reset
varchar(255)
array_cycle_of_interest_payment
varchar(255)
array_cycle_of_principal_redemption
varchar(255)
array_cycle_of_rate_reset
varchar(255)
array_fixed_variable
varchar(255)
array_increase_decrease
varchar(255)
array_next_principal_redemption_payment
varchar(255)
array_rate
varchar(255)
business_day_convention
varchar(5)
calendar
varchar(2)
capitalization_end_date
timestamp
contract_deal_date
timestamp
contractid
varchar(255)
*
contract_role
varchar(6)
contract_performance
varchar(10)
*
contract_type
varchar(15)
*
currency
varchar(10)
currency2
varchar(10)
cycle_anchor_date_of_dividend_payment
timestamp
cycle_anchor_date_of_fee
timestamp
cycle_anchor_date_of_interest_calculation_base
timestamp
cycle_anchor_date_of_interest_payment
timestamp
cycle_anchor_date_of_optionality
timestamp
cycle_anchor_date_of_principal_redemption
timestamp
cycle_anchor_date_of_rate_reset
timestamp
cycle_anchor_date_of_scaling_index
timestamp
cycle_of_dividend_payment
varchar(10)
cycle_of_fee
varchar(10)
cycle_of_interest_calculation_base
varchar(10)
cycle_of_interest_payment
varchar(10)
cycle_of_optionality
varchar(10)
cycle_of_principal_redemption
varchar(10)
cycle_of_rate_reset
varchar(10)
cycle_of_scaling_index
varchar(10)
cycle_point_of_interest_payment
varchar(1)
cycle_point_of_rate_reset
varchar(1)
*
day_count_convention
varchar(10)
delivery_settlement
varchar(1)
end_of_month_convention
varchar(5)
fee_accrued
numeric
fee_basis
varchar(1)
fee_rate
numeric
fixing_period
varchar(255)
initial_exchange_date
timestamp
interest_calculation_base
varchar(10)
interest_calculation_base_amount
numeric
life_cap
numeric
life_floor
numeric
market_object_code
varchar(255)
market_object_code_of_dividend_rate
varchar(255)
market_object_code_of_rate_reset
varchar(255)
market_object_code_of_scaling_index
varchar(255)
market_value_observed
numeric
maturity_date
timestamp
maximum_penalty_free_disbursement
varchar(255)
next_principal_redemption_payment
numeric
next_reset_rate
numeric
nominal_interest_rate
numeric
nominal_interest_rate2
numeric
notional_principal
numeric
notional_principal2
numeric
object_code_of_prepayment_model
varchar(255)
penalty_rate
numeric
penalty_type
varchar(1)
period_cap
numeric
period_floor
numeric
premium_discount_atied
numeric
price_at_purchase_date
numeric
price_at_termination_date
numeric
purchase_date
timestamp
quantity
numeric
rate_spread
numeric
rounding_convention
varchar(255)
scaling_effect
varchar(5)
scaling_index_at_contract_deal_date
numeric
settlement_period
varchar(255)
status_date
timestamp
x_day_notice
varchar(255)
termination_date
timestamp
delinquency_period
varchar(255)
grace_period
varchar(255)
market_object_code_of_dividends
varchar(255)
rate_multiplier
numeric
* ⬈
contract_uuid
uuid
⬈
counterparty_id
uuid
* 🔎
creator_id
uuid
-
Foreign keys
Type Name On terms_contractuuid_fk
contract_uuid
terms_counterparty_id_fk
counterparty_id
-
Constraints
Name Definition terms_business_day_convention_check
((business_day_convention)::text ~* ’^(NOS
terms_calendar_check
((calendar)::text ~* ’^(NC
terms_fee_basis_check
((fee_basis)::text ~* ’^(A
terms_delivery_settlement_check
((delivery_settlement)::text ~* ’^(D
terms_cycle_of_dividend_payment_check
cycle_of_dividend_payment)::text ~ `(([-]?)P(?:([-]?)Y)?(?:([-]?)M)?(?:([-]?)W)?(?:([-]?[0-9]+)D)?L(?:([0-1]?)'::text)
terms_cycle_of_interest_calculation_base_check
cycle_of_interest_calculation_base)::text ~ `(([-]?)P(?:([-]?)Y)?(?:([-]?)M)?(?:([-]?)W)?(?:([-]?[0-9]+)D)?L(?:([0-1]?)'::text)
terms_cycle_of_interest_payment_check
cycle_of_interest_payment)::text ~ `(([-]?)P(?:([-]?)Y)?(?:([-]?)M)?(?:([-]?)W)?(?:([-]?[0-9]+)D)?L(?:([0-1]?)'::text)
terms_cycle_of_principal_redemption_check
cycle_of_principal_redemption)::text ~ `(([-]?)P(?:([-]?)Y)?(?:([-]?)M)?(?:([-]?)W)?(?:([-]?[0-9]+)D)?L(?:([0-1]?)'::text)
terms_cycle_of_rate_reset_check
cycle_of_rate_reset)::text ~ `(([-]?)P(?:([-]?)Y)?(?:([-]?)M)?(?:([-]?)W)?(?:([-]?[0-9]+)D)?L(?:([0-1]?)'::text)
terms_cycle_of_scaling_index_check
cycle_of_scaling_index)::text ~ `(([-]?)P(?:([-]?)Y)?(?:([-]?)M)?(?:([-]?)W)?(?:([-]?[0-9]+)D)?L(?:([0-1]?)'::text)
terms_cycle_point_of_interest_payment_check
((cycle_point_of_interest_payment)::text ~* ’^(B
terms_contract_performance_check
((contract_performance)::text ~* ’^(PF
terms_penalty_type_check
((penalty_type)::text ~* ’^(N
-
-
Table terms_history
Index Name Data type * 🔑
id
bigint GENERATED BY DEFAULT AS IDENTITY
accrued_interest
numeric
amortization_date
timestamp
array_cycle_anchor_date_of_interest_payment
varchar(255)
array_cycle_anchor_date_of_principal_redemption
varchar(255)
array_cycle_anchor_date_of_rate_reset
varchar(255)
array_cycle_of_interest_payment
varchar(255)
array_cycle_of_principal_redemption
varchar(255)
array_cycle_of_rate_reset
varchar(255)
array_fixed_variable
varchar(255)
array_increase_decrease
varchar(255)
array_next_principal_redemption_payment
varchar(255)
array_rate
varchar(255)
business_day_convention
varchar(5)
calendar
varchar(2)
capitalization_end_date
timestamp
contract_deal_date
timestamp
contractid
varchar(255)
*
contract_role
varchar(6)
contract_performance
varchar(10)
*
contract_type
varchar(15)
*
currency
varchar(10)
currency2
varchar(10)
cycle_anchor_date_of_dividend_payment
timestamp
cycle_anchor_date_of_fee
timestamp
cycle_anchor_date_of_interest_calculation_base
timestamp
cycle_anchor_date_of_interest_payment
timestamp
cycle_anchor_date_of_optionality
timestamp
cycle_anchor_date_of_principal_redemption
timestamp
cycle_anchor_date_of_rate_reset
timestamp
cycle_anchor_date_of_scaling_index
timestamp
cycle_of_dividend_payment
varchar(10)
cycle_of_fee
varchar(10)
cycle_of_interest_calculation_base
varchar(10)
cycle_of_interest_payment
varchar(10)
cycle_of_optionality
varchar(10)
cycle_of_principal_redemption
varchar(10)
cycle_of_rate_reset
varchar(10)
cycle_of_scaling_index
varchar(10)
cycle_point_of_interest_payment
varchar(1)
cycle_point_of_rate_reset
varchar(1)
*
day_count_convention
varchar(10)
delivery_settlement
varchar(1)
end_of_month_convention
varchar(5)
fee_accrued
numeric
fee_basis
varchar(1)
fee_rate
numeric
fixing_period
varchar(255)
initial_exchange_date
timestamp
interest_calculation_base
varchar(10)
interest_calculation_base_amount
numeric
life_cap
numeric
life_floor
numeric
market_object_code
varchar(255)
market_object_code_of_dividend_rate
varchar(255)
market_object_code_of_rate_reset
varchar(255)
market_object_code_of_scaling_index
varchar(255)
market_value_observed
numeric
maturity_date
timestamp
maximum_penalty_free_disbursement
varchar(255)
next_principal_redemption_payment
numeric
next_reset_rate
numeric
nominal_interest_rate
numeric
nominal_interest_rate2
numeric
notional_principal
numeric
notional_principal2
numeric
object_code_of_prepayment_model
varchar(255)
penalty_rate
numeric
penalty_type
varchar(1)
period_cap
numeric
period_floor
numeric
premium_discount_atied
numeric
price_at_purchase_date
numeric
price_at_termination_date
numeric
purchase_date
timestamp
quantity
numeric
rate_spread
numeric
rounding_convention
varchar(255)
scaling_effect
varchar(5)
scaling_index_at_contract_deal_date
numeric
settlement_period
varchar(255)
x_day_notice
varchar(255)
termination_date
timestamp
delinquency_period
varchar(255)
grace_period
varchar(255)
market_object_code_of_dividends
varchar(255)
rate_multiplier
numeric
*
creator_id
uuid
⬈
contractuuid
uuid
⬈
status_date
timestamp
-
Foreign keys
Type Name On fk-contracts_history-terms_history
contractuuid, status_date
-
Constraints
Name Definition terms_history_business_day_convention_check
((business_day_convention)::text ~* ’^(NOS
terms_history_calendar_check
((calendar)::text ~* ’^(NC
terms_history_fee_basis_check
((fee_basis)::text ~* ’^(A
terms_history_delivery_settlement_check
((delivery_settlement)::text ~* ’^(D
terms_history_cycle_of_dividend_payment_check
cycle_of_dividend_payment)::text ~ `(([-]?)P(?:([-]?)Y)?(?:([-]?)M)?(?:([-]?)W)?(?:([-]?[0-9]+)D)?L(?:([0-1]?)'::text)
terms_history_cycle_of_interest_calculation_base_check
cycle_of_interest_calculation_base)::text ~ `(([-]?)P(?:([-]?)Y)?(?:([-]?)M)?(?:([-]?)W)?(?:([-]?[0-9]+)D)?L(?:([0-1]?)'::text)
terms_history_cycle_of_interest_payment_check
cycle_of_interest_payment)::text ~ `(([-]?)P(?:([-]?)Y)?(?:([-]?)M)?(?:([-]?)W)?(?:([-]?[0-9]+)D)?L(?:([0-1]?)'::text)
terms_history_cycle_of_principal_redemption_check
cycle_of_principal_redemption)::text ~ `(([-]?)P(?:([-]?)Y)?(?:([-]?)M)?(?:([-]?)W)?(?:([-]?[0-9]+)D)?L(?:([0-1]?)'::text)
terms_history_cycle_of_rate_reset_check
cycle_of_rate_reset)::text ~ `(([-]?)P(?:([-]?)Y)?(?:([-]?)M)?(?:([-]?)W)?(?:([-]?[0-9]+)D)?L(?:([0-1]?)'::text)
terms_history_cycle_of_scaling_index_check
cycle_of_scaling_index)::text ~ `(([-]?)P(?:([-]?)Y)?(?:([-]?)M)?(?:([-]?)W)?(?:([-]?[0-9]+)D)?L(?:([0-1]?)'::text)
terms_history_cycle_point_of_interest_payment_check
((cycle_point_of_interest_payment)::text ~* ’^(B
terms_history_contract_performance_check
((contract_performance)::text ~* ’^(PF
terms_history_penalty_type_check
((penalty_type)::text ~* ’^(N
-
-
Table transactions
Index Name Data type * 🔑
transactionid
uuid
additional_information
json
*
user_id
uuid
*
credit_payment_channel_id
uuid
*
debit_payment_channel_id
uuid
*
process_time
timestamp
*
value
numeric
*
system_time
timestamp
*
status
varchar(15)
*
units
varchar(10)
* 🔑 ⬈
eventid
uuid
-
Foreign keys
Type Name On fk_transactions_business_events_eventid
eventid
-
(🔑) - Primary key
(*) - Mandatory
(⬈) - Foreign key
(🔎) - Constraint
-
3. Dependencies and libraries
3.1. Dependencies
Description
The following dependencies are used in the project to provide various functionalities and features:
-
spring-kafka
-
Purpose: Spring for Apache Kafka for building Kafka-based messaging systems.
-
Usage: Producing and consuming messages from Kafka topics.
-
-
spring-cloud-starter-openfeign
-
Purpose: The spring-cloud-starter-openfeign dependency is used in Spring Boot applications to simplify the process of creating REST clients. It integrates the Feign client library into your application, providing a declarative way to define RESTful service clients.
-
Usage: Use spring-cloud-starter-openfeign to define interfaces for RESTful services and easily make HTTP requests to those services. Feign handles the creation of the HTTP request and mapping of the response to Java objects, reducing the boilerplate code typically required for REST client implementations.
-
-
spring-cloud-starter-loadbalancer
-
Purpose: The spring-cloud-starter-loadbalancer dependency is used in Spring Boot applications to provide client-side load balancing. It integrates with Spring Cloud’s load balancing features, allowing applications to distribute traffic across multiple instances of a service.
-
Usage: Use spring-cloud-starter-loadbalancer to enable client-side load balancing in your application. It provides a simple API for making requests to services registered with a service registry (e.g., Eureka), automatically handling the load balancing logic. This helps improve the availability and scalability of your application by distributing traffic evenly across service instances.
-
-
modelmapper (version 0.7.5)
-
Purpose: The
modelmapperdependency simplifies the process of mapping objects between different data models by automatically determining how properties should be mapped from one object to another. -
Usage: Use
modelmapperto streamline the mapping process between DTOs (Data Transfer Objects), entities, and other data models, reducing the need for manual mapping code and improving code maintainability.
-
-
BlockCypher (version 2.0)
-
Purpose: Provides access to BlockCypher APIs for blockchain integration.
-
Usage: Requires a Blockcypher API token. Use the library to make API calls for tasks like:
-
Accessing blockchain data (transactions, blocks)
-
Managing wallets and addresses (create, send/receive bitcoins)
-
-
-
iban4j (version 3.2.1)
-
Purpose: Provides utilities for working with International Bank Account Numbers (IBANs).
-
Usage: The iban4j library allows you to:
-
Validate IBANs: Verify if a string is a valid IBAN.
-
(Optional) Generate IBANs: Create a valid IBAN (less common).
-
Extract information from IBANs: Parse an IBAN to retrieve details like country code, bank code, and account number.
-
-
3.2. Libraries
Description
The following libraries are used in the project to provide various functionalities and features:
-
actus-core (version 1.0.1)
-
Purpose: The
actus-corelibrary provides core functionality and utilities for working with financial contracts and cash flow projections based on the ACTUS standard. -
Usage: Use to perform calculations, projections, and analysis of financial contracts and cash flows according to the ACTUS (Algorithmic Contract Types Unified Standards) standard.
-
4. Exception handling
Description
The RestExceptionHandler class is responsible for handling various exceptions that may occur during the execution of RESTful API endpoints. It provides centralized exception handling to ensure consistent error responses across the application.
Example usage
@ControllerAdvice
public class RestExceptionHandler {
@ExceptionHandler({ TransactionException.class, IllegalArgumentException.class, TransactionSystemException.class,
HttpMessageNotReadableException.class })
public ResponseEntity<Response<String>> exceptionToDoHandler(Exception ex) { (1)
final Response<String> error = new Response<>();
error.setStatus(HttpStatus.BAD_REQUEST.value());
error.setMessage(ex.getMessage());
return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Response<List<String>>> handleValidationException(MethodArgumentNotValidException ex) { (2)
BindingResult bindingResult = ex.getBindingResult();
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
List<String> errorMessages = fieldErrors.stream()
.map(fieldError -> String.format("%s: %s", fieldError.getField(), fieldError.getDefaultMessage()))
.toList();
Response<List<String>> error = new Response<>();
error.setStatus(HttpStatus.BAD_REQUEST.value());
error.setMessage("Validation failed due to provided invalid data");
error.setData(errorMessages);
return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(value = { AccessDeniedException.class })
public ResponseEntity<Response<String>> accessDeniedExceptionHandler(Exception ex) { (3)
final Response<String> error = new Response<>();
error.setStatus(HttpStatus.UNAUTHORIZED.value());
error.setMessage("Access Denied...");
return new ResponseEntity<>(error, HttpStatus.UNAUTHORIZED);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> exceptionHandler(Exception ex) { (4)
final ErrorResponse error = new ErrorResponse();
error.setErrorCode(HttpStatus.BAD_REQUEST.value());
error.setMessage("The request could not be understood by the server due to malformed syntax.");
return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity<Response<List<String>>> handleConstraintViolationException(
ConstraintViolationException exception) { (5)
List<String> errorMessages = new ArrayList<>();
for (ConstraintViolation<?> violation : exception.getConstraintViolations()) {
String propertyPath = extractPropertyPath(violation.getPropertyPath().toString());
errorMessages.add(String.format("[%s]: %s", propertyPath, violation.getMessage()));
}
Response<List<String>> error = new Response<>();
error.setStatus(HttpStatus.BAD_REQUEST.value());
error.setMessage("Validation failed due to provided invalid data");
error.setData(errorMessages);
return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
}
}
| 1 | ExceptionToDo handler
|
| 2 | handleValidationException handler
|
| 3 | AccessDeniedException handler
|
| 4 | Generic exception handler
|
| 5 | handleConstraintViolationException handler
|
Customization
-
Additional exception handlers can be added to address specific use cases or domain-specific exceptions.
-
Error messages and status codes can be customized based on application requirements and error scenarios.
6. TransactionServiceController
6.1. Transfer
6.1.1. Sequential flow
Transfer process
This process includes transfer of funds from one account to another based on the provided TransferDto. Here below are process steps -
Data validation
-
The system checks if the transfer data is valid.
-
It ensures that the transfer amount is greater than zero.
-
It verifies the existence of sender and receiver contracts and payment channels.
Transfer process
-
If data is valid, the system proceeds with the transfer process.
-
It saves transaction details, initializes business events, and updates contract balances.
-
Finally, it logs the transfer completion.
If the transfer data is invalid or any step fails, appropriate error messages are returned.
6.1.2. Endpoint
Description
This endpoint allows users with the appropriate permissions to transfer funds based on the provided data.
URL
/transfer
Method
POST
Request body
The request body should contain a JSON object. The structure of each object should adhere to the TransferDto format.
Example request body
{
"value" : 1000,
"contractUUID" : "a1933b07-a12c-4666-9669-8a1bda511086",
"receiver" : "2ae5b30b-3fba-4f4b-a45f-c1d0c03b4144"
}
Responses
-
200 OK: Transaction success. Returns a JSON response containing details of the transaction.
Example response body
{
"status": 200,
"message": "Transaction success",
"data": "e9f0e281-ed53-43e4-a8a2-bc191d5e5aa5"
}
-
400 bad request: If the request body is not in the correct format or if there are validation errors.
-
401 unauthorized: If the user is not authenticated or lacks the necessary permissions to transfer.
-
5xx server error: If there is a server-side error while processing the request.
Example
{
"status": 400,
"message": "Invalid sender contactUUID",
"data": null
}
6.1.3. Methods
Description
This method is responsible for validating a transfer request, updating the notional principal of credit and debit contracts, and saving the transaction details in the system.
Signature
public Response<UUID> transfer(TransferDto transferDto) throws URISyntaxException
Parameters
-
TransferDto(Type: TransferDto): The transfer request data containing information about the contract UUID, receiver, and transfer amount.
Returns
-
Response<UUID>: A response object indicating the success of the transfer operation. It contains the HTTP status code, a message indicating the success of the transaction, and the unique identifier of the transfer event.
Example usage
public Response<UUID> transfer(TransferDto transferDto) throws URISyntaxException {
log.info("userID : {}, request : {}", usersHelper.getUserID(), transferDto);
// Transfer data validation
TransactionDetailsDto transfer = validator.validateEvent(transferDto); (1)
// Initializing event to process transfer
BusinessEvents event = transferHelper.initializeEvent(transfer); (2)
// Updating creditPaymentChannel
contractUpdateWorker.updateNotionalPrincipal(transfer.getCreditContract(), transfer.getValue(),
event.getEventTime()); (3)
// Updating debitPaymentChannel
BigDecimal debitValue = transfer.getValue().multiply(BigDecimal.valueOf(-1.0));
contractUpdateWorker.updateNotionalPrincipal(transfer.getDebitContract(), debitValue, event.getEventTime()); (4)
// Saving transaction
BusinessEvents transferEvent = transactionWorker.saveTransaction(event, transfer); (5)
return new Response<>(HttpStatus.OK.value(), Messages.TRANSACTION_SUCCESS, transferEvent.getEventID()); (6)
}
| 1 | Validates the transfer request data using the validator.validateEvent() method. |
| 2 | The method initializes an event to process the transfer using the transferHelper.initializeEvent() method. |
| 3 | It updates the notional principal of the credit payment channel by calling contractUpdateWorker.updateNotionalPrincipal() with the credit contract details, transfer value, and event time. |
| 4 | It updates the notional principal of the debit payment channel by calling contractUpdateWorker.updateNotionalPrincipal() with the debit contract details, negative transfer value, and event time. |
| 5 | The method saves the transaction details using the transactionWorker.saveTransaction() method. |
| 6 | Finally, it returns a response object with HTTP status code 200 (OK), a success message, and the unique identifier of the transfer event. |
Exceptions
-
URISyntaxException is thrown by this method when parsing a malformed Uniform Resource Identifier (URI) string. However, exceptions may occur within the validator or worker methods, which are handled internally.
6.1.4. Model classes
Description
The TransferDto class represents a data transfer object used for transferring funds between contracts.
-
value-
Type: BigDecimal
-
Description: Represents the amount of funds to be transferred.
-
Constraints: Not null.
-
Example: 1000
-
-
contractUUID-
Type: UUID
-
Description: Represents the UUID of the contract initiating the transfer.
-
Constraints: Not null.
-
Example: a1933b07-a12c-4666-9669-8a1bda511086
-
-
receiver-
Type: UUID
-
Description: Represents the UUID of the receiving contract.
-
Constraints: Not null.
-
Example: 2ae5b30b-3fba-4f4b-a45f-c1d0c03b4144
-
Example usage
TransferDto transfer = new TransferDto();
transfer.setValue(new BigDecimal("100.00"));
transfer.setContractUUID(UUID.randomUUID());
transfer.setReceiver(UUID.randomUUID());
6.1.5. Validation
Description
The validateEvent method is responsible for validating transfer input data, including currency, balance, and contract details. It ensures that the provided transfer information is valid and meets the necessary criteria for processing the transaction.
Parameters
-
transferDto: Contains contractUUID, transaction value, and other relevant information necessary for performing the transfer.
Returns
-
TransactionDetailsDto: Contains transaction details required for processing the transfer.
Example usage
public TransactionDetailsDto validateEvent(TransferDto transferDto) {
TransactionDetailsDto transfer = new TransactionDetailsDto();
// Transfer amount validation
Assert.isTrue(transferDto.getValue().doubleValue() > 0, Messages.INVALID_AMOUNT);
transfer.setValue(transferDto.getValue()); (1)
// Sender details validation
this.validateSender(transferDto, transfer); (2)
// Receiver details validation
this.validateReceiver(transferDto, transfer); (3)
// Sender and receiver accounts currency validation
Assert.isTrue(validateCurrency(transfer.getDebitPaymentChannel(), transfer.getCreditPaymentChannel()),
Messages.INVALID_CURRENCY); (4)
transfer.setUnits(String.valueOf(transfer.getDebitPaymentChannel().getDetails().get(Constants.UNITS)));
// Sender account balance validation
Assert.isTrue(validateBalance(transfer.getDebitContract(), transfer.getValue()), Messages.INSUFFICIENT_BALANCE); (5)
return transfer;
}
| 1 | Transfer amount validation
|
| 2 | Sender details validation
|
| 3 | Receiver details validation
|
| 4 | Currency validation
|
| 5 | Sender account balance validation
|
6.1.6. Testing
Description
This section provides an overview of the testing strategy and objectives for the transfer method.
Example usage
@Test
void transferTest() throws URISyntaxException { (1)
TransferDto transferDto = new TransferDto();
BigDecimal value = new BigDecimal("100");
transferDto.setContractUUID(debitContract.getContractUUID());
transferDto.setReceiver(creditPaymentChannel.getPaymentChannelID());
transferDto.setValue(value);
Response transferResponse = transferServiceImpl.transfer(transferDto);
assertEquals(Messages.TRANSACTION_SUCCESS, transferResponse.getMessage());
Contracts creditContracts1 = contractRepo.findById(creditContract.getContractUUID()).get();
BigDecimal creditNotionalPrincipal = creditContracts1.getContractTerms().get(0).getNotionalPrincipal();
Contracts debitContract1 = contractRepo.findById(debitContract.getContractUUID()).get();
BigDecimal debitNotionalPrincipal = debitContract1.getContractTerms().get(0).getNotionalPrincipal();
assertEquals(new BigDecimal("600.0"), creditNotionalPrincipal);
assertEquals(new BigDecimal("400.0"), debitNotionalPrincipal);
}
| 1 | transferTest()
|
6.2. Transaction
6.2.1. Sequential flow
Transaction process
This process includes transactions of different event types based on the provided TransactionDto. Here below are process steps -
Data validation
-
Incoming requests are handled at "/transaction" endpoint.
-
Transaction data is validated using the @Valid annotation.
-
Event IDs are retrieved from the transaction data.
-
Each transaction is individually validated for correctness.
Transaction process
-
Valid transactions proceed to the processing phase.
-
Processing involves updating contract information and performing associated event processes.
-
Transaction details are saved alongside the associated business event.
-
Responses are generated based on transaction success or failure.
-
Logs track transaction progress and error handling ensures proper response generation.
6.2.2. Endpoint
Description
This endpoint allows the processing of transactions for various event types across all contract types except UMP. Transactions include events such as IP, PR, FP, IED, and more.
URL
/transaction
Method
POST
Request body
The request body should contain a JSON array. The structure of each object should adhere to the TransactionDto format.
Example request body
[
{
"eventID": "4e3723af-ece4-4934-963b-bfbabb510212",
"value": 3320.8481981622112,
"processTime": "2023-01-01T00:00"
}
]
Responses
-
200 OK: Transaction success. Returns a response containing a list of transaction process responses.
Example response body
{
"status": 200,
"message": "Transactions processed successfully",
"data": [
{
"eventID": "4e3723af-ece4-4934-963b-bfbabb510212",
"valid": "TRUE",
"details": "Transaction success"
}
]
}
-
400 bad request: If the request body is not in the correct format or if there are validation errors.
-
401 unauthorized: If the user is not authenticated or lacks the necessary permissions for the transaction.
-
5xx server error: If there is a server-side error while processing the request.
Example
{
"status": 400,
"message": "Invalid eventID",
"data": null
}
|
Ensure that the request body is a JSON object containing a list of valid TransactionDto objects. The response body includes a list of TransactionResponseDto objects, providing details about the processed transactions and their validation status. |
6.2.3. Methods
-
Method: transaction
Description
This method processes transactions for all contract types except UMP. It receives a list of transaction data objects, executes the transactions, validates them, and returns a list of response objects indicating the status of each transaction.
Signature
public ResponseEntity<Response<List<TransactionResponseDto>>> transaction( @Valid @RequestBody List<TransactionDto> transactionDtoList)Parameters
-
transactionDtoList (List of TransactionDto): A list containing information about the events to be processed.Returns
-
Responses with HTTP status codes indicating the success or failure of the transaction processing.
Example usage
public ResponseEntity<Response<List<TransactionResponseDto>>> transaction( @Valid @RequestBody List<TransactionDto> transactionDtoList) { // Execute the transactions List<TransactionResponseDto> transactionResponseList = transactionsService .executeTransaction(transactionDtoList); (1) // Check if all transactions were valid boolean allTransactionsValid = transactionResponseList.stream() .allMatch(responseDto -> responseDto.getValid().equals(Constants.TRUE)); (2) if (allTransactionsValid) { // Return the responses with HTTP status OK return new ResponseEntity<>(new Response<>(HttpStatus.OK.value(), "Transactions processed successfully", transactionResponseList), HttpStatus.OK); } else { // Return the responses with HTTP status BAD_REQUEST return new ResponseEntity<>(new Response<>(HttpStatus.BAD_REQUEST.value(), "Validation failed due to provided invalid data", transactionResponseList), HttpStatus.BAD_REQUEST); (3) } }Internal workflow1 Executes transactions based on the provided transaction data. 2 Checks if all transactions are valid. 3 Returns responses with HTTP status codes indicating the success or failure of the transaction processing.
-
-
Method: executeTransaction
Description
This method is responsible for executing transactions. It validates the input transaction data, processes valid transactions, and returns a list of response objects indicating the status of each transaction.
Signature
public List<TransactionResponseDto> executeTransaction(List<TransactionDto> transactionDtoList)Parameters
-
transactionDtoList (List of TransactionDto): The list of transaction data to be processed.Returns
-
List of
TransactionResponseDto: A list of response objects indicating the status of each transaction.Example usage
public List<TransactionResponseDto> executeTransaction(List<TransactionDto> transactionDtoList) { // Retrieve eventIDs from input List<UUID> eventIDList = transactionDtoList.stream().map(TransactionDto::getEventID).toList(); (1) // Validate all transactions and accumulate responses List<TransactionResponseDto> transactionResponseDtoList = transactionDtoList.stream() .map(transactionData -> validator.validateTransactionData(transactionData, eventIDList)).toList(); (2) // Process transactions only if all are valid if (transactionResponseDtoList.stream() .allMatch(responseDto -> responseDto.getValid().equals(Constants.TRUE))) { (3) transactionResponseDtoList = transactionDtoList.stream().map(this::processTransaction).toList(); } return transactionResponseDtoList; (4) }
Internal workflow1 Extracts event IDs from the input transaction data. 2 Validates each transaction data object and accumulates the validation responses. 3 Processes transactions only if all are valid. 4 Returns a list of response objects indicating the status of each transaction. -
6.2.4. Model classes
-
TransactionDto
Description
The
TransactionDtoclass represents a data transfer object (DTO) for a transaction. It encapsulates information about a transaction including its event ID, value, and process time.Attributes-
eventID-
Type: UUID
-
Description: Represents the unique identifier of the event associated with the transaction.
-
Constraints: Not null.
-
Example: 4e3723af-ece4-4934-963b-bfbabb510212
-
-
value-
Type: BigDecimal
-
Description: Represents the value of the transaction.
-
Constraints: Not null.
-
Example: 3320.8481981622112
-
-
processTime-
Type: LocalDateTime
-
Description: Represents the timestamp when the transaction was processed.
-
Constraints: Not null.
-
Example: 2023-01-01T00:00
Example usage
TransactionDto transaction = new TransactionDto(); transaction.setEventID(UUID.randomUUID()); transaction.setValue(new BigDecimal("100.00")); transaction.setProcessTime(LocalDateTime.now()); -
-
-
TransactionResponseDto
Description
The
TransactionResponseDtoclass represents a data transfer object (DTO) for a transaction response. It encapsulates information about the status of a transaction along with any additional details.Attributes-
eventID-
Type: UUID
-
Description: Represents the unique identifier of the event associated with the transaction.
-
Constraints: Not null.
-
Example: 4e3723af-ece4-4934-963b-bfbabb510212
-
-
valid-
Type: String
-
Description: Indicates whether the transaction is valid or not.
-
Constraints: Can take values "TRUE" or "FALSE".
-
Example: TRUE
-
-
details-
Type: String
-
Description: Provides additional details about the transaction, such as error messages or processing notes.
-
Example: Transaction success
-
-
|
This class is typically used to communicate the outcome of a transaction processing operation, such as whether it was successful or encountered an error. |
6.2.5. Validation
Description
The validateTransactionData method is responsible for validating transaction input data, including event ID, event status, and other related parameters. It performs a series of validation checks to ensure that the transaction can be processed successfully.
Parameters
-
transactionDto(TransactionDto): Contains information about the transaction, including event ID, transaction value, etc. -
eventIDList(List<UUID>): A list of provided event IDs to perform the transaction.
Returns
-
TransactionResponseDto: Represents the result of the transaction validation process, including the validity status and any associated details.
Example usage
public TransactionResponseDto validateTransactionData(TransactionDto transactionDto, List<UUID> eventIDList) {
BusinessEvents businessEvent = null;
TransactionResponseDto eventData = new TransactionResponseDto();
try {
// EventID validation
businessEvent = this.validateEventID(transactionDto.getEventID()); (1)
// Event status validation
businessEvent = this.validateEventStatus(businessEvent); (2)
if (!businessEvent.getEventType().equalsIgnoreCase(Constants.OPS)) {
// Non OPS events validation
this.validateNonOPSEvents(businessEvent, transactionDto, eventIDList); (3)
}
eventData.setEventID(transactionDto.getEventID());
eventData.setValid(Constants.TRUE);
eventData.setDetails(Constants.VALID_EVENT); (4)
} catch (Exception e) {
e.printStackTrace();
eventData.setEventID(transactionDto.getEventID());
eventData.setValid(Constants.FALSE);
eventData.setDetails(e.getMessage());
}
return eventData;
}
| 1 | EventID validation
|
| 2 | Event status validation
|
| 3 | Non-OPS events validation
|
| 4 | Setting response data
|
|
Validate the structure and content of the TransactionDto object before passing it to this method to avoid unexpected behavior. |
6.2.6. Testing
Description
This section provides an overview of the testing strategy and objectives for the transaction method.
Example usage
@Test
void testExecuteTransaction6() { (1)
when(eventsRepo.findById(event.getEventID())).thenReturn(Optional.of(event));
when(paymentRepo.findById(ArgumentMatchers.<UUID>any())).thenReturn(Optional.of(debitPaymentChannel));
when(contractRepo.findById(ArgumentMatchers.<UUID>any())).thenReturn(Optional.of(debitContract));
TransactionResponseDto trasactionResponse = new TransactionResponseDto();
trasactionResponse.setDetails(Messages.TRANSACTION_SUCCESS);
trasactionResponse.setValid("TRUE");
terms.setInitialExchangeDate(LocalDateTime.parse("2023-06-21T23:59:59"));
BigDecimal NotionalPrincipal = new BigDecimal("20000.0");
BigDecimal RemainingValue = new BigDecimal("18000.0");
terms.setNotionalPrincipal(NotionalPrincipal);
event.setStatus("Pending");
event.setEventType("IED");
event.setRemainingValue(RemainingValue);
TransactionDto transactionDto = new TransactionDto();
BigDecimal Value = new BigDecimal("-2000");
transactionDto.setEventID(event.getEventID());
transactionDto.setProcessTime(LocalDateTime.parse("2023-06-22T23:59:59"));
transactionDto.setValue(Value);
ArrayList<TransactionDto> transactionDtoList = new ArrayList<>();
transactionDtoList.add(transactionDto);
List<TransactionResponseDto> executeTransaction = transferServiceImpl.executeTransaction(transactionDtoList);
TransactionResponseDto response = executeTransaction.get(0);
assertEquals("TRUE", response.getValid());
assertEquals(Messages.TRANSACTION_SUCCESS, response.getDetails());
}
| 1 | testExecuteTransaction6()
|
6.3. Get transactions
6.3.1. Sequential flow
Get transactions process
This process includes retrieval of a list of transactions based on specified filters and pagination parameters. Here below are process steps -
Data validation
-
Upon receiving a GET request to the
/txsendpoint, the server validates the query parameters includingfilterDto,page, andsize.
Get transactions process
-
The server parses the query parameters and sets up pagination based on the provided
pageandsize. -
It generates a JPA specification from the
TransactionFilterDtoto filter transactions. -
The server executes a database query using the generated specification and pagination settings.
-
Retrieved transactions are sent back to the client as a response.
6.3.2. Endpoint
Description
This endpoint allows developers to fetch transactions based on specified filters and pagination parameters.
URL
/txs
Method
GET
Request filter parameters
Parameters |
Type |
Required |
Description |
JSON object |
Yes |
Filter parameters for fetching transactions. |
|
page |
Integer |
No |
Page number for pagination. Default value is 0. |
size |
Integer |
No |
Number of transactions per page. Default value is 10. |
Responses
-
200 OK: Success. Returns a list of transactions matching the specified filters.
Example response body
{
"status": 200,
"message": "Success",
"data": [
{
"transactionID": "78fe0787-7dd2-44b3-bc13-d67254218848",
"eventID": "2858d468-d51c-482d-bc0a-a291438045d4",
"processTime": "2023-01-01T00:00:00",
"systemTime": "2024-02-19T16:57:39",
"debitPaymentChannelID": "13c3861e-bcc6-48ed-9db1-91cb6825328a",
"creditPaymentChannelID": "fb0fdb85-87ee-4af2-b39a-f3a23227203c",
"value": 50000,
"units": "INR",
"status": "processed",
"additionalInformation": null,
"userID": "902375cc-4f72-428f-8db0-95a7baa69b51"
},
{
"transactionID": "18d57dd4-5898-40af-aa06-52eb7cd28ebb",
"eventID": "f771b128-c948-4dea-8359-6a43e1f4ef3f",
"processTime": "2023-01-01T00:00:00",
"systemTime": "2024-02-20T12:01:03",
"debitPaymentChannelID": "13c3861e-bcc6-48ed-9db1-91cb6825328a",
"creditPaymentChannelID": "fb0fdb85-87ee-4af2-b39a-f3a23227203c",
"value": 50000,
"units": "INR",
"status": "processed",
"additionalInformation": null,
"userID": "902375cc-4f72-428f-8db0-95a7baa69b51"
},
{
"transactionID": "b0936731-9b0f-4236-8c52-465490d1f6fa",
"eventID": "61f04124-6a7c-4471-9ea5-70b82dafe225",
"processTime": "2023-01-01T00:00:00",
"systemTime": "2024-02-20T12:13:51",
"debitPaymentChannelID": "13c3861e-bcc6-48ed-9db1-91cb6825328a",
"creditPaymentChannelID": "fb0fdb85-87ee-4af2-b39a-f3a23227203c",
"value": 50000,
"units": "INR",
"status": "processed",
"additionalInformation": null,
"userID": "902375cc-4f72-428f-8db0-95a7baa69b51"
},
{
"transactionID": "df5bfea5-2e79-475d-96f3-1f98c05286d2",
"eventID": "bc17d4d1-18f1-464c-8e2a-af9bfa4752be",
"processTime": "2023-01-01T00:00:00",
"systemTime": "2024-02-20T13:11:28",
"debitPaymentChannelID": "13c3861e-bcc6-48ed-9db1-91cb6825328a",
"creditPaymentChannelID": "fb0fdb85-87ee-4af2-b39a-f3a23227203c",
"value": 50000,
"units": "INR",
"status": "processed",
"additionalInformation": null,
"userID": "902375cc-4f72-428f-8db0-95a7baa69b51"
},
{
"transactionID": "c7d78a3d-9a4a-49d8-919e-459db44f5686",
"eventID": "d20d11ba-eaeb-4e4c-a89f-8a16ab48f019",
"processTime": "2023-01-01T00:00:00",
"systemTime": "2024-02-20T14:58:51",
"debitPaymentChannelID": "2ae5b30b-3fba-4f4b-a45f-c1d0c03b4144",
"creditPaymentChannelID": "fb0fdb85-87ee-4af2-b39a-f3a23227203c",
"value": 50000,
"units": "INR",
"status": "processed",
"additionalInformation": null,
"userID": "902375cc-4f72-428f-8db0-95a7baa69b51"
},
{
"transactionID": "c7c7e576-68a1-46c9-b8d0-55af6e02016e",
"eventID": "b06f7336-6a2c-42f5-a64e-5358085a7688",
"processTime": "2023-01-01T00:00:00",
"systemTime": "2024-02-20T15:00:42",
"debitPaymentChannelID": "fb0fdb85-87ee-4af2-b39a-f3a23227203c",
"creditPaymentChannelID": "2ae5b30b-3fba-4f4b-a45f-c1d0c03b4144",
"value": 2500,
"units": "INR",
"status": "processed",
"additionalInformation": null,
"userID": "902375cc-4f72-428f-8db0-95a7baa69b51"
},
{
"transactionID": "3c00ed45-3131-4f2e-9351-3a8f0d3508dd",
"eventID": "b508767f-055c-46f6-a0c4-5ead61aed2b1",
"processTime": "2023-01-01T00:00:00",
"systemTime": "2024-02-20T15:01:54",
"debitPaymentChannelID": "fb0fdb85-87ee-4af2-b39a-f3a23227203c",
"creditPaymentChannelID": "2ae5b30b-3fba-4f4b-a45f-c1d0c03b4144",
"value": 3000,
"units": "INR",
"status": "processed",
"additionalInformation": null,
"userID": "902375cc-4f72-428f-8db0-95a7baa69b51"
},
{
"transactionID": "43eb5e8d-6d66-44e6-be25-c089ed9ed8bb",
"eventID": "b508767f-055c-46f6-a0c4-5ead61aed2b1",
"processTime": "2023-01-01T00:00:00",
"systemTime": "2024-02-20T15:02:35",
"debitPaymentChannelID": "fb0fdb85-87ee-4af2-b39a-f3a23227203c",
"creditPaymentChannelID": "2ae5b30b-3fba-4f4b-a45f-c1d0c03b4144",
"value": 3000,
"units": "INR",
"status": "processed",
"additionalInformation": null,
"userID": "902375cc-4f72-428f-8db0-95a7baa69b51"
},
{
"transactionID": "7e96e7d6-2b18-4c9c-ba28-4a9ed8f12d10",
"eventID": "45409163-2c2f-4c06-91a1-5b08c5a05c18",
"processTime": "2023-01-01T00:00:00",
"systemTime": "2024-02-20T15:31:02",
"debitPaymentChannelID": "fb0fdb85-87ee-4af2-b39a-f3a23227203c",
"creditPaymentChannelID": "2ae5b30b-3fba-4f4b-a45f-c1d0c03b4144",
"value": 5000,
"units": "INR",
"status": "processed",
"additionalInformation": null,
"userID": "902375cc-4f72-428f-8db0-95a7baa69b51"
},
{
"transactionID": "6b453065-d29d-4046-ba65-7caea90dac91",
"eventID": "af4206fb-3cd9-40a9-b654-74fcfa6d118f",
"processTime": "2023-01-01T00:00:00",
"systemTime": "2024-02-20T15:35:45",
"debitPaymentChannelID": "fb0fdb85-87ee-4af2-b39a-f3a23227203c",
"creditPaymentChannelID": "2ae5b30b-3fba-4f4b-a45f-c1d0c03b4144",
"value": 2000,
"units": "INR",
"status": "processed",
"additionalInformation": null,
"userID": "902375cc-4f72-428f-8db0-95a7baa69b51"
}
]
}
-
400 bad request: If the request body is not in the correct format or if there are validation errors.
-
401 unauthorized: If the user is not authenticated or lacks the necessary permissions for retrieving the transactions.
-
5xx server error: If there is a server-side error while processing the request.
6.3.3. Methods
Description
This method fetches transactions based on filters provided in the TransactionFilterDto object.
Parameters
-
filterDto(Type: TransactionFilterDto, Source: Query Parameter): Filter parameters for fetching transactions. The filter criteria are specified in the TransactionFilterDto object. -
page(Type: int, Source: Query Parameter, Default Value: 0): Page number for pagination. -
size(Type: int, Source: Query Parameter, Default Value: 10): Number of transactions per page.
Returns
-
ResponseEntity<Response<List<Transactions>>>: Returns a response entity containing a list of transactions matching the specified filters.
Example usage
public ResponseEntity<Response<List<Transactions>>> getTransactions(
@Valid @ParameterObject TransactionFilterDto filterDto,
@RequestParam(name = "page", defaultValue = "0") int page,
@RequestParam(name = "size", defaultValue = "10") int size) {
// Create Pageable object
Pageable pageable = PageRequest.of(page, size); (1)
// Get transactions based on the provided filters and pagination
List<Transactions> finalTransactionList = transactionsService.getTransactions(filterDto, pageable); (2)
// Return the transactions with HTTP status OK
return new ResponseEntity<>(new Response<>(HttpStatus.OK.value(), Messages.SUCCESS, finalTransactionList),
HttpStatus.OK); (3)
}
| 1 | Pagination is applied to the list of transactions to improve performance and manage large data sets efficiently. |
| 2 | The method uses the provided filter parameters and pagination settings to retrieve transactions from the transactionsService. |
| 3 | Returns the list of transactions matching the specified filters. |
Exceptions
-
None explicitly thrown by this method. However, ensure to handle any potential errors gracefully and provide informative error messages.
6.3.4. Model classes
Description
The TransactionFilterDto class represents a data transfer object (DTO) used for filtering transactions based on various criteria.
-
transactionId-
Type: UUID
-
Description: Represents the unique identifier of the transaction.
-
Example: 18d57dd4-5898-40af-aa06-52eb7cd28ebb
-
-
userID-
Type: UUID
-
Description: Represents the unique identifier of the user associated with the transaction.
-
Example: 902375cc-4f72-428f-8db0-95a7baa69b51
-
-
eventID-
Type: UUID
-
Description: Represents the unique identifier of the event associated with the transaction.
-
Example: f771b128-c948-4dea-8359-6a43e1f4ef3f
-
-
processTime-
Type: String
-
Description: Represents the timestamp indicating the processing time of the transaction.
-
Example: 2023-01-01T00:00:00
-
-
debitPaymentChannelID-
Type: UUID
-
Description:Represents the unique identifier of the debit payment channel used in the transaction.
-
Example: 13c3861e-bcc6-48ed-9db1-91cb6825328a
-
-
creditPaymentChannelID-
Type: UUID
-
Description: Represents the unique identifier of the credit payment channel used in the transaction.
-
Example: fb0fdb85-87ee-4af2-b39a-f3a23227203c
-
-
status-
Type: String
-
Description: Represents the status of the transaction.
-
Example: processed
-