dscf-banking 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/MIT-LICENSE +0 -0
- data/README.md +0 -0
- data/Rakefile +0 -0
- data/app/controllers/dscf/banking/accounts_controller.rb +152 -0
- data/app/controllers/dscf/banking/application_controller.rb +0 -0
- data/app/controllers/dscf/banking/applications_controller.rb +113 -0
- data/app/controllers/dscf/banking/interest_configurations_controller.rb +0 -0
- data/app/controllers/dscf/banking/interest_rate_tiers_controller.rb +0 -0
- data/app/controllers/dscf/banking/interest_rate_types_controller.rb +0 -0
- data/app/controllers/dscf/banking/product_approvals_controller.rb +0 -0
- data/app/controllers/dscf/banking/product_categories_controller.rb +0 -0
- data/app/controllers/dscf/banking/transaction_types_controller.rb +27 -0
- data/app/controllers/dscf/banking/transactions_controller.rb +275 -0
- data/app/controllers/dscf/banking/virtual_account_products_controller.rb +0 -0
- data/app/jobs/dscf/banking/application_job.rb +0 -0
- data/app/mailers/dscf/banking/application_mailer.rb +0 -0
- data/app/models/concerns/dscf/banking/auditable.rb +0 -0
- data/app/models/dscf/banking/account.rb +110 -0
- data/app/models/dscf/banking/application.rb +70 -0
- data/app/models/dscf/banking/application_record.rb +0 -0
- data/app/models/dscf/banking/interest_configuration.rb +0 -0
- data/app/models/dscf/banking/interest_rate_tier.rb +0 -0
- data/app/models/dscf/banking/interest_rate_type.rb +0 -0
- data/app/models/dscf/banking/product_approval.rb +0 -0
- data/app/models/dscf/banking/product_audit_log.rb +0 -0
- data/app/models/dscf/banking/product_category.rb +0 -0
- data/app/models/dscf/banking/transaction.rb +68 -0
- data/app/models/dscf/banking/transaction_type.rb +20 -0
- data/app/models/dscf/banking/virtual_account_product.rb +0 -0
- data/app/serializers/dscf/banking/account_serializer.rb +11 -0
- data/app/serializers/dscf/banking/application_serializer.rb +16 -0
- data/app/serializers/dscf/banking/interest_configuration_serializer.rb +0 -0
- data/app/serializers/dscf/banking/interest_rate_tier_serializer.rb +0 -0
- data/app/serializers/dscf/banking/interest_rate_type_serializer.rb +0 -0
- data/app/serializers/dscf/banking/product_approval_serializer.rb +0 -0
- data/app/serializers/dscf/banking/product_category_serializer.rb +0 -0
- data/app/serializers/dscf/banking/transaction_serializer.rb +19 -0
- data/app/serializers/dscf/banking/transaction_type_serializer.rb +9 -0
- data/app/serializers/dscf/banking/virtual_account_product_serializer.rb +0 -0
- data/app/services/dscf/banking/account_creation_service.rb +53 -0
- data/app/services/dscf/banking/base_transaction_service.rb +99 -0
- data/app/services/dscf/banking/deposit_service.rb +97 -0
- data/app/services/dscf/banking/transfer_service.rb +78 -0
- data/app/services/dscf/banking/withdrawal_service.rb +100 -0
- data/config/routes.rb +27 -0
- data/db/migrate/20250830211002_create_dscf_banking_product_categories.rb +0 -0
- data/db/migrate/20250830211027_create_dscf_banking_interest_rate_types.rb +0 -0
- data/db/migrate/20250831063605_add_code_and_remove_fields_from_interest_rate_types.rb +0 -0
- data/db/migrate/20250831064917_create_dscf_banking_virtual_account_products.rb +0 -0
- data/db/migrate/20250831072627_create_dscf_banking_interest_configurations.rb +0 -0
- data/db/migrate/20250831080745_create_dscf_banking_interest_rate_tiers.rb +0 -0
- data/db/migrate/20250831082356_create_dscf_banking_product_approvals.rb +0 -0
- data/db/migrate/20250831083907_create_dscf_banking_product_audit_logs.rb +0 -0
- data/db/migrate/20250831084706_allow_null_virtual_account_product_id_in_product_audit_logs.rb +0 -0
- data/db/migrate/20250912193134_create_dscf_banking_applications.rb +20 -0
- data/db/migrate/20250912203527_create_dscf_banking_accounts.rb +21 -0
- data/db/migrate/20250919084147_add_account_type_to_accounts.rb +6 -0
- data/db/migrate/20250919084927_make_account_associations_optional.rb +6 -0
- data/db/migrate/20250919182831_create_dscf_banking_transaction_types.rb +14 -0
- data/db/migrate/20250919184220_create_dscf_banking_transactions.rb +21 -0
- data/db/seeds.rb +125 -0
- data/lib/dscf/banking/engine.rb +0 -0
- data/lib/dscf/banking/version.rb +1 -1
- data/lib/dscf/banking.rb +0 -0
- data/lib/tasks/dscf/banking_tasks.rake +0 -0
- data/spec/factories/dscf/banking/accounts.rb +79 -0
- data/spec/factories/dscf/banking/applications.rb +65 -0
- data/spec/factories/dscf/banking/interest_configurations.rb +0 -0
- data/spec/factories/dscf/banking/interest_rate_tiers.rb +0 -0
- data/spec/factories/dscf/banking/interest_rate_types.rb +0 -0
- data/spec/factories/dscf/banking/product_approvals.rb +0 -0
- data/spec/factories/dscf/banking/product_audit_logs.rb +0 -0
- data/spec/factories/dscf/banking/product_categories.rb +0 -0
- data/spec/factories/dscf/banking/transaction_types.rb +56 -0
- data/spec/factories/dscf/banking/transactions.rb +52 -0
- data/spec/factories/dscf/banking/virtual_account_products.rb +0 -0
- metadata +30 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0e4889491f1e8d88b8355eb069e349a28b386c19ceb0b24ad31c106568e9ac46
|
4
|
+
data.tar.gz: 9c9a3692230d26e79093a1fad8ad6efced44e35682155608cf7d172c3d843d16
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f691b1c9f323255accfc2bc3bd910b0eba87518fd2cdec4839f4f611a9338de25a65e5886bec16a8e5f13904d7223c34ab7b4f0f4a0f6d73905e19097386a441
|
7
|
+
data.tar.gz: 616b0ea1fbfcb0e939e424ebddaa4c5f23391bf29177df480dc064884e83c2e6bfdac14069b5e2411ed2cc5355a412ff5ecd4e160ba350e14cf759dcffc86099
|
data/MIT-LICENSE
CHANGED
File without changes
|
data/README.md
CHANGED
File without changes
|
data/Rakefile
CHANGED
File without changes
|
@@ -0,0 +1,152 @@
|
|
1
|
+
module Dscf::Banking
|
2
|
+
class AccountsController < ApplicationController
|
3
|
+
include Dscf::Core::Common
|
4
|
+
|
5
|
+
def activate
|
6
|
+
account = Dscf::Banking::Account.find(params[:id])
|
7
|
+
|
8
|
+
unless account.can_be_activated?
|
9
|
+
return render json: {
|
10
|
+
success: false,
|
11
|
+
error: "Failed to activate account",
|
12
|
+
errors: [ "Account cannot be activated from current status: #{account.status}" ]
|
13
|
+
}, status: :unprocessable_entity
|
14
|
+
end
|
15
|
+
|
16
|
+
if account.activate!
|
17
|
+
render json: {
|
18
|
+
success: true,
|
19
|
+
data: account_data(account),
|
20
|
+
message: "Account activated successfully"
|
21
|
+
}
|
22
|
+
else
|
23
|
+
render json: {
|
24
|
+
success: false,
|
25
|
+
error: "Failed to activate account",
|
26
|
+
errors: account.errors.full_messages
|
27
|
+
}, status: :unprocessable_entity
|
28
|
+
end
|
29
|
+
rescue ActiveRecord::RecordNotFound
|
30
|
+
render json: {
|
31
|
+
success: false,
|
32
|
+
error: "Account not found"
|
33
|
+
}, status: :not_found
|
34
|
+
end
|
35
|
+
|
36
|
+
def suspend
|
37
|
+
account = Dscf::Banking::Account.find(params[:id])
|
38
|
+
|
39
|
+
unless account.can_be_suspended?
|
40
|
+
return render json: {
|
41
|
+
success: false,
|
42
|
+
error: "Failed to suspend account",
|
43
|
+
errors: [ "Account cannot be suspended from current status: #{account.status}" ]
|
44
|
+
}, status: :unprocessable_entity
|
45
|
+
end
|
46
|
+
|
47
|
+
if account.suspend!
|
48
|
+
render json: {
|
49
|
+
success: true,
|
50
|
+
data: account_data(account),
|
51
|
+
message: "Account suspended successfully"
|
52
|
+
}
|
53
|
+
else
|
54
|
+
render json: {
|
55
|
+
success: false,
|
56
|
+
error: "Failed to suspend account",
|
57
|
+
errors: account.errors.full_messages
|
58
|
+
}, status: :unprocessable_entity
|
59
|
+
end
|
60
|
+
rescue ActiveRecord::RecordNotFound
|
61
|
+
render json: {
|
62
|
+
success: false,
|
63
|
+
error: "Account not found"
|
64
|
+
}, status: :not_found
|
65
|
+
end
|
66
|
+
|
67
|
+
def close
|
68
|
+
account = Dscf::Banking::Account.find(params[:id])
|
69
|
+
|
70
|
+
unless account.can_be_closed?
|
71
|
+
return render json: {
|
72
|
+
success: false,
|
73
|
+
error: "Failed to close account",
|
74
|
+
errors: [ "Account cannot be closed from current status: #{account.status}" ]
|
75
|
+
}, status: :unprocessable_entity
|
76
|
+
end
|
77
|
+
|
78
|
+
if account.close!
|
79
|
+
render json: {
|
80
|
+
success: true,
|
81
|
+
data: account_data(account),
|
82
|
+
message: "Account closed successfully"
|
83
|
+
}
|
84
|
+
else
|
85
|
+
render json: {
|
86
|
+
success: false,
|
87
|
+
error: "Failed to close account",
|
88
|
+
errors: account.errors.full_messages
|
89
|
+
}, status: :unprocessable_entity
|
90
|
+
end
|
91
|
+
rescue ActiveRecord::RecordNotFound
|
92
|
+
render json: {
|
93
|
+
success: false,
|
94
|
+
error: "Account not found"
|
95
|
+
}, status: :not_found
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
def account_data(account)
|
101
|
+
{
|
102
|
+
id: account.id,
|
103
|
+
account_number: account.account_number,
|
104
|
+
name: account.name,
|
105
|
+
status: account.status,
|
106
|
+
activation_date: account.activation_date,
|
107
|
+
closure_date: account.closure_date,
|
108
|
+
current_balance: account.current_balance,
|
109
|
+
available_balance: account.available_balance,
|
110
|
+
minimum_balance: account.minimum_balance,
|
111
|
+
currency: account.currency,
|
112
|
+
active: account.active,
|
113
|
+
application_id: account.application_id,
|
114
|
+
virtual_account_product_id: account.virtual_account_product_id,
|
115
|
+
created_at: account.created_at,
|
116
|
+
updated_at: account.updated_at
|
117
|
+
}
|
118
|
+
end
|
119
|
+
|
120
|
+
def model_params
|
121
|
+
params.require(:payload).permit(
|
122
|
+
:application_id,
|
123
|
+
:virtual_account_product_id,
|
124
|
+
:name,
|
125
|
+
:status,
|
126
|
+
:activation_date,
|
127
|
+
:closure_date,
|
128
|
+
:current_balance,
|
129
|
+
:available_balance,
|
130
|
+
:minimum_balance,
|
131
|
+
:currency,
|
132
|
+
:active,
|
133
|
+
account_properties: {}
|
134
|
+
)
|
135
|
+
end
|
136
|
+
|
137
|
+
def eager_loaded_associations
|
138
|
+
[ :application, :virtual_account_product ]
|
139
|
+
end
|
140
|
+
|
141
|
+
def allowed_order_columns
|
142
|
+
%w[id account_number name status activation_date closure_date current_balance created_at updated_at]
|
143
|
+
end
|
144
|
+
|
145
|
+
def default_serializer_includes
|
146
|
+
{
|
147
|
+
application: {},
|
148
|
+
virtual_account_product: {}
|
149
|
+
}
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
File without changes
|
@@ -0,0 +1,113 @@
|
|
1
|
+
module Dscf::Banking
|
2
|
+
class ApplicationsController < ApplicationController
|
3
|
+
include Dscf::Core::Common
|
4
|
+
|
5
|
+
def approve
|
6
|
+
application = Dscf::Banking::Application.find(params[:id])
|
7
|
+
|
8
|
+
unless application.can_be_approved_via_api?
|
9
|
+
return render json: {
|
10
|
+
success: false,
|
11
|
+
error: "Failed to approve application",
|
12
|
+
errors: [ "Application cannot be approved from current status: #{application.status}" ]
|
13
|
+
}, status: :unprocessable_entity
|
14
|
+
end
|
15
|
+
|
16
|
+
if application.approve!
|
17
|
+
render json: {
|
18
|
+
success: true,
|
19
|
+
data: application_data(application),
|
20
|
+
message: "Application approved successfully"
|
21
|
+
}
|
22
|
+
else
|
23
|
+
render json: {
|
24
|
+
success: false,
|
25
|
+
error: "Failed to approve application",
|
26
|
+
errors: application.errors.full_messages
|
27
|
+
}, status: :unprocessable_entity
|
28
|
+
end
|
29
|
+
rescue ActiveRecord::RecordNotFound
|
30
|
+
render json: {
|
31
|
+
success: false,
|
32
|
+
error: "Application not found"
|
33
|
+
}, status: :not_found
|
34
|
+
end
|
35
|
+
|
36
|
+
def reject
|
37
|
+
application = Dscf::Banking::Application.find(params[:id])
|
38
|
+
rejection_reason = params[:rejection_reason]
|
39
|
+
|
40
|
+
unless application.can_be_rejected_via_api?
|
41
|
+
return render json: {
|
42
|
+
success: false,
|
43
|
+
error: "Failed to reject application",
|
44
|
+
errors: [ "Application cannot be rejected from current status: #{application.status}" ]
|
45
|
+
}, status: :unprocessable_entity
|
46
|
+
end
|
47
|
+
|
48
|
+
if application.reject!(rejection_reason)
|
49
|
+
render json: {
|
50
|
+
success: true,
|
51
|
+
data: application_data(application),
|
52
|
+
message: "Application rejected successfully"
|
53
|
+
}
|
54
|
+
else
|
55
|
+
render json: {
|
56
|
+
success: false,
|
57
|
+
error: "Failed to reject application",
|
58
|
+
errors: application.errors.full_messages
|
59
|
+
}, status: :unprocessable_entity
|
60
|
+
end
|
61
|
+
rescue ActiveRecord::RecordNotFound
|
62
|
+
render json: {
|
63
|
+
success: false,
|
64
|
+
error: "Application not found"
|
65
|
+
}, status: :not_found
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def application_data(application)
|
71
|
+
{
|
72
|
+
id: application.id,
|
73
|
+
application_number: application.application_number,
|
74
|
+
applicant_type: application.applicant_type,
|
75
|
+
status: application.status,
|
76
|
+
user_id: application.user_id,
|
77
|
+
virtual_account_product_id: application.virtual_account_product_id,
|
78
|
+
form_data: application.form_data,
|
79
|
+
submitted_at: application.submitted_at,
|
80
|
+
completed_at: application.completed_at,
|
81
|
+
rejection_reason: application.rejection_reason,
|
82
|
+
created_at: application.created_at,
|
83
|
+
updated_at: application.updated_at
|
84
|
+
}
|
85
|
+
end
|
86
|
+
|
87
|
+
def model_params
|
88
|
+
params.require(:payload).permit(
|
89
|
+
:user_id,
|
90
|
+
:virtual_account_product_id,
|
91
|
+
:applicant_type,
|
92
|
+
:status,
|
93
|
+
form_data: {}
|
94
|
+
)
|
95
|
+
end
|
96
|
+
|
97
|
+
def eager_loaded_associations
|
98
|
+
[ :user, :virtual_account_product ]
|
99
|
+
end
|
100
|
+
|
101
|
+
def allowed_order_columns
|
102
|
+
%w[id application_number status submitted_at completed_at created_at updated_at]
|
103
|
+
end
|
104
|
+
|
105
|
+
def default_serializer_includes
|
106
|
+
{
|
107
|
+
user: {},
|
108
|
+
virtual_account_product: {},
|
109
|
+
account: {}
|
110
|
+
}
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Dscf::Banking
|
2
|
+
class TransactionTypesController < ApplicationController
|
3
|
+
include Dscf::Core::Common
|
4
|
+
|
5
|
+
private
|
6
|
+
|
7
|
+
def model_params
|
8
|
+
params.require(:payload).permit(
|
9
|
+
:code,
|
10
|
+
:name,
|
11
|
+
:description
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
def eager_loaded_associations
|
16
|
+
[]
|
17
|
+
end
|
18
|
+
|
19
|
+
def allowed_order_columns
|
20
|
+
%w[id code name created_at updated_at]
|
21
|
+
end
|
22
|
+
|
23
|
+
def default_serializer_includes
|
24
|
+
{}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,275 @@
|
|
1
|
+
module Dscf::Banking
|
2
|
+
class TransactionsController < ApplicationController
|
3
|
+
include Dscf::Core::Common
|
4
|
+
|
5
|
+
# Transfer money between accounts (from test cases)
|
6
|
+
def transfer
|
7
|
+
debit_account = Dscf::Banking::Account.find_by(account_number: transfer_params[:debit_account_number])
|
8
|
+
credit_account = Dscf::Banking::Account.find_by(account_number: transfer_params[:credit_account_number])
|
9
|
+
|
10
|
+
unless debit_account
|
11
|
+
return render json: {
|
12
|
+
success: false,
|
13
|
+
error: "Debit account not found",
|
14
|
+
errors: [ "Account with number #{transfer_params[:debit_account_number]} not found" ]
|
15
|
+
}, status: :not_found
|
16
|
+
end
|
17
|
+
|
18
|
+
unless credit_account
|
19
|
+
return render json: {
|
20
|
+
success: false,
|
21
|
+
error: "Credit account not found",
|
22
|
+
errors: [ "Account with number #{transfer_params[:credit_account_number]} not found" ]
|
23
|
+
}, status: :not_found
|
24
|
+
end
|
25
|
+
|
26
|
+
result = Dscf::Banking::TransferService.new(
|
27
|
+
debit_account: debit_account,
|
28
|
+
credit_account: credit_account,
|
29
|
+
amount: transfer_params[:amount],
|
30
|
+
description: transfer_params[:description] || "Transfer between accounts",
|
31
|
+
transaction_type_code: transfer_params[:transaction_type_code] || "TRANSFER"
|
32
|
+
).execute
|
33
|
+
|
34
|
+
if result.success?
|
35
|
+
render json: {
|
36
|
+
success: true,
|
37
|
+
data: transaction_data(result.transaction),
|
38
|
+
message: "Transfer completed successfully"
|
39
|
+
}
|
40
|
+
else
|
41
|
+
render json: {
|
42
|
+
success: false,
|
43
|
+
error: "Transfer failed",
|
44
|
+
errors: result.errors
|
45
|
+
}, status: :unprocessable_entity
|
46
|
+
end
|
47
|
+
rescue StandardError => e
|
48
|
+
render json: {
|
49
|
+
success: false,
|
50
|
+
error: "Transfer failed",
|
51
|
+
errors: [ e.message ]
|
52
|
+
}, status: :internal_server_error
|
53
|
+
end
|
54
|
+
|
55
|
+
# Deposit money to account (from mobile banking - Abole)
|
56
|
+
def deposit
|
57
|
+
account = Dscf::Banking::Account.find_by(account_number: deposit_params[:account_number])
|
58
|
+
|
59
|
+
unless account
|
60
|
+
return render json: {
|
61
|
+
success: false,
|
62
|
+
error: "Account not found",
|
63
|
+
errors: [ "Account with number #{deposit_params[:account_number]} not found" ]
|
64
|
+
}, status: :not_found
|
65
|
+
end
|
66
|
+
|
67
|
+
result = Dscf::Banking::DepositService.new(
|
68
|
+
account: account,
|
69
|
+
amount: deposit_params[:amount],
|
70
|
+
description: deposit_params[:description] || "Deposit to account",
|
71
|
+
transaction_type_code: deposit_params[:transaction_type_code] || "DEPOSIT"
|
72
|
+
).execute
|
73
|
+
|
74
|
+
if result.success?
|
75
|
+
render json: {
|
76
|
+
success: true,
|
77
|
+
data: transaction_data(result.transaction),
|
78
|
+
message: "Deposit completed successfully"
|
79
|
+
}
|
80
|
+
else
|
81
|
+
render json: {
|
82
|
+
success: false,
|
83
|
+
error: "Deposit failed",
|
84
|
+
errors: result.errors
|
85
|
+
}, status: :unprocessable_entity
|
86
|
+
end
|
87
|
+
rescue StandardError => e
|
88
|
+
render json: {
|
89
|
+
success: false,
|
90
|
+
error: "Deposit failed",
|
91
|
+
errors: [ e.message ]
|
92
|
+
}, status: :internal_server_error
|
93
|
+
end
|
94
|
+
|
95
|
+
# Withdraw money from account
|
96
|
+
def withdrawal
|
97
|
+
account = Dscf::Banking::Account.find_by(account_number: withdrawal_params[:account_number])
|
98
|
+
|
99
|
+
unless account
|
100
|
+
return render json: {
|
101
|
+
success: false,
|
102
|
+
error: "Account not found",
|
103
|
+
errors: [ "Account with number #{withdrawal_params[:account_number]} not found" ]
|
104
|
+
}, status: :not_found
|
105
|
+
end
|
106
|
+
|
107
|
+
result = Dscf::Banking::WithdrawalService.new(
|
108
|
+
account: account,
|
109
|
+
amount: withdrawal_params[:amount],
|
110
|
+
description: withdrawal_params[:description] || "Withdrawal from account",
|
111
|
+
transaction_type_code: withdrawal_params[:transaction_type_code] || "WITHDRAWAL"
|
112
|
+
).execute
|
113
|
+
|
114
|
+
if result.success?
|
115
|
+
render json: {
|
116
|
+
success: true,
|
117
|
+
data: transaction_data(result.transaction),
|
118
|
+
message: "Withdrawal completed successfully"
|
119
|
+
}
|
120
|
+
else
|
121
|
+
render json: {
|
122
|
+
success: false,
|
123
|
+
error: "Withdrawal failed",
|
124
|
+
errors: result.errors
|
125
|
+
}, status: :unprocessable_entity
|
126
|
+
end
|
127
|
+
rescue StandardError => e
|
128
|
+
render json: {
|
129
|
+
success: false,
|
130
|
+
error: "Withdrawal failed",
|
131
|
+
errors: [ e.message ]
|
132
|
+
}, status: :internal_server_error
|
133
|
+
end
|
134
|
+
|
135
|
+
# Cancel a transaction
|
136
|
+
def cancel
|
137
|
+
transaction = Dscf::Banking::Transaction.find(params[:id])
|
138
|
+
|
139
|
+
unless transaction.status == "pending"
|
140
|
+
return render json: {
|
141
|
+
success: false,
|
142
|
+
error: "Cannot cancel transaction",
|
143
|
+
errors: [ "Only pending transactions can be cancelled" ]
|
144
|
+
}, status: :unprocessable_entity
|
145
|
+
end
|
146
|
+
|
147
|
+
if transaction.update(status: :cancelled)
|
148
|
+
render json: {
|
149
|
+
success: true,
|
150
|
+
data: transaction_data(transaction),
|
151
|
+
message: "Transaction cancelled successfully"
|
152
|
+
}
|
153
|
+
else
|
154
|
+
render json: {
|
155
|
+
success: false,
|
156
|
+
error: "Failed to cancel transaction",
|
157
|
+
errors: transaction.errors.full_messages
|
158
|
+
}, status: :unprocessable_entity
|
159
|
+
end
|
160
|
+
rescue ActiveRecord::RecordNotFound
|
161
|
+
render json: {
|
162
|
+
success: false,
|
163
|
+
error: "Transaction not found"
|
164
|
+
}, status: :not_found
|
165
|
+
end
|
166
|
+
|
167
|
+
# Get transaction details with related account information
|
168
|
+
def details
|
169
|
+
transaction = Dscf::Banking::Transaction.includes(:account, :debit_account, :credit_account, :transaction_type).find(params[:id])
|
170
|
+
|
171
|
+
render json: {
|
172
|
+
success: true,
|
173
|
+
data: transaction_data_with_details(transaction)
|
174
|
+
}
|
175
|
+
rescue ActiveRecord::RecordNotFound
|
176
|
+
render json: {
|
177
|
+
success: false,
|
178
|
+
error: "Transaction not found"
|
179
|
+
}, status: :not_found
|
180
|
+
end
|
181
|
+
|
182
|
+
private
|
183
|
+
|
184
|
+
def transfer_params
|
185
|
+
params.require(:transfer).permit(:debit_account_number, :credit_account_number, :amount, :description, :transaction_type_code)
|
186
|
+
end
|
187
|
+
|
188
|
+
def deposit_params
|
189
|
+
params.require(:deposit).permit(:account_number, :amount, :description, :transaction_type_code)
|
190
|
+
end
|
191
|
+
|
192
|
+
def withdrawal_params
|
193
|
+
params.require(:withdrawal).permit(:account_number, :amount, :description, :transaction_type_code)
|
194
|
+
end
|
195
|
+
|
196
|
+
def transaction_data(transaction)
|
197
|
+
{
|
198
|
+
id: transaction.id,
|
199
|
+
reference_number: transaction.reference_number,
|
200
|
+
amount: transaction.amount.to_f,
|
201
|
+
currency: transaction.currency,
|
202
|
+
description: transaction.description,
|
203
|
+
status: transaction.status,
|
204
|
+
account_id: transaction.account_id,
|
205
|
+
debit_account_id: transaction.debit_account_id,
|
206
|
+
credit_account_id: transaction.credit_account_id,
|
207
|
+
transaction_type_id: transaction.transaction_type_id,
|
208
|
+
created_at: transaction.created_at,
|
209
|
+
updated_at: transaction.updated_at
|
210
|
+
}
|
211
|
+
end
|
212
|
+
|
213
|
+
def transaction_data_with_details(transaction)
|
214
|
+
{
|
215
|
+
id: transaction.id,
|
216
|
+
reference_number: transaction.reference_number,
|
217
|
+
amount: transaction.amount.to_f,
|
218
|
+
currency: transaction.currency,
|
219
|
+
description: transaction.description,
|
220
|
+
status: transaction.status,
|
221
|
+
account: account_summary(transaction.account),
|
222
|
+
debit_account: account_summary(transaction.debit_account),
|
223
|
+
credit_account: account_summary(transaction.credit_account),
|
224
|
+
transaction_type: {
|
225
|
+
id: transaction.transaction_type.id,
|
226
|
+
code: transaction.transaction_type.code,
|
227
|
+
name: transaction.transaction_type.name
|
228
|
+
},
|
229
|
+
created_at: transaction.created_at,
|
230
|
+
updated_at: transaction.updated_at
|
231
|
+
}
|
232
|
+
end
|
233
|
+
|
234
|
+
def account_summary(account)
|
235
|
+
return nil unless account
|
236
|
+
{
|
237
|
+
id: account.id,
|
238
|
+
account_number: account.account_number,
|
239
|
+
name: account.name,
|
240
|
+
currency: account.currency,
|
241
|
+
current_balance: account.current_balance
|
242
|
+
}
|
243
|
+
end
|
244
|
+
|
245
|
+
def model_params
|
246
|
+
params.require(:payload).permit(
|
247
|
+
:account_id,
|
248
|
+
:transaction_type_id,
|
249
|
+
:debit_account_id,
|
250
|
+
:credit_account_id,
|
251
|
+
:amount,
|
252
|
+
:currency,
|
253
|
+
:description,
|
254
|
+
:status
|
255
|
+
)
|
256
|
+
end
|
257
|
+
|
258
|
+
def eager_loaded_associations
|
259
|
+
[ :account, :transaction_type, :debit_account, :credit_account ]
|
260
|
+
end
|
261
|
+
|
262
|
+
def allowed_order_columns
|
263
|
+
%w[id reference_number amount currency status created_at updated_at]
|
264
|
+
end
|
265
|
+
|
266
|
+
def default_serializer_includes
|
267
|
+
{
|
268
|
+
account: {},
|
269
|
+
transaction_type: {},
|
270
|
+
debit_account: {},
|
271
|
+
credit_account: {}
|
272
|
+
}
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|